QR Code Transaction
Note:QR Code Transactions are currently only available for Payflex
What is a QR Code Transaction?
QR Code Payments enable customers to complete transactions by scanning a QR code using a mobile wallet or payment app. The QR code contains key transaction details such as the merchant identifier, transaction amount, currency, and reference number. The platform supports dynamic QR codes (generated per transaction with real-time data). This payment method offers a fast, secure, and contactless experience. When initiating a QR code payment, the API response will return the encoded QR code data (as string text) for display to the customer.
The QR code payment request allows POS Applications to integrate QR code payment processing into their applications. To process a QR code payment the POS must initiate a QR code payment request to POSBuddy Cloud via a REST API call, in order to understand if the transaction succeeded of failed.
Note:Every QR code payment request needs to include Authentication
QR Code Payment Request
POST
The following API call types are available for a QR code payment, ensure to make use of the correct endpoint.
| API CALL TYPES | ENDPOINT |
|---|---|
| Asynchronous | /v/1/payment/async |
| Synchronous | /v/1/payment/sync |
Example: QR Code Payment
BODY
The following is an example of a QR_CODE_PAYMENT request body for R15.00
{
"launchType": "QR_CODE_PAYMENT",
"merchantID": "merchantID",
"posID": "posId",
"serialNumber": "serialNumber",
"transactionAmount": 1500,
"extraParameters": {
"transactionUuid" : "bdf9d0af-17b3-48ca-8a0b-37dc52bf49bc",
"externalRRN": "HcMQSFcY",
"externalTerminalId": "98100010",
"externalInvoiceGUID": "2fdca02f-3cbe-4e8c-82ad-86a1a16b72e8",
"externalTransactionDateTime" : "2025-09-17T09:16:59.6387832+00:00"
}
}String apiUrl = "https://paymentuat.test.thumbzup.com/posbuddy-cloud/v/1/";
JSONObject extraParameters = new JSONObject();
extraParameters.put("transactionUuid", UUID.randomUUID().toString());
extraParameters.put("externalRRN", "HcMQSFcY");
extraParameters.put("externalTerminalId", "98100010");
extraParameters.put("externalInvoiceGUID", "2fdca02f-3cbe-4e8c-82ad-86a1a16b72e8");
extraParameters.put("externalTransactionDateTime", "2025-09-17T09:16:59.6387832+00:00");
JSONObject requestBody = new JSONObject();
requestBody.put("launchType", "QR_CODE_PAYMENT");
requestBody.put("merchantID", merchantID);
requestBody.put("posId", posId);
requestBody.put("serialNumber", serialNumber);
requestBody.put("transactionAmount", 1500);
requestBody.put("extraParameters", extraParameters);
// See Authentication for details of the generateHeaders function
Map<String, String> headers = generateHeaders(secretKey, accessKey, userAgent, serialNumber, posId);
RequestBodyEntity request = Unirest.post(apiUrl + "payment/sync")
.headers(headers)
.body(requestBody.toString());
HttpResponse<JsonNode> response = request.asJson();# See Authentication page for details of the variables
RESPONSE=$(curl --request POST \
--url "$API_URL/v/1/payment/sync" \
--header "X-pos-id: POS-STORE123-TERM01" \
--header "X-tu-authorization: protocol:TU1,accesskey:$ACCESS_KEY,signedheaders:User-Agent;X-tu-date;X-tu-random,signature:$SIGNATURE" \
--header "X-tu-random: $RANDOM_VAL" \
--header "X-tu-serial: $SERIAL_NUMBER" \
--header "X-tu-date: $TU_DATE" \
--header "User-Agent: $USER_AGENT" \
--header "Content-Type: application/json" \
--data "{
\"launchType\": \"QR_CODE_PAYMENT\",
\"merchantID\": \"$MERCHANT_ID\",
\"posId\": \"POS-STORE123-TERM01\",
\"serialNumber\": \"$SERIAL_NUMBER\",
\"transactionAmount\": 1500,
\"extraParameters\": {
\"transactionUuid\": \"0c116ebf-53e0-465d-afad-6c174a4abb49\",
\"externalRRN\": \"HcMQSFcY\",
\"externalTerminalId\": \"98100010\",
\"externalInvoiceGUID\": \"2fdca02f-3cbe-4e8c-82ad-86a1a16b72e8\",
\"externalTransactionDateTime\": \"2025-09-17T09:16:59.6387832+00:00\"
}
}" \
)Request Body Fields
The following table describes the REQUIRED request body fields of the QR_CODE_PAYMENT request message.
FIELD | TYPE | DESCRIPTION | EXAMPLE |
|---|---|---|---|
REQUIRED | |||
launchType | STRING | Must be “QR_CODE_PAYMENT”. | QR_CODE_PAYMENT |
merchantID | STRING | The merchant ID assigned to the merchant. | 910100000000001 |
posId | STRING | The POS ID is a unique identifier for the originating Point of Sale terminal. In multi-terminal environments, each device requires a distinct alphanumeric identifier (e.g., POS1, POS2, CHECKOUT_A). | POS-STORE123-TERM01 |
serialNumber | STRING | The serial number of the target payment terminal for this payment request. | PC05P2CG10036 |
transactionAmount | LONG | The full transaction amount to be charged in cents. | 1500 |
extraParameters Object
The following table describes the OPTIONAL extraParameters object of the QR_CODE_PAYMENT request message.
FIELD | TYPE | DESCRIPTION | EXAMPLE |
|---|---|---|---|
transactionUuid | STRING ALPHANUMERIC | A Universally Unique Identifier (UUID) assigned to each transaction so it can be uniquely tracked, referenced, or correlated across different systems. Most programming languages provide built-in functions to generate UUIDs. Examples: // Kotlin // JavaScript `# Pythontransaction_uuid = str(uuid.uuid4())Although this is an optional field, it is strongly recommended for the POS to send this value. | bdf9d0af-17b3-48ca-8a0b-37dc52bf49bc |
externalRRN | STRING ALPHANUMERIC | A RRN generated by some 3rd party ERP systems. Although this is an optional field, it is strongly recommended for the POS to send this value. | ABCDEF123456 |
externalTerminalId | STRING | A terminal identifier for device configured on the 3rd party ERP system. Although this is an optional field, it is strongly recommended for the POS to send this value. | 98100010 |
externalInvoiceGUID | STRING ALPHANUMERIC | A GUID that identifies a particular invoice that may appear on more than one transaction. Although this is an optional field, it is strongly recommended for the POS to send this value. | 2fdca02f-3cbe-4e8c-82ad-86a1a16b72e9 |
externalTransactionDateTime | STRING | A date and time the transaction was generated on the 3rd party ERP systems. Has the format of “yyyy-MM-dd'T'HH:mm:ss” Although this is an optional field, it is strongly recommended for the POS to send this value. | 2017-04-28T09:30:00 |
merchantName | STRING | The name of the merchant that requested the transaction, as stored at the bank. | Merchant A |
transactionDescription | STRING | Reference description for the merchant’s records. | 3rd party app desc |
transactionReferenceNumber | STRING | Reference number field that also appears in a merchant portal when available. | ref#123456 |
cellNumberToSMSReceipt | STRING | 10-digit cell phone number for receipt SMS destination. Can be blank. | 0721234567 |
emailAddressToSendReceipt | ALPHANUMERIC | Valid email address for receipt email destination. Can be blank. | |
isReceiptRequired | BOOLEAN | If set to true, at least one of the receipt parameters above needs to be set. | true |
alwaysShowTransactionStatusScreen | BOOLEAN | Once the Ecentric Payment App has processed a transaction there is a status screen that shows the success/failure of processing. | true |
externalSTAN | STRING | A systems trace number generated by some 3rd party ERP systems. | 123456 |
externalTransactionGUID | STRING ALPHANUMERIC | A GUID that identifies a specific transaction generated by 3rd party ERP systems. | 2fdca02f-3cbe-4e8c-82ad-86a1a16b72e8 |
latitude | STRING | A geolocation identifier indicating the latitude position of the device. | -28.1619942 |
longitude | STRING | A geolocation identifier indicating the longitude position of the device. | 30.2350981 |
accuracy | STRING | A accuracy indicator of the geolocation. |
QR Code Payment Response
Result Codes
| RESULTCODE | DESCRIPTION |
|---|---|
| 01 | Successful transaction |
| 02 | Declined transaction |
| 03 | Aborted transaction |
| 04 | Error occurred with the transaction |
API Call Types
Note:Please take note of the tables below around the API Call Type that is being used and the response type that can be expected per API Call Type.
API CALL TYPES | RESPONSE TYPE | DESCRIPTION |
|---|---|---|
Webhook | If the POS is making use of the Asynchronous REST API call, the POS will receive a JSON BODY response for a QR code payment request, however the JSON BODY response will just be a confirmation that POSBuddy cloud received the request. Once the QR code payment is finalised on the terminal, a webhook callback is sent to the POS to confirm the transaction outcome. The webhook ismandatory when making use of Asynchronous REST API calls. Please refer to the Webhook section to set up webhooks. | |
JSON BODY | If the POS is making use of the Synchronous REST API call, the POS will receive a JSON BODY response for a QR code payment request. The POS has the option to also receive a webhook response for the QR code payment request, however this is optional. |
Example: QR Code Payment
Note:
- The “receiptBundle” will only be present if the field “isReceiptDataAvailable” is set to true in the request.
- The “transactionUuid” will not be present if an error occurred whilst communicating with server.
BODY
The following is an example of a QR_CODE_PAYMENT response body the POS Application will receive.
{
"resultDescription": "APPROVED",
"buildInfo": "Ecentric",
"isReceiptDataAvailable": true,
"resultCode": "01",
"receiptBundle": {
"CARD_DESCRIPTION" = "",
"MERCHANT_REGION_CODE": "09",
"RC_ALT": "00",
"CASH_AMOUNT_CENTS": "0",
"SEQ_NO": "000",
"STATUS": "APPROVED",
"BUDGET_PERIOD": "0",
"CARD_TYPE": "",
"PAN_WITH_BIN": "",
"MERCHANT_ID": "770000000000123",
"TIMESTAMP": "1745476020950",
"EXTERNAL_TRANSACTION_DATETIME": "",
"PROCESSING_CODE": "0",
"RC_DESCRIPTION": "Approved",
"EXTERNAL_INVOICE_GUID": "aaaaaaaa-ffff-1111-2222-8cbbcc334426",
"REPLACEMENT_MERCHANT_ID": "",
"BATCH_NO": "000",
"AUTH_PROFILE": "0",
"INTERCHANGE": "null",
"ESC_BY_AUTH_CODE": "226 00 IH 15882",
"TX_TYPE": "0",
"ACC_TYPE_DESC": "Default",
"TIP_AMOUNT": "",
"CURRENCY_CODE": "0710",
"AUTH_CODE": "",
"RC": "00",
"AID": "",
"ATC": "",
"CRY": "",
"CVM": "none",
"PAN": "",
"RRN": "511427060006",
"TSI": "",
"TVR": "",
"APSN": "",
"DATE": "2025-04-24T06:27:06.749+0000",
"STAN": "",
"NAME_ON_CARD": "",
"AMOUNT_CENTS": "1000",
"ABS_AMOUNT": "10.00",
"TOKEN": "",
"RECEIPT_NUMBER": "",
"EXTENDED_TRX_TYPE": "",
"TERMINAL_ID": "77012398",
"TX_TYPE_DESCRIPTION": "QR PAYMENT",
"EXTERNAL_TERMINAL_ID": "",
"FORMATTED_AMOUNT": "R 10.00",
"DESCRIPTION": "511427060006",
"BATCH_NUMBER": "0",
"SETTLEMENT_DATE": "",
"SURCHARGE_AMOUNT": "0.00",
"EXTERNAL_TRANSACTION_GUID": "",
"CARD_BIN": "",
"TRANSACTION_INFO": "22600IH15882",
"REPLACEMENT_TERMINAL_ID": "",
"POS_ENTRY": "",
"RC_ISO_DESCRIPTION": "Success",
"APPLICATION_LABEL": "",
"MERCHANT_CITY": "Cape Town",
"MERCHANT_NAME": "Istore",
"CUSTOMER_NAME": "",
"APP_VERSION": "",
"CARD_SEQ_NO": "0",
"APP_LABEL": "",
"INVOICE_NUM": "",
"MESSAGE_1": "",
"MESSAGE_2": "",
"CARD_TRANSACTION_TYPE": "ALTERNATIVE_PAYMENT",
"FORMATTED_CASH_AMOUNT": "R 0.00",
"CASH_AMOUNT": "0.00",
"RESULT_CODE": "00",
"MERCHANT_COUNTRY_CODE": "ZA",
"REPRINT": "false",
"PAN_HASH": "",
"AMOUNT": "10.00",
"TIP_LABEL": "",
"DIGITS": "",
"CVM_ABSA": ""
},
"merchantID": "770000000000123",
"serialNumber": "PF5544544664",
"posId": "POS-STORE123-TERM01",
"launchType": "QR_CODE_PAYMENT",
"transactionUuid": "bdf9d0af-17b3-48ca-8a0b-37dc52bf49bc",
"appVersion": "1.9.2",
"transactionAmount": "1500"
}Response Body Fields
The following table describes the response body fields of the QR_CODE_PAYMENT response message.
FIELDS | TYPE | DESCRIPTION | EXAMPLE |
|---|---|---|---|
launchType | STRING | Echo of the launchType used in the POSBuddy Cloud request. | QR_CODE_PAYMENT |
resultCode | STRING | Represents the result status of the intent call to the Ecentric Payment App | 01 |
resultDescription | STRING | A user readable representation of the above resultCode i.e. Approved for resultCode 01. | APPROVED |
merchantID | STRING | Echo of the merchantID used in the request. | 910100000000001 |
merchantName | STRING | The name of the merchant that requested the transaction as stored at the bank. | Merchant A |
transactionAmount | STRING | Approved total transactionAmount. | 1500 |
transactionDescription | STRING | Echo of the transactionDescription used to launch the Ecentric Payment App. | 3rd party app desc |
isReceiptDataAvailable | STRING | Boolean indicating whether a receiptBundle object is available. Will always be included for approved or declined transactions. | true |
receiptBundle | STRING | Consists of a sub-bundle of server parameters that can be used by the partner application to create a receipt. | See QR_CODE_PAYMENT response body. |
appVersion | STRING | The software version currently running on the Ecentric Payment App. | 1.9.2 |
externalSTAN | STRING | Echo of the systems trace number generated by some 3rd party ERP systems. | 123456 |
externalRRN | STRING | Echo of the RRN generated by some 3rd party ERP systems. | ABCDEF123456 |
externalTransactionGUID | STRING | Echo of the GUID that identifies a specific transaction generated by 3rd party ERP systems. | 2fdca02f-3cbe-4e8c-82ad-86a1a16b72e8 |
externalInvoiceGUID | STRING | Echo of the GUID that identifies a particular invoice that may appear on more than one transaction. | 2fdca02f-3cbe-4e8c-82ad-86a1a16b72e9 |
externalTransactionDateTime | STRING | Echo of the date and time the transaction was generated on the 3rd party ERP systems. Has the format of “yyyy-MM-dd'T'HH:mm:ss” | 2017-04-28T09:30:00 |
externalTerminalId | STRING | Echo of the terminal identifier for device configured on the 3rd party ERP system. | 98100010 |
transactionUuid | STRING | Echo of the Unique ID of a transaction. | bdf9d0af-17b3-48ca-8a0b-37dc52bf49bc |
terminalId | STRING | This is an automatically system-assigned terminalID of the payment terminal’s identity number, which can be used to assist with settlement information and is returned in BASE36 format. | 77012398 |
latitude | STRING | Echo of geolocation identifier indicating the latitude position of the device. | -28.1619942 |
longitude | STRING | Echo of geolocation identifier indicating the longitude position of the device. | 30.2350981 |
accuracy | STRING | Echo of accuracy indicator of the geolocation. | |
serialNumber | STRING | The serial number for the device that was used for the RETAIL_AUTH intent call. | PC05P2CG10036 |
posId | STRING | Echo of the posId present in the request. | POS-STORE123-TERM01 |
Error Handling
Example: Errors
The following table contains typical errors that might occur and how to handle these errors:
| ERROR MESSAGE | SOLUTION |
|---|---|
| Incorrect merchantID/ not present | Ensure that you have entered the correct merchantID. |
| posId is not present | Ensure that you include the posId in your request. |
| serialNumber not present | Ensure that you include the serialNumber in you request. |
| Terminal <serial_number> is offline | Ensure the requested terminal is turned on and has established a valid connection to POSBuddy Cloud. |
| launchType not present | Ensure you provide the launchType “QR_CODE_PAYMENT” |
| transactionAmount not present | Ensure that you are sending through a valid transactionAmount. |
| Duplicate UUID | Ensure that a unique UUID is sent through for every new QR code payment transaction. Note: Only relevant if you provide the optional transactionUuid in the request. |
BODY
The following is an example of a QR_CODE_PAYMENT ERROR response body that the POS Application will receive.
{
"resultDescription": "ERROR",
"errorBundle": {
"description": "ERROR",
"reference": "",
"errorType": "TRANSACTION",
"message": "Error communicating with server"
},
"buildInfo": "Ecentric_DEBUG_Ecentric_INT",
"isReceiptDataAvailable": "false",
"resultCode": "04",
"merchantID": "910100000000001",
"serialNumber": "PC05P2CG10036",
"posId": "POS-STORE123-TERM01",
"launchType": "QR_CODE_PAYMENT",
"appVersion": "1.9.8",
"transactionAmount": "1500"
}Updated about 5 hours ago
