QR Ph API
How do I integrate QR Ph into my online checkout? How do I generate QR Ph codes for in-store use?
Account activation and configuration is required before development
We need to configure your account before your developers can start testing and integration. Kindly message [email protected] to request for key configuration.
During testing with your test API keys, once the QR Ph code is generated, do not push through with the payment as these QR Ph codes are live QR Ph codes. If you will be using your test API keys, it's recommended to only test the generation of the QR Ph codes.
For more assistance, kindly reach out to [email protected] or [email protected]
Overview
QR Ph is the Philippine's QR code standard supervised by the BSP and aims to provide a quick and secure way to accept payments from multiple banks and e-wallets, all using one QR Ph code.
Supported Banks, E-Wallets, Issuers
Bank | E-Wallets & Other Issuers |
---|---|
Asia United Bank Corporation (AUB) | GCash (G-Xchange, Inc.) |
Bank of the Philippine Islands (BPI) | Maya Philippines, Inc. |
BDO Unibank Inc | ShopeePay Philippines, Inc. |
Metropolitan Bank and Trust Company (MetroBank) | GrabPay (Gpay Network PH, Inc.) |
Philippine National Bank (PNB) | PPS-PEPP Financial Services Corporation |
Rizal Commercial Banking Corporation (RCBC) | Starpay Corporation |
Robinsons Bank Corporation | TayoCash, Inc. |
Security Bank Corporation | Traxion Pay, Inc. |
Union Bank of the Philippines (UBP) | USSC Money Services, Inc. |
China Banking Corporation | Zybi Tech, Inc. |
Land Bank of the Philippines | CIS Bayad Center, Inc. |
AllBank (A Thrift Bank), Inc. | DCPAY Philippines, Inc. |
Queen City Development Bank, Inc. or QueenBank, A Thrift Bank | |
Sterling Bank of Asia, Inc. (A Savings Bank) | |
Philippine Savings Bank | |
Cebuana Lhuillier Rural Bank, Inc. | |
Rural Bank of Guinobatan, Inc. | |
SeaBank Philippines Inc. (A Rural Bank) | |
GoTyme Bank Corporation |
Integrating QR Ph through the Payment Intent Workflow
The payment intent workflow is the main workflow used to make payments via PayMongo. Before getting started with integrating QR Ph, make sure that you are familiar with the payment intent workflow. To enable QR Ph, a few additional steps just needs to be added to the existing workflow.
Enabling QR Ph as a payment method for online use-case
{
"data": {
"attributes": {
"amount": 10000,
"payment_method_allowed": [
"card",
"dob",
"paymaya",
"qrph" # add this
],
# ...
}
}
- In this step, set
qrph
astype
in the request body. When using qrph, you only need to provide the address (optional), name, email, and phone (optional) underbilling
.
3. Attach the payment method to the created payment intent as normal. Once the Payment Method is attached, the Payment Intent status transitions from awaiting_payment_method
to awaiting_next_action
awaiting_payment_method
to awaiting_next_action
4. Display the dynamic QRPH code on your front-end or checkout. The QRPH image_url
is a base-64 image string and is available on the /attach
response under next_action
.
image_url
is a base-64 image string and is available on the /attach
response under next_action
.{
"data": {
"id": "pi_uv6817kG7JbbvqJnSwE2uXsc",
"type": "payment_intent",
"attributes": {
"amount": 100000,
# ...
"payment_method_allowed": [
"qrph"
],
"payments": \[],
"next_action": {
"code": {
"id": "code_UKixJpQNzEfMm9T7NahbcXNe",
"amount": 100000,
"image_url": "data:image/png;base64,iVBORw0KG...CYII=",
"label": "Test Paymongo"
},
"type": "consume_qr"
},
# ...
}
}
}
5. Once the customer has successfully paid, the payment intent status will transition to succeeded
.
succeeded
.- To determine if the QR Ph payment has already been paid, a webhook call will be made to the nominated and registered webhook endpoint subscribed to the
payment.paid
event. You may refer to our Webhook API to learn more. - If after 30 minutes, you have not received any webhook call, you may also check the status of the payment intent through the Retrieve a Payment Intent API. Kindly note that checking the status of the payment intent through the GET Payment Intent API should only be used if there is no webhook call and shouldn't be used as the default way of checking the status of a payment.
{
"data": {
"id": "evt_123",
"type": "event",
"attributes": {
"type": "payment.paid",
"livemode": true,
"data": {
"id": "pay_Haq1UQKf4p7b4cDRcxRrnF8j",
"type": "payment",
"attributes": {
"access_url": null,
"amount": 2000,
"balance_transaction_id": "bal_txn_wWWuZhjS4N45b5YYLS38cXTR",
"billing": {
"address": {
"city": "",
"country": "",
"line1": "",
"line2": "",
"postal_code": "",
"state": ""
},
"email": "[email protected]",
"name": "Test Customer",
"phone": ""
},
"currency": "PHP",
"description": "test 1",
"disputed": false,
"external_reference_number": "SBuAjs2",
"fee": 400,
"instant_settlement": null,
"livemode": true,
"net_amount": 1600,
"origin": "links",
"payment_intent_id": "pi_EXpLFBparajBVHFiU78NKdY3",
"payout": null,
"source": {
"id": "qrph_Xp5eLQKwhJZd4njwa4EFXfa1",
"type": "qrph",
"provider": {
"id": "333444",
"code_id": "code_6K7HdrvrCrH937BSpJ6K4T5i"
}
},
"statement_descriptor": "Test",
"status": "paid",
"tax_amount": 0,
"metadata": {
"pm_reference_number": "SBuAjs2"
},
"refunds": [],
"taxes": [
{
"amount": 43,
"currency": "PHP",
"inclusive": true,
"name": "VAT",
"type": "vat",
"value": "1200_bps"
}
],
"available_at": 1721984400,
"created_at": 1721812323,
"credited_at": 1722416400,
"paid_at": 1721812322,
"updated_at": 1721812323
}
}
}
}
}
{
"data": {
"id": "pi_EXpLFBparajBVHFiU78NKdY3",
"type": "payment_intent",
"attributes": {
"amount": 2000,
"capture_type": "automatic",
"client_key": "pi_EXpLFBparajBVHFiU78NKdY3_client_412VZQwShMeZDZLFwZmXmiyE",
"currency": "PHP",
"description": "test 1",
"livemode": true,
"statement_descriptor": "test",
"status": "succeeded",
"last_payment_error": null,
"payment_method_allowed": [
"paymaya",
"brankas",
"qrph",
"dob",
"gcash",
"grab_pay"
],
"payments": [
{
"id": "pay_Haq1UQKf4p7b4cDRcxRrnF8j",
"type": "payment",
"attributes": {
"access_url": null,
"amount": 2000,
"balance_transaction_id": "bal_txn_wWWuZhjS4N45b5YYLS38cXTR",
"billing": {
"address": {
"city": "",
"country": "",
"line1": "",
"line2": "",
"postal_code": "",
"state": ""
},
"email": "[email protected]",
"name": "test1",
"phone": ""
},
"currency": "PHP",
"description": "test 1",
"disputed": false,
"external_reference_number": "SBuAjs2",
"fee": 400,
"instant_settlement": null,
"livemode": true,
"net_amount": 1600,
"origin": "links",
"payment_intent_id": "pi_EXpLFBparajBVHFiU78NKdY3",
"payout": null,
"source": {
"id": "qrph_Xp5eLQKwhJZd4njwa4EFXfa1",
"type": "qrph",
"provider": {
"id": "333444",
"code_id": "code_6K7HdrvrCrH937BSpJ6K4T5i"
}
},
"statement_descriptor": "test",
"status": "paid",
"tax_amount": 0,
"metadata": {
"pm_reference_number": "SBuAjs2"
},
"refunds": [],
"taxes": [
{
"amount": 43,
"currency": "PHP",
"inclusive": true,
"name": "VAT",
"type": "vat",
"value": "1200_bps"
}
],
"available_at": 1721984400,
"created_at": 1721812323,
"credited_at": 1722416400,
"paid_at": 1721812322,
"updated_at": 1721812323
}
}
],
"next_action": null,
"payment_method_options": null,
"metadata": {
"pm_reference_number": "SBuAjs2"
},
"setup_future_usage": null,
"created_at": 1721812019,
"updated_at": 1721812323
}
}
}
- If the QR Ph payment failed or the QR Ph code is expired (not paid within 30 mins from the time the QR Ph image URL was generated), the payment intent will revert back to
awaiting_payment_method
. You may create a new payment method resource and attach it to the payment intent to generate a new QR Ph code.
- For failed QR Ph payments, a webhook call will be made to the nominated and registered webhook endpoint subscribed to the
payment.failed
event. You may also check the status of the payment intent through the Retrieve a Payment Intent API - For expired QR Ph codes, a webhook call will be made to the nominated and registered webhook endpoint subscribed to the
qrph.expired
event.
- For failed QR Ph payments, a webhook call will be made to the nominated and registered webhook endpoint subscribed to the
{
"data": {
"id": "evt_123",
"type": "event",
"attributes": {
"type": "payment.failed",
"livemode": true,
"data": {
"id": "pay_kVjqqErX7nJatqtdJnTGdXs5",
"type": "payment",
"attributes": {
"access_url": null,
"amount": 2000,
"balance_transaction_id": null,
"billing": {
"address": {
"city": "",
"country": "",
"line1": "",
"line2": "",
"postal_code": "",
"state": ""
},
"email": "[email protected]",
"name": "test",
"phone": ""
},
"currency": "PHP",
"description": "test 2",
"disputed": false,
"external_reference_number": "FVFYMiG",
"failed_code": "RJCT",
"failed_message": "Unknown processing error.",
"fee": 0,
"instant_settlement": null,
"livemode": true,
"net_amount": 0,
"origin": "links",
"payment_intent_id": "pi_cufYwN1b9mzrvKpXXQLknRiB",
"payout": null,
"source": {
"id": "qrph_SprjmBZcaJKKHryvJvs3FoEL",
"type": "qrph",
"provider": {
"id": "444555",
"code_id": "code_xBF4wAhRSp3uagh3c8K3zB7i"
}
},
"statement_descriptor": "Test",
"status": "failed",
"tax_amount": 0,
"metadata": null,
"refunds": [],
"taxes": [],
"created_at": 1721814835,
"credited_at": null,
"paid_at": 1721814834,
"updated_at": 1721814835
}
}
}
}
}
{
"data": {
"id": "pi_cufYwN1b9mzrvKpXXQLknRiB",
"type": "payment_intent",
"attributes": {
"amount": 2000,
"capture_type": "automatic",
"client_key": "pi_cufYwN1b9mzrvKpXXQLknRiB_client_NyzkVvzEKsb9QtaBj3fexFsq",
"currency": "PHP",
"description": "test 2",
"livemode": true,
"statement_descriptor": "Test",
"status": "awaiting_payment_method",
"last_payment_error": null,
"payment_method_allowed": [
"gcash",
"paymaya",
"grab_pay",
"brankas",
"qrph",
"dob"
],
"payments": [
{
"id": "pay_kVjqqErX7nJatqtdJnTGdXs5",
"type": "payment",
"attributes": {
"access_url": null,
"amount": 2000,
"balance_transaction_id": null,
"billing": {
"address": {
"city": "",
"country": "",
"line1": "",
"line2": "",
"postal_code": "",
"state": ""
},
"email": "[email protected]",
"name": "test",
"phone": ""
},
"currency": "PHP",
"description": "test 2",
"disputed": false,
"external_reference_number": "FVFYMiG",
"failed_code": "RJCT",
"failed_message": "Unknown processing error.",
"fee": 0,
"instant_settlement": null,
"livemode": true,
"net_amount": 0,
"origin": "links",
"payment_intent_id": "pi_cufYwN1b9mzrvKpXXQLknRiB",
"payout": null,
"source": {
"id": "qrph_SprjmBZcaJKKHryvJvs3FoEL",
"type": "qrph",
"provider": {
"id": "444555",
"code_id": "code_xBF4wAhRSp3uagh3c8K3zB7i"
}
},
"statement_descriptor": "Test",
"status": "failed",
"tax_amount": 0,
"metadata": null,
"refunds": [],
"taxes": [],
"created_at": 1721814835,
"credited_at": null,
"paid_at": 1721814834,
"updated_at": 1721814835
}
}
],
"next_action": null,
"payment_method_options": null,
"metadata": {
"pm_reference_number": "FVFYMiG"
},
"setup_future_usage": null,
"created_at": 1721814680,
"updated_at": 1721814835
}
}
}
{
"data": {
"id": "evt_Y4BLNd6MhCDc4SYCWngSAq2Y",
"type": "event",
"attributes": {
"type": "qrph.expired",
"livemode": true,
"data": {
"id": "qrph_Dbzwvb5X44BSJc4MgLpZXFaF",
"type": "qrph",
"attributes": {
"code_id": "code_i7CXZFeM9xFcB1p3DsjRE5Lr",
"livemode": true,
"organization_id": "org_hQBQmY5mDBPCpFmGSBfKJV2w",
"created_at": "2024-08-07T15:59:11.179+08:00",
"source_id": "src_FnGTG2jUXrCXSrK7UBX2Zj1h",
"source_status": "expired",
"payment_intent_id": "pi_3z1Va2HEd1cfjAWzx6N7Cppm"
}
},
"previous_data": {},
"created_at": 1723019372,
"updated_at": 1723019372
}
}
}
QR Ph codes generated using the Payment Intent flow and not paid within 30 minutes will expire and should not be used anymore. Once the QR Ph code is expired, the customer won't be able to pay anymore. These QR Ph codes are also designed to be one-time use only.
Generating Reusable QR Ph Codes
Currently only supports the generation of Static QR Ph Codes. For Static QR Ph codes, customers input the payment amount after scanning the QR Ph code. These reusable QR Ph Codes can be used primarily for in-store use and displayed at your store's point of purchase in the form of a standee or digital display.
QR Ph Code Resource
{
"data": {
"id": "code_rmDbeEY1oxyPRU9zuKHEEX5y", #unique ID assigned to each QR Ph code
"type": "code",
"attributes": {
"mobile_number": "+639191234567",
"qr_image": "data:image/png;base64,iVB...mCC",
"name": "Paymongo Test"
}
}
}
Attribute | Description |
---|---|
qr_image | Base64-encoded, data/image URL of the QR image generated using the generated QR string. |
mobile_number | Recipient of the SMS notification we send out for every payment made using the code |
name | Store name that will appear when scanning the QRPH code. Applies to all providers |
Creating a Static QR Ph Code
Generates QR Ph codes and creates a code record for it via API.
1. Call the API Endpoint using your Live API Keys, which can be found on your PayMongo dashboard once activated.
- It's important to note that each QR Code will have a unique QR Code ID which can be used to reference each generated QR Code.
Payload
{
"data": {
"attributes": {
"kind": "instore",
"mobile_number": "+639191234567"
}
}
Parameter | Description | Validation | Value |
---|---|---|---|
mobile_number | Mobile number that will receive the SMS confirmation on a successful payment Note: If no mobile_number is added, no SMS notification will be sent for successful QR Ph payments | Optionalmobile_number | +639191234567 |
kind | Kind of QR Ph code to generate | Required | 'instore' |
notes | Additional notes to be used to identify the generated code (for your internal use, does not get displayed to the customer) | Optional String | 'Main Branch' 'Cashier 1' |
2. Convert the Base-64-encoded string from the API response into an image.
- The QR Ph image will be in the API response under
data.attributes.qr_image
as a Base64-encoded string. You can use any Base-64 to Image Converter to convert the QR Image string into an actual image.
{
"data": {
"id": "code_Yk3HN6HvWddSrNwhM3dKkYeA",
"type": "code",
"attributes": {
"mobile_number": "+639191234567",
"qr_image": "data:image/png;base64,iVBO...ggg==", #This is the base-64-enconded string
"name": "Paymongo Test"
}
}
}
3. Start accepting payments with your static QR Ph code!
- Once you have converted the string into an image, you can now print out or display this QR Ph code in your store.
4. Finish
- To determine if the QR Ph payment has already been paid, a webhook call will be made to the nominated and registered webhook endpoint subscribed to the
payment.paid
event.
Updated about 2 months ago