Endpoints
Endpoints
The system provides 2 endpoints for Merchants
orgId and merchantId are issued by the provider when you sign up — you don't create them yourself
Create a Pay-In Request
POST https://api.please-payment.com/api/PaymentRequest/org/{orgId}/action/SubmitPayInRequest/{merchantId}
Creates a Payment Request and returns a QR Code for the customer to scan and transfer funds directly into the Merchant's account.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
RefId1 |
string | ✅ | Reference ID from the Merchant (must be unique) |
RefId2 |
string | ❌ | Additional reference 2 |
RefId3 |
string | ❌ | Additional reference 3 |
PayerName |
string | ✅ | Name of the payer |
RequestedAmount |
number | ✅ | Amount (must be greater than 0 and within the range set by the Merchant) |
Currency |
string | ✅ | Currency — currently only THB is supported |
QrProvider |
string | ✅ | Bank issuing the QR — PP (PromptPay) or SCB |
Description |
string | ❌ | Description of the transaction |
CustomerEmail |
string | ❌ | Customer's email |
CustomerPhone |
string | ❌ | Customer's phone number |
Tags |
string | ❌ | Tag for grouping transactions |
Sample Request
{
"RefId1": "ORDER-20260701-001",
"PayerName": "Somchai Jaidee",
"RequestedAmount": 325,
"Currency": "THB",
"QrProvider": "PP",
"Description": "Payment for goods",
"RefId2": "CUST-12345"
}
Response
{
"status": "OK",
"description": "Success",
"paymentResponse": {
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"sessionId": "session-abc123",
"type": "PayIn",
"status": "Pending",
"requestedAmount": 325.00,
"generatedAmount": 325.52,
"currency": "THB",
"qrCode": "00020101021...",
"qrCodeImage": "data:image/png;base64,...",
"paymentUrl": "https://...",
"websocketPath": "/realtime/payment-tx",
"createdAt": "2026-07-01T10:00:00Z",
"expireAt": "2026-07-01T10:15:00Z",
"isQrAvailable": true,
"payInBankCode": "SCB",
"payInBankAccountNo": "xxx-xxxxx-x",
"payInBankAccountName": "Company Name",
"payInPromptPayId": null,
"slipUploadUrl": "/payin-slip-upload/org123/3fa85f64-5717-4562-b3fc-2c963f66afa6/a1b2c3d4-..."
}
}
Response Fields
| Field | Description |
|---|---|
id |
UUID of the Payment Request — keep it for reference |
status |
Current status (see Payment Status) |
requestedAmount |
The amount requested |
generatedAmount |
The actual amount to be paid (may include a randomized fraction of a baht for matching) |
isQrAvailable |
true if a QR Code is ready for the customer to scan, false if the destination account doesn't support QR (e.g. not linked to PromptPay) — see details below |
qrCodeImage |
The QR Code image as Base64 — can be displayed directly in your app (empty when isQrAvailable is false) |
payInBankCode |
Destination bank code |
payInBankAccountNo |
Destination account number |
payInBankAccountName |
Destination account name |
payInPromptPayId |
Destination PromptPay number (if any) |
sessionId |
Used to connect via WebSocket to receive real-time status |
websocketPath |
The WebSocket path (/realtime/payment-tx) |
expireAt |
When the QR Code expires |
slipUploadUrl |
Relative path to the slip upload page — has no domain prefix, must be concatenated with https://merchant.please-payment.com (see explanation below) to form the full URL, then given to the customer to open the slip upload page without needing to log in |
Important — which domain to concatenate:
slipUploadUrlis a relative path only. You must concatenate it with thehttps://merchant.please-payment.comdomain yourself. For example, ifslipUploadUrlis/payin-slip-upload/org123/xxx/yyy, form the full URL ashttps://merchant.please-payment.com/payin-slip-upload/org123/xxx/yyy
Displaying the QR and Account Info
Always check isQrAvailable before rendering:
| Scenario | How to display |
|---|---|
isQrAvailable = true |
Show the QR Code from qrCodeImage for the customer to scan as usual |
isQrAvailable = false |
No QR Code — show the account details (payInBankCode, payInBankAccountNo, payInBankAccountName, payInPromptPayId) so the customer can enter the transfer manually |
Note: It's recommended to always show the account details (
payInBankCode,payInBankAccountNo,payInBankAccountName,payInPromptPayId) alongside the QR Code — some customers may prefer to transfer manually even when a QR is available
Recommended: Turn
slipUploadUrlinto a QR Code displayed on your payment page — the customer scans it with their phone camera and opens the slip upload page directly, without typing the URL. Works for both standard Pay-In and Pay-In P2P
Slip Upload Page
When the customer opens the Slip Upload URL, they'll see the slip upload page for that Payment Request, which offers:
- Upload slip image — choose an image from the camera or the phone's gallery
- Slip reference number — enter the first 4 and last 4 digits of the slip reference number (alphanumeric) for matching and duplicate detection
- Note — an optional field for additional text
- Duplicate slip check — the system automatically warns if a slip with the same reference number already exists
The customer does not need to log in to use this page — the URL already has a token embedded and expires after 24 hours
Even if the HTTP status code is
200, you must still check thestatusfield in the response body — if"OK", it succeeded; any other value indicates an error (see Error Handling)
Create a Pay-In Request (P2P)
POST https://api.please-payment.com/api/PaymentRequest/org/{orgId}/action/SubmitPayInRequestP2P/{merchantId}
Creates a Peer-to-Peer (P2P) Pay-In Request — the system automatically matches it with a pending Pay-Out Request, and the customer transfers funds directly to the recipient's account (instead of transferring via the system's QR Code).
What is P2P? Instead of funds going into the Merchant's account first and then being transferred out, P2P lets the sender transfer directly to the recipient — the system's role is to match and confirm the transaction.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
RefId1 |
string | ✅ | Reference ID from the Merchant (must be unique) |
RefId2 |
string | ❌ | Additional reference 2 |
RefId3 |
string | ❌ | Additional reference 3 |
PayerName |
string | ✅ | Name of the payer |
RequestedAmount |
number | ✅ | Amount (must be greater than 0 and within the range set by the Merchant) |
Currency |
string | ✅ | Currency — currently only THB is supported |
QrProvider |
string | ✅ | PP or SCB (used internally by the system for matching) |
Description |
string | ❌ | Description of the transaction |
Sample Request
{
"RefId1": "P2P-ORDER-20260701-001",
"PayerName": "Somchai Jaidee",
"RequestedAmount": 1000,
"Currency": "THB",
"QrProvider": "PP"
}
Response
{
"status": "OK",
"description": "Success",
"paymentResponse": {
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"type": "PayIn",
"status": "Pending",
"requestedAmount": 1000.00,
"generatedAmount": 1000.00,
"currency": "THB",
"qrCode": null,
"qrCodeImage": "",
"isQrAvailable": false,
"payInBankCode": "KBANK",
"payInBankAccountNo": "012-3-45678-9",
"payInBankAccountName": "Recipient Account Name",
"payInPromptPayId": "0812345678",
"slipUploadUrl": "/payin-slip-upload/org123/3fa85f64-5717-4562-b3fc-2c963f66afa6/a1b2c3d4-..."
}
}
Differences from Standard Pay-In
| Standard Pay-In | Pay-In P2P | |
|---|---|---|
isQrAvailable |
true (usually) |
false (usually) — P2P accounts are often not linked to PromptPay |
qrCodeImage |
QR Code image | Empty ("") when isQrAvailable = false |
payInBankAccountName |
Merchant's account | The recipient's account (from the matched Pay-Out Request) |
| Transfer method | Scan the QR Code | Transfer directly to the account specified in the response (enter account details manually) |
slipUploadUrl |
✅ | ✅ (very important — the customer must upload a slip as proof) |
Important: For P2P —
isQrAvailableis usuallyfalsebecause the destination account may not be linked to PromptPay. In this case you must display the account details (payInBankCode,payInBankAccountNo,payInBankAccountName,payInPromptPayId) so the customer can enter the transfer manually, and also showslipUploadUrlso they can upload proof of transfer.
Important — which domain to concatenate:
slipUploadUrlis a relative path, same as standard Pay-In. You must concatenate it withhttps://merchant.please-payment.comyourself, e.g.https://merchant.please-payment.com/payin-slip-upload/org123/xxx/yyy(see the full explanation in Response Fields above)
Recommended: Turn
slipUploadUrlinto a QR Code shown alongside the destination account details — the customer transfers funds, then scans the QR to open the slip upload page directly without typing the URL (see the slip upload page example above)
Error
ERROR_NO_P2P_ACCOUNT_MATCH: If there is no pending Pay-Out Request in the system, you'll receive this error — meaning there's currently no matching transaction available.
Create a Pay-Out Request
POST https://api.please-payment.com/api/PaymentRequest/org/{orgId}/action/SubmitPayOutRequest/{merchantId}
Creates a request to transfer funds out to a destination account.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
RefId1 |
string | ✅ | Reference ID from the Merchant (must be unique) |
RefId2 |
string | ❌ | Additional reference 2 |
RefId3 |
string | ❌ | Additional reference 3 |
RequestedAmount |
number | ✅ | Amount (must be greater than 0) |
QrProvider |
string | ✅ | Must be PP (PromptPay only, for Pay-Out) |
BankCode |
string | ✅ | Destination bank code, e.g. SCB, KBANK, BAY — see all supported codes |
BankAccountNo |
string | ✅ | Destination account number |
BankAccountName |
string | ✅ | Destination account name |
PromptPayId |
string | ❌ | Destination PromptPay number |
AccountType |
string | ❌ | Account type: Native or PromptPay |
Destination account details:
BankCode+BankAccountNo+BankAccountNamemust always be sent (see Supported Bank Codes), even when paying out via PromptPay — if you also know the destination's PromptPay number, you may additionally sendPromptPayId+AccountType, or sendPayinBankAccountId(an ID from the system) instead of all of the above
Recommended: If you know the destination account's PromptPay number, it's recommended to send
PromptPayId— transferring via PromptPay lets the system process faster, and the recipient receives funds more quickly
Sample Request (Bank Account Transfer)
{
"RefId1": "PAYOUT-20260701-001",
"RequestedAmount": 500,
"QrProvider": "PP",
"BankCode": "KBANK",
"BankAccountNo": "0123456789",
"BankAccountName": "Somchai Jaidee",
"AccountType": "Native"
}
Sample Request (PromptPay Transfer)
{
"RefId1": "PAYOUT-20260701-002",
"RequestedAmount": 200,
"QrProvider": "PP",
"PromptPayId": "0812345678",
"AccountType": "PromptPay"
}
Response
{
"status": "OK",
"description": "Success",
"paymentResponse": {
"id": "7bc95f12-3a21-4f89-c4ed-1d852a77bfc8",
"type": "PayOut",
"status": "Pending",
"requestedAmount": 500.00,
"currency": "THB",
"createdAt": "2026-07-01T10:05:00Z"
}
}
Create a Withdrawal Request
POST https://api.please-payment.com/api/PaymentRequest/org/{orgId}/action/SubmitWithdrawalRequest/{merchantId}
Use this endpoint when the Merchant itself is withdrawing funds out to its own account — as opposed to a standard Pay-Out, which transfers funds out to the Merchant's customer. Internally the system creates the exact same kind of request as a Pay-Out, just flagged as a withdrawal, so it appears separately from ordinary Pay-Outs in reporting.
Request body, fee calculation, response shape, and webhooks are all 100% identical to Create a Pay-Out Request — the only difference is the endpoint path (
SubmitWithdrawalRequestinstead ofSubmitPayOutRequest). Everything documented above for Pay-Out applies here unchanged.
Request Body
Same as Create a Pay-Out Request — RefId1, RefId2, RefId3, RequestedAmount, QrProvider, and destination account fields (BankCode+BankAccountNo+BankAccountName, or PromptPayId+AccountType, or PayinBankAccountId).
Sample Request
{
"RefId1": "WITHDRAW-20260701-001",
"RequestedAmount": 500,
"QrProvider": "PP",
"BankCode": "KBANK",
"BankAccountNo": "0123456789",
"BankAccountName": "Somchai Jaidee",
"AccountType": "Native"
}
Response
{
"status": "OK",
"description": "Success",
"paymentResponse": {
"id": "7bc95f12-3a21-4f89-c4ed-1d852a77bfc8",
"type": "PayOut",
"status": "Pending",
"requestedAmount": 500.00,
"currency": "THB",
"createdAt": "2026-07-01T10:05:00Z"
}
}
Webhooks: No new event type — a Withdrawal Request still fires the same
PaymentOut.Success/PaymentOut.Rejectedevents documented in Webhooks, with the same payload fields.