New payment URLs
Following the decommissioning of the Payconiq brand in Belgium, these URL changes are essential to ensure compliance and
mark the final phase in aligning our branding with the new Bancontact Pro identity.

Please implement adaptations described here promptly to avoid service interruptions and guarantee the continued acceptance of mobile payments via Bancontact Pay and Wero.

Changes are already available in our pre-production environement and will be rolled out in production starting 11/05/2026

# Static QR Code

## Introduction

Static QR Code allows you to add a printed static QR code to your point of sale (PoS) and link it to your cash register system.
Your PoS sends the payment information to the QR code, your consumers scan the QR code with their preferred payment application and confirm the transaction.

## Process Flow

The following section outlines the key steps involved in a Static QR Code payment with Bancontact Pro API. The process involves several key parties, each playing a specific role in completing the transaction.

### Prerequisites

* **API Key** – This is used to secure the request between the **Merchant’s backend** and **Bancontact Pro’s backend**. Do not share your API keys in public areas such as online sites or client-side code.
* **Merchant CallbackUrl** (*Optional*) – This URL will be called by Bancontact Pro’s backend servers in order to send the status of the payment to the merchant.


### Involved Parties

The following parties participate in a display-based in-store payment with Bancontact :

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


### Step-by-Step Payment Flow

This section outlines a typical **“Static QR Code”** in-store payment flow using Bancontact . The process begins when the transaction is initiated at the merchant’s location and ends when both the merchant and the consumer receive the final confirmation.

* The **Merchant frontend** displays a Static QR code, visible to the consumers.
* The **Merchant backend** issues a REST request to the **Bancontact backend** to create the payment, providing parameters like amount, currency, description, and other relevant parameters.
* The **Bancontact backend** responds with the created payment ID and other relevant detail to the **Merchant backend**
* The **Payer app** scans the QR code to initiate the payment process.
* The **Payer app** sends a request for payment details to the **Bancontact backend**. The POS ID present in the Static QR is matched with a POS ID on **Bancontact backend**.
* **Bancontact backend** sends the payment details tot he **Payer App**, which contains the name of the merchant and the amount to pay.
* The consumer confirms the payment n the **Payer app** using PIN, fingerprint, or face ID. The **Payer app** then submits the payment request to the **Bancontact backend** for authorization.
* A payment response is sent back by the **Bancontact backend** to the **Payer App**, indicating whether the payment was successful or failed.
* The **Bancontact backend** sends a payment notification with the payment status to the **merchant backend** via the configured callback URL.
* The **merchant frontend** displays the payment  status.


> **Important Note:** The order in which the merchant and consumer receive payment status notifications is **not guaranteed**. Network and connectivity differences may cause one party to receive the update before the other.


## Payment Flow Diagram

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

![Visualized diagram of the Static QR payment flow](/assets/staticqr2x.9f89c2ca2ac3d1d99a8d8d8fa9110d41405a26f742faa60f7c07cb614f716c71.85e0cfdd.jpg)

## Implementation Guide

> For the full endpoint documentation, please refer to the [Merchant Payment API](/apis/merchant-payment.openapi).


### 1. Create a Static QR Code

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

#### Static QR Code Parameters

The QR code contains the following parameters:

| Attribute | Description |
|  --- | --- |
| `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) = 250x250Large (L) = 400x400 Extra Large (XL) = 800x800  The sizes only applies to PNG format.  *If not provided, the default size is Small. |
| `c`  [String, required] | The  UTF-8 URL encoded content. This is comprised of the location URL scheme. |


#### Static QR Code creation process

table
thead
tr
th
Activity
th
Comment
tbody
tr
td
strong
1.
 Obtain the pre-requisite information
td

        • Format of the  QR code.
br

        • Size of the  QR code.
br

        • Location URL scheme.
br

        • Payment profile ID of the merchant.
br

        • POS ID.
      
tr
td
strong
2.
 Build the  service URL
td

        Sample format:
br
code
https://qrcodegenerator.api.bancontact.net/qrcode?f={imageFormat}&s={ImageSize}&c=
br
br

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

        Sample URL (SVG):
br
code
https://qrcodegenerator.api.bancontact.net/qrcode?f=SVG&c=
tr
td
strong
3.
 UTF-8 encoded  URL parameters
td

        Encode the following using UTF-8:
br

        • POS ID
br
br

        Unencoded POS ID:
br
code
POS00001
br
br

        Encoded POS ID:
br
code
POS00001
tr
td
strong
4.
 Build the URL payload
td

        Format:
br
code
https://payconiq.com/l/1/{PaymentProfileId}/{POSId}
br
br

        Example:
br
code
https://payconiq.com/l/1/5bb37284e35e2b29e363df22/POS00001
tr
td
strong
5.
 UTF-8 encode the URL payload
td

        Before Encoding:
br
code
https://payconiq.com/l/1/5bb37284e35e2b29e363df22/POS00001
br
br

        After Encoding:
br
code
https%3A%2F%2Fpayconiq.com%2Fl%2F1%2F5bb37284e35e2b29e363df22%2FPOS00001
tr
td
strong
6.
 Combine service URL and encoded payload
td

        Full URL:
br
code
https://qrcodegenerator.api.bancontact.net/qrcode?f=PNG&s=XL&c=https%3A%2F%2Fpayconiq.com%2Fl%2F1%2F5bb37284e35e2b29e363df22%2FPOS00001
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. Create Payment

In order to initiate a payment, you will first have to create it through Bancontact via a **POST** request.  Each request will result in a unique payment identifier which will be valid for **two minutes (120 seconds)**.

If the payment does not take place within these two minutes, a new payment must be created.

#### 📦 Request Body

#### 📥 Response

#### 🔧 Error Codes for `create`

| HTTP Status | Code | Meaning |
|  --- | --- | --- |
| 400 | `BODY_MISSING` | A json needs to be provided |
| 400 | `FIELD_IS_REQUIRED` | Field X is mandatory |
| 400 | `FIELD_IS_INVALID` | Field X is invalid |
| 401 | `UNAUTHORIZED` | user doesn’t have an access token |
| 403 | `ACCESS_DENIED` | The JWT could not be verified (different format) - The JWT doesn’t contain the required authority to access the resource requested |
| 404 | `MERCHANT_PROFILE_NOT_FOUND` | The merchant profile does not exist |
| 422 | `UNABLE_TO_PAY_CREDITOR` | Variable reason(Depends on automatic processing). |
| 500 | `TECHNICAL_ERROR` | Technical error in Payment service |
| 503 | `TRY_AGAIN_LATER` | one of the internal services is unavailable |


#### 🔍 Sample Request – `create payment`

### 3. The Bancontact Callback

You can specify a callback URL where the **Bancontact  backend** will 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 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](/guides/general/callback052025).


#### 📦 Request Body

#### 📥 Response

*(No defined response schema)*

#### 🔍 Sample Request – `callback`

#### Callback Failure

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

### 4. 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

#### 🔧 Error Codes for `merchant-get-payment`

| HTTP Status | Code | Meaning |
|  --- | --- | --- |
| 401 | `UNAUTHORIZED` | caller doesn’t have an api-key access token |
| 403 | `ACCESS_DENIED` | api-key access token is invalid, creditor is not a participant of the requested payment |
| 404 | `PAYMENT_NOT_FOUND` | no payment could be found |
| 500 | `TECHNICAL_ERROR` | Technical error in Payment service |


#### 🔍 Sample Request – `merchant-get-payment`

### 5. 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

#### 📥 Response

#### 🔧 Error Codes for `search`

| HTTP Status | Code | Meaning |
|  --- | --- | --- |
| 401 | `UNAUTHORIZED` | caller doesn’t have an api-key access token |
| 403 | `ACCESS_DENIED` | api-key access token is invalid, creditor it's not a participant of the requested payment |
| 500 | `TECHNICAL_ERROR` | Technical error in Payment service |


#### 🔍 Sample Request – `search`

## Canceling a Payment

Endpoint `delete-payment` can be used to cancel a created payment that is still in status `PENDING`.
The endpoint can also be used to cancel a payment in `IDENTIFIED` status, as long as the consumer has
not initiated payment confirmation.

### 🧩 Path Parameters

- `id` *(string, required)* — Payment Id


### 🔧 Error Codes for `delete-payment`

| HTTP Status | Code | Meaning |
|  --- | --- | --- |
| 401 | `UNAUTHORIZED` | user doesn't have an access token |
| 403 | `ACCESS_DENIED` | access token is invalid |
| 403 | `CALLER_NOT_ALLOWED_TO_CANCEL` | if caller is not a participant of the payment |
| 404 | `PAYMENT_NOT_FOUND` | payment is not found in the system |
| 422 | `PAYMENT_NOT_PENDING` | payment is not in pending or identify state |
| 500 | `TECHNICAL_ERROR` | Technical error in Payment service |


### 🔍 Sample Request – `delete-payment`