Skip to content

POST /qr/generate ​

Generate PromptPay and merchant QR codes for receiving payments.

Endpoint ​

http
POST /qr/generate

Full URL: https://api.easyslip.com/v1/qr/generate

v1 Only

QR code generation is only available in API v1.

Authentication ​

Required. See Authentication Guide.

http
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

Request ​

QR Types ​

TypeDescription
PROMPTPAYPromptPay QR code: mobile number, national ID, e-wallet ID, or your registered Biller ID (Tag 30)
KSHOPKasikorn K-Shop merchant QR code
MAE_MANEEMae Manee merchant QR code
TUNGNGERNTungngern merchant QR code
BILL_PAYMENTLegacy, still supported: Biller ID QR, the same QR as PROMPTPAY with billerId

Type Definitions ​

typescript
// 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.

json
{
  "type": "PROMPTPAY",
  "billerId": "010555123456701",
  "ref1": "INV20261014001",
  "ref2": "CUSTOMER001",
  "amount": 125.50
}

The example ID is illustrative; replace it with your own registered Biller ID.

FieldRequiredFormat
typeYes"PROMPTPAY"
billerIdYesString of exactly 15 digits including the suffix; leading zeroes preserved
ref1Yes1-20 printable ASCII characters; not whitespace-only
ref2NoSame format as ref1; omit when unused
amountNoPositive 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.

json
{
  "type": "BILL_PAYMENT",
  "billerId": "010555123456701",
  "ref1": "INV20261014001",
  "ref2": "CUSTOMER001",
  "amount": 125.50
}

PromptPay ​

bash
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
  }'
javascript
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);
php
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'] . '">';
python
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 ​

json
{
  "type": "KSHOP",
  "ref1": "ORDER12345",
  "amount": 250.00
}

Mae Manee ​

json
{
  "type": "MAE_MANEE",
  "ref1": "ORDER12345",
  "amount": 500.00
}

Tungngern ​

json
{
  "type": "TUNGNGERN",
  "ref1": "ORDER12345",
  "merchantName": "MY STORE",
  "amount": 750.00
}

Response ​

Success (200) ​

json
{
  "status": 200,
  "data": {
    "image": "iVBORw0KGgoAAAANSUhEUgAA...",
    "mime": "image/png",
    "payload": "00020101021230..."
  }
}

Response Fields ​

FieldTypeDescription
imagestringBase64-encoded PNG image
mimestringMIME type (image/png)
payloadstringQR code payload string

Error Responses ​

Invalid Request (400) ​

json
{
  "status": 400,
  "message": "invalid_request",
  "details": [
    { "field": "ref1", "message": "Required" }
  ]
}

PROMPTPAY requests with msisdn, natId or eWalletId return details as a single message:

json
{
  "status": 400,
  "message": "invalid_request",
  "details": "ref1 and ref2 are only allowed with billerId"
}

Unauthorized (401) ​

json
{
  "status": 401,
  "message": "unauthorized"
}

Parameter Reference ​

PromptPay ​

ParameterTypeRequiredDescription
typestringYes"PROMPTPAY"
msisdnstringOne ofMobile number (0xxxxxxxxx)
natIdstringOne ofNational ID (13 digits)
eWalletIdstringOne ofE-wallet ID (15 digits)
billerIdstringOne ofBiller ID (15 digits including the suffix, leading zeroes preserved)
ref1stringWith billerIdReference 1 (1-20 printable ASCII characters, case preserved); required with billerId
ref2stringNoReference 2, only with billerId (same format as ref1)
amountnumberNoAmount (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 ​

ParameterTypeRequiredDescription
typestringYes"KSHOP"
ref1stringYesReference 1 (1-20 alphanumeric, uppercase)
amountnumberNoAmount (max 2 decimals)

Mae Manee ​

ParameterTypeRequiredDescription
typestringYes"MAE_MANEE"
ref1stringYesReference 1 (1-20 alphanumeric, uppercase)
amountnumberNoAmount (max 2 decimals)

Tungngern ​

ParameterTypeRequiredDescription
typestringYes"TUNGNGERN"
ref1stringYesReference 1 (1-20 alphanumeric, uppercase)
merchantNamestringNoMerchant name (1-25 characters)
amountnumberNoAmount (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 (PROMPTPAY with billerId, and BILL_PAYMENT) preserve case and support printable ASCII.

Bank Slip Verification API for Thai Banking