2.1 Create PayOut
POST /api/v2/withdrawals
- p2c
- p2p
Request
- Headers
- Body
| Parameter | Type | Required | Description |
|---|---|---|---|
| X-Api-Key | string | Yes | Your enabled merchant API key. |
| X-Signature | string | Yes | Lowercase hexadecimal HMAC-SHA256 of the exact raw JSON body, using the API signing secret. |
| Content-Type | string | Yes | application/json. |
v2 does not require X-Timestamp or X-Request-Id. See authentication.
| Parameter | Type | Required | Description |
|---|---|---|---|
order_id | string, max 255 characters | Yes | Your withdrawal identifier. Unique per merchant and operation type for idempotency. |
amount | JSON number | Yes | Positive amount, at most two decimal places. Do not send a quoted string. |
currency | string, 3 letters | Yes | Use BDT for this guide; it must match the selected shop's currency. |
method | string | No | Exact active shop code. Omit to use your default active shop. Do not add surrounding spaces. |
customer_account_id | JSON integer | No | Your customer's account identifier used by the shared payment checks. Send an integer, not a quoted number; 0 is preserved. Omit or use null when unavailable. |
callback_url | HTTPS URL | Yes | Absolute callback URL without embedded credentials. |
account_number | string, max 255 characters | Yes | Recipient account. For a card shop, 12–19 digits; for a mobile shop, + followed by 8–15 digits, with the first digit non-zero. Other formats depend on the shop. |
fields | JSON object | No* | Additional data defined by the selected shop's PayOut schema. See shop fields. |
fields.merchant_user_ip | string (IPv4 or IPv6) | Shop-dependent | Customer IP address. Supported for every shop; required only when the selected shop's input schema requires it. Omit or use null when optional and unavailable. |
The mobile rule applies to the selected shop's mobile method, not every wallet or opaque identifier. Card identifiers contain digits only, without spaces or hyphens. callback_url must be an absolute HTTPS URL string without embedded credentials, whitespace, or control characters.
The v1 recipient field card_number becomes top-level account_number in v2. For a shop configured with the mobile payment method, a BDT-format example is "account_number": "+8801700000000"; the local number "01700000000" fails that method's validation. Other wallet methods use their assigned format. The method request value remains your shop code, even when its payment method is mobile. Confirm the recipient format supported by your assigned payout channel.
See the v1-to-v2 request-field mapping before migrating customer data: customer_account_id accepts only a JSON integer, and v1 merchant_user_ip moves to fields.merchant_user_ip.
The v2 protocol does not require fields, but the selected shop may require individual keys. fields must be a JSON object, not an array. It cannot override protocol fields such as method, customer_account_id, account_number, recipient_account, or account_channel.
Example request
Example for an active card shop with no additional required fields. Replace your_bdt_shop with your actual shop code:
{
"order_id": "WD-BDT-1001",
"amount": 500,
"currency": "BDT",
"method": "your_bdt_shop",
"customer_account_id": 77,
"callback_url": "https://merchant.example.com/webhooks/payfield",
"account_number": "4111111111111111",
"fields": {
"merchant_user_ip": "203.0.113.10"
}
}
Send one JSON object and no query string. Use the v2 authentication headers. The successful response is HTTP 200.
Response
Response fields
HTTP 200.
| Parameter | Type | Description |
|---|---|---|
| transaction_id | string | Payfield transaction ID. Store it for status requests. |
Example response
- Success
- Error
{
"transaction_id": "12345"
}
HTTP 400 for an invalid request:
{
"error": {
"code": 400,
"message": "Bad request"
}
}
See API errors for other responses.
Use your assigned P2P shop code as method and its configured fields. Confirm that the PayOut channel is enabled for your shop. The v2 request and response structure is shared across these shop types.
Request
- Headers
- Body
| Parameter | Type | Required | Description |
|---|---|---|---|
| X-Api-Key | string | Yes | Your enabled merchant API key. |
| X-Signature | string | Yes | Lowercase hexadecimal HMAC-SHA256 of the exact raw JSON body, using the API signing secret. |
| Content-Type | string | Yes | application/json. |
v2 does not require X-Timestamp or X-Request-Id. See authentication.
| Parameter | Type | Required | Description |
|---|---|---|---|
order_id | string, max 255 characters | Yes | Your withdrawal identifier. Unique per merchant and operation type for idempotency. |
amount | JSON number | Yes | Positive amount, at most two decimal places. Do not send a quoted string. |
currency | string, 3 letters | Yes | Use BDT for this guide; it must match the selected shop's currency. |
method | string | No | Exact active shop code. Omit to use your default active shop. Do not add surrounding spaces. |
customer_account_id | JSON integer | No | Your customer's account identifier used by the shared payment checks. Send an integer, not a quoted number; 0 is preserved. Omit or use null when unavailable. |
callback_url | HTTPS URL | Yes | Absolute callback URL without embedded credentials. |
account_number | string, max 255 characters | Yes | Recipient account. For a card shop, 12–19 digits; for a mobile shop, + followed by 8–15 digits, with the first digit non-zero. Other formats depend on the shop. |
fields | JSON object | No* | Additional data defined by the selected shop's PayOut schema. See shop fields. |
fields.merchant_user_ip | string (IPv4 or IPv6) | Shop-dependent | Customer IP address. Supported for every shop; required only when the selected shop's input schema requires it. Omit or use null when optional and unavailable. |
The mobile rule applies to the selected shop's mobile method, not every wallet or opaque identifier. Card identifiers contain digits only, without spaces or hyphens. callback_url must be an absolute HTTPS URL string without embedded credentials, whitespace, or control characters.
The v1 recipient field card_number becomes top-level account_number in v2. For a shop configured with the mobile payment method, a BDT-format example is "account_number": "+8801700000000"; the local number "01700000000" fails that method's validation. Other wallet methods use their assigned format. The method request value remains your shop code, even when its payment method is mobile. Confirm the recipient format supported by your assigned payout channel.
See the v1-to-v2 request-field mapping before migrating customer data: customer_account_id accepts only a JSON integer, and v1 merchant_user_ip moves to fields.merchant_user_ip.
The v2 protocol does not require fields, but the selected shop may require individual keys. fields must be a JSON object, not an array. It cannot override protocol fields such as method, customer_account_id, account_number, recipient_account, or account_channel.
Example request
Example for an active card shop with no additional required fields. Replace your_bdt_shop with your actual shop code:
{
"order_id": "WD-BDT-1001",
"amount": 500,
"currency": "BDT",
"method": "your_bdt_shop",
"customer_account_id": 77,
"callback_url": "https://merchant.example.com/webhooks/payfield",
"account_number": "4111111111111111",
"fields": {
"merchant_user_ip": "203.0.113.10"
}
}
Send one JSON object and no query string. Use the v2 authentication headers. The successful response is HTTP 200.
Response
Response fields
HTTP 200.
| Parameter | Type | Description |
|---|---|---|
| transaction_id | string | Payfield transaction ID. Store it for status requests. |
Example response
- Success
- Error
{
"transaction_id": "12345"
}
HTTP 400 for an invalid request:
{
"error": {
"code": 400,
"message": "Bad request"
}
}
See API errors for other responses.
A successful create response does not confirm that the recipient was paid. Retrieve the current result even after HTTP 200.
Store transaction_id and check its status. A retry with the same order_id and equivalent request returns the same response without creating another withdrawal. Reusing the order_id with different request data returns 409. Idempotency is scoped to the merchant and withdrawal type, across shops; an existing v1 withdrawal with the same ID also conflicts. See API errors.