Complete API Documentation for Payment Processing
This API provides payment processing capabilities including deposits, withdrawals, balance queries, and order management.
All API requests require authentication using API key and JWT signature.
All requests must include a valid JWT signature for security.
// Example parameters (exclude 'signature' field)
const params = {
merchantId: "your_merchant_id",
transactionId: "unique_transaction_id",
bankAccountNumber: "1234567890",
bankName: "KBANK",
name: "John Doe",
amount: 1000,
callbackUrl: "https://your-domain.com/callback",
type: "QR",
timestamp: 1640995200
};
// Sort parameters alphabetically by key
const sortedParams = {};
Object.keys(params)
.sort()
.forEach(key => {
sortedParams[key] = params[key];
});
// Using jsonwebtoken library
const jwt = require('jsonwebtoken');
const signature = jwt.sign(sortedParams, apiKey, {
algorithm: 'HS256',
noTimestamp: true
});
// Add signature to your parameters
const requestData = {
...params,
signature: signature
};
Core payment processing functionality
Content-Type: application/json and x-api-key.
| Parameter | Type | Required | Description |
|---|---|---|---|
| merchantId | string | Yes | Must match the merchant bound to x-api-key (main_username) |
| transactionId | string | Yes | Your unique reference; rejected if already used for this merchant |
| bankAccountNumber | string | Yes | Customer / payer bank account number |
| bankName | string | Yes | Payer bank code (e.g. KBANK, SCB, BBL) |
| name | string | Yes | Account holder name |
| amount | number | Yes | Requested deposit amount (THB) |
| callbackUrl | string | Yes | Your server URL for status callbacks |
| type | string | Yes | e.g. QR, BANK_TRANSFER |
| signature | string | Yes | JWT (HS256) over the other fields — see /jwt/create |
| timestamp | number | Yes | Unix time; must match the signed payload (seconds or ms, consistent with signing) |
signature. Use POST /api/v1/jwt/create with a params object that matches the body fields you will send.
{
"merchantId": "testmerchant",
"transactionId": "MERCHANT20241009001",
"bankAccountNumber": "9876543210",
"bankName": "SCB",
"name": "John Doe",
"amount": 1000,
"callbackUrl": "https://yourdomain.com/api/payment/deposit-callback",
"type": "QR",
"timestamp": 1728470400000,
"signature": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
HTTP 200. Envelope: status is "success", message e.g. "Create Success", and data as below.
Important: referenceId is the internal order id (DP…) for payment links and order query. amount and depositAmount are the exact transfer amount the customer must pay (may differ from the requested amount for uniqueness). qrcode is the raw PromptPay payload string, or null if the platform account has no PromptPay id. url is the hosted payment page (QRPAYPLUS_URL?ref=…), not payment_url.
{
"status": "success",
"message": "Create Success",
"data": {
"merchantId": "testmerchant",
"referenceId": "DP1640995200ABC123",
"transactionId": "MERCHANT20241009001",
"status": "pending",
"amount": 999.99,
"depositAmount": 999.99,
"qrcode": "0002010102123853000066...",
"url": "https://pay.example.com/?ref=DP1640995200ABC123",
"bankAccountNumber": "1234567890",
"bankAccountName": "Platform Bank Account",
"bankName": "KBANK",
"promptpayNumber": "0812345678",
"expireDate": "2024-01-01T12:05:00.000Z",
"platformBankId": "550e8400-e29b-41d4-a716-446655440000",
"is_api": true,
"customerData": {
"bankAccountNumber": "9876543210",
"bankName": "SCB",
"name": "John Doe"
}
}
}
Most errors return status: "error", a message, and a numeric code (body may still be HTTP 200). Some handlers return only code and message without status.
{
"status": "error",
"message": "Invalid signature",
"code": 400
}
| Parameter | Type | Required | Description |
|---|---|---|---|
| agent_order_no | string | Yes | Unique order identifier |
| amount | number | Yes | Amount in THB |
| bank_code | string | Yes | Bank code (e.g., KBANK, SCB) |
| account_no | string | Yes | Bank account number |
| account_name | string | Yes | Account holder name |
| callback_url | string | Yes | Webhook callback URL |
| timestamp | string | Yes | Unix timestamp |
| signature | string | Yes | JWT signature |
{
"code": 200,
"message": "Success",
"data": {
"order_no": "WD1640995200XYZ789",
"agent_order_no": "unique_order_id",
"amount": 1000,
"fee": 15,
"transfer_amount": 985,
"status": "pending"
}
}
| Parameter | Type | Required | Description |
|---|---|---|---|
| timestamp | number | Yes | Unix timestamp |
| signature | string | Yes | JWT signature |
{
"code": 200,
"message": "Success",
"data": {
"balance": 50000,
"currency": "THB"
}
}
| Parameter | Type | Required | Description |
|---|---|---|---|
| order_no | string | No | Platform order number |
| agent_order_no | string | No | Agent order number |
| timestamp | number | Yes | Unix timestamp |
| signature | string | Yes | JWT signature |
{
"code": 200,
"message": "Success",
"data": {
"order_no": "DP1640995200ABC123",
"agent_order_no": "unique_transaction_id",
"status": "completed",
"amount": 1000,
"fee": 5,
"actual_amount": 995,
"created_at": "2024-01-01T12:00:00.000Z",
"completed_at": "2024-01-01T12:03:00.000Z"
}
}
Helper endpoints for common operations
| Parameter | Type | Required | Description |
|---|---|---|---|
| params | object | Yes | Parameters to sign (excluding 'signature') |
| api_key | string | No | API key (uses header if not provided) |
{
"code": 200,
"message": "Success",
"data": {
"signature": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"algorithm": "HS256",
"payload": {
"amount": 1000,
"bankAccountNumber": "9876543210",
"bankName": "SCB",
"callbackUrl": "https://yourdomain.com/callback",
"merchantId": "testmerchant",
"name": "John Doe",
"timestamp": 1728470400000,
"transactionId": "MERCHANT20241009001",
"type": "QR"
}
}
}
{
"code": 200,
"message": "Success",
"data": {
"banks": [
{
"code": "KBANK",
"name": "Kasikorn Bank",
"name_th": "ธนาคารกสิกรไทย",
"active": true
},
{
"code": "SCB",
"name": "Siam Commercial Bank",
"name_th": "ธนาคารไทยพาณิชย์",
"active": true
}
]
}
}
{
"code": 200,
"message": "OK",
"data": {
"status": "healthy",
"timestamp": "2024-01-01T12:00:00.000Z",
"uptime": 3600.5
}
}
Our server will send HTTP POST requests to your callback URLs when payment status changes.
The status field in the callback body depends on type (deposit vs withdrawal). Use the tables below to interpret callback payloads.
Deposit callbacks use a single terminal status when funds are confirmed:
| Status | Meaning |
|---|---|
completed |
Deposit successful; payment is complete. |
Withdrawal callbacks may use one of the following values during the withdrawal lifecycle:
| Status | Meaning |
|---|---|
waiting |
Waiting to be processed. |
processing |
Withdrawal order is being processed. |
created |
Withdrawal order was created and is waiting to enter processing. |
in batch |
Withdrawal order is queued in a withdrawal batch before payout. |
completed |
Withdrawal completed successfully (payout done). |
cancelled |
Withdrawal was cancelled; it will not be retried. |
failed |
Withdrawal failed; it will not be retried. |
POST https://your-domain.com/callback
Content-Type: application/json
{
"order_no": "DP1640995200ABC123",
"agent_order_no": "unique_transaction_id",
"type": "deposit",
"amount": 1000,
"fee": 5,
"transfer_amount": 995,
"actual_amount": 995,
"status": "completed",
"timestamp": "1640995380",
"signature": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
| Parameter | Type | Description |
|---|---|---|
| order_no | string | Platform order number |
| agent_order_no | string | Your transaction ID |
| type | string | Transaction type (deposit/withdrawal) |
| amount | number | Original amount |
| fee | number | Processing fee |
| transfer_amount | number | Amount to transfer |
| actual_amount | number | Actual received amount |
| status | string | Order status — see Deposit callback status (deposit) or Withdraw callback status (withdrawal) |
| timestamp | string | Unix timestamp |
| signature | string | JWT signature for verification |
// Your server should respond with:
{
"code": 200,
"message": "Success"
}
Common error responses and their meanings
| Code | Message | Description |
|---|---|---|
| 200 | Success | Request completed successfully |
| 400 | Invalid signature | JWT signature verification failed |
| 400 | transactionId already exists | Transaction ID is already used |
| 401 | Invalid API key | API key is invalid or missing |
| 403 | IP not in whitelist | Your IP address is not authorized |
| 403 | merchantId does not match API key | Merchant ID doesn't match the API key |
| 500 | Internal server error | Server encountered an unexpected error |