Download OpenAPI specification:
Company Payment API for the P2PPay peer-matching flow. Peer matching PayIn transactions do not use a provider-hosted QR; instead, the end user transfers the exact amount to a configured peer bank account, and the company uploads the resulting bank slip to reconcile the transaction.
This API enables companies to:
POST /payIn/create with channel/type + peerBank/peerAccountNumber
(the sender's bank & account). The response contains the destination peer
bank account (bank, accountNumber, peerAccountName) the user must
transfer to, plus the exact amount (the platform may adjust the
requested amount by cents to guarantee uniqueness).amount from the sender peer account.POST /slip/upload with the bank-slip image (multipart).
The platform verifies the slip QR, enforces duplicate/destination/time
rules, then attempts to auto-match it to the pending PayIn.callbackUrl. The company can also poll with POST /status/{refId}.signature) by key alphabeticallykey1=value1key2=value2... (no quoting/escaping, values must be string or null)signature = md5(payload + signKey) as lowercase hexRetrieves the list of available PayIn channels for the authenticated company
{- "status": 0,
- "message": "Success",
- "success": true,
- "code": 0,
- "channels": [
- "PROMPTPAY",
- "TRUEWALLET",
- "BANKTRANSFER"
]
}Retrieves the list of available PayOut channels for the authenticated company
{- "status": 0,
- "message": "Success",
- "success": true,
- "code": 0,
- "channels": [
- "BANKTRANSFER",
- "PROMPTPAY"
]
}Retrieves per-channel configuration (min/max amount, allowed exact amounts)
for PayIn channels available to the authenticated company. Useful before
calling POST /payIn/create to pre-validate amounts.
{- "status": 0,
- "message": "Success",
- "success": true,
- "code": 0,
- "channels": [
- {
- "channel": "BANKTRANSFER",
- "exactAmounts": [
- 100,
- 300,
- 500,
- 1000
], - "minAmount": 100,
- "maxAmount": 200000
}
]
}Retrieves per-channel configuration (min/max amount, allowed exact amounts) for PayOut channels available to the authenticated company.
{- "status": 0,
- "message": "Success",
- "success": true,
- "code": 0,
- "channels": [
- {
- "channel": "BANKTRANSFER",
- "exactAmounts": [
- 100,
- 300,
- 500,
- 1000
], - "minAmount": 100,
- "maxAmount": 200000
}
]
}Retrieves the list of available PayIn channels for the authenticated company
{- "status": 0,
- "message": "Success",
- "success": true,
- "code": 0,
- "channels": [
- "PROMPTPAY",
- "TRUEWALLET",
- "BANKTRANSFER"
]
}Retrieves per-channel configuration (min/max amount, allowed exact amounts)
for PayIn channels available to the authenticated company. Useful before
calling POST /payIn/create to pre-validate amounts.
{- "status": 0,
- "message": "Success",
- "success": true,
- "code": 0,
- "channels": [
- {
- "channel": "BANKTRANSFER",
- "exactAmounts": [
- 100,
- 300,
- 500,
- 1000
], - "minAmount": 100,
- "maxAmount": 200000
}
]
}Creates a new peer-matching PayIn transaction (deposit/top-up).
The platform reserves a destination peer bank account for the company
and returns it in the response (bank, accountNumber, peerAccountName).
The end user must transfer the exact returned amount from
peerBank/peerAccountNumber, then the company calls POST /slip/upload
with the bank-slip image to reconcile the transaction.
Minimum Amount: 100
Peer-Matching Notes:
peerBank and peerAccountNumber identify the sender account the end
user will transfer from. Providing them improves auto-match accuracy.amount field in the response as the amount the user must send.Signature Calculation:
| channel required | string Payment channel to use |
| type required | string Enum: "PAYIN" "TOPUP" Transaction type |
| externalRefId required | string Unique external reference ID provided by company |
required | string or number Requested amount (minimum 100). Server may adjust by cents to ensure uniqueness. |
| callbackUrl | string or null <uri> URL to receive status callbacks (http/https only) |
| memberName | string Member name |
| memberPhoneNumber | string Member phone number |
| peerBank | string Sender bank code for peer matching. Recommended to improve auto-match accuracy on slip upload. |
| peerAccountNumber | string Sender bank account number for peer matching |
| signature | string MD5 signature for request validation |
{- "channel": "BANKTRANSFER",
- "type": "PAYIN",
- "externalRefId": "ORDER-12345",
- "requestedAmount": "1000.00",
- "memberName": "John Doe",
- "memberPhoneNumber": "0812345678",
- "peerBank": "SCB",
- "peerAccountNumber": "1234567890",
- "signature": "5d41402abc4b2a76b9719d911017c592"
}{- "status": 0,
- "message": "Success",
- "success": true,
- "code": 0,
- "transaction": {
- "type": "PAYIN",
- "status": "PENDING",
- "refId": "TX-20260422-001",
- "externalRefId": "ORDER-12345",
- "providerRefId": "string",
- "memberName": "string",
- "memberPhoneNumber": "string",
- "peerBank": "string",
- "peerAccountNumber": "string",
- "peerAccountName": "string",
- "requestedAmount": "1000.00",
- "requestTime": "string",
- "amount": "1000.03",
- "confirmedAmount": "string",
- "accountBalanceBefore": "string",
- "accountBalanceAfter": "string",
- "fee": "string",
- "feePercent": "string",
- "feePerTx": "string",
- "approveMethod": "string",
- "confirmStatus": "string",
- "confirmAt": "string",
- "confirmBy": "string",
- "transactionTime": "string",
- "transactionRemark": "string",
- "qrRawData": "string",
- "qrImage": "string",
- "qrImageType": "string",
- "lastFailReason": "string",
- "bank": "SCB",
- "accountNumber": "1234567890",
- "createdAt": "string",
- "updatedAt": "string",
}
}Uploads a bank-slip image to reconcile a pending peer-matching PayIn
transaction. The upload is multipart/form-data with a single image
file field.
Processing steps (server-side):
bank_slip_image record with status
PENDING plus an associated transaction_evidence record.DUP MATCHED and the evidence is rejected.BankExpect for the
company using amount + peerBank + peerAccountNumber + time
window. On a unique match, the corresponding PayIn transaction is
confirmed and a status callback is scheduled.Auto-match outcomes (recorded on the evidence / returned via later status):
MATCHED <externalRefId> — slip bound to a pending transactionNOT MATCH - NO TXCANDIDATE FOUNDNOT MATCH - MULTIPLE TXCANDIDATE FOUNDNOT MATCH - OUT OF TIME (N hours ago) — slip timestamp older than 24hNOT MATCH - ALREADY MATCHED <externalRefId>NOT MATCH - REFUNDEDThe HTTP response returns the stored image(s) metadata. The final match
result is reported asynchronously via POST /status/{refId} or the
status callback.
| image required | string <binary> Bank slip image file (PNG / JPEG / WebP). Sent as multipart/form-data field |
[- {
- "imageId": "10231",
- "evidenceId": "20557",
- "path": "uploads/bank_slips/20260422/9f8e7d6c5b4a3210",
- "createdAt": "2019-08-24T14:15:22Z"
}
]Retrieves the list of available PayOut channels for the authenticated company
{- "status": 0,
- "message": "Success",
- "success": true,
- "code": 0,
- "channels": [
- "BANKTRANSFER",
- "PROMPTPAY"
]
}Retrieves per-channel configuration (min/max amount, allowed exact amounts) for PayOut channels available to the authenticated company.
{- "status": 0,
- "message": "Success",
- "success": true,
- "code": 0,
- "channels": [
- {
- "channel": "BANKTRANSFER",
- "exactAmounts": [
- 100,
- 300,
- 500,
- 1000
], - "minAmount": 100,
- "maxAmount": 200000
}
]
}Creates a new peer-matching PayOut transaction (withdrawal).
peerBank and peerAccountNumber are the destination account owned by
the end user / member.
Minimum Amount: 300
Signature Calculation:
| channel required | string Payment channel to use |
| type required | string Value: "PAYOUT" Transaction type |
| externalRefId required | string Unique external reference ID provided by company |
required | string or number Requested amount (minimum 300) |
| callbackUrl | string or null <uri> URL to receive status callbacks |
| memberName | string Member name |
| memberPhoneNumber | string Member phone number |
| peerBank | string Destination (payee) bank code |
| peerAccountNumber | string Destination (payee) account number |
| signature | string MD5 signature for request validation |
{- "channel": "BANKTRANSFER",
- "type": "PAYOUT",
- "externalRefId": "WITHDRAW-12345",
- "requestedAmount": "5000.00",
- "memberName": "Jane Doe",
- "memberPhoneNumber": "0823456789",
- "peerBank": "KBANK",
- "peerAccountNumber": "9876543210",
- "signature": "5d41402abc4b2a76b9719d911017c592"
}{- "status": 0,
- "message": "Success",
- "success": true,
- "code": 0,
- "transaction": {
- "type": "PAYIN",
- "status": "PENDING",
- "refId": "TX-20260422-001",
- "externalRefId": "ORDER-12345",
- "providerRefId": "string",
- "memberName": "string",
- "memberPhoneNumber": "string",
- "peerBank": "string",
- "peerAccountNumber": "string",
- "peerAccountName": "string",
- "requestedAmount": "1000.00",
- "requestTime": "string",
- "amount": "1000.03",
- "confirmedAmount": "string",
- "accountBalanceBefore": "string",
- "accountBalanceAfter": "string",
- "fee": "string",
- "feePercent": "string",
- "feePerTx": "string",
- "approveMethod": "string",
- "confirmStatus": "string",
- "confirmAt": "string",
- "confirmBy": "string",
- "transactionTime": "string",
- "transactionRemark": "string",
- "qrRawData": "string",
- "qrImage": "string",
- "qrImageType": "string",
- "lastFailReason": "string",
- "bank": "SCB",
- "accountNumber": "1234567890",
- "createdAt": "string",
- "updatedAt": "string",
}
}Returns the peer-match fulfillment state for a peer-matching PayOut (withdraw) transaction, identified by internal refId.
Use this when you need to see which peer deposits are being used to
fulfill a withdraw order and how much is still outstanding. The
regular POST /status/{refId} endpoint only returns top-level
transaction state; this endpoint adds the underlying
PeerWithdrawRequest accounting (amount / matchedAmount / pendingAmount
/ remainingAmount) plus each PeerToPeerMatch that has been attached
so far.
Accounting semantics:
amount — total amount the platform is trying to fulfill from peersmatchedAmount — amount already confirmed by peer depositspendingAmount — amount locked to PENDING matches awaiting slip confirmationremainingAmount = amount - matchedAmount - pendingAmountMatch statuses (peerMatches[].status):
PENDING — deposit reserved against this withdraw, awaiting slip confirmationCONFIRMED — deposit slip verified, amount added to matchedAmountREJECTED — match cancelled (e.g. slip verification failed)EXPIRED — slip window passed without confirmation; amount releasedWithdraw request statuses (peerWithdrawRequest.status):
OPEN — still accepting new matchesFULFILLED — fully covered (no more matches will be created)STALE — expired without full fulfillmentPrivacy / compactness: Only the destination account
(destBank / destAccountNumber) the peer depositor paid to, and a
signed, time-limited slipImageUrl pointing at the uploaded slip, are
returned per match. Counterparty (depositor) identifiers, member info,
the raw slip QR string, and the full slip-verify JSON are intentionally
omitted — this endpoint is designed to be compact and cheap to poll;
use the admin peer-monitor API for full forensics.
| refId required | string Internal transaction reference ID of the PayOut |
{- "status": 0,
- "message": "Success",
- "success": true,
- "code": 0,
- "refId": "TX-20260422-001",
- "externalRefId": "WITHDRAW-12345",
- "transactionStatus": "PROCESSING",
- "requestedAmount": "5000.00",
- "amount": "5000.00",
- "peerWithdrawRequest": {
- "id": "4201",
- "amount": "5000.00",
- "matchedAmount": "3000.00",
- "pendingAmount": "1000.00",
- "remainingAmount": "1000.00",
- "status": "OPEN",
- "expireAt": "2019-08-24T14:15:22Z",
- "isExpired": true
}, - "peerMatches": [
- {
- "matchId": "8812",
- "matchedAmount": "1000.00",
- "status": "CONFIRMED",
- "destBank": "SCB",
- "destAccountNumber": "1234567890",
- "slipExpireAt": "2019-08-24T14:15:22Z",
- "isSlipExpired": true,
- "confirmedAt": "2019-08-24T14:15:22Z",
- "slipImageUrl": "slip-images/uploads/bank_slips/20260422/abc123?expires=1714051200&sig=b7f3"
}
], - "summary": {
- "totalMatches": 3,
- "confirmedCount": 2,
- "pendingCount": 1,
- "rejectedCount": 0,
- "expiredCount": 0
}
}Same as POST /payOut/peerMatches/{refId} but looks up the PayOut by
the external reference ID originally provided by the company when the
transaction was created.
| externalRefId required | string External transaction reference ID (provided by company) of the PayOut |
{- "status": 0,
- "message": "Success",
- "success": true,
- "code": 0,
- "refId": "TX-20260422-001",
- "externalRefId": "WITHDRAW-12345",
- "transactionStatus": "PROCESSING",
- "requestedAmount": "5000.00",
- "amount": "5000.00",
- "peerWithdrawRequest": {
- "id": "4201",
- "amount": "5000.00",
- "matchedAmount": "3000.00",
- "pendingAmount": "1000.00",
- "remainingAmount": "1000.00",
- "status": "OPEN",
- "expireAt": "2019-08-24T14:15:22Z",
- "isExpired": true
}, - "peerMatches": [
- {
- "matchId": "8812",
- "matchedAmount": "1000.00",
- "status": "CONFIRMED",
- "destBank": "SCB",
- "destAccountNumber": "1234567890",
- "slipExpireAt": "2019-08-24T14:15:22Z",
- "isSlipExpired": true,
- "confirmedAt": "2019-08-24T14:15:22Z",
- "slipImageUrl": "slip-images/uploads/bank_slips/20260422/abc123?expires=1714051200&sig=b7f3"
}
], - "summary": {
- "totalMatches": 3,
- "confirmedCount": 2,
- "pendingCount": 1,
- "rejectedCount": 0,
- "expiredCount": 0
}
}Uploads a bank-slip image to reconcile a pending peer-matching PayIn
transaction. The upload is multipart/form-data with a single image
file field.
Processing steps (server-side):
bank_slip_image record with status
PENDING plus an associated transaction_evidence record.DUP MATCHED and the evidence is rejected.BankExpect for the
company using amount + peerBank + peerAccountNumber + time
window. On a unique match, the corresponding PayIn transaction is
confirmed and a status callback is scheduled.Auto-match outcomes (recorded on the evidence / returned via later status):
MATCHED <externalRefId> — slip bound to a pending transactionNOT MATCH - NO TXCANDIDATE FOUNDNOT MATCH - MULTIPLE TXCANDIDATE FOUNDNOT MATCH - OUT OF TIME (N hours ago) — slip timestamp older than 24hNOT MATCH - ALREADY MATCHED <externalRefId>NOT MATCH - REFUNDEDThe HTTP response returns the stored image(s) metadata. The final match
result is reported asynchronously via POST /status/{refId} or the
status callback.
| image required | string <binary> Bank slip image file (PNG / JPEG / WebP). Sent as multipart/form-data field |
[- {
- "imageId": "10231",
- "evidenceId": "20557",
- "path": "uploads/bank_slips/20260422/9f8e7d6c5b4a3210",
- "createdAt": "2019-08-24T14:15:22Z"
}
]Manually triggers a status callback for a transaction using the internal reference ID (refId)
| refId required | string Internal transaction reference ID |
{- "status": 0,
- "message": "Success",
- "success": true,
- "code": 0
}Manually triggers a status callback for a transaction using the external reference ID (externalRefId provided by company)
| externalRefId required | string External transaction reference ID (provided by company) |
{- "status": 0,
- "message": "Success",
- "success": true,
- "code": 0
}Retrieves the current status of a transaction using the internal reference ID (refId)
| refId required | string Internal transaction reference ID |
{- "status": 0,
- "message": "Success",
- "success": true,
- "code": 0,
- "transaction": {
- "type": "PAYIN",
- "status": "PENDING",
- "refId": "TX-20260422-001",
- "externalRefId": "ORDER-12345",
- "providerRefId": "string",
- "memberName": "string",
- "memberPhoneNumber": "string",
- "peerBank": "string",
- "peerAccountNumber": "string",
- "peerAccountName": "string",
- "requestedAmount": "1000.00",
- "requestTime": "string",
- "amount": "1000.03",
- "confirmedAmount": "string",
- "accountBalanceBefore": "string",
- "accountBalanceAfter": "string",
- "fee": "string",
- "feePercent": "string",
- "feePerTx": "string",
- "approveMethod": "string",
- "confirmStatus": "string",
- "confirmAt": "string",
- "confirmBy": "string",
- "transactionTime": "string",
- "transactionRemark": "string",
- "qrRawData": "string",
- "qrImage": "string",
- "qrImageType": "string",
- "lastFailReason": "string",
- "bank": "SCB",
- "accountNumber": "1234567890",
- "createdAt": "string",
- "updatedAt": "string",
- "companyName": "Example Company",
- "signature": "5d41402abc4b2a76b9719d911017c592"
}
}Retrieves the current status of a transaction using the external reference ID (externalRefId provided by company)
| externalRefId required | string External transaction reference ID (provided by company) |
{- "status": 0,
- "message": "Success",
- "success": true,
- "code": 0,
- "transaction": {
- "type": "PAYIN",
- "status": "PENDING",
- "refId": "TX-20260422-001",
- "externalRefId": "ORDER-12345",
- "providerRefId": "string",
- "memberName": "string",
- "memberPhoneNumber": "string",
- "peerBank": "string",
- "peerAccountNumber": "string",
- "peerAccountName": "string",
- "requestedAmount": "1000.00",
- "requestTime": "string",
- "amount": "1000.03",
- "confirmedAmount": "string",
- "accountBalanceBefore": "string",
- "accountBalanceAfter": "string",
- "fee": "string",
- "feePercent": "string",
- "feePerTx": "string",
- "approveMethod": "string",
- "confirmStatus": "string",
- "confirmAt": "string",
- "confirmBy": "string",
- "transactionTime": "string",
- "transactionRemark": "string",
- "qrRawData": "string",
- "qrImage": "string",
- "qrImageType": "string",
- "lastFailReason": "string",
- "bank": "SCB",
- "accountNumber": "1234567890",
- "createdAt": "string",
- "updatedAt": "string",
- "companyName": "Example Company",
- "signature": "5d41402abc4b2a76b9719d911017c592"
}
}Returns the peer-match fulfillment state for a peer-matching PayOut (withdraw) transaction, identified by internal refId.
Use this when you need to see which peer deposits are being used to
fulfill a withdraw order and how much is still outstanding. The
regular POST /status/{refId} endpoint only returns top-level
transaction state; this endpoint adds the underlying
PeerWithdrawRequest accounting (amount / matchedAmount / pendingAmount
/ remainingAmount) plus each PeerToPeerMatch that has been attached
so far.
Accounting semantics:
amount — total amount the platform is trying to fulfill from peersmatchedAmount — amount already confirmed by peer depositspendingAmount — amount locked to PENDING matches awaiting slip confirmationremainingAmount = amount - matchedAmount - pendingAmountMatch statuses (peerMatches[].status):
PENDING — deposit reserved against this withdraw, awaiting slip confirmationCONFIRMED — deposit slip verified, amount added to matchedAmountREJECTED — match cancelled (e.g. slip verification failed)EXPIRED — slip window passed without confirmation; amount releasedWithdraw request statuses (peerWithdrawRequest.status):
OPEN — still accepting new matchesFULFILLED — fully covered (no more matches will be created)STALE — expired without full fulfillmentPrivacy / compactness: Only the destination account
(destBank / destAccountNumber) the peer depositor paid to, and a
signed, time-limited slipImageUrl pointing at the uploaded slip, are
returned per match. Counterparty (depositor) identifiers, member info,
the raw slip QR string, and the full slip-verify JSON are intentionally
omitted — this endpoint is designed to be compact and cheap to poll;
use the admin peer-monitor API for full forensics.
| refId required | string Internal transaction reference ID of the PayOut |
{- "status": 0,
- "message": "Success",
- "success": true,
- "code": 0,
- "refId": "TX-20260422-001",
- "externalRefId": "WITHDRAW-12345",
- "transactionStatus": "PROCESSING",
- "requestedAmount": "5000.00",
- "amount": "5000.00",
- "peerWithdrawRequest": {
- "id": "4201",
- "amount": "5000.00",
- "matchedAmount": "3000.00",
- "pendingAmount": "1000.00",
- "remainingAmount": "1000.00",
- "status": "OPEN",
- "expireAt": "2019-08-24T14:15:22Z",
- "isExpired": true
}, - "peerMatches": [
- {
- "matchId": "8812",
- "matchedAmount": "1000.00",
- "status": "CONFIRMED",
- "destBank": "SCB",
- "destAccountNumber": "1234567890",
- "slipExpireAt": "2019-08-24T14:15:22Z",
- "isSlipExpired": true,
- "confirmedAt": "2019-08-24T14:15:22Z",
- "slipImageUrl": "slip-images/uploads/bank_slips/20260422/abc123?expires=1714051200&sig=b7f3"
}
], - "summary": {
- "totalMatches": 3,
- "confirmedCount": 2,
- "pendingCount": 1,
- "rejectedCount": 0,
- "expiredCount": 0
}
}Same as POST /payOut/peerMatches/{refId} but looks up the PayOut by
the external reference ID originally provided by the company when the
transaction was created.
| externalRefId required | string External transaction reference ID (provided by company) of the PayOut |
{- "status": 0,
- "message": "Success",
- "success": true,
- "code": 0,
- "refId": "TX-20260422-001",
- "externalRefId": "WITHDRAW-12345",
- "transactionStatus": "PROCESSING",
- "requestedAmount": "5000.00",
- "amount": "5000.00",
- "peerWithdrawRequest": {
- "id": "4201",
- "amount": "5000.00",
- "matchedAmount": "3000.00",
- "pendingAmount": "1000.00",
- "remainingAmount": "1000.00",
- "status": "OPEN",
- "expireAt": "2019-08-24T14:15:22Z",
- "isExpired": true
}, - "peerMatches": [
- {
- "matchId": "8812",
- "matchedAmount": "1000.00",
- "status": "CONFIRMED",
- "destBank": "SCB",
- "destAccountNumber": "1234567890",
- "slipExpireAt": "2019-08-24T14:15:22Z",
- "isSlipExpired": true,
- "confirmedAt": "2019-08-24T14:15:22Z",
- "slipImageUrl": "slip-images/uploads/bank_slips/20260422/abc123?expires=1714051200&sig=b7f3"
}
], - "summary": {
- "totalMatches": 3,
- "confirmedCount": 2,
- "pendingCount": 1,
- "rejectedCount": 0,
- "expiredCount": 0
}
}Retrieves balance information for all active company accounts (PAYIN and PAYOUT)
{- "status": 0,
- "message": "Success",
- "success": true,
- "code": 0,
- "accounts": [
- {
- "name": "MAIN_PAYIN",
- "status": "ACTIVE",
- "type": "PAYIN",
- "balance": 50000,
- "holdBalance": 1000
}
]
}Retrieves the list of supported bank codes for transactions
{- "status": 0,
- "message": "Success",
- "success": true,
- "code": 0,
- "data": [
- {
- "bank": "SCB",
- "name": "SIAM COMMERCIAL BANK",
- "nameTh": "ธนาคาร ไทยพาณิชย์",
- "numCode": "014"
}
]
}