💳 PromptPay QR Generator API

Generate EMV-compliant PromptPay QR codes for Thai payment system

📖 Overview

The PromptPay QR Generator API creates EMV-compliant QR codes for Thailand's PromptPay payment system. Generate QR codes for mobile numbers, tax IDs, or e-Wallet IDs with optional payment amounts.

📱 Multiple ID Types

Support for mobile numbers, tax IDs, and e-Wallet IDs

💰 Optional Amounts

Generate QR codes with or without predefined payment amounts

🔧 EMV Compliant

Follows EMV QR Code specification for payment systems

🖼️ Multiple Formats

Base64 image output and raw QR code data

About PromptPay: PromptPay is Thailand's national e-payment system that allows real-time money transfers using mobile numbers or tax identification numbers.

🌐 Base URL

https://api.lorwongam.com/api/promptpay-qr-generator/

🔐 Authentication

No authentication required. This is a public API that can be accessed without any API keys or tokens.

📡 API Endpoints

GET / POST / Generate PromptPay QR Code

Generate a PromptPay QR code for the specified recipient and optional amount. Parameters can be supplied as a query string or as a JSON POST body (the same names are used in both).

Request Parameters

Parameter Type Required Default Description
target string Required Mobile number (Thai national or +66), 13-digit Tax ID, or 15-digit e-Wallet ID
amount number Optional null Payment amount in Thai Baht (THB). Omit or leave blank to leave the QR amount open for the payer to fill in.
size integer Optional 300 Pixel size passed to goQR.me. Accepts 50–1000; values outside that range fall back to the default (300).
format string Optional image Response mode: image returns raw PNG bytes; json returns a JSON envelope with metadata; base64 returns a slim JSON wrapper containing only the image data URI.

Target auto-detection

The server inspects target to pick the PromptPay merchant-account prefix and reports the result as target_type in JSON responses:

Detected target_type Format Example
phone 10-digit Thai mobile (0XXXXXXXXX) or +66XXXXXXXXX 0812345678
tax_id 13-digit Tax ID 1234567890123
ewallet 15-digit e-Wallet ID 123456789012345

Example Request — GET (JSON)

curl "https://api.lorwongam.com/api/promptpay-qr-generator/?target=0812345678&amount=100.50&size=300&format=json"

Example Request — POST (image bytes)

curl -X POST "https://api.lorwongam.com/api/promptpay-qr-generator/" \ -H "Content-Type: application/json" \ -d '{ "target": "0812345678", "amount": 100.50, "size": 300 }' --output qr.png

Example Request — Tax ID without amount (base64)

curl -X POST "https://api.lorwongam.com/api/promptpay-qr-generator/" \ -H "Content-Type: application/json" \ -d '{ "target": "1234567890123", "size": 400, "format": "base64" }'

📊 Response Format

format=json

Full JSON envelope with the raw EMV payload string alongside the encoded image:

{ "success": true, "message": "QR code generated successfully", "payload": "00020101021229370016A000000677010111011300668123456785802TH53037645406100.506304F88B", "qr_url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA...", "target": "0812345678", "amount": 100.5, "target_type": "phone", "qr_size": 300 }

amount is null when the caller did not provide one. target_type is one of phone, tax_id, or ewallet.

format=base64

Slimmer JSON wrapper containing only the image data URI and the EMV payload. Note that this shape uses the key image_base64 and size (not qr_size):

{ "success": true, "image_base64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA...", "payload": "00020101021229370016A000000677010111011300668123456785802TH53037645406100.506304F88B", "target": "0812345678", "amount": 100.5, "size": 300 }

format=image (default)

The response body is the raw PNG bytes with Content-Type: image/png and Content-Disposition: inline; filename="promptpay-qr.png". No JSON envelope is sent.

Error Response

All errors are JSON with HTTP 400 and the shape { "error": "...", "message": "..." }:

Missing target

{ "error": "Missing required parameter: target", "message": "Please provide a phone number, tax ID, or e-wallet ID" }

Unsupported format

{ "error": "Invalid format parameter", "message": "Supported formats: image, json, base64" }

Note: A target that doesn't match any of the three recognised patterns is not rejected — the server just generates a QR with the literal string and reports "target_type": "phone". Strict ID validation is the caller's responsibility.

🔧 EMV QR Code Structure

The generated QR codes follow the EMV® QR Code Specification for Payment Systems. The payload field in JSON responses is the exact TLV string the server encoded.

TLV Tag Meaning Example
00 Payload Format Indicator (always 01) 00020101
01 Point of Initiation Method — 11 static, 12 dynamic (dynamic is used whenever an amount is supplied) 0112
29 Merchant Account Information (PromptPay ID, prefixed with the AID A000000677010111) 29370016A00000067701011101130066812345678
54 Transaction Amount (only when supplied) 540100.50
53 Transaction Currency (always 764 = THB) 5303764
58 Country Code (always TH) 5802TH
63 CRC checksum 6304F88B

📋 Usage Guidelines

Important: Validate PromptPay IDs in your own code before calling the API. The server only rejects an empty/missing target — any other input is accepted verbatim.

Best Practices

  • ID validation: Strip whitespace and +66 prefixes yourself; check digit length matches 10 (phone), 13 (tax), or 15 (ewallet).
  • Amount precision: Up to 2 decimal places (e.g. 100.50).
  • Sizing: 300px is good for web, 500–1000px for print.
  • Testing: Always scan the QR with a real PromptPay app before going to production.

Mobile Number Formats

  • Thai mobile numbers start with 06, 08, or 09.
  • You can pass either 0XXXXXXXXX or +66XXXXXXXXX; the server normalises to the 66 prefix internally.
  • Total length: 10 digits (with leading 0) or 11 digits (with +66).

⚠️ Error Codes

There is no numeric code field. Every error response is JSON with HTTP 400 and the shape { "error": "<title>", "message": "<details>" }:

error When
Missing required parameter: target No target was supplied at all
Invalid format parameter format is not one of image, json, base64

🔗 Integration Examples

HTML image display

Point an <img> tag straight at the endpoint with the default image format:

<img src="/api/promptpay-qr-generator/?target=0812345678&amount=100.50&size=400" alt="PromptPay QR" />

JavaScript fetch (JSON)

fetch('/api/promptpay-qr-generator/?target=0812345678&amount=100.50&format=json') .then(r => r.json()) .then(data => { if (data.success) { document.getElementById('qr').src = data.qr_url; // data:image/png;base64,... console.log('Detected:', data.target_type); // "phone" console.log('Payload:', data.payload); // raw EMV TLV string } });

JavaScript fetch (raw PNG)

fetch('/api/promptpay-qr-generator/?target=0812345678') .then(r => r.blob()) .then(blob => URL.createObjectURL(blob)) .then(url => document.getElementById('qr').src = url);

🚦 Rate Limits

This endpoint is rate-limited per client identity (IP address, or API key when one is supplied): 30 requests per minute. When the budget is exhausted the API responds with HTTP 429 and includes X-RateLimit-* headers so clients can self-throttle. The exact policy is configured in api/includes/api_config.php.

🎯 Ready to Try?

Test the PromptPay QR Generator API with our interactive web interface or start integrating it into your application.

Try Web Interface Test API Endpoint