Bancontact WIP

Bancontact Wallet Initiated Payments (WIP) allows initiation by the merchant or the consumer of a card-not-present payment transaction without performing Strong Customer Authentication after previous enrollment of the Bancontact Card in a container object called a Payment Agreement

That enables the customers to offer one-click payment flows and the customers/merchants to initiate recurrent payment flows, unlocking value for use cases like e-commerce, gaming and market places, and enabling subscription models.

📘

On Payment Agreements

A Payment Agreement is a container object facilitating a model where you can easily initiate subsequent payment charges against a consumer account, without the need for consumer interaction. This is important for scenarios such as recurring payments, or any case where merchants want to initiate payments on their own schedule.

Payment Method Properties

Available country codesBE
Processing (Presentation) currenciesEUR
Settlement currenciesEUR
Consumer currenciesEUR
Minimum transaction amountEUR 0.01
Maximum transaction amountEUR 500.00
Session timeout1 hour
RefundFull, partial and multiple partial are all available.
SandboxYes, PPRO-Hosted

Authentication Flow

The authentication flow for Bancontact WIP is very similar to Bancontact, also including a Hosted Payment Page (HPP) redirect for initial customer initiated transactions + Scan QR Code or App Intent or 3DS.

For card-non-present e-commerce flows (Bancontact WIP) the transaction doesn't need to be authenticated.

Bancontact's HPP for Desktop

Bancontact's HPP for Desktop

Link and Pay Integration Flow

Link and Pay works by registering the card payment instrument and initiating the first payment charge in a single step.

1. Create an Agreement + customer initiated transaction at TRANSACTION

During the initial consumer-initiated transaction, merchants are required to create a payment agreement. PPRO will securely store the consumer's card details as part of this agreement, and SCA will be needed. For subsequent transactions, the merchant simply needs to provide the agreement ID as input for WIP transactions.

This eliminates the need for the user to authenticate or follow the regular flow again, as the stored card information will be used to process the payment seamlessly.


In your <https://api.girogate.de>TRANSACTION POST request, include:

tag=bancontactwip
&txtype=AGREEMENT
&login=johndoetest
&password=wXBrpVporFVjGO4R
&contractid=JOHNDOETESTCONTRACT
&accountholdername=John%20Doe
&channel=testchannel
&tag=bcmc
&countrycode=BE
&currency=EUR
&amount=1055
&amounttype=MAX
&startdate=2023-11-03T11:23:47.123Z
&enddate=2024-11-03T11:23:47.123Z
&frequencyinterval=1
&frequencytype=MONTHLY
&merchantredirecturl=https%3A%2F%2Fmerchant.com%2Fwork%2Fppro2%2Flanding.php
&notificationurl=https%3A%2F%2Fmerchant.com%2Fwork%2Fppro2%2Fnotification.php
&initialtransactionmerchanttxid=MYp3MF6zHDQm
&initialtransactionisocurrency=EUR
&initialtransactionamount=1000
&initialtransactionnotificationurl=https%3A%2F%2Fmerchant.com%2Fwork%2Fppro2%2Fnotification.php
&specin.dynamicdescriptor=DynDescriptor
&specin.initiation=consumer
&returnmode=urlencodeext

Many of the fields should appear familiar from the standard TRANSACTION call from Simple API. Regarding the new fields:

Field NameM/O/CDescription
returnmodeMCan be set as urlencodeext or json
txtypeMMust always be set to AGREEMENT
loginMThe PPRO-provided login.
passwordMThe PPRO-provided password.
contractidMDefines the merchant for whom PPRO is processing the transaction.
channelMThe channel in the contract to use for the transaction. testchannel for testing and livechannel for production.
tagMMust always be set to bancontactwip
currencyMThe 3-letter ISO currency code (e.g. EUR)
amountMThe amount to wire in the currency’s smallest representable unit as per ISO4217.
Example:
For EUR 0.01, the amount is 1.
For EUR 1.00, the amount is 100.
countrycodeMThe 2-letter ISO country code from which the consumer will be paying. This also typically aligns with the locale of the payment method, as many methods are only valid in a single country. For details, see payment method-specific documentation.
accountholdernameMThe account holder - minimum of 3 characters, up to 100 characters. UTF-8.
merchantredirecturlMThe URL the consumer will be redirected to after the transaction succeeded or in case of abort/failure.
Minimum length of 13 characters. Maximum length of 255 characters. Must start with http:// or https://. Allowed characters are the ascii range [a-zA-Z0-9] and the following characters: -._~:/?#[]@!$&'()*+,;=%
notificationurlMThe URL signalled for the final status of an agreement via Notification. The same restrictions as for merchantredirecturl apply.
amounttypeOIf value is EXACT, then subsequent transaction amounts must match the amount specified in the agreement. If MAX, any amount beneath the agreed amount is supported. Defaults to MAX.
startdateOThe earliest date after which the consumer agrees to be charged. Defaults to the agreement creation date.
enddateOThe last date you can charge the consumer under this agreement.
frequencyintervalOA number describing the interval between payments. Example: if the value is 2 and frequencyType is WEEKLY, then it means the consumer agrees to be charged every 2 weeks. Defaults to 1.
frequencytypeCDAILY, WEEKLY, MONTHLY or YEARLY. Required if frequencyinterval is included.
initialtransactionmerchanttxidMSame format as merchanttxid in a TRANSACTION request.
initialtransactionamountMSame format as amount in a TRANSACTION request.
initialtransactionisocurrencyMSame format as currency in a TRANSACTION request.
initialtransactionnotificationurlMThe URL signalled for the final status of a transaction via Notification. The same restrictions as for merchantredirecturl apply.
specin.initiationMSet as consumer.
specin.dynamicdescriptorODefines the text on the consumer’s proof of payment (e.g. bank statement record and similar).

Typical use cases for this feature: providing (sub-)shop name, a thank you message, product description, etc.
AGREEMENTID=agr_2sd3jkds3lsdk32lsd8ak
&STATUS=PENDING
&TXID=140011837448
&MERCHANTTXID=MYp3MF6zHDQm
&ERRMSG=
&CHANNEL=testchannel
&TAG=bancontactwip
&REDIRECTURL=https%3A%2F%2Fbancontact%2Dppro%2Ecom%2FT%2FI%3Ftx%3D140011837448%26rs%3D4eukBgRfmvKOSMU3BOmuvGk4bpbwg3Vb%26cs%3Dc7dbb38be368a0589bc0eecca68b859ad75af6906aa59b8cc09c685ecd4d29ff
&REDIRECTSECRET=fA7QdJvIIZBiWicglpI32MMT1aAchhR8
&SPECOUT.BEPURL=BEP%3A%2F%2F1BANCONTACT%2EPPRO%2ECOM%2FBEP%2F140011837448
&SPECOUT.PAYMENTPURPOSE=6HMJ2EE+Dynamic+++Descriptor+nValue
&SPECOUT.POLLINGHASH=e1b9a672%2D1203%2D4825%2D8fcd%2Defa1bb0a81d5
&SPECOUT.PREFERREDLANGUAGE=fr
&SPECOUT.QRPAYLOAD=BEP%3A%2F%2F1BANCONTACT%2EPPRO%2ECOM%2FBEP%2F140011837448
&SPECOUT.SRCCOUNTRY=BE
&SPECOUT.SRCIBAN=DE96888888881111111111
&SPECOUT.TXDATETIME=2025%2D02%2D06T14%3A29%3A52
&SPECOUT.URLINTENT=bepgenapp%3A%2F%2FDoTx%3FTransId%3D1BANCONTACT%2EPPRO%2ECOM%2FBEP%2F40011837448
&RAND3541121862=68b6e261641d64274a87d5153b1fb273299f90cb
Field NameDescription
AGREEMENTIDThe id of the persisted agreement. Example: agr_2sd3jkds3lsdk32lsd8ak.
You will need to store this value so you can pass it in future TRANSACTION calls once the AGREEMENTSTATUS is ACTIVE.
STATUSEnum with possible values: PENDING, ACTIVE, FAILED, REVOKED_BY_CONSUMER, REVOKED_BY_MERCHANT. For this specific response the status PENDING or FAILED are possible.

❗️

Link between Agreement Creation and Transaction Success

Agreements are created only for successful transactions.
If a transaction returns as FAILED the agreement will not be created and return the status FAILED.

2. Wait for Status Change Notification

After initiating an agreement creation and transaction, wait for a notification indicating a status change for the transaction and the agreement.

PPRO sends notifications whenever the state of a transaction changes to either SUCCEEDED or FAILED. These notifications are transmitted to a script running on your web server using an HTTP(S) POST request. PPRO expects a response which verifies that you received the complete notification without errors. In case of a transmission failure, PPRO retransmits the notifications in defined intervals for a determined maximum number of retries.
After a successful receipt, call GETTXSTATUS to get the transaction status.

Transaction Notifications

txid=140011837448  
&finaltimestamp=2025-11-03T11%3A23%3A47-00%3A00  
&sha256hash=dfbcdd35ff5c418e7bd8cbd736cb2708592825fab74a46d1c6baac3884a98686

Agreement Notifications

agreementid=agr_2sd3jkds3lsdk32lsd8ak  
&finaltimestamp=2025-11-03T11%3A23%3A47-00%3A00  
&sha256hash=dfbcdd35ff5c418e7bd8cbd736cb2708592825fab74a46d1c6baac3884a98686
Field NameDescription
agreementidThe agreementid value returned in the AGREEMENT call.

More about this flow at Simple API's Notifications.

3.1. Retrieve Agreement Status at GETAGREEMENTSTATUS

In your <https://api.girogate.de>GETAGREEMENTSTATUS POST request, include:

txtype=GETAGREEMENTSTATUS
&login=johndoetest
&password=wXBrpVporFVjGO4R
&contractid=JOHNDOETESTCONTRACT
&agreementid=agr_2sd3jkds3lsdk32lsd8ak
&returnmode=urlencodeext
AGREEMENTID=agr_2sd3jkds3lsdk32lsd8ak
&REQUESTSTATUS=SUCCEEDED
&STATUS=ACTIVE
&ERRMSG=
&CHANNEL=testchannel
&TAG=bancontactwip
&REDIRECTSECRET=fA7QdJvIIZBiWicglpI32MMT1aAchhR8

3.2. Retrieve Transactional Status at GETTXSTATUS

In your <https://api.girogate.de>GETTXSTATUS POST request, include:

txtype=GETTXSTATUS
&login=johndoetest
&password=wXBrpVporFVjGO4R
&contractid=JOHNDOETESTCONTRACT
&txid=140011837449
&returnmode=urlencodeext
REQUESTSTATUS=SUCCEEDED
&REQUESTFAILREASON=
&STATUS=SUCCEEDED
&TXID=140011837449
&MERCHANTTXID=MYp3MF6zHDQm
&ERRMSG=
&REDIRECTURL=
&TAG=bancontactwip
&REDIRECTURL=https%3A%2F%2Fbancontact%2Dppro%2Ecom%2FT%2FI%3Ftx%3D140011837448%26rs%3D4eukBgRfmvKOSMU3BOmuvGk4bpbwg3Vb%26cs%3Dc7dbb38be368a0589bc0eecca68b859ad75af6906aa59b8cc09c685ecd4d29ff
&REDIRECTSECRET=fA7QdJvIIZBiWicglpI32MMT1aAchhR8
&FAILREASON=
&CHANNEL=testchannel
&SPECOUT.BEPURL=BEP%3A%2F%2F1BANCONTACT%2EPPRO%2ECOM%2FBEP%2F140011837448
&SPECOUT.PAYMENTPURPOSE=6HMJ2EE+Dynamic+++Descriptor+nValue
&SPECOUT.POLLINGHASH=e1b9a672%2D1203%2D4825%2D8fcd%2Defa1bb0a81d5
&SPECOUT.PREFERREDLANGUAGE=fr
&SPECOUT.QRPAYLOAD=BEP%3A%2F%2F1BANCONTACT%2EPPRO%2ECOM%2FBEP%2F140011837448
&SPECOUT.SRCCOUNTRY=BE
&SPECOUT.SRCIBAN=DE96888888881111111111
&SPECOUT.TXDATETIME=2025%2D02%2D06T14%3A29%3A52
&SPECOUT.URLINTENT=bepgenapp%3A%2F%2FDoTx%3FTransId%3D1BANCONTACT%2EPPRO%2ECOM%2FBEP%2F40011837448
&RAND3541121862=68b6e261641d64274a87d5153b1fb273299f90cb

Field NameM/O/CDescription
returnmodeMCan be set as urlencodeext or json
txtypeMMust always be set to GETTXSTATUS
loginMThe PPRO-provided login.
passwordMThe PPRO-provided password.
contractidMDefines the merchant for whom PPRO is processing the transaction.
txidMThe id of the transaction for which you are requesting the status

4. Create subsequent transactions at TRANSACTION

Once you confirm an agreement is active, you can pass the AGREEMENTID value when you make a TRANSACTION request.
The request structure is the same as a TRANSACTION call input for the payment method in question, plus this added AGREEMENTID field and by using SPECIN.INITIATION=MERCHANT when initializing the transaction.
In the TRANSACTION call output, you should see that the recurring payment succeeds immediately without the need to redirect / authenticate the consumer.

Differentiate one-click payments from recurrent merchant initiated payments with the field specin.initiation as describe below.

📘

WIP transactions confirmation

WIP transactions succeed or fail synchronously. There is no redirect and no consumer interaction. In the healthy case, the status is immediately SUCCEEDED and no notification is sent (unlike PENDING > SUCCEEDED status changes).


In your <https://api.girogate.de>TRANSACTION POST request, include:

tag=bancontactwip
&txtype=TRANSACTION
&countrycode=BE
&currency=EUR
&amount=1055
&agreementid=10000
&merchanttxid=MYp3MF6zHDQm
&login=johndoe
&password=wXBrpVporFVjGO4R
&contractid=JOHNDOETESTCONTRACT
&channel=testchannel
&merchantredirecturl=https%3A%2F%2Fmerchant.com%2Fwork%2Fppro2%2Flanding.php
&notificationurl=https%3A%2F%2Fmerchant.com%2Fwork%2Fppro2%2Fnotification.php
&specin.dynamicdescriptor=DynDescriptor
&accountholdername=Tester+Doe
&preferredlanguage=fr
&returnmode=urlencodeext
&specin.initiation=merchant
Field NameM/O/CDescription
returnmodeMCan be set as urlencodeext or json
txtypeMMust always be set to TRANSACTION
agreementidMThe agreementid value returned in the AGREEMENT call
loginMThe PPRO-provided login.
passwordMThe PPRO-provided password.
contractidMDefines the merchant for whom PPRO is processing the transaction.
channelMThe channel in the contract to use for the transaction. testchannel for testing and livechannel for production.
tagMMust always be set to bancontactwip
currencyMThe 3-letter ISO currency code (e.g. EUR)
amountMThe amount to wire in the currency’s smallest representable unit as per ISO4217.
Example:
For EUR 0.01, the amount is 1.
For EUR 1.00, the amount is 100.
countrycodeMThe 2-letter ISO country code from which the consumer will be paying. This also typically aligns with the locale of the payment method, as many methods are only valid in a single country. For details, see payment method-specific documentation.
accountholdernameMThe account holder - minimum of 3 characters, up to 100 characters. UTF-8.
merchantredirecturlMThe URL the consumer will be redirected to after the transaction succeeded or in case of abort/failure.
Minimum length of 13 characters. Maximum length of 255 characters. Must start with http:// or https://. Allowed characters are the ascii range [a-zA-Z0-9] and the following characters: -._~:/?#[]@!$&'()*+,;=%
notificationurlMThe URL signalled for the final status of a transaction. The same restrictions as for merchantredirecturl apply.
merchanttxidOYour transaction identifier.
Allowed characters: [a-zA-Z0-9.,-_].
Maximum of 40 characters.
Uniqueness is not enforced and is your responsibility in the context of a contract.
preferredlanguageOThe 2-letter language code (e.g. de) of the language preferred when presenting payment pages to the consumer.
specin.initiationMThe party initiating the transaction:

- consumer - one-click payment

- merchant - recurring payment
REQUESTSTATUS=SUCCEEDED
&STATUS=SUCCEEDED
&TXID=140011837449
&ERRMSG=
&CHANNEL=testchannel
&TAG=bancontactwip
&REDIRECTSECRET=d6rSVahlxK0t0Du8tpD12VRE3PosHBUA
&SPECOUT.BEPURL=BEP%3A%2F%2F1BANCONTACT%2EPPRO%2ECOM%2FBEP%2F140011837448
&SPECOUT.CARDBIN=670999
&SPECOUT.CARDLAST4DIGITS=9999
&SPECOUT.CARDTOKEN=S-621f64eb-6271c974-abcd-abcd-abcd-492f7b123456
&SPECOUT.PAYMENTPURPOSE=2G2ABCD
&SPECOUT.SRCBIC=GKCCBEBB
&SPECOUT.SRCCOUNTRY=BE
&SPECOUT.SRCIBAN=BE12561483123456
&SPECOUT.CARDEXPIRY=2604
&SPECOUT.CARDMASKEDPAN=60799XXXXXX9999

Agreement and Cards Lifecycle Management

Agreement/Token Expiration

Agreements will work for 365 days after creation. Make sure you stop displaying the card link on the consumer’s payment options/applications before that time, and request the consumer to re-link a payment card - note that re-linking a card is a new payment flow; it is not possible to update an existing link.

Cards Expiration

The agreement is tied to the Card Number when it's first created. Since Bancontact debit cards expire, the scheme recommends that the issuers don’t verify the expiry date for WIP transactions. Those transactions should continue working if the card number remains the same on card renewal.

The customer is responsible for asking consumers to update the card details before expiry, and to re-link the renewed card if necessary. For this reason, we output SPECOUT.CARDBIN and SPECOUT.CARDLAST4DIGITS which can be displayed as e.g. 123456XXXXXX7890 in a confirmation dialog.

Cancel an Agreement at CANCELAGREEMENT


In your <https://api.girogate.de>CANCELAGREEMENT POST request, include:

txtype=CANCELAGREEMENT
&login=johndoetest
&password=password
&contractid=JOHNDOETESTCONTRACT
&agreementid=agr_2sd3jkds3lsdk32lsd8ak
&returnmode=json
Field NameM/O/CDescription
returnmodeMCan be set as urlencodeext or json.
txtypeMMust always be set to CANCELAGREEMENT
loginMThe PPRO-provided login.
passwordMThe PPRO-provided password.
contractidMDefines the merchant for whom PPRO is processing the transaction.
agreementidMThe agreementid value returned in the AGREEMENT call.
REQUESTSTATUS=SUCCEEDED
&STATUS=REVOKED_BY_MERCHANT
&AGREEMENTID=agr_2sd3jkds3lsdk32lsd8ak
&ERRMSG=
&CHANNEL=testchannel
&TAG=bancontactwip
&REDIRECTSECRET=P7QEgfywdtrB7pgwdVEVzu4gqrHOXA1m

Retrieve All transactions for a specific Agreement

In your <https://api.girogate.de>GETAGREEMENTTXSTATUS POST request, include:

txtype=GETAGREEMENTTXSTATUS
&login=johndoetest
&password=password
&contractid=JOHNDOETESTCONTRACT
&agreementid=agr_2sd3jkds3lsdk32lsd8ak
&page=
&returnmode=json
Field NameM/O/CDescription
returnmodeMCan be set as urlencodeext or json
txtypeMMust always be set to GETAGREEMENTSTATUS
loginMThe PPRO-provided login.
passwordMThe PPRO-provided password.
contractidMDefines the merchant for whom PPRO is processing the transaction.
agreementidMThe agreementid value returned in the AGREEMENT call
pageOThe NEXTPAGE token returned from previous calls to this endpoint, if the transaction list was paginated.
TRANSACTIONS[0].TXID=140011837449  
&TRANSACTIONS[0].STATUS=SUCCEEDED  
&TRANSACTIONS[0].TXID=140011837449  
&TRANSACTIONS[0].FAILREASON=  
&TRANSACTIONS[0].MERCHANTTXID=MYp3MF6zHDQm  
&TRANSACTIONS[0].ERRMSG=  
&TRANSACTIONS[0].CHANNEL=testchannel  
&TRANSACTIONS[0].TAG=bancontactwip  
&TRANSACTIONS[0].REDIRECTURL=https%3A%2F%2Fmerchant.com%2Fwork%2Fppro2%2Flanding.php  
&NEXTPAGE=sSD22i3jfDS2fjkjsJ
TRANSACTIONS=[  
  {  
      "TXID":150000635350,  
      "STATUS":"SUCCEEDED",  
      "FAILREASON":"INVALID",  
      "MERCHANTTXID":"53498e0a-50be-4bad-bf99-6a071073b218",  
      "FUNDSSTATUS":"WAITING",  
      "ERRMSG":"",  
      "CHANNEL":"testchannel",  
      "TAG":"mock",  
      "REDIRECTURL":"https://vo3z67veza.execute-api.eu-central-1.amazonaws.com/default/authenticator.html?payment-charge-id=charge_h8bXXb606YAMJHLM22Dyw"  
  },  
  {  
    ...  
  }  
]  
NEXTPAGE=sSD22i3jfDS2fjkjsJ
Field NameDescription
TRANSACTIONSA list of TRANSACTIONs made under the agreement.
NEXTPAGEA token that can be passed as a page in subsequent calls to this endpoint to get the next page of transactions if the list is too long for one response.