Disputes
A cardholder's bank can pull a payment back weeks after it settled. BillKit mirrors those chargebacks read-only. There is nothing to configure, and no contest flow, because Mollie does not expose one.
What a dispute is here
A dispute is a chargeback: the cardholder told their bank they do not accept a payment, and the bank pulled the money back out of your Mollie balance. It is not a refund. A refund is you returning money; a chargeback is a bank taking it, usually with a fee, and usually long after the original payment looked final.
BillKit does not run the chargeback. Your acquirer and Mollie do. What BillKit gives you is a record of one against the payment, the subscription and the customer it belongs to, so a chargeback shows up in the same place as the rest of that customer’s billing history instead of only in your Mollie dashboard.
Disputes are read-only. There is no endpoint to create, contest or close one, and that is not a gap in the API. See Why you cannot contest from BillKit.
The two states
| Status | What it means |
|---|---|
| open | The chargeback was received. The funds are already out of your balance. |
| won | Mollie reversed the chargeback. The funds came back to you. |
There is deliberately no lost status, and that is the single most important thing to
understand about this resource.
Mollie’s chargeback model exposes exactly two signals: a chargeback is received, and it may
later be reversed. An upheld chargeback, one you effectively lost, simply never reverses.
Nothing arrives to say so. BillKit could invent a lost state by starting a timer and declaring
defeat when it expires, and it does not, because a late reversal would then contradict a terminal
financial outcome the API had already published. A standing chargeback stays open indefinitely.
If you need “lost” for your own accounting, derive it on your side from age, but treat it as an
estimate, not a fact, and let a later dispute.closed correct you.
When the money moves
Funds leave on open, not on close. By the time the dispute row exists, your balance has
already been debited. This is why dispute.created is the event worth acting on: it is the one
that has a financial consequence, and waiting for a resolution that may never come means acting
weeks late or not at all.
| Event | When it fires |
|---|---|
| dispute.created | A chargeback was received. Funds are already withdrawn. |
| dispute.closed | The chargeback reversed, open to won. Funds returned. |
A chargeback that Mollie has already reversed by the time BillKit first sees it emits both events
back to back, so a listener that only handles dispute.closed still gets a consistent picture.
What BillKit does not do to the subscription
Nothing automatic. A dispute does not cancel, pause or suspend the subscription it came from, and it does not block future renewals.
That is a deliberate choice rather than an omission. A chargeback can be fraud on a stolen card, in which case you almost certainly want to end service immediately. It can equally be a customer who forgot what the line item was, in which case cancelling their subscription turns a support conversation into a lost account. BillKit cannot tell those apart, so it tells you and lets you decide.
The usual shape is to listen for dispute.created, look at the subscription it names, and apply
your own policy: cancel, suspend access, or just open a ticket.
Reading disputes
curl "https://api.billkit.eu/v1/disputes?limit=20" \
-H "Authorization: Bearer $BILLKIT_API_KEY" Each dispute carries the amount and currency taken, the reason code the bank supplied when it
supplied one, and links back to the payment, subscription and customer involved. One-shot
payments are covered too: a dispute points at either a payment or a one_shot_payment, never
both.
Full field-by-field shapes are in the API reference: List disputes and Retrieve a dispute. In the console they are under Disputes, with the same data and a timeline per dispute.
Reconciliation, if a webhook goes missing
Mollie notifies the original payment’s webhook again when a chargeback reverses. If that delivery
is lost, the dispute would sit open forever even though the money came back.
A background reconciler covers that. Disputes stuck open past a staleness threshold are re-read
from Mollie through the same code path the webhook uses, so dispute.closed still fires and your
own systems still hear about it. Polling stops after 180 days: a reversal that late is vanishingly
rare, and if one does arrive it still comes through the inbound webhook.
You do not need to configure or trigger any of this. It is mentioned because “the webhook was dropped” is a real failure mode and it is worth knowing that it is already handled.
Why you cannot contest from BillKit
Mollie has no API-side evidence or representment flow. You cannot submit documentation, argue a chargeback, or accept one through the Mollie API, and therefore not through BillKit either. Contesting a chargeback happens with your acquirer, through Mollie’s own dashboard and support, outside both APIs.
An endpoint here that appeared to let you contest would be a lie about what happens next, so there isn’t one.
Test mode
Test-mode payments support disputes. Mollie simulates chargebacks against test payments, and they
flow through the same webhook, the same table and the same events as live ones, so you can build
and verify your dispute.created handling without waiting for a real cardholder to dispute
something.
Chargeback fees are charged by your acquirer and settled on your Mollie balance. They are not part of the BillKit dispute record, and they do not appear on a BillKit invoice or credit note.
BillKit