Developer · API v1

API Document Guide

Complete documentation to integrate FIREPAY Gateway deposits, withdrawals, statements, and webhooks for Bangladesh currency (BDT).

Version v1Format JSONWallets: 4Base {API_HOST}/v1

Confidential — for integrating merchant developers · Last updated July 2026

Technical API payloads, field names, and code samples remain in English for integration accuracy.

01

Overview

FIREPAY Gateway lets your platform accept mobile-wallet deposits and send withdrawals to customer wallet numbers in Bangladesh (BDT).

Deposits

Your server creates a deposit via API → customer is redirected to a hosted payment page → customer cashes out to an agent wallet and submits their TrxID → FIREPAY automatically verifies and approves the deposit

Withdrawals

Your server creates a withdrawal via API (status pending) → admin releases to an agent (processing) → agent approves or rejects → every status change is sent to your webhook

Statements

Your server requests a date-range summary (Opening, Deposit, Withdraw, Fee, Settlement, Adjustment, Closing) — scoped to your API key only

Integration

Server-to-server REST API authenticated with an API key

02

Base URLs

Your FIREPAY administrator provides the production API_HOST and PAYMENT_HOST for your environment. Do not hardcode hosts from public materials.

Production

Commercial API

https://{API_HOST}/v1

Payment page

https://{PAYMENT_HOST}

Local dev

Commercial API

http://localhost:3001/v1

Payment page

http://localhost:5173

All commercial endpoints are prefixed with /v1. Payment pages are served at /deposit/{deposit_id}?token=... on the payment base URL.

03

Fees

amount

Gross wallet move (what the player paid or received)

fee_percent

Platform fee percent for this client

fee_amount

FIREPAY's share

client_amount

What settles to you (amount − fee_amount)

04

Authentication

Every commercial API request must include a valid client API key.

Obtaining an API key

Ask your FIREPAY administrator for:

  • API key
  • Default webhook URL

Keys are created in the backoffice Clients page. The full API key is shown once at creation — store it securely on your server. Clients do not generate their own keys.

Key format: fp_{prefix}_{secret} (example: fp_a1b2c3d4_xK9mN2pQ7rS4tU8vW1yZ3)

Request headers

Authorization

Bearer fp_xxxxxxxx

X-API-Key

Alternative to Authorization — pass the raw key

Content-Type

application/json

create-deposit.sh
SHELL
curl -X POST "https://{API_HOST}/v1/deposits" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 500,
"wallet": "bkash",
"order_id": "ORD-1001",
"return_url": "https://yoursite.com/payment/return"
}'

Security

Never expose API keys in client-side code, mobile apps, or public repositories. Call FIREPAY only from your backend.
05

Response format

Success

success.json
JSON
{
"success": true,
"data": { }
}

HTTP status 200 for reads, 201 for creates.

Error

error.json
JSON
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "order_id and return_url are required"
}
}
06

IDs & order references

Understanding these values prevents broken reconciliation after payment.

order_id (request)

Who creates it

You

Example

ORD-1001

Use for

Your unique order reference (must be unique per client)

external_order_id

Who creates it

FIREPAY (echo)

Example

ORD-1001

Use for

Same as your request order_id — match webhooks & return URL to this

order_id (response)

Who creates it

FIREPAY

Example

K7M9P2Q4R5

Use for

Internal FIREPAY order number (10 chars)

deposit_id

Who creates it

FIREPAY

Example

DPABCD1234

Use for

Public deposit ID — DP + 8 characters

withdrawal_id

Who creates it

FIREPAY

Example

WDXYZ98765

Use for

Public withdrawal ID — WD + 8 characters

Rules for integrators

  • Return URL query param order_id is always your original reference (external_order_id).
  • In JSON responses and webhooks, prefer external_order_id when matching your shop order.
  • Credit the player only after webhook / GET confirmation — never from the browser redirect alone.
07

Quick start

  1. Create deposit — POST /v1/deposits with amount, wallet, unique order_id, and return_url.
  2. Redirect customer — Send the user to payment_url from the response.
  3. Customer pays — They cash out to the agent wallet number shown on the page and submit their TrxID.
  4. Auto verification — FIREPAY automatically verifies the payment and updates the deposit status.
  5. Confirm on your server — Trust webhooks (and/or poll GET /v1/deposits/:depositId). Return URL is a UX redirect only — always verify server-side before crediting the player.
sequence.txt
TEXT
Your server FIREPAY Customer
| | |
|-- POST /v1/deposits ---->| |
|<-- payment_url ----------| |
| | |
|-- redirect customer ---------------------------->|
| |<-- cash out + TrxID --|
| |-- verify + approve ---|
|<-- webhook deposit.approved |
| |-- redirect return_url >|
08

Deposit flow

End-to-end deposit lifecycle between your merchant system and FIREPAY.

  1. Merchant submits deposit — POST /v1/deposits
  2. FIREPAY validates the request
  3. FIREPAY returns payment_url + agent_number with status pending
  4. Merchant processes the response
  5. Merchant redirects the customer to payment_url
  6. Hosted page: customer pays + submits TrxID → Cash Out → automatic verification
  7. FIREPAY approves / rejects / expires
  8. Webhook callback → merchant credits if approved
  9. return_url is UX only — process result server-side

Critical

Never credit from return_url alone — wait for deposit.approved webhook or GET status.
09

Wallets API

GET/v1/wallets
API key required

Returns branding for bKash / Nagad / Rocket / Upay plus the global deposit countdown minutes.

wallets.response.json
JSON
{
"success": true,
"data": {
"deposit_expiry_minutes": 15,
"wallets": [
{
"wallet": "bkash",
"header_color": "#E2136E",
"accent_color": "#E2136E",
"logo_path": "uploads/wallet-logos/bkash.png",
"logo_url": "https://{CDN_HOST}/uploads/wallet-logos/bkash.png"
},
{
"wallet": "nagad",
"header_color": "#F6921E",
"accent_color": "#F6921E",
"logo_url": "https://{CDN_HOST}/uploads/wallet-logos/nagad.png"
},
{
"wallet": "rocket",
"header_color": "#6B2D8B",
"accent_color": "#00A651",
"logo_url": "https://{CDN_HOST}/uploads/wallet-logos/rocket.png"
},
{
"wallet": "upay",
"header_color": "#E31837",
"accent_color": "#E31837",
"logo_url": "https://{CDN_HOST}/uploads/wallet-logos/upay.png"
}
]
}
}
10

Deposits API

Create deposit

POST/v1/deposits
API key required

amount

Type

number

Required

Yes

Description

Deposit amount in BDT (e.g. 500 or 500.00)

wallet

Type

string

Required

Yes

Description

bkash | nagad | rocket | upay

order_id

Type

string

Required

Yes

Description

Your unique order reference (unique per client)

return_url

Type

string

Required

Yes

Description

HTTPS URL — redirect customer after payment

callback_url

Type

string

Required

No

Description

Override webhook URL for this deposit only

create-deposit.response.json
JSON
{
"success": true,
"data": {
"deposit_id": "DPABCD1234",
"order_id": "K7M9P2Q4R5",
"external_order_id": "ORD-1001",
"status": "pending",
"amount": 500,
"fee_percent": 5,
"fee_amount": 25,
"client_amount": 475,
"wallet": "bkash",
"wallet_label": "bKash",
"wallet_logo_url": "https://{CDN_HOST}/uploads/wallet-logos/bkash.png",
"wallet_header_color": "#E2136E",
"wallet_accent_color": "#E2136E",
"agent_number": "01623072275",
"payment_url": "https://{PAYMENT_HOST}/deposit/DPABCD1234?token=...",
"expires_at": "2026-07-14T15:30:00.000Z",
"deposit_expiry_minutes": 15
}
}

deposit_id

Public FIREPAY deposit ID (DP + 8 chars)

order_id

Internal FIREPAY order number

external_order_id

Your original order_id from the request

agent_number

Wallet number the customer must cash out to

payment_url

Hosted payment page — redirect the customer here

expires_at

Deposit session expiry (default 15 minutes, configurable)

client_amount

Amount that settles to you after fee

Get deposit status

GET/v1/deposits/:depositId
API key required

Poll this if the customer closes the browser before redirect, or to confirm webhook data.

get-deposit.response.json
JSON
{
"success": true,
"data": {
"deposit_id": "DPABCD1234",
"order_id": "K7M9P2Q4R5",
"external_order_id": "ORD-1001",
"status": "approved",
"amount": 500,
"fee_percent": 5,
"fee_amount": 25,
"client_amount": 475,
"wallet": "bkash",
"wallet_label": "bKash",
"agent_number": "01623072275",
"customer_trx_id": "DFC78W6RL3",
"return_url": "https://yoursite.com/payment/return",
"expires_at": "2026-07-14T15:30:00.000Z",
"approved_at": "2026-07-14T15:12:00.000Z",
"created_at": "2026-07-14T15:00:00.000Z"
}
}

Submit TrxID (server-side, optional)

POST/v1/deposits/:depositId/submit-trx
Not required (uses page token)

Rate limit: 10 requests per minute per IP. Normally the customer submits TrxID on the hosted payment page. This endpoint is available if you build a custom payment UI.

trx_id

Type

string

Required

Yes

Description

Customer transaction ID from their wallet app

token

Type

string

Required

Yes

Description

Page token from payment_url

submit-trx.response.json
JSON
{
"success": true,
"data": {
"deposit_id": "DPABCD1234",
"status": "awaiting_sms",
"message": "Transaction ID submitted. Awaiting confirmation.",
"verification_expires_at": "2026-07-14T15:15:00.000Z"
}
}

If payment is already verified, status may be approved immediately with a return_url in the response (including your original order_id as the query param).

Hosted payment page

Redirect the customer to payment_url. The page is wallet-branded (bKash / Nagad / Rocket / Upay) and shows the assigned agent cash-out number.

1

Customer sees amount, agent wallet number, and deposit timer

2

Customer sends money from their wallet app (Cash Out / Send Money)

3

Customer enters TrxID and taps Submit

4

If deposit timer hits 00:00 → redirect with status=expired

5

Verification wait while payment is confirmed

6

On approval → status=approved; verify timeout → status=rejected

Return URL query parameters

FIREPAY appends these parameters when redirecting the customer:

status

Example

approved

Description

approved | review | fraud | rejected | expired

deposit_id

Example

DPABCD1234

Description

FIREPAY deposit ID

order_id

Example

ORD-1001

Description

Your original order_id (external_order_id)

return-url.example.txt
TEXT
https://yoursite.com/payment/return?status=approved&deposit_id=DPABCD1234&order_id=ORD-1001

Do not credit from return URL

Do not credit the player from the return URL alone. Wait for deposit.approved webhook or confirm with GET /v1/deposits/:depositId.
11

Withdrawal flow

Create → pending (backoffice hold) → admin processing → agent result → webhooks.

  1. Merchant submits withdrawal — POST /v1/withdrawals
  2. FIREPAY validates the request
  3. Status pending — held in backoffice; webhook: withdrawal.pending
  4. Merchant processes the response
  5. Admin sets processing (agent assigned); webhook: withdrawal.processing
  6. Agent/admin approved / rejected — callback result
  7. Merchant completes or refunds

Optional: poll GET /v1/withdrawals/:id if webhook is delayed.

12

Withdrawals API

Request a payout to a customer mobile-wallet number. Flow: create → status pending (held in backoffice, no agent yet) → admin sets processing (agent assigned) → agent approves or rejects. FIREPAY notifies your webhook on every status change.

Create withdrawal

POST/v1/withdrawals
API key required

amount

Type

number

Required

Yes

Description

Withdrawal amount in BDT

wallet

Type

string

Required

Yes

Description

bkash | nagad | rocket | upay

customer_phone

Type

string

Required

Yes

Description

Recipient wallet number (BD mobile, e.g. 017XXXXXXXX)

order_id

Type

string

Required

Yes

Description

Your unique withdrawal reference (unique per client)

callback_url

Type

string

Required

No

Description

Override webhook URL for this withdrawal only

create-withdrawal.response.json
JSON
{
"success": true,
"data": {
"withdrawal_id": "WDXYZ98765",
"order_id": "N4P6Q8R0S1",
"external_order_id": "WDR-9001",
"status": "pending",
"amount": 1000,
"fee_percent": 2,
"fee_amount": 20,
"client_amount": 980,
"wallet": "bkash",
"wallet_label": "bKash",
"customer_phone": "01712345678",
"assigned_agent_id": null,
"auto_withdraw": false,
"created_at": "2026-07-14T15:00:00.000Z"
}
}

On create, FIREPAY also sends withdrawal.pending to your webhook. Withdrawals do not auto-expire while pending or processing.

Get withdrawal status

GET/v1/withdrawals/:withdrawalId
API key required
get-withdrawal.response.json
JSON
{
"success": true,
"data": {
"withdrawal_id": "WDXYZ98765",
"order_id": "N4P6Q8R0S1",
"external_order_id": "WDR-9001",
"status": "approved",
"amount": 1000,
"fee_percent": 2,
"fee_amount": 20,
"client_amount": 980,
"wallet": "bkash",
"wallet_label": "bKash",
"customer_phone": "01712345678",
"agent_trx_id": "8XJ2K9LM",
"reject_remarks": null,
"expires_at": null,
"approved_at": "2026-07-14T15:08:00.000Z",
"rejected_at": null,
"created_at": "2026-07-14T15:00:00.000Z"
}
}
13

Statements API

Fetch your Client Summary totals for a date range (same numbers as the FIREPAY Report → Client Summary page).

Security & timezone

Results are always limited to the client that owns the API key. You cannot request another client's data. Calendar days use Asia/Dhaka.

Get statement summary

GET/v1/statements/summary
API key required

from_date

Type

string

Required

Yes

Description

Start date YYYY-MM-DD (inclusive)

to_date

Type

string

Required

Yes

Description

End date YYYY-MM-DD (inclusive)

statements.response.json
JSON
{
"success": true,
"data": {
"from_date": "2026-07-28",
"to_date": "2026-07-28",
"timezone": "Asia/Dhaka",
"currency": "BDT",
"opening": 3338.8,
"deposit": 0,
"withdraw": 1100,
"fee": 9.9,
"settlement": 0,
"adjustment": 0,
"closing": 2248.7
}
}

opening

Opening balance at the start of from_date

deposit

Approved deposits in the period (gross)

withdraw

Approved withdrawals in the period (gross)

fee

Total fees in the period (deposit + withdraw)

settlement

Client settlements / top-ups net in the period

adjustment

Client adjustments net in the period

closing

Closing balance at the end of to_date

statements.sh
SHELL
curl -G "https://{API_HOST}/v1/statements/summary" \
-H "Authorization: Bearer YOUR_API_KEY" \
--data-urlencode "from_date=2026-07-28" \
--data-urlencode "to_date=2026-07-28"
14

Webhooks

Ask your administrator to set a default webhook URL on your client account (backoffice → Clients → Edit client). FIREPAY sends POST requests with JSON event payloads for both deposits and withdrawals.

Delivery

Method

POST

Content-Type

application/json

User-Agent

FIREPAY-Webhook/1.0

Timeout

10 seconds

Retries

Up to 3

Respond with HTTP 200 quickly. Handle events idempotently (same deposit_id / withdrawal_id may be delivered more than once).

Per-transaction override

Pass optional callback_url when creating a deposit or withdrawal to override the client default webhook URL for that transaction only.

Events

deposit.approved

When fired

Payment confirmed

Action on your side

Credit the player

deposit.review

When fired

Held for review (e.g. balance chain)

Action on your side

Do not credit yet

deposit.fraud

When fired

Fraud signal

Action on your side

Do not credit

deposit.rejected

When fired

Rejected (verify timeout / admin)

Action on your side

Do not credit / mark failed

withdrawal.pending

When fired

Withdrawal created (held in backoffice)

Action on your side

Record as pending on your side

withdrawal.processing

When fired

Admin released to an agent

Action on your side

Update status — payout in progress

withdrawal.approved

When fired

Agent (or admin) completed payout

Action on your side

Complete withdrawal on your side

withdrawal.rejected

When fired

Agent (or admin) rejected the withdrawal

Action on your side

Mark failed / refund flow

withdrawal.expired

When fired

Marked expired by admin (rare)

Action on your side

Mark failed / refund flow

Payload structure

webhook.envelope.json
JSON
{
"event": "deposit.approved",
"timestamp": "2026-07-14T15:12:00.000Z",
"data": { }
}
webhook.deposit.approved.json
JSON
{
"event": "deposit.approved",
"timestamp": "2026-07-14T15:12:00.000Z",
"data": {
"deposit_id": "DPABCD1234",
"order_id": "K7M9P2Q4R5",
"external_order_id": "ORD-1001",
"amount": 500,
"fee_percent": 5,
"fee_amount": 25,
"client_amount": 475,
"wallet": "bkash",
"trx_id": "DFC78W6RL3",
"approved_at": "2026-07-14T15:12:00.000Z"
}
}
webhook.deposit.review.json
JSON
{
"event": "deposit.review",
"timestamp": "2026-07-14T15:12:00.000Z",
"data": {
"deposit_id": "DPABCD1234",
"order_id": "K7M9P2Q4R5",
"external_order_id": "ORD-1001",
"amount": 500,
"fee_percent": 5,
"fee_amount": 25,
"client_amount": 475,
"wallet": "nagad",
"trx_id": "75NRHGZ1",
"status": "review",
"reason": "Balance chain mismatch — manual review required",
"at": "2026-07-14T15:12:00.000Z"
}
}
webhook.deposit.rejected.json
JSON
{
"event": "deposit.rejected",
"timestamp": "2026-07-14T15:18:00.000Z",
"data": {
"deposit_id": "DPABCD1234",
"order_id": "K7M9P2Q4R5",
"external_order_id": "ORD-1001",
"amount": 500,
"fee_percent": 5,
"fee_amount": 25,
"client_amount": 475,
"wallet": "bkash",
"trx_id": "DFC78W6RL3",
"remarks": null,
"rejected_at": "2026-07-14T15:18:00.000Z"
}
}
webhook.withdrawal.pending.json
JSON
{
"event": "withdrawal.pending",
"timestamp": "2026-07-14T15:00:00.000Z",
"data": {
"withdrawal_id": "WDXYZ98765",
"order_id": "N4P6Q8R0S1",
"external_order_id": "WDR-9001",
"amount": 1000,
"fee_percent": 2,
"fee_amount": 20,
"client_amount": 980,
"wallet": "bkash",
"customer_phone": "01712345678",
"status": "pending",
"created_at": "2026-07-14T15:00:00.000Z"
}
}
webhook.withdrawal.processing.json
JSON
{
"event": "withdrawal.processing",
"timestamp": "2026-07-14T15:05:00.000Z",
"data": {
"withdrawal_id": "WDXYZ98765",
"order_id": "N4P6Q8R0S1",
"external_order_id": "WDR-9001",
"amount": 1000,
"fee_percent": 2,
"fee_amount": 20,
"client_amount": 980,
"wallet": "bkash",
"customer_phone": "01712345678",
"status": "processing",
"at": "2026-07-14T15:05:00.000Z"
}
}
webhook.withdrawal.approved.json
JSON
{
"event": "withdrawal.approved",
"timestamp": "2026-07-14T15:08:00.000Z",
"data": {
"withdrawal_id": "WDXYZ98765",
"order_id": "N4P6Q8R0S1",
"external_order_id": "WDR-9001",
"amount": 1000,
"fee_percent": 2,
"fee_amount": 20,
"client_amount": 980,
"wallet": "bkash",
"customer_phone": "01712345678",
"status": "approved",
"trx_id": "8XJ2K9LM",
"approved_at": "2026-07-14T15:08:00.000Z"
}
}
webhook.withdrawal.rejected.json
JSON
{
"event": "withdrawal.rejected",
"timestamp": "2026-07-14T15:18:00.000Z",
"data": {
"withdrawal_id": "WDXYZ98765",
"order_id": "N4P6Q8R0S1",
"external_order_id": "WDR-9001",
"amount": 1000,
"fee_percent": 2,
"fee_amount": 20,
"client_amount": 980,
"wallet": "bkash",
"customer_phone": "01712345678",
"status": "rejected",
"remarks": "Invalid account number",
"rejected_at": "2026-07-14T15:18:00.000Z"
}
}
webhook.withdrawal.expired.json
JSON
{
"event": "withdrawal.expired",
"timestamp": "2026-07-14T16:00:00.000Z",
"data": {
"withdrawal_id": "WDXYZ98765",
"order_id": "N4P6Q8R0S1",
"external_order_id": "WDR-9001",
"amount": 1000,
"fee_percent": 2,
"fee_amount": 20,
"client_amount": 980,
"wallet": "bkash",
"customer_phone": "01712345678",
"status": "expired",
"expired_at": "2026-07-14T16:00:00.000Z"
}
}
15

Status reference

Deposit statuses

pending

Created; customer has not submitted TrxID yet

awaiting_trx

Intermediate / transitional state

awaiting_sms

TrxID submitted; awaiting payment confirmation

approved

Payment confirmed — credit the customer

review

Held for manual review — do not credit yet

fraud

Fraud signal — do not credit

rejected

Verification failed, timed out, or admin rejected

expired

Deposit session timed out

Withdrawal statuses

pending

Created; held in backoffice until admin releases (webhook: withdrawal.pending)

processing

Assigned to an agent for payout (webhook: withdrawal.processing)

approved

Agent/admin completed payout — complete on your side (webhook: withdrawal.approved)

rejected

Agent/admin rejected (see reject_remarks / webhook remarks)

expired

Marked expired by admin (rare; no auto-expiry on pending/processing)

16

Error codes

401

Code

UNAUTHORIZED

Description

Missing or invalid API key

403

Code

CLIENT_INACTIVE

Description

Client account disabled

403

Code

FORBIDDEN

Description

Invalid payment page token

400

Code

VALIDATION_ERROR

Description

Missing or invalid request fields

400

Code

INVALID_AMOUNT

Description

Amount must be positive

400

Code

INVALID_WALLET

Description

Wallet must be bkash, nagad, rocket, or upay

400

Code

INVALID_PHONE

Description

customer_phone is not a valid BD mobile

400

Code

INVALID_TRX_ID

Description

Transaction ID format invalid

409

Code

DUPLICATE_ORDER

Description

order_id already used for this client

409

Code

DUPLICATE_TRX_ID

Description

TrxID already used for this wallet

409

Code

ALREADY_PROCESSED

Description

Withdrawal already approved or rejected

404

Code

NOT_FOUND

Description

Deposit or withdrawal not found

410

Code

EXPIRED

Description

Deposit or withdrawal window expired

17

Code examples

Node.js — create deposit, redirect, and verify

deposit.js
JS
const API_KEY = process.env.FIREPAY_API_KEY;
const BASE = process.env.FIREPAY_API_BASE; // https://{API_HOST}/v1
async function createDeposit({ amount, wallet, orderId, returnUrl }) {
const res = await fetch(`${BASE}/deposits`, {
method: 'POST',
headers: {
Authorization: `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
amount,
wallet,
order_id: orderId,
return_url: returnUrl,
}),
});
const json = await res.json();
if (!json.success) throw new Error(json.error?.message);
return json.data; // payment_url, deposit_id, external_order_id
}
async function getDeposit(depositId) {
const res = await fetch(`${BASE}/deposits/${depositId}`, {
headers: { Authorization: `Bearer ${API_KEY}` },
});
const json = await res.json();
if (!json.success) throw new Error(json.error?.message);
return json.data;
}
// Checkout:
app.post('/checkout/deposit', async (req, res) => {
const deposit = await createDeposit({
amount: req.body.amount,
wallet: 'bkash',
orderId: `ORD-${Date.now()}`,
returnUrl: 'https://yoursite.com/payment/return',
});
res.redirect(deposit.payment_url);
});
// After redirect — verify server-side:
app.get('/payment/return', async (req, res) => {
const deposit = await getDeposit(req.query.deposit_id);
if (
deposit.status === 'approved' &&
deposit.external_order_id === req.query.order_id
) {
// creditPlayer(deposit.external_order_id, deposit.amount);
}
res.send('OK');
});

Node.js — create withdrawal

withdrawal.js
JS
async function createWithdrawal({ amount, wallet, customerPhone, orderId, callbackUrl }) {
const res = await fetch(`${BASE}/withdrawals`, {
method: 'POST',
headers: {
Authorization: `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
amount,
wallet,
customer_phone: customerPhone,
order_id: orderId,
...(callbackUrl ? { callback_url: callbackUrl } : {}),
}),
});
const json = await res.json();
if (!json.success) throw new Error(json.error?.message);
return json.data;
}

PHP — create deposit

create-deposit.php
PHP
<?php
$apiKey = getenv('FIREPAY_API_KEY');
$payload = [
'amount' => 500,
'wallet' => 'bkash',
'order_id' => 'ORD-' . time(),
'return_url' => 'https://yoursite.com/payment/return',
];
$ch = curl_init('https://{API_HOST}/v1/deposits');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_RETURNTRANSFER => true,
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
if (!$response['success']) {
throw new Exception($response['error']['message'] ?? 'API error');
}
header('Location: ' . $response['data']['payment_url']);
exit;

Python — poll deposit status

get_deposit.py
PYTHON
import os
import requests
API_KEY = os.environ["FIREPAY_API_KEY"]
BASE = os.environ["FIREPAY_API_BASE"] # https://{API_HOST}/v1
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
def get_deposit(deposit_id: str) -> dict:
r = requests.get(f"{BASE}/deposits/{deposit_id}", headers=HEADERS, timeout=30)
r.raise_for_status()
data = r.json()
if not data.get("success"):
raise RuntimeError(data.get("error", {}).get("message"))
return data["data"]
# Match your order with external_order_id
# d = get_deposit("DPABCD1234")
# if d["status"] == "approved" and d["external_order_id"] == "ORD-1001":
# credit_player(...)
18

Production checklist

  • Use HTTPS for all API calls and webhook endpoints
  • Store API keys server-side only
  • Configure a webhook URL with your FIREPAY administrator (or use callback_url)
  • Use a unique order_id per deposit and withdrawal
  • Match shop orders using external_order_id
  • Credit only on deposit.approved (webhook and/or confirmed GET)
  • Poll GET /v1/deposits/:id if the customer closes the browser before redirect
  • Handle all withdrawal webhook events (pending, processing, approved, rejected)
  • Handle webhook events idempotently (retries)
  • Use GET /v1/statements/summary for your Opening / Deposit / Withdraw / Fee / Settlement / Adjustment / Closing totals
  • Request API key + webhook URL from your FIREPAY administrator before go-live