NEW PayNext Extra Installment QR

Topics covered on this page

PayNext Extra Installment QR

Accept offline installment payments from TrueMoney Wallet users through your point-of-sale (POS) system using the PayNext Extra Installment QR payment method.

📋 Overview

Property Value
Payment method PayNext Extra Installment QR
Source type installment_paynext_extra_qr
Payment flow offline
Supported countries Thailand
Currency THB
Minimum amount No minimum
Maximum amount āļŋ5,000.00 (500000)
Minimum API version 2017-11-02

✅ How to enable PayNext Extra Installment QR

To enable PayNext Extra Installment QR for your account, email support@omise.co to request the feature. You will be required to review and accept updated terms and conditions before the payment method is activated.

🔄 Payment flow

PayNext Extra Installment QR uses an offline payment flow. Once the charge is created, your POS terminal displays a QR code which the customer scans using their TrueMoney Wallet app. Authorization happens entirely offline — there is no browser redirect.

PayNext Extra Installment QR – payment flow

Important: There are two separate expiry windows to be aware of: - Source expiry: If the customer does not scan the QR code within the time allowed, the source expires and the charge becomes expired. - Charge expiry: If the charge is not completed within 1 day of creation (see expires_at in the charge response), it expires automatically.

These are independent. Build your retry logic to handle both: display a new QR code for a scan timeout; treat a 1-day expiry as an abandoned order.

The payment flow proceeds as follows:

  1. The customer selects PayNext Extra Installment QR as their payment method at the POS terminal.
  2. Your POS system generates and displays a QR code.
  3. The customer opens the TrueMoney Wallet app and scans the QR code.
  4. The customer selects their preferred installment term and interest rate.
  5. A payment summary is displayed for review.
  6. The customer confirms the payment.

⚙ïļ Implementation

To accept a PayNext Extra Installment QR payment, complete the following steps:

  1. Create a source — Create a new payment source with type: installment_paynext_extra_qr using Omise.js or a mobile SDK (iOS / Android).
  2. Create a charge — Create a new charge using the source identifier returned in Step 1. The charge response contains the QR code image.
  3. Display the QR code — Extract the QR code from source.scannable_code.image.download_uri in the charge response and display it on the POS terminal.
  4. Verify the charge — After receiving the charge.complete webhook event, retrieve the charge to confirm its status (optional but recommended).

Use your public key to create the source (client-side). Use your secret key to create the charge (server-side).

If source creation and charge creation must both happen server-side, you can combine them into a single API request using your secret key.

Step 1 — Creating a source

When the customer confirms they want to pay with PayNext Extra Installment QR, create a new source with the following parameters.

Parameter Type Required Description
amount integer Yes Payment amount in subunits. Maximum 500000 (āļŋ5,000.00). No minimum. See Limits.
currency string Yes Must be THB.
type string Yes Must be installment_paynext_extra_qr.
promotion_code string No A promotional code provided by TrueMoney.

The following examples create a new PayNext Extra Installment QR source for āļŋ500.00 (50000). Replace omise_public_key / $OMISE_PUBLIC_KEY with your test public key from your dashboard.

In Omise.js, type is passed as the first argument to createSource.

Omise.js

Omise.setPublicKey(omise_public_key);

Omise.createSource('installment_paynext_extra_qr', {
  "amount": 50000,
  "currency": "THB"
}, function(statusCode, response) {
  console.log(response);
});

cURL

curl https://api.omise.co/sources \
  -u $OMISE_PUBLIC_KEY: \
  -d "amount=50000" \
  -d "currency=THB" \
  -d "type=installment_paynext_extra_qr"

Example response

{
  "object": "source",
  "id": "src_test_601oy3f2u9m8llki4eh",
  "livemode": false,
  "location": "/sources/src_test_601oy3f2u9m8llki4eh",
  "amount": 50000,
  "currency": "THB",
  "flow": "offline",
  "type": "installment_paynext_extra_qr",
  "charge_status": "unknown",
  "created_at": "2024-06-11T01:52:37Z",
  "barcode": null,
  "bank": null,
  "email": null,
  "installment_term": null,
  "ip": "35.198.236.178",
  "absorption_type": null,
  "name": null,
  "mobile_number": null,
  "phone_number": null,
  "platform_type": null,
  "scannable_code": null,
  "billing": null,
  "shipping": null,
  "items": [],
  "references": null,
  "provider_references": null,
  "store_id": null,
  "store_name": null,
  "terminal_id": null,
  "zero_interest_installments": null,
  "receipt_amount": null,
  "discounts": [],
  "promotion_code": null
}

The id field (prefixed src_) is the source identifier used in the following step.

Notable response fields

Field Description
installment_term null at source creation. The customer selects their installment term after scanning the QR code in the TrueMoney Wallet app. Do not expect or validate this value at this stage.
scannable_code null at source creation. The QR code is populated here once the charge is created. See Displaying the QR code.
absorption_type Controls whether the merchant or the customer absorbs the installment interest. null indicates the default configured for your account. Contact support@omise.co if you need to change the absorption behaviour.
charge_status Reflects the status of any charge associated with this source. unknown at source creation; updates to pending once a charge is created.

Step 2 — Creating a charge

Create a charge using the source identifier from Step 1.

Parameter Type Required Description
amount integer Yes Must match the amount of the source.
currency string Yes Must match the currency of the source.
source string Yes The source id returned in Step 1.
return_uri string No URL to redirect the customer to after payment completion.

Replace $OMISE_SECRET_KEY with your test secret key from your dashboard and $SOURCE_ID with the id of the source.

cURL

curl https://api.omise.co/charges \
  -u $OMISE_SECRET_KEY: \
  -d "amount=50000" \
  -d "currency=THB" \
  -d "return_uri=http://example.com/orders/345678/complete" \
  -d "source=$SOURCE_ID"

Example response

{
  "object": "charge",
  "id": "chrg_test_601oy3hvu3uq3nq3tyd",
  "location": "/charges/chrg_test_601oy3hvu3uq3nq3tyd",
  "amount": 50000,
  "currency": "THB",
  "funding_currency": "THB",
  "funding_amount": 50000,
  "net": 48047,
  "fee": 1825,
  "fee_vat": 128,
  "interest": 0,
  "interest_vat": 0,
  "refunded_amount": 0,
  "transaction_fees": {
    "fee_flat": "0.0",
    "fee_rate": "3.65",
    "vat_rate": "7.0"
  },
  "status": "pending",
  "authorize_uri": "https://pay.omise.co/payments/pay2_test_601oy3hxhpyo26m91kh/authorize",
  "return_uri": "http://example.com/orders/345678/complete",
  "source": {
    "object": "source",
    "id": "src_test_601oy2ze4198tfx1qme",
    "livemode": false,
    "amount": 50000,
    "currency": "THB",
    "flow": "offline",
    "type": "installment_paynext_extra_qr",
    "charge_status": "pending",
    "scannable_code": {
      "object": "barcode",
      "type": "qr",
      "image": {
        "object": "document",
        "livemode": false,
        "id": "docu_test_601oy3k3ijlgvs0a2d8",
        "deleted": false,
        "filename": "qrcode.png",
        "location": "/charges/chrg_test_601oy3hvu3uq3nq3tyd/documents/docu_test_601oy3k3ijlgvs0a2d8",
        "kind": "qr",
        "download_uri": "https://api.omise.co/charges/chrg_test_601oy3hvu3uq3nq3tyd/documents/docu_test_601oy3k3ijlgvs0a2d8/downloads/9F489F5C90D7AD27",
        "created_at": "2024-06-11T01:52:38Z"
      }
    },
    "provider_references": {
      "reference_number_1": "pay2_test_601oy3hxhpyo26m91kh",
      "reference_number_2": null
    }
  },
  "authorized": false,
  "capturable": false,
  "capture": true,
  "paid": false,
  "expired": false,
  "reversed": false,
  "reversible": false,
  "refundable": false,
  "partially_refundable": false,
  "disputable": false,
  "voided": false,
  "can_perform_void": false,
  "livemode": false,
  "created_at": "2024-06-11T01:52:38Z",
  "paid_at": null,
  "expires_at": "2024-06-12T01:52:38Z"
}

Notable response fields

Field Description
source.scannable_code.image.download_uri The URL of the QR code image to display on your POS terminal. Fetch and render this image immediately after the charge is created. The URL requires authentication with your secret key.
expires_at The datetime at which the charge automatically expires if not completed. For PayNext Extra Installment QR this is 1 day after creation.
source.provider_references.reference_number_1 A TrueMoney-issued transaction reference number. Retain this value — it is required when raising support tickets or performing reconciliation with TrueMoney. reference_number_2 is not used for this payment method and will always be null.
net The amount that will be settled to your account after fees and VAT are deducted.

Creating a source and charge in a single request

If both source creation and charge creation must happen server-side, you can combine them into a single API call using your secret key.

curl https://api.omise.co/charges \
  -u $OMISE_SECRET_KEY: \
  -d "amount=50000" \
  -d "currency=THB" \
  -d "return_uri=http://example.com/orders/345678/complete" \
  -d "source[type]=installment_paynext_extra_qr"

Step 3 — Completing the charge

The charge is created with a status of pending. The following sections explain how to display the QR code, receive the webhook event, and confirm the final charge status.

Full payment sequence

sequenceDiagram participant Customer participant OmiseJS participant Merchant participant OmiseAPI participant TrueMoney Customer->>OmiseJS: Send payment details OmiseJS->>OmiseAPI: Request source OmiseAPI-->>OmiseJS: Return source OmiseJS->>Merchant: Pass source to merchant Merchant->>OmiseAPI: Request charge OmiseAPI-->>Merchant: Send charge.create webhook OmiseAPI-->>Merchant: Return charge with QR code Merchant->>Customer: Display QR code on POS terminal Customer->>TrueMoney: Scan QR code and confirm payment TrueMoney-->>OmiseAPI: Return payment result OmiseAPI-->>Merchant: Send charge.complete webhook Merchant-->>Customer: Send charge result

Authorising the charge

Extract the QR code URL from the charge response and display it on your POS terminal:

charge
  └── source
        └── scannable_code
              └── image
                    └── download_uri  ← QR code image URL

Fetch the image from download_uri using your secret key and render it at the POS terminal. The customer then scans the QR code with their TrueMoney Wallet app to complete the payment.

Testing: In test mode, go to the specific charge on the Omise dashboard, click Actions, and manually mark the charge as Successful or Failed. Use this to verify your webhook handler before going live.

Receiving the charge completion webhook

Set up an endpoint on your server to receive webhook events, and register it on the Omise dashboard. Omise sends a charge.complete event when the charge reaches a final status.

Verifying the charge status

After receiving the charge.complete webhook, retrieve the charge by its id and confirm that the status in the retrieved charge matches the status in the webhook event.

Status Meaning
successful Payment was received.
failed Payment failed. Check failure_code and failure_message for details.
expired The charge was not completed within the allowed time.

Possible failure codes

Failure code Description
failed_processing General payment processing failure.

â†Đïļ Voids and refunds

  • Voids: A PayNext Extra Installment QR charge can only be voided on the same day as the transaction authorisation.
  • Refunds: Refunds can only be issued within 30 days of a successful payment.

For refund instructions, see the Refunds API documentation.

📊 Limits

Amount (subunits) Amount (THB)
Minimum None No minimum
Maximum 500000 āļŋ5,000.00

🔧 Troubleshooting

The charge status is expired

There are two causes:

  • Scan timeout: The customer did not scan the QR code within the allowed time. Display a new QR code by creating a new source and charge.
  • 1-day charge timeout: The charge was not completed within 1 day of creation (see expires_at in the charge response). This typically indicates an abandoned order. No retry is necessary unless the customer returns.

The charge status is failed with failure_code: failed_processing

A general processing failure occurred on the TrueMoney side. Prompt the customer to retry the payment. If the issue persists, contact support@omise.co.

The customer was redirected to return_uri but the charge is still pending

Do not rely solely on the return_uri redirect to determine charge status. Always wait for the charge.complete webhook event and verify the charge status by retrieving it from the API.

The QR code is not displaying

Confirm that your POS system is fetching the image from source.scannable_code.image.download_uri in the charge response. This field is null at source creation and only populated once the charge is created. Also confirm the request is authenticated with your secret key.

The amount is rejected with a validation error

Confirm the amount does not exceed the maximum of 500000 (āļŋ5,000.00). There is no minimum. Also confirm the amount and currency values on the charge request exactly match those on the source.

The promotion_code field has no effect

Promotional codes are issued by TrueMoney and must be valid and active at the time of source creation. Contact TrueMoney directly to verify that the code is active and applicable to your transaction.

❓ Frequently asked questions

Which countries and currencies does PayNext Extra Installment QR support? PayNext Extra Installment QR is supported in Thailand only and processes payments in Thai Baht (THB).

Does the customer need a TrueMoney Wallet account? Yes. The customer must have an active TrueMoney Wallet account to scan the QR code and complete the payment.

What is the difference between PayNext Extra Installment QR and PayNext Extra Installment App Redirection? PayNext Extra Installment QR is designed for offline POS environments. Your terminal displays a QR code that the customer scans. PayNext Extra Installment App Redirection is designed for online checkouts, where the customer is redirected to TrueMoney Wallet via their browser or the app. QR charges expire after 1 day; App Redirection charges expire after 7 days.

Where is the QR code in the API response? The QR code image URL is at source.scannable_code.image.download_uri inside the charge response. It is null at source creation and only populated after the charge is created.

What happens if the customer does not scan the QR code in time? The charge status becomes expired. Create a new source and charge to generate a fresh QR code.

Can I use this payment method without Omise.js? Yes. If both source creation and charge creation occur on your server, you can use the single-request approach with your secret key — no client-side SDK required. See Creating a source and charge in a single request.

Can I refund a PayNext Extra Installment QR charge? Yes, refunds are supported within 30 days of a successful payment. Voids are only possible on the same day as the transaction. See the Refunds API documentation.

How do I test this integration? Use your test public and secret keys from the Omise dashboard. After creating a charge, go to the charge on the dashboard, click Actions, and manually mark it as Successful or Failed.

Where can I find my API keys? See How to access Omise API keys.

🔑 API keys

For information on how to obtain your public and secret keys, see How to access Omise API keys.

Omise uses cookies to improve your overall site experience and collect information on your visits and browsing behavior. By continuing to browse our website, you agree to our Privacy Policy. Learn more