Flexible bank transfer reconciliation (Beta)
This feature is in beta.
Virtual IBANs and the Unmatched Credit Transfer API are currently available to a limited set of merchants in the Netherlands, Belgium, France, and Germany. Contact us or your account/sales manager to request early access.
General information
By default, Mollie automatically matches incoming bank transfers to open payments using the payment reference and amount. This works well for straightforward cases — but bank transfers are inherently uncontrolled: customers may forget the reference, mistype the amount, or send a single transfer covering multiple invoices.
The Flexible Reconciliation feature gives you programmatic control over these edge cases. It combines two things:
- Virtual IBANs (vIBANs) — a dedicated IBAN assigned exclusively to your Mollie profile for receiving bank transfers. Unlike a Mollie business account, a vIBAN is not a bank account: funds received via your vIBAN land in your Mollie balance and are paid out to your business bank account on the normal settlement schedule. The vIBAN is issued in your profile's name, and is compliant with the Verification of Payee regulation — your customers will see a green checkmark in their banking app confirming the IBAN matches your business.
- Unmatched Credit Transfer API — when automatic matching fails, Mollie notifies you via webhook and lets you decide: match the funds to one or more payments, or return them to the sender
This is especially useful for platforms, billing software, and B2B merchants who deal with partial payments, combined invoices, or customers who routinely omit payment references.
How it works
Step 1: Share your virtual IBAN with customers
Once provisioned, your virtual IBAN is unique to your Mollie profile. Display it on your invoices, order confirmations, and checkout pages as the payment destination.
With a standard bank transfer, all merchants share the same Mollie IBAN — the payment reference is the only way to identify which merchant and which order a transfer belongs to. With a vIBAN, the IBAN itself is dedicated to your profile, so incoming transfers always land in your Mollie balance regardless of the reference. Mollie still uses the reference to match the transfer to one of your open payments, but if matching fails, you stay in control via the API instead of the funds being returned automatically.
Tip: Still include a payment reference in your instructions. This maximises the chance of automatic matching and reduces the number of unmatched transfers you need to handle.
Step 2: Create open payments (standard flow)
Create a payment via the Create payment endpoint with method:banktransfer, status will remain as open.
curl -X POST https://api.mollie.com/v2/payments \
-H "Authorization: Bearer live_xxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"amount": { "currency": "EUR", "value": "120.00" },
"description": "Invoice INV-2024-0099",
"redirectUrl": "https://example.com/order/INV-2024-0099",
"method": "banktransfer"
}'When the customer pays correctly (right reference, right amount), Mollie matches and settles automatically — no
further action needed.
Step 3: Receive the webhook for unmatched transfers
When a transfer cannot be matched automatically, Mollie sends a webhook event to your endpoint.
Event type: unmatched-credit-transfer.received
{
"resource": "event",
"id": "event_GvJ8WHrp5isUdRub9CJyH",
"type": "unmatched-credit-transfer.received",
"entityId": "uct_abcDEFghij123456789",
"createdAt": "2025-09-24T14:15:00.0Z",
"_embedded": {
"entity": {
"resource": "unmatched-credit-transfer",
"id": "uct_abcDEFghij123456789",
"profileId": "pfl_abcDEFghi",
"amount": {
"value": "120.00",
"currency": "EUR"
},
"source": {
"format": "iban",
"accountHolderName": "Dhr J Doe",
"iban": "NL************6789",
"bic": "TESTNL2A"
},
"remittanceInformation": {
"unstructured": "transfer text field goes here",
"references": {
"creditorReference": "RF0000000000",
"endToEndId": "ABC123"
}
},
"status": "matched",
"paymentIds" : ["tr_123abc", "tr_890xyz"],
"expiresAt": "2025-09-26T14:13:00.0Z",
"createdAt": "2025-09-24T14:15:00.0Z",
"_links": {
"self": {
"href": "https://api.mollie.com/v2/unmatched-credit-transfers/uct_abcDEFghij123456789",
"type": "application/hal+json"
},
"documentation": {
"href": "https://docs.mollie.com/reference/unmatched-credit-transfer-api",
"type": "text/html"
}
}
}
}The embedded entity gives you everything you need to make a reconciliation decision: the sender's account details, the amount, and any remittance information they included.
Step 4: Fetch the unmatched credit transfer
Use the entityId from the webhook to retrieve the unmatched credit transfer resource via the Get unmatched credit transfer endpoint.
curl https://api.mollie.com/v2/unmatched-credit-transfers/uct_abcDEFghij123456789 \
-H "Authorization: Bearer live_xxxxxxxxxxxxxxx" You can also use the List unmatched credit transfers endpoint to retrieves a list of unmatched credit transfers for your profile.
Step 5: Resolve the transfer
Once you receive the unmatched-credit-transfer.received webhook, you have up to 2 days to resolve the transfer. If 2 days pass, the transfer will be returned to the sender.
You cannot match an unmatched transfer to a payment with a different amount by adjusting the payment amount. The total of thepaymentIdsyou provide must exactly equal the amount of the unmatched credit transfer.
Once you've identified what the funds are for, take one of two actions.
Option A: Match the funds to one or more payments
Use this when you can identify the payment(s) the customer intended to pay. You can match to an existing open payment, or — for maximum flexibility — create a new payment first and then immediately match the unmatched funds to it.
Matching to a payment:
curl -X POST https://api.mollie.com/v2/unmatched-credit-transfers/uct_abcDEFghij123456789/match \
-H "Authorization: Bearer live_xxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d "paymentIds": ["tr_PaymentToken"]"Matching to multiple payments (e.g. a customer paying two invoices in one transfer):
curl -X POST https://api.mollie.com/v2/unmatched-credit-transfers/uct_abcDEFghij123456789/match \
-H "Authorization: Bearer live_xxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"paymentIds": ["tr_PaymentToken1","tr_PaymentToken2"]
}'The action is processed asynchronously. Mollie will send an unmatched-credit-transfer.matched webhook once the funds are settled against the payments you specified.
Option B: Return the funds to the sender
Use this when you cannot identify the customer or the funds don't correspond to any open invoice, and you want to
refund them.
curl -X POST https://api.mollie.com/v2/unmatched-credit-transfers/uct_abcDEFghij123456789/return \
-H "Authorization: Bearer live_xxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{}'Mollie will send an unmatched-credit-transfer.returned webhook once the return is processed.
Status reference
| Status | Description |
|---|---|
received | The credit transfer has been received but not yet matched or returned. |
matched | The credit transfer has been matched to one or more payments. |
returned | The credit transfer has been returned to the sender. |
expired | The credit transfer has expired without being matched or returned. |
Webhook events
| Event type | Triggered when |
|---|---|
unmatched-credit-transfer.received | A new unmatched credit transfer is created (matching failed) |
unmatched-credit-transfer.matched | The transfer is successfully matched and settled to payment(s) |
unmatched-credit-transfer.returned | The transfer has been returned to the sender. |
unmatched-credit-transfer.expired | The transfer expired without a resolution being applied |
Updated 17 days ago