Skip to navigation

Decode QR

View as Markdown

Decodes a scanned QR string and returns the fields needed for getQuotation and executePayout.

When to use decodeQr vs lookupPaymentCode

  • Use decodeQr for EMV / local QR payloads captured from a scan (or Bolivia encrypted QR).
  • Use lookupPaymentCode for bank and e-wallet transfer destinations that are not QR payloads: PIX keys, phone numbers, bank account numbers, BREB keys, Africa till/paybill lookup, Vietnam account+BIN, Indonesia e-wallet phones and bank accounts, and NG/GH/ZM bank or mobile-money numbers. Calling decodeQr with those destinations returns 400 INVALID_REQUEST.

Flow

  1. Authenticates the request and verifies customer_id exists under your account (registered via registerCustomer).
  2. Derives routing hints from the QR, then parses and enriches the QR string for the destination corridor.
  3. Validates supported country/currency for the QR against your account configuration (INVALID_COUNTRY_CODE, INVALID_CURRENCY when not allowed).
  4. Computes is_dynamic and is_business from QR metadata when available, otherwise from fallback rules on the decoded data.
  5. Creates a PENDING transaction and returns tx_id.

Authentication

  • REQUIRED: Basic Auth: Authorization: Basic base64(client_id:client_secret).
  • Body-based client_id / client_secret is deprecated and not supported.
  • Exchange app identity comes from authentication (do not rely on a body exchange_app_id).

Request body

  • qr_string (string, required) — EMV / local QR payload. For KE/TZ a numeric till/paybill may be passed as qr_string.
  • customer_id (string, required) — registered customer; must not contain /.
  • partner_transaction_id (string, optional)
  • partner_app_id (string, optional, 1–64 chars [a-zA-Z0-9_-]) — tags the transaction with a partner sub-app; body wins over the value stored on the customer.
  • wallet_identifier (string, optional): stored on the transaction when provided.
  • country_code (string, optional override): ISO alpha-2. Required when the QR string is not EMV-parseable:
  • BO — Bolivia encrypted QR
  • KE / TZ — a typed till or paybill number instead of an EMV QR (requires merchant_id)
  • merchant_id (string, optional): Till or paybill number for KE/TZ when using decodeQr directly.
  • account_reference (string, optional): Paybill bill reference when the merchant expects one.

Response (200 JSON) — curated public fields only.

  • is_dynamic, is_business, amount, merchant, country, tx_id, currency, partner_transaction_id (empty string if not sent)
  • missing_fields (optional): machine-readable schemas for required data not yet satisfied
  • suggested_values (optional): hints keyed by field paths for UI prefill
  • sender / recipient (optional): grouped echoes when meaningful after decode
  • qr_type (Philippines): qrph_p2m for a merchant QR, qrph_p2p for a personal wallet QR.
  • recipient.bank_name and recipient.bank_list_code (Philippines): the beneficiary institution and its code from listBanks?country_code=PH, usable directly as payment_destination_code.
  • Africa (KE/TZ): merchant_id, merchant_name, payment_type (till or paybill), merchant_info when a typed till or paybill is decoded
  • When amount > 0 and pricing succeeds: amount_usd, fee, percentage_fee, fixed_fee (USD values rounded to 2 decimal places). exchange_rate is not returned here (use getQuotation / executePayout).

Satisfying missing_fields:

  • amount (static QR): send the amount to getQuotation, then as amount_confirmed to executePayout.

  • recipient.name (Vietnam): the name normally comes from the bank’s account-name inquiry during decode, so it is listed only when that inquiry returned nothing. recipient.bank_no is always echoed: if it is not a code in listBanks?country_code=VN, the destination is not payable (cardless-ATM withdrawal codes, merchant category 6011, are the common case). If the bank is listed, retry decodeQr once; if the name is still missing, pass recipient_name at executePayout. recipient.name_first / recipient.name_last are derived from it.

  • recipient.account or recipient.account_no on a merchant QR: the destination could not be resolved on the payment network. Do not execute; it is rejected with MISSING_REQUIRED_FIELDS before any balance is locked.

Bank terminology: Prefer grouped recipient.bank_no; legacy flat keys are mapped internally.

Payout flow: decodeQr or lookupPaymentCode → getQuotation (recommended when locking fees/amount) → executePayout.

LATAM is_dynamic: Open-amount and manual-amount QRs return is_dynamic: false with amount: 0 until getQuotation supplies the amount.

Errors: CUSTOMER_NOT_ELIGIBLE, INVALID_COUNTRY_CODE, INVALID_CURRENCY, corridor amount limit violations, and INVALID_REQUEST when a typed destination is sent to decodeQr instead of lookupPaymentCode.

See Corridor Examples and lookupPaymentCode for per-country sample requests.

Authentication

AuthorizationBasic

Basic Auth: base64(client_id:client_secret)

Query parameters

dpintegerOptional0-10Defaults to 2

Decimal places for monetary fields in the response (USD amounts, fees, exchange rates). Default 2, which rounds sub-cent fees to 0. Use dp=4 or higher to reconcile against exact deducted totals: at full precision amount_usd + percentage_fee + fixed_fee equals the amount deducted from your balance. Rounding is applied to the response only; all stored values and balance deductions always use full precision.

Request

This endpoint expects an object.
qr_stringstringRequired

EMV / local QR string, or for KE/TZ a numeric till/paybill number.

customer_idstringRequired
partner_transaction_idstringOptional
partner_app_idstringOptional

Optional partner sub-app id (1–64 chars, [a-zA-Z0-9_-]). Body value wins over the customer profile value.

payment_currencystringOptional
ISO 4217 source currency when it cannot be resolved from the QR.
wallet_identifierstringOptional
country_codestringOptional

ISO alpha-2 override. Required when QR is not EMV-parseable (e.g. BO encrypted QR, or KE/TZ + merchant_id).

merchant_idstringOptional

Till or paybill number for KE/TZ, typed instead of scanned, via decodeQr. Prefer /lookupPaymentCode for the same flow.

account_referencestringOptional

Paybill account reference: the account, bill or customer number the paybill expects. Required for Kenya paybills (returned in missing_fields when absent); optional for TZ.

Response

OK
is_dynamicbooleanOptional
is_businessbooleanOptional
amountdoubleOptional
merchantstringOptional
merchant_idstringOptional

Africa (KE/TZ) till or paybill number when returned.

merchant_namestringOptional

Africa (KE/TZ) verified merchant display name when returned.

payment_typeenumOptional

Africa (KE/TZ) payment destination type when returned.

Allowed values:
merchant_infoobjectOptional

Africa (KE/TZ) merchant metadata when returned.

countrystringOptional
tx_idstringOptional
currencystringOptional
partner_transaction_idstringOptional
amount_usddoubleOptional
feedoubleOptional
percentage_feedoubleOptional
fixed_feedoubleOptional
missing_fieldslist of maps from strings to anyOptional
suggested_valuesmap from strings to anyOptional
sendermap from strings to anyOptional
recipientmap from strings to anyOptional

Errors

400
Bad Request Error