Skip to content
Last updated

Introduction

This solution allows you to create a closed loop payment system to top up payment cards or wristbands. Ideal for festivals, employee cards, student cards…etc.

With Top-Up, you print a fixed payment QR code on a top-up medium of your choosing, your consumers scan the QR code with their preferred payment application and confirm the transaction.

Top-Up QR codes can be scanned and paid multiple times and remain valid until they are revoked. The QR Code amount can be

  • Defined by the consumer: you generate an open value QR code, the payment amount is provided by the consumer upon scanning it.
  • Modifiable by the consumer: you generate a QR code with a predefined amount, but the consumer can modify it upon scanning it.
  • Fixed: you generate a QR code with a fixed amount, it cannot be changed by the consumer.

Important Note:

  • The behaviour of the QR Code (Defined, Modifiable, Fixed) needs to be set up by our Support Team upon product creation.
  • A Callback URL will similarly have to be provided upon product creation. Our Top Up solution does cannot function without a predefined callback URL.

Process Flow

The following section outlines the key steps involved in a Top Up online payment with Bancontact Payconiq. The process involves several key parties, each playing a specific role in completing the transaction.

Prerequisites

  • Merchant CallbackUrl – This URL will be called by Bancontact Payconiq’s backend servers in order to send the status of the payment to the merchant.
  • API Key (Optional) – This is used to secure the request between the Merchant’s backend and Bancontact Payconiq’s backend. Do not share your API keys in public areas such as online sites or client-side code.
  • QR Code URL Scheme – The Bancontact Payconiq template QR Code URL Scheme.
  • PPID or Product Profile ID – unique identifier of the product handling the payment.

Involved Parties

The following parties participate in a Top Up payment with Bancontact Payconiq:

  • Payer Application: The consumer's preferred payment app used to complete the transaction.
  • Merchant Frontend: The receipt on which the QR code is printed.
  • Merchant Backend: The merchant’s server-side system that integrates with Bancontact Payconiq.
  • Bancontact Payconiq Backend: The backend system responsible for handling payment processing and integration services.

Step-by-Step Payment Flow

  • The Merchant Backend creates a one-time usage QR code using the Bancontact Payconiq service URL. The QR code will contain parameters such as the amount to be paid, a discription and a payment reference.
  • The QR Code is printed on the Merchant Fronted.
  • The Payer App reads the details of the QR code and presents them for payment confirmation. The details would contain the amount to pay, the merchant name and a description.
  • The consumer confirms the payment in the Payer app using PIN, fingerprint, or face ID. The Payer App then submits the payment request to the Bancontact Payconiq backend for authorization.
  • A payment response is sent back by the Bancontact Payconiq backend to the Payer App, indicating whether the payment was successful or failed.
  • The Bancontact Payconiq backend sends a payment notification with the payment status to the merchant backend via the configured callback URL.
  • The merchant backend acknowledges the callback notification.
  • The merchant frontend is notified of the status of the payment.

NB: The order of consumer and merchant notification is not sequential. One may arrive before the other depending on internet and network connections.

Payment Flow Diagram

In the following diagrams you will find a visual overview of the process flows presented above:

TOP UP

Implementation Guide

For the full endpoint documentation, please refer to the Merchant Payment API.

1. Creating QR Code

In order to create a QR code you need to use the Bancontact Payconiq service URL as illustrated below. Once created, you will be able to print the Static QR on the medium of your choice.

QR Code Parameters

The QR code contains the following parameters:

AttributeDescription
f
[String :: Enum]
Allowed Values: SVG, PNG
Image format. If not provided, the default format is PNG.
s
[String :: Enum]
Allowed Values: S, M, L, XL
Image size of the QR code to generate.
Small (S) = 180x180
Medium (M) = 250x250
Large (L) = 400x400
Extra Large (XL) = 800x800
The sizes only applies to PNG format.
*If not provided, the default size is Small.
cl
[String :: Enum]
Allowed Values: magenta, black
The colour of the QR code.
Default is magenta.
c
[String, required]
The Payconiq UTF-8 URL encoded content. This is comprised of the template URL scheme.
c.D
[String, optional]
Maximum Length: 35 chars
UTF-8 URL encoded description of the payment
c.A
[String, optional]
Minimum: 1
Maximum: 999999
UTF-8 URL encoded amount of the QR code in Euro cents.
c.R
[String, optional]
Maximum Length: 35 chars
UTF-8 URL encoded reference of the QR code.

QR code creation process

ActivityComment
1. Obtain the pre-requisite information needed to generate the Payconiq QR Code.• Format of the Payconiq QR code.
• Size of the Payconiq QR code.
• Template URL scheme.
• Product profile id of the merchant.
• Amount of the Payconiq QR code.
• Description of the Payconiq QR code.
• Reference of the Payconiq QR code.
2. Build the Payconiq service URL using the optional parameters which include:
• Image format (PNG or SVG)
• Image size (S, M, L, XL). This only applies to PNG.
Sample format:
https://qrcodegenerator.api.bancontact.net/qrcode?f={imageFormat}&s={ImageSize}&c=

Example Output URL (PNG):
https://qrcodegenerator.api.bancontact.net/qrcode?f=PNG&s=L&c=

Sample URL (SVG)
https://qrcodegenerator.api.bancontact.net/qrcode?f=SVG&c=
3. UTF-8 encode the Payconiq URL payload parameter values using UTF-8 as the destination character set.
This means encoding the following:
• Description
• Amount
• Reference.
Payconiq unencoded URL payload parameters
D=Receipt Payment
A=1000
R=sd89sd91?sd9

Payconiq encoded URL payload parameters:
D=Receipt%20Payment
A=1000
R=sd89sd91%3Fsd9
4. Build the Payconiq URL payload using the following details.
• Template URL scheme.
• Product profile id of the merchant.
• Amount of the Payconiq QR code.
• Description of the Payconiq QR code.
• Reference of the Payconiq QR code.
Sample format:

https://payconiq.com/t/1/{productProfileId?D={Enc_description}&A={Enc_amount}&R={Enc_reference}

Sample URL payload:
https://payconiq.com/t/1/5c18cbd1296e9a26d3278518?D=Receipt%20Payment&A=1000&R=sd89sd91%3Fsd9
5. UTF-8 encode the Payconiq URL Payload from step 4.Payconiq URL Payload before Encoding:
https://payconiq.com/t/1/5c18cbd1296e9a26d3278518?D=Invoice%20Payment&A=1000&R=sd89sd91%3Fsd9

Payconiq URL Payload after Encoding:
https%3A%2F%2Fpayconiq.com%2Ft%2F1%2F5c18cbd1296e9a26d3278518%3FD%3DReceipt%2520Payment%26A%3D1000%26R%3Dsd89sd91%253Fsd9
6. Build full URL by combining results from step 2 and step 5.

Sample full URL:

https://qrcodegenerator.api.bancontact.net/qrcode?f=PNG&s=XL&c=https%3A%2F%2Fpayconiq.com%2Ft%2F1%2F5c18cbd1296e9a26d3278518%3FD%3DReceipt%2520Payment%26A%3D1000%26R%3Dsd89sd91%253Fsd9

You can now execute the URL in a web view to obtain your Static QR Code and print it on the medium of your choice.

2. The Bancontact Payconiq Callback

Bancontact Payconiq's backend will call the specified callback URL to send notifications about the status of a payment. This will allow you to take appropriate action and process the payment data.

The merchant backend must verify that the notification message originated from Bancontact Payconiq backend was not altered or corrupted during the tranmission. To do so, please ensure signature validation.

For the full Callback documentation, please refer to the Callback Guide.

📦 Request Body

paymentIdstring= 24 charactersrequired

PaycBancontact Payconiq Company Payment ID

currencystringrequired

Only EUR is supported currently

Default "EUR"
amountinteger(int64)required

Requested amount in cents

descriptionstring
referencestring
createdAtstring(date-time)required

When the payment was created

expireAtstring(date-time)

When the payment is going to expire. After that date the payment can't be confirmed anymore

succeededAtstring(date-time)

if the payment is SUCCEEDED, then this field represents the date-time on which the payment was SUCCEEDED

statusstring(MerchantPaymentStatus)required
StatusDescription
PENDINGThe merchant has created the payment and and is pending to proceed with identify step.
IDENTIFIEDThe user has scanned the payment's QR code with the Payconiq By Bancontact APP.
AUTHORIZEDThe user has confirmed the payment and the bank authorized it.
AUTHORIZATION_FAILEDThe authorization with the bank failed.
FAILEDSomething went wrong during the payment process(e.g authorization failed).
SUCCEEDEDThe payment has succeeded.
CANCELLEDWhen the payment has been canceled after the user has scanned it, or the merchant has cancelled the payment.
EXPIREDThe payment has expired.
PENDING_MERCHANT_ACKNOWLEDGEMENTThe payment is waiting for the merchant to acknowledge.
VOIDEDThe payment has been voided
Enum"PENDING""IDENTIFIED""AUTHORIZED""AUTHORIZATION_FAILED""SUCCEEDED""FAILED""CANCELLED""EXPIRED""PENDING_MERCHANT_ACKNOWLEDGEMENT""VOIDED"
debtorobjectrequired

Customer that paid

debtor.​ibanstringrequired

Debtor's IBAN masked

debtor.​namestring

Debtor's first name

📥 Response

(No defined response schema)

🔍 Sample Request – callback

curl -i -X POST \
  https://merchant.api.preprod.bancontact.net/callback \
  -H 'Content-Type: application/json' \
  -H 'Signature: YOUR_API_KEY_HERE' \
  -H 'User-Agent: Payconiq' \
  -d '{
    "paymentId": "5f91483d-78a7-4914-bc6f=",
    "currency": "EUR",
    "amount": 0,
    "description": "string",
    "reference": "19848995",
    "createdAt": "2019-08-24T14:15:22Z",
    "expireAt": "2019-08-24T14:15:22Z",
    "succeededAt": "2019-08-24T14:15:22Z",
    "status": "PENDING",
    "debtor": {
      "iban": "*************12636",
      "name": "John"
    }
  }'

Callback Failure

In the event you do not receive a callback or the callback validation fails, please refer to "4. Get Payment Details". This alternative will also allow you to confirm the status of a transaction in order to complete the payment.

3. Get Payment Details

By calling this endpoint you can obtain the details of an existing payment transaction by passing the unique payment ID.

Note: it is highly recommended to implement this call as a fallback option if callback fails.

🧩 Path Parameters

  • id (string, required)

📥 Response

paymentIdstring= 24 charactersrequired

id of the payment

createdAtstring(date-time)required

the creation time of the payment

expireAtstring(date-time)required

the time from which the payment will be expired

succeededAtstring(date-time)

if the payment is SUCCEEDED, then this field represents the date-time on which the payment was SUCCEEDED

currencystring(Currency)required

Currency code. Only EUR is supported ISO 4217

Default "EUR"
Value"EUR"
statusstring(MerchantPaymentStatus)required
StatusDescription
PENDINGThe merchant has created the payment and and is pending to proceed with identify step.
IDENTIFIEDThe user has scanned the payment's QR code with the Payconiq By Bancontact APP.
AUTHORIZEDThe user has confirmed the payment and the bank authorized it.
AUTHORIZATION_FAILEDThe authorization with the bank failed.
FAILEDSomething went wrong during the payment process(e.g authorization failed).
SUCCEEDEDThe payment has succeeded.
CANCELLEDWhen the payment has been canceled after the user has scanned it, or the merchant has cancelled the payment.
EXPIREDThe payment has expired.
PENDING_MERCHANT_ACKNOWLEDGEMENTThe payment is waiting for the merchant to acknowledge.
VOIDEDThe payment has been voided
Enum"PENDING""IDENTIFIED""AUTHORIZED""AUTHORIZATION_FAILED""SUCCEEDED""FAILED""CANCELLED""EXPIRED""PENDING_MERCHANT_ACKNOWLEDGEMENT""VOIDED"
creditorobject(PaymentCreditorResponse)required

Creditor account set to receive the payment

creditor.​profileIdstring

The configuration ID of the Merchant

creditor.​merchantIdstring

the Id of the merchant

creditor.​namestring

Merchant's company name that will be shown to the debtor

creditor.​ibanstring

Creditor's Bank Account Iban to where the money will be sent to for this current payment

creditor.​identifyCallbackUrlstring

callbackUrl to which the merchant will be notified about the payment identification

creditor.​callbackUrlstring

callbackUrl to which the merchant will be notified about the payment payout

debtorobject
amountinteger(int64)required

Amount in cents originally requested. If no amount was requested by creditor, this will be 0

descriptionstring

merchant's description of the payment

messagestring

debtor's message of the payment

referencestring
bulkIdstring

Field used to reference a bulk batch, so the merchant can choose how to bulk the payments. Mandatory if merchant profile does have bulking enabled, otherwise will miss from the response. If it's not set in the create call it will default to the value configured in the profile if it exists, otherwise its value will be defaulted by the application.

_linksobject(Links)

Provides information to navigate to our REST interfaces dynamically, by including hypermedia links to them. Note that for some links inclusion depends on the status of the payment (e.g. cancel link will be available on PENDING and refund on SUCCEEDED)

🔧 Error Codes for merchant-get-payment

HTTP StatusCodeMeaning
401UNAUTHORIZEDcaller doesn’t have an api-key access token
403ACCESS_DENIEDapi-key access token is invalid, creditor it's not a participant of the requested payment
404PAYMENT_NOT_FOUNDno payment could be found
500TECHNICAL_ERRORTechnical error in Payment service

🔍 Sample Request – merchant-get-payment

curl -i -X GET \
  'https://merchant.api.preprod.bancontact.net/v3/payments/{id}' \
  -H 'Authorization: YOUR_API_KEY_HERE'

4. Get Payment List

You can also retrieve a list of payments by specifying how many records to return, as well as a filter on the results for the total number of records returned per page.

📦 Request Body

fromstring(date-time)

default is today - 1day (yesterday)

tostring(date-time)
paymentStatusesArray of strings(MerchantPaymentStatus)
Items Enum"PENDING""IDENTIFIED""AUTHORIZED""AUTHORIZATION_FAILED""SUCCEEDED""FAILED""CANCELLED""EXPIRED""PENDING_MERCHANT_ACKNOWLEDGEMENT""VOIDED"
referencestring

📥 Response

sizeinteger>= 0required

Size of the elements returned in current page

totalPagesintegerrequired

Total number of pages in the backend for the list requested

totalElementsintegerrequired

Total number of elements in the list requested

numberintegerrequired

Current page number

detailsArray of objects(GetPaymentResponse)
HTTP StatusCodeMeaning
401UNAUTHORIZEDcaller doesn’t have an api-key access token
403ACCESS_DENIEDapi-key access token is invalid, creditor it's not a participant of the requested payment
500TECHNICAL_ERRORTechnical error in Payment service
curl -i -X POST \
  'https://merchant.api.preprod.bancontact.net/v3/payments/search?page=0&size=10' \
  -H 'Authorization: YOUR_API_KEY_HERE' \
  -H 'Content-Type: application/json' \
  -d '{
    "from": "2019-08-24T14:15:22Z",
    "to": "2019-08-24T14:15:22Z",
    "paymentStatuses": [
      "PENDING"
    ],
    "reference": "19848995"
  }'