POST /qr/generate
Generate PromptPay and merchant QR codes for receiving payments.
Endpoint
POST /qr/generateFull URL: https://api.easyslip.com/v1/qr/generate
v1 Only
QR code generation is only available in API v1.
Authentication
Required. See Authentication Guide.
Authorization: Bearer YOUR_API_KEY
Content-Type: application/jsonRequest
QR Types
| Type | Description |
|---|---|
PROMPTPAY | PromptPay QR code: mobile number, national ID, e-wallet ID, or your registered Biller ID (Tag 30) |
KSHOP | Kasikorn K-Shop merchant QR code |
MAE_MANEE | Mae Manee merchant QR code |
TUNGNGERN | Tungngern merchant QR code |
BILL_PAYMENT | Legacy, still supported: Biller ID QR, the same QR as PROMPTPAY with billerId |
Type Definitions
// Request Types
type QRGenerateRequest =
| PromptPayRequest
| KShopRequest
| MaeManeeRequest
| TungngernRequest | BillPaymentRequest;
interface PromptPayRequest {
type: 'PROMPTPAY';
// Exactly one of msisdn, natId, eWalletId, billerId
msisdn?: string; // Mobile number (0xxxxxxxxx)
natId?: string; // National ID (13 digits)
eWalletId?: string; // E-wallet ID (15 digits)
billerId?: string; // Biller ID: 15 digits, including the suffix; preserve leading zeroes
ref1?: string; // Required with billerId: 1-20 printable ASCII characters, case preserved
ref2?: string; // Only with billerId: same format as ref1; omit when unused
amount?: number; // Max 2 decimals; with billerId 0.01 to 9999999999.99
}
// Legacy, still supported: gives the same QR as PROMPTPAY with billerId
interface BillPaymentRequest {
type: 'BILL_PAYMENT';
billerId: string; // 15 digits, including the suffix; preserve leading zeroes
ref1: string; // 1-20 printable ASCII characters, case preserved
ref2?: string; // Same format as ref1; omit when unused
amount?: number; // 0.01 to 9999999999.99, at most 2 decimals
}
interface KShopRequest {
type: 'KSHOP';
ref1: string; // Reference 1 (1-20 alphanumeric, uppercase)
amount?: number;
}
interface MaeManeeRequest {
type: 'MAE_MANEE';
ref1: string; // Reference 1 (1-20 alphanumeric, uppercase)
amount?: number;
}
interface TungngernRequest {
type: 'TUNGNGERN';
ref1: string; // Reference 1 (1-20 alphanumeric, uppercase)
merchantName?: string; // Merchant name (1-25 characters)
amount?: number;
}
// Response
interface QRGenerateResponse {
status: 200;
data: QRData;
}
interface QRData {
image: string; // Base64-encoded PNG image
mime: string; // MIME type (image/png)
payload: string; // QR code payload string
}
// Error Response
interface ErrorResponse {
status: number;
message: string;
details?: string | Array<{ field: string; message: string }>;
}Examples
PromptPay (Biller ID)
Use type PROMPTPAY with the 15-digit Biller ID registered with your bank or payment provider. This endpoint generates a payment QR; it does not issue or register a Biller ID, or check whether that ID is active.
{
"type": "PROMPTPAY",
"billerId": "010555123456701",
"ref1": "INV20261014001",
"ref2": "CUSTOMER001",
"amount": 125.50
}The example ID is illustrative; replace it with your own registered Biller ID.
| Field | Required | Format |
|---|---|---|
type | Yes | "PROMPTPAY" |
billerId | Yes | String of exactly 15 digits including the suffix; leading zeroes preserved |
ref1 | Yes | 1-20 printable ASCII characters; not whitespace-only |
ref2 | No | Same format as ref1; omit when unused |
amount | No | Positive number, at most 2 decimals, 0.01 to 9999999999.99 THB |
Do not send msisdn, natId or eWalletId together with billerId (400). References are preserved exactly, including case and spaces. Use the reference format required by your bank for your Biller ID. Omitting amount lets the payer enter it. The response (image, mime, payload) is unchanged from the existing QR types.
Payload structure follows the Bank of Thailand Thai QR Code standard, page 15.
Bill Payment (legacy)
BILL_PAYMENT is still supported with the same fields (billerId, ref1, ref2, amount) and the same validation. For the same input it returns exactly the same QR and payload as PROMPTPAY with billerId. New integrations should use PROMPTPAY.
{
"type": "BILL_PAYMENT",
"billerId": "010555123456701",
"ref1": "INV20261014001",
"ref2": "CUSTOMER001",
"amount": 125.50
}PromptPay
curl -X POST https://api.easyslip.com/v1/qr/generate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "PROMPTPAY",
"msisdn": "0812345678",
"amount": 100.00
}'const generateQR = async (config) => {
const response = await fetch('https://api.easyslip.com/v1/qr/generate', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify(config)
});
const result = await response.json();
if (result.status !== 200) {
throw new Error(result.message);
}
return result.data;
};
// Generate PromptPay QR
const qr = await generateQR({
type: 'PROMPTPAY',
msisdn: '0812345678',
amount: 100.00
});
// Display QR code
const img = document.createElement('img');
img.src = `data:${qr.mime};base64,${qr.image}`;
document.body.appendChild(img);function generateQR(array $config): array
{
$apiKey = getenv('EASYSLIP_API_KEY');
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => 'https://api.easyslip.com/v1/qr/generate',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json'
],
CURLOPT_POSTFIELDS => json_encode($config)
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
if ($result['status'] !== 200) {
throw new Exception($result['message']);
}
return $result['data'];
}
// Generate PromptPay QR
$qr = generateQR([
'type' => 'PROMPTPAY',
'msisdn' => '0812345678',
'amount' => 100.00
]);
// Save as file
$imageData = base64_decode($qr['image']);
file_put_contents('qr-code.png', $imageData);
// Or display inline
echo '<img src="data:' . $qr['mime'] . ';base64,' . $qr['image'] . '">';import requests
import base64
import os
def generate_qr(config: dict) -> dict:
response = requests.post(
'https://api.easyslip.com/v1/qr/generate',
headers={
'Authorization': f'Bearer {os.environ["EASYSLIP_API_KEY"]}',
'Content-Type': 'application/json'
},
json=config
)
result = response.json()
if result['status'] != 200:
raise Exception(result['message'])
return result['data']
# Generate PromptPay QR
qr = generate_qr({
'type': 'PROMPTPAY',
'msisdn': '0812345678',
'amount': 100.00
})
# Save as file
image_data = base64.b64decode(qr['image'])
with open('qr-code.png', 'wb') as f:
f.write(image_data)
print(f"Payload: {qr['payload']}")K-Shop
{
"type": "KSHOP",
"ref1": "ORDER12345",
"amount": 250.00
}Mae Manee
{
"type": "MAE_MANEE",
"ref1": "ORDER12345",
"amount": 500.00
}Tungngern
{
"type": "TUNGNGERN",
"ref1": "ORDER12345",
"merchantName": "MY STORE",
"amount": 750.00
}Response
Success (200)
{
"status": 200,
"data": {
"image": "iVBORw0KGgoAAAANSUhEUgAA...",
"mime": "image/png",
"payload": "00020101021230..."
}
}Response Fields
| Field | Type | Description |
|---|---|---|
image | string | Base64-encoded PNG image |
mime | string | MIME type (image/png) |
payload | string | QR code payload string |
Error Responses
Invalid Request (400)
{
"status": 400,
"message": "invalid_request",
"details": [
{ "field": "ref1", "message": "Required" }
]
}PROMPTPAY requests with msisdn, natId or eWalletId return details as a single message:
{
"status": 400,
"message": "invalid_request",
"details": "ref1 and ref2 are only allowed with billerId"
}Unauthorized (401)
{
"status": 401,
"message": "unauthorized"
}Parameter Reference
PromptPay
| Parameter | Type | Required | Description |
|---|---|---|---|
type | string | Yes | "PROMPTPAY" |
msisdn | string | One of | Mobile number (0xxxxxxxxx) |
natId | string | One of | National ID (13 digits) |
eWalletId | string | One of | E-wallet ID (15 digits) |
billerId | string | One of | Biller ID (15 digits including the suffix, leading zeroes preserved) |
ref1 | string | With billerId | Reference 1 (1-20 printable ASCII characters, case preserved); required with billerId |
ref2 | string | No | Reference 2, only with billerId (same format as ref1) |
amount | number | No | Amount (max 2 decimals; with billerId 0.01 to 9999999999.99) |
TIP
You must provide exactly one of: msisdn, natId, eWalletId, or billerId. ref1 and ref2 are only allowed with billerId; sending them with another identifier returns 400.
Bill Payment (legacy)
Same fields as PROMPTPAY with billerId (type "BILL_PAYMENT", billerId, ref1, ref2, amount), same QR.
K-Shop
| Parameter | Type | Required | Description |
|---|---|---|---|
type | string | Yes | "KSHOP" |
ref1 | string | Yes | Reference 1 (1-20 alphanumeric, uppercase) |
amount | number | No | Amount (max 2 decimals) |
Mae Manee
| Parameter | Type | Required | Description |
|---|---|---|---|
type | string | Yes | "MAE_MANEE" |
ref1 | string | Yes | Reference 1 (1-20 alphanumeric, uppercase) |
amount | number | No | Amount (max 2 decimals) |
Tungngern
| Parameter | Type | Required | Description |
|---|---|---|---|
type | string | Yes | "TUNGNGERN" |
ref1 | string | Yes | Reference 1 (1-20 alphanumeric, uppercase) |
merchantName | string | No | Merchant name (1-25 characters) |
amount | number | No | Amount (max 2 decimals) |
Notes
- QR code generation does not consume verification quota
- Generated QR codes are valid indefinitely
- Amount is optional - customer can enter amount when paying
- KSHOP, MAE_MANEE and TUNGNGERN ref1 fields are alphanumeric and normalized to uppercase. Biller ID references (
PROMPTPAYwithbillerId, andBILL_PAYMENT) preserve case and support printable ASCII.