# Integrate Payconiq by Bancontact
This tutorial shows you how to integrate Payconiq by Bancontact (opens new window) payments using Chargebee.js. Payconiq by Bancontact is a European mobile payment solution that enables customers to pay by scanning QR codes with their smartphone app.
# Supported regions
Payconiq by Bancontact is available in:
- Belgium
- Netherlands
- Luxembourg
# What you'll build
By the end of this tutorial, you'll have a working integration that:
- Creates payment intents for Payconiq by Bancontact.
- Handles Payconiq payment flow.
- Creates subscriptions after successful payment authorization.
# Prerequisites
Before you begin, ensure you have enabled Payconiq by Bancontact (opens new window) via Adyen in Chargebee Billing.
# Setting up Chargebee JS
# Inserting chargebee.js script in your application
Include the following script in your HTML page. You need to do this only once per page.
<script src="https://js.chargebee.com/v2/chargebee.js"></script>
# Initializing a Chargebee instance
Inside your JavaScript code, initialize chargebee with the publishable key (opens new window) once the page is loaded and get 'chargebee instance' object. This object is used further to create components.
Example:
var cbInstance = Chargebee.init({
site: "site-name", // your test site
domain: "https://mybilling.acme.com" // this is an optional parameter.
publishableKey: "test__"
})
2
3
4
5
Learn more about initializing a Chargebee instance.
# Create a payment intent
About `payment_intent`
A payment_intent
resource manages a customer's payment session. It tracks the amount, currency, payment status, and failed payment attempts, and helps prevent duplicate charges for the same session. The payment_intent
automatically updates its status based on authorization and capture events, and issues refunds if an error occurs after payment.
# Server-side implementation
Security
Always create payment intents on your server to protect sensitive information.
Create a payment intent using the Create Payment Intent API (opens new window):
curl https://{site-name}.chargebee.com/api/v2/payment_intents \
-u {fullaccess_api_key}: \
-d amount=500 \
-d currency_code="EUR" \
-d payment_method_type="payconiq_by_bancontact"
2
3
4
5
# Client-side implementation
Call your server endpoint from the frontend:
function createPaymentIntent() {
return fetch('/payment-intents', {
method: 'POST',
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
amount: 500,
currency_code: 'EUR',
payment_method_type: 'payconiq_by_bancontact'
})
}).then(function(response) {
return response.json();
}).then(function(responseJson) {
return responseJson.payment_intent;
});
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Implement the payment flow
# Step 1: Load the payment method
Load the Payconiq by Bancontact integration using the load
method:
cbInstance.load("payconiq_by_bancontact")
# Step 2: Handle the payment
Use the handlePayment
method to initiate the payment process.
cbInstance.load("payconiq_by_bancontact").then(() => {
cbInstance.handlePayment("payconiq_by_bancontact", {
paymentIntent: () => {
return createPaymentIntent();
},
renderInfo: {
heading: "Scan QR code",
timerLabel: "This QR code is valid for {time}", // timer will be reflected in place of {time}
timerDurationSeconds: 15 * 60, // 15 minutes
buttonText: "Continue to Payconiq by Bancontact",
}
}).then(intent => {
// Payment intent is pending - customer needs to scan QR code
return createSubscription(intent.id);
}).catch(err => {
console.error('Payment failed:', err);
});
});
function createSubscription(paymentIntentId) {
return fetch('/subscriptions', {
method: 'POST',
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
paymentIntentId: paymentIntentId,
plan_id: 'pro_plan',
plan_quantity: 1,
billingAddress: {
// Add billing address details
},
customer: {
// Add customer details
}
})
}).then(response => response.json());
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
TIP
For complete parameter documentation, see the API Reference.
# Step 3: Monitor payment status
After calling handlePayment
, the payment intent status is pending
while the customer scans the QR code. You need to poll the payment intent status until it becomes authorized
or fails.
Use the Retrieve payment intent API (opens new window) to check the status:
async function waitForAuthorization(intentId, MAX_RETRIES = 10) {
for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
const response = await fetch(`/payment-intents/${intentId}`, {
method: "GET",
headers: {
"Content-Type": "application/json"
}
});
const intent = await response.json();
const status = intent?.payment_intent?.status;
if (status === "authorized") {
return intent.payment_intent;
}
if (status === "failed") {
throw new Error(`Payment ${status}`);
}
// If not done, wait before the next attempt
await new Promise(r => setTimeout(r, 2000));
}
throw new Error(`Authorization not received after ${MAX_RETRIES} retries`);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# Payment status reference
For detailed information about payment intent statuses, see the Payment Intent API documentation (opens new window).
Status | Description | Action |
---|---|---|
inited | Payment intent created | Not applicable in this flow |
in_progress | Customer is scanning QR code | Continue polling |
authorized | Payment successful | Create subscription |
consumed | Payment used for subscription | Do not reuse |
expired | Payment timed out | Show error, allow retry |
failed | Payment failed | Show error, allow retry |
Using webhooks
Use webhooks (opens new window) for production use, instead of making the subscription creation request from the client-side, it's more secure and reliable to respond to webhooks from Chargebee on the server-side. Listen to the payment_intent_updated
(opens new window) event via webhooks and create the subscription when the payment_intent.status
(opens new window) is authorized.
# Create a subscription (server)
Pass the ID of the successfully authorized payment_intent
to Chargebee’s create a subscription API (opens new window).
- Curl
