3. Enhancements
Get the most out of your payment links by applying the optimizations and tips below.
3.1 Custom return URL
If a customer successfully completes the payment, they are redirected back to the paylink URL with a message indicating that the payment was successful.
However, if you include a returnUrl variable when initiating the paylink, the customer will be redirected to that URL after a successful payment instead.
{
"returnUrl": "https://www.domain.com/return/"
}This allows you to display your own custom confirmation message or thank-you page.
3.2 Apply look and feel
The default paylink URL is displayed in a clean, standard layout. However, you can customize the paylink to match your own branding, for example, by adjusting the colors or adding a background image and logo.
The guide for configuring a custom look and feel for your paylink can be found here.
3.3 Default language
The paylink payment screen is available in more than 20 different languages. You can set the language when initiating a paylink using the customer.locale variable.
{
"customer": {
"locale": "en_GB"
}
}The customer.locale variable can contain the following values:
| Value | Language |
|---|---|
| nl_NL | Dutch |
| en_GB | British English |
| en_US | American English |
| fr_FR | French (France) |
| de_DE | German |
| nl_BE | Dutch (Belgium) |
| fr_BE | French (Belgium) |
| pl_PL | Polish |
| it_IT | Italian |
| es_ES | Spanish |
| no_NO | Norwegian (Nynorsk) |
| nb_NO | Norwegian (Bokmål) |
| sv_SE | Swedish |
| fi_FI | Finnish |
| da_DK | Danish |
| ro_RO | Romanian |
| pt_PT | Portuguese |
| hu_HU | Hungarian |
| cs_CZ | Czech |
| bg_BG | Bulgarian |
| sl_SI | Slovenian |
3.4 Free variables
When initiating a paylink transaction, you can use the description and reference variables to provide information shown on the customer’s payment screen and bank statement, as well as to store your internal order ID.
If you need to pass additional internal data, you can use free variables. The variable stats.extra1 is available to all merchants, while stats.extra2 and stats.extra3 depend on your package.
{
"stats": {
"extra1": "Free variable value 1",
"extra2": "Free variable value 2",
"extra3": "Free variable value 3"
}
}These free variables are also included in export files and can be used for searching within the Admin Panel. Each free variable can contain up to 64 characters.
3.5 Payment attempts
You can check the status of a paylink using the status.code variable. If you also want to view the individual payment attempts made by the customer, you can retrieve them through the payments variable.
This variable contains an object for each payment attempt, including details such as the payment method, status, and amount. If the payment was successful and authentication was applied through the Order.Status API, the object will also include available customer data (e.g IBAN or masked/hashed credit card number).
In the example below, the customer made two payment attempts.
- Payment attempt 1 with order ID 68e679c4-4744-8136-21e5-047601470092 was made via Bancontact (payment option ID: 436) with status: CANCEL (-90).
- Payment attempt 2 with order ID 68e67c08-4744-858c-2f70-047601470092 was made via iDEAL (payment option ID: 10) with status: PAID (100).
{
"payments": [
{
"id": "68e679c4-4744-8136-21e5-047601470092",
"paymentMethod": {
"id": 436
},
"customerKey": null,
"customerId": null,
"customerName": null,
"customerMethod": null,
"ipAddress": "100.101.102.103",
"status": {
"code": -90,
"action": "CANCEL"
},
"amount": {
"value": 150,
"currency": "EUR"
}
},
{
"id": "68e67c08-4744-858c-2f70-047601470092",
"paymentMethod": {
"id": 10
},
"customerKey": "1fe2a644d006b4b18ac515be2209490b",
"customerId": "NL23REVO1264023850",
"customerName": "John Doe",
"customerMethod": {
"type": "iban",
"data": {
"iban": "NL23REVO1264023850",
"name": "John Doe",
"bic": "REVONL22"
}
},
"ipAddress": "100.101.102.103",
"status": {
"code": 100,
"action": "PAID"
},
"amount": {
"value": 150,
"currency": "EUR"
}
}
]
}3.6 Offer BNPL
The request shown here works for most payment methods. However, if you want to offer Buy Now, Pay Later (BNPL), you must include additional information; otherwise, the BNPL payment option will not appear in the paylink.
BNPL methods typically require both customer and order data to perform an acceptance check. Here’s an example of what such a request might look like:
{
"customer": {
"email": "[email protected]",
"firstName": "John",
"lastName": "Doe",
"birthDate": "1999-11-22",
"gender": "M",
"phone": "0612345678"
},
"order": {
"deliveryAddress": {
"street": "P.C. Hooftstraat",
"streetNumber": "100",
"zipCode": "3202XA",
"city": "Amsterdam",
"country": "NL",
"firstName": "John",
"lastName": "Doe"
},
"invoiceAddress": {
"firstName": "John",
"lastName": "Doe",
"street": "P.C. Hooftstraat",
"streetNumber": "100",
"zipCode": "3202XA",
"city": "Amsterdam",
"country": "NL"
},
"products": [
{
"id": "ART1234",
"description": "Article 1234",
"type": "ARTICLE",
"price": {
"value": 33350
},
"quantity": 1,
"vatPercentage": 0
}
]
}
}We also recommend including customer and order data when processing PayPal transactions, as this information is required to qualify for Seller Protection.
3.7 Paylink QR code
Paylinks are primarily generated to be sent to customers via email or SMS. However, you can also generate a QR code for a paylink.
There are many free libraries available online for most programming languages that can generate QR codes. QR codes are particularly useful for displaying on invoices, allowing customers to quickly scan and complete their payment.
3.8 Testmode
During the development process, you may want to test the paylink without performing an actual payment each time. To make this easier, we’ve developed the sandbox mode.
By setting the integration.test variable while initiating a transaction, you can start the paylink in sandbox mode.
{
"integration": {
"test": false
}
}When a payment is initiated in sandbox mode, you’ll be redirected to our Sandbox payment screen, where you can easily test any desired payment status.
To verify your test payment, enter the secret in the Sandbox payment screen. You can find this secret in the Admin Panel by going to Settings > Sales locations and clicking the SL-code of the relevant sales location. A popup will appear displaying the secret, a 40-character hash.
3.8 Best Practice: Generate Payment Links on Demand
When implementing QR code payments, avoid generating payment links in advance (for example, when creating an invoice).
A common implementation is:
- Create a payment link through the API.
- Generate a QR code containing that payment link.
- Print or embed the QR code on the invoice.
While functional, this approach creates payment links for every invoice, regardless of whether the customer ever initiates a payment. This can result in a large number of unused payment links.
Recommended approach
Instead, let the QR code point to a page within your own application.
The recommended flow is:
- Generate a QR code that links to your own payment page (for example, https://merchant.com/pay/{invoiceId}).
- When the customer scans the QR code, retrieve the invoice details from your system.
- Present the available payment methods to the customer.
- Only when the customer chooses to pay, create a payment through the API.
- Redirect the customer to the payment URL returned by the API.
Benefits
- Payment links are only created when a customer actually starts a payment.
- Reduces the number of unused payment links.
- Gives you full control over the payment experience.
- Allows invoice information and payment options to be displayed before creating the payment.
- Makes it easier to apply business logic, such as validating invoice status or preventing duplicate payments.
This on-demand payment creation approach is the recommended integration pattern for QR code-based invoice payments.
Updated about 1 month ago