QR Codes V1
QR codes payment instrument allows you to receive payments directly from end user's mobile banking app balance or eWallet balance. In Indonesia, our merchants can receive payments from any providers connected on QRIS network. (e.g. OVO, Gopay, DANA, LinkAja, BCA, Shopeepay, full list here )
Create QR Code
Endpoint: Create QR Code
POST https://api.xendit.co/qr_codes
Request Parameters
Example: Create QRIS QR Code
curl https://api.xendit.co/qr_codes -X POST \
-u xnd_development_O46JfOtygef9kMNsK+ZPGT+TeStIngw3Dn+R1k+2fT/7GlCAN3jg==: \
-d external_id='testing_id_123' \
-d type='DYNAMIC' \
-d callback_url='https://yourwebsite.com/callback'\
-d amount=1500
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.xendit.co/qr_codes');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "external_id=testing_id_123&type=DYNAMIC&callback_url=https://yourwebsite.com/callback&amount=1500");
curl_setopt($ch, CURLOPT_USERPWD, 'xnd_development_O46JfOtygef9kMNsK+ZPGT+TeStIngw3Dn+R1k+2fT/7GlCAN3jg==' . ':' . '');
$headers = array();
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close($ch);
const x = new require("xendit-node")({
secretKey:
"xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==",
});
const { QrCode } = x;
const qrcodeSpecificOptions = {};
const q = new QrCode(qrcodeSpecificOptions);
const resp = await q.createCode({
externalID: "testing_id_123",
type: "DYNAMIC",
callbackURL: "https://yourwebsite.com/callback",
amount: 1500,
});
console.log(resp);
from xendit import Xendit, QRCodeType
api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
xendit_instance = Xendit(api_key=api_key)
QRCode = xendit_instance.QRCode
qrcode = QRCode.create(
external_id="qrcode-id-1594794038",
type=QRCodeType.DYNAMIC,
callback_url="https://webhook.site",
amount=4000,
)
print(qrcode)
Header Parameter | Type | Description |
---|---|---|
for-user-idoptional |
string |
The sub-account user-id that you want to make this transaction for. This header is only used if you have access to xenPlatform. See xenPlatform for more information |
with-fee-ruleoptional |
string |
Fee Rule ID that you would like to apply to payments coming into this QR Code Please note: If you include this parameter, we will return the fee_rule_id in the header of the API response. If for-user-id header is not present, Fee Rule will still be routed from master account to the specified destination account This header is only used if you have access to xenPlatform. See xenPlatform for more information |
Body Parameter | Type | Description |
---|---|---|
external_id required |
string |
An ID of your choice. Often it is unique identifier in your system like customer ID or order ID Note: It has to be unique per creation request |
type required |
string |
DYNAMIC or STATIC Note: DYNAMIC QR code contains the payment value upon scanning and can be paid a single time, subsequent transactions are refunded Note: STATIC QR code requires end user to input the payment value and can be paid multiple times |
callback_urlrequired |
string |
The URL to receive payment notification after payment has been made by end user |
amountoptional |
number |
The payment value embedded in the QR code, end user can only pay the specified amount after scanning the QR code. For STATIC QR code, amount parameter will be ignored. Note: Min amount is 1,500 IDR Note: Max amount is 10,000,000 IDR |
metadataoptional |
object |
Object of additional information the user may use. Users define the JSON properties and values. You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. |
Response Parameters
Example: Create QRIS QR Code API Success Response
{
"id": "qr_8182837te-87st-49ing-8696-1239bd4d759c",
"external_id": "testing_id_123",
"amount": 1500,
"qr_string": "0002010102##########CO.XENDIT.WWW011893600#######14220002152#####414220010303TTT####015CO.XENDIT.WWW02180000000000000000000TTT52 045######ID5911XenditQRIS6007Jakarta6105121606##########3k1mOnF73h11111111#3k1mOnF73h6v53033605401163040BDB",
"callback_url": "https://yourwebsite.com/callback",
"type": "DYNAMIC",
"status": "ACTIVE",
"created": "2020-01-08T18:18:18.661Z",
"updated": "2020-01-08T18:18:18.661Z",
"metadata": {
"branch_code": "senayan_372",
}
}
Parameter | Type | Description |
---|---|---|
id required |
string |
Unique identifier for this transaction |
external_id required |
string |
Unique identifier specified by merchant for QR code creation |
amount required |
number |
Amount specified in request Note: Value will be NULL if QR type is STATIC |
qr_string required |
string |
QR string to be rendered for display to end users. QR string to image rendering are commonly available in software libraries (e.g Nodejs, PHP, Java) |
callback_url required |
string |
The URL provided by merchant to receive payment notification after payment has been made by end user |
type required |
string |
DYNAMIC or STATIC |
status required |
string |
ACTIVE (QR code can be paid) or INACTIVE (QR code has been paid for DYNAMIC QR) |
created required |
string |
Timestamp ISO 8601 when the QR code was created (in UTC) |
updated required |
string |
Timestamp ISO 8601 when the QR code was patched (in UTC) |
metadata optional |
object |
User defined object with JSON properties and values passed in during charge creation. Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. |
Error Codes
Example: Create QRIS QR Code API Error Response
{
"error_code": "API_VALIDATION_ERROR",
"message": "Amount must be within range [1500, 10000000]"
}
Error Code | Description |
---|---|
DUPLICATE_ERROR409 |
The payment with the same external_id has already been made before. |
DATA_NOT_FOUND409 |
QRIS merchant not found, please contact our customer success team for activation. |
REQUEST_FORBIDDEN_ERROR403 |
API key in use does not have necessary permissions to perform the request. Please assign proper permissions for the key. Learn more here |
API_VALIDATION_ERROR400 |
There is invalid input in one of the required request fields. |
Get QR Code by External ID
GET https://api.xendit.co/qr_codes/:external_id
Request Parameters
Example: Get QR Code by external_id
curl https://api.xendit.co/qr_codes/external_id -X GET \
-u xnd_development_O46JfOtygef9kMNsK+ZPGT+TeStIngw3Dn+R1k+2fT/7GlCAN3jg==: \
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.xendit.co/qr_codes/external_id');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_USERPWD, 'xnd_development_O46JfOtygef9kMNsK+ZPGT+TeStIngw3Dn+R1k+2fT/7GlCAN3jg==' . ':' . '');
$result = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close($ch);
const x = new require("xendit-node")({
secretKey:
"xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==",
});
const { QrCode } = x;
const qrcodeSpecificOptions = {};
const q = new QrCode(qrcodeSpecificOptions);
const resp = await q.getCode({
externalID: "testing_id_123",
});
console.log(resp);
from xendit import Xendit
api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
xendit_instance = Xendit(api_key=api_key)
QRCode = xendit_instance.QRCode
qrcode = QRCode.get_by_ext_id(
external_id="qrcode-id-1594794038",
)
print(qrcode)
Header Parameter | Type | Description |
---|---|---|
for-user-idoptional |
string |
The sub-account user-id that you want to make this transaction for. This header is only used if you have access to xenPlatform. See xenPlatform for more information |
Path Parameter | Type | Description |
---|---|---|
external_id required |
string |
Merchant provided unique ID used to create QR code |
Response Parameters
Example: Get QR Code by external_id Success Response
{
"id": "qr_8182837te-87st-49ing-8696-1239bd4d759c",
"external_id": "testing_id_123",
"amount": 1500,
"qr_string": "0002010102##########CO.XENDIT.WWW011893600#######14220002152#####414220010303TTT####015CO.XENDIT.WWW02180000000000000000000TTT52045######ID5911XenditQRIS6007Jakarta6105121606##########3k1mOnF73h11111111#3k1mOnF73h6v53033605401163040BDB",
"callback_url": "https://yourwebsite.com/callback",
"type": "DYNAMIC",
"status": "ACTIVE",
"created": "2020-01-08T18:18:18.661Z",
"updated": "2020-01-08T18:18:18.661Z",
"metadata": {
"branch_code": "senayan_372",
}
}
Parameter | Type | Description |
---|---|---|
id required |
string |
Unique identifier for this transaction |
external_id required |
string |
Unique identifier specified by merchant for QR code creation |
amount required |
number |
Amount specified in request Note: Value will be NULL if QR type is STATIC |
qr_string required |
string |
QR string to be rendered for display to end users. QR string to image rendering are commonly available in software libraries (e.g Nodejs, PHP, Java) |
callback_url required |
string |
The URL provided by merchant to receive payment notification after payment has been made by end user |
type required |
string |
Type of QR code - DYNAMIC or STATIC |
status required |
string |
ACTIVE (QR code can be paid) or INACTIVE (QR code has been paid for DYNAMIC QR) |
created required |
string |
Timestamp ISO 8601 when the QR code was created (in UTC) |
updated required |
string |
Timestamp ISO 8601 when the QR code was patched (in UTC) |
metadata optional |
object |
User defined object with JSON properties and values passed in during charge creation. Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. |
Error Codes
Example: Create QRIS QR Code API Error Response
{
"error_code": "DATA_NOT_FOUND",
"message": "QR code with external_id testing_id_123 not found"
}
Error Code | Description |
---|---|
DATA_NOT_FOUND404 |
The QR code with specified external_id does not exist. |
REQUEST_FORBIDDEN_ERROR403 |
API key in use does not have necessary permissions to perform the request. Please assign proper permissions for the key. Learn more here |
Get Payments by External ID
Provides the feature to retrieve all payments that were made into a particular QR code. This endpoint is particularly useful if each QR code is set up to receive multiple payments (e.g. offline static QR codes)
GET https://api.xendit.co/qr_codes/payments?external_id={external_id}&from={created}&to={created}&limit={number}
Request Parameters
Example: Get Array of Payments by external_id
curl 'https://api.xendit.co/qr_codes/payments?external_id=testing_qr&from=2021-01-04T08:09:30.000Z&to=2021-01-04T08:22:29.000Z&limit=2' -X GET \
-u xnd_development_O46JfOtygef9kMNsK+ZPGT+TeStIngw3Dn+R1k+2fT/7GlCAN3jg==: \
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.xendit.co/qr_codes/payments?external_id=testing_qr&from=2021-01-04T08:09:30.000Z&to=2021-01-04T08:22:29.000Z&limit=2');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_USERPWD, 'xnd_development_O46JfOtygef9kMNsK+ZPGT+TeStIngw3Dn+R1k+2fT/7GlCAN3jg==' . ':' . '');
$result = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close($ch);
const x = new require("xendit-node")({
secretKey:
"xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==",
});
const { QrCode } = x;
const qrcodeSpecificOptions = {};
const q = new QrCode(qrcodeSpecificOptions);
const resp = await q.getPayments({
externalID: "testing_id_123",
from: "2021-01-04T08:09:30.000Z",
to: "2021-02-04T07:44:20.332Z",
limit: 10,
});
console.log(resp);
Path Parameter | Type | Description |
---|---|---|
external_id required |
string |
Merchant provided unique transaction ID used to create QR code |
limit optional |
number |
Default = 10. Number of payment transactions to be returned in response array |
from optional |
string |
Starting timestamp for time based filters using created , timestamp must be earlier than to parameter |
to optional |
string |
Ending timestamp for time based filters using created , timestamp must be later than from parameter |
Response Parameters
Example: Get Array of Payments by external_id Success Response
[
{
"id": "qrpy_8182837te-87st-49ing-8696-1239bd4d759c",
"amount": 1500,
"created": "2020-01-08T18:18:18.857Z",
"qr_code": {
"id": "qr_8182837te-87st-49ing-8696-1239bd4d759c",
"external_id": "testing_id_123",
"qr_string": "0002010102##########CO.XENDIT.WWW011893600#######14220002152#####414220010303TTT####015CO.XENDIT.WWW02180000000000000000000TTT52045######ID5911XenditQRIS6007Jakarta6105121606##########3k1mOnF73h11111111#3k1mOnF73h6v53033605401163040BDB",
"type": "DYNAMIC",
"metadata": {
"branch_code": "senayan_372"
}
},
"status": "COMPLETED",
"payment_detail": {
"receipt_id": "120318666",
"source": "GOPAY"
}
},
{
"id": "qrpy_8182837te-87st-49ing-8696-1229bd22222",
"amount": 1500,
"created": "2020-01-08T18:18:20.857Z",
"qr_code": {
"id": "qr_8182837te-87st-49ing-8696-1239bd4d759c",
"external_id": "testing_id_123",
"qr_string": "0002010102##########CO.XENDIT.WWW011893600#######14220002152#####414220010303TTT####015CO.XENDIT.WWW02180000000000000000000TTT52045######ID5911XenditQRIS6007Jakarta6105121606##########3k1mOnF73h11111111#3k1mOnF73h6v53033605401163040BDB",
"type": "DYNAMIC",
"metadata": {
"branch_code": "senayan_372"
}
},
"status": "COMPLETED",
"payment_detail": {
"receipt_id": "000111666",
"source": "GOPAY"
}
}
]
Parameter | Type | Description | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
idrequired |
string |
Unique identifier for this transaction | ||||||||||||
amountrequired |
number |
Amount paid by end user | ||||||||||||
createdrequired |
string |
Timestamp ISO 8601 when the QR code was paid (in UTC) | ||||||||||||
qr_coderequired |
object |
QR code object associated with the QR code payment QR code fields
|
||||||||||||
statusrequired |
string |
Status of payment. Possible value(s): COMPLETED | ||||||||||||
payment_detailrequired |
object |
Contains information about the payment that has been shared across the payment network payment_detail fields
|
Error Codes
Example: Get Array of Payments by external_id
{
"error_code": "DATA_NOT_FOUND",
"message": "QR code with external_id testing_id_123 not found"
}
Error Code | Description |
---|---|
DATA_NOT_FOUND404 |
The QR code with specified external_id does not exist. |
REQUEST_FORBIDDEN_ERROR403 |
API key in use does not have necessary permissions to perform the request. Please assign proper permissions for the key. Learn more here |
Simulate Payment (for completion of payment in test mode)
POST https://api.xendit.co/qr_codes/:external_id/payments/simulate
Request Parameters (test mode)
Example: Simulate Payment in Test Mode
curl https://api.xendit.co/qr_codes/:external_id/payments/simulate -X POST \
-u xnd_development_O46JfOtygef9kMNsK+ZPGT+TeStIngw3Dn+R1k+2fT/7GlCAN3jg==: \
-d amount=1500
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.xendit.co/qr_codes/:external_id/payments/simulate');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "amount=1500");
curl_setopt($ch, CURLOPT_USERPWD, 'xnd_development_O46JfOtygef9kMNsK+ZPGT+TeStIngw3Dn+R1k+2fT/7GlCAN3jg==' . ':' . '');
$headers = array();
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close($ch);
const x = new require("xendit-node")({
secretKey:
"xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==",
});
const { QrCode } = x;
const qrcodeSpecificOptions = {};
const q = new QrCode(qrcodeSpecificOptions);
const resp = await q.simulate({
externalID: "testing_id_123",
});
console.log(resp);
Header Parameter | Type | Description |
---|---|---|
for-user-idoptional |
string |
The sub-account user-id that you want to make this transaction for. This header is only used if you have access to xenPlatform. See xenPlatform for more information |
Path Parameter | Type | Description |
---|---|---|
external_id required |
string |
Unique identifier specified by merchant for QR code creation |
Body Parameter | Type | Description |
---|---|---|
amountoptional |
number |
The payment value for simulation in callback to test mode endpoint Note: Min amount is 1,500 IDR Note: Max amount is 10,000,000 IDR |
Response Parameters (test mode)
Example: Simulate Payment (test mode) Success Response
{
"id": "qrpy_8182837te-87st-49ing-8696-1239bd4d759c",
"amount": 1500,
"created": "2020-01-08T18:18:18.857Z",
"qr_code": {
"id": "qr_8182837te-87st-49ing-8696-1239bd4d759c",
"external_id": "testing_id_123",
"qr_string": "0002010102##########CO.XENDIT.WWW011893600#######14220002152#####414220010303TTT####015CO.XENDIT.WWW02180000000000000000000TTT52045######ID5911XenditQRIS6007Jakarta6105121606##########3k1mOnF73h11111111#3k1mOnF73h6v53033605401163040BDB",
"type": "DYNAMIC",
"metadata": {
"branch_code": "senayan_372",
}
},
"status": "COMPLETED",
}
Parameter | Type | Description | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
idrequired |
string |
Unique identifier for this transaction | ||||||||||||
amountrequired |
number |
Amount paid by end user | ||||||||||||
createdrequired |
string |
Timestamp ISO 8601 when the QR code was paid (in UTC) | ||||||||||||
qr_coderequired |
object |
QR code object associated with the QR code payment QR code fields
|
||||||||||||
statusrequired |
string |
Status of payment. Possible value(s): COMPLETED |
Error Codes
Example: Create QRIS QR Code API Error Response
{
"error_code": "DATA_NOT_FOUND",
"message": "QR code with external_id testing_id_123 not found"
}
Error Code | Description |
---|---|
INACTIVE_QR_CODE410 |
Payment simulation for DYNAMIC QRIS has been completed previously. DYNAMIC QRIS is inactive. |
DATA_NOT_FOUND404 |
The QR code with specified external_id does not exist. |
REQUEST_FORBIDDEN_ERROR403 |
API key in use does not have necessary permissions to perform the request. Please assign proper permissions for the key. Learn more here |
API_VALIDATION_ERROR400 |
There is invalid input in one of the required request fields. |
Payment Status Callback
Xendit notifies your system upon successful payments via callback. You need to provide an URL to receive callback.
The payment notification will be sent as POST request to the URL you set. Xendit attach x-callback-token
header that you can validate against Verification Token in Callback Settings to verify message authenticity.
Please response back with status 200 immediately. Learn more about Callback
Payment Callback Payload
Header Parameter | Type | Description |
---|---|---|
x-callback-tokenrequired |
string |
Your Xendit unique callback token to verify the origin of the callback |
{
"event": "qr.payment",
"id": "qrpy_8182837te-87st-49ing-8696-1239bd4d759c",
"amount": 1500,
"created": "2020-01-08T18:18:18.857Z",
"qr_code": {
"id": "qr_8182837te-87st-49ing-8696-1239bd4d759c",
"external_id": "testing_id_123",
"qr_string": "0002010102##########CO.XENDIT.WWW011893600#######14220002152#####414220010303TTT####015CO.XENDIT.WWW02180000000000000000000TTT52045######ID5911XenditQRIS6007Jakarta6105121606##########3k1mOnF73h11111111#3k1mOnF73h6v53033605401163040BDB",
"type": "DYNAMIC",
"metadata": {
"branch_code": "senayan_372"
}
},
"status": "COMPLETED",
"payment_detail": {
"receipt_id": "000111666",
"source": "GOPAY"
}
}
Parameter | Type | Description | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
eventrequired |
string |
Available value: "qr.payment" | ||||||||||||
idrequired |
string |
Unique identifier for this transaction | ||||||||||||
amountrequired |
number |
Amount paid by end user | ||||||||||||
createdrequired |
string |
Timestamp ISO 8601 when the QR code was paid (in UTC) | ||||||||||||
qr_coderequired |
object |
QR code object associated with the QR code payment QR code fields
|
||||||||||||
statusrequired |
string |
Status of payment. Possible value(s): COMPLETED | ||||||||||||
payment_detailrequired |
object |
Contains information about the payment that has been shared across the payment network payment_detail fields
|