ALLOW from Attesso and execute it on Mollie as a payment, then report the outcome. This is the Mollie recipe for the pattern in Bind an authorization to your PSP: authorize first, execute second, report finality. Attesso authorizes and records; your backend calls Mollie to execute, then reports the outcome to Attesso. Attesso never calls Mollie.
API host: https://api.mollie.com/v2. Test mode uses a test_ API key and live uses live_ (or the testmode parameter with an organization access token); test and live data are fully isolated. Mollie’s test mode supports EUR only.
New to Attesso? The quickstart covers creating a workspace, a test key, and the approval trust this recipe assumes.
Execute the approved action
Create the payment from the same immutable proposed action you sent to/authorizations; bind the two systems with your external_action_reference.
webhookUrl reachability at creation (a loopback URL is rejected); in local development point it at a public tunnel.
The loop runs once per Authorization. Under a RECURRING mandate, every execution takes this same authorize, execute, report path, each one counted against the mandate’s per-period budget.
Report the outcome to Attesso
- Definite acceptance (
paid, orauthorizedfor manually captured methods): commit withprovider_transaction_reference: payment.id. - Definite non-acceptance (
failed,expired,canceled): cancel withreason: EXECUTION_FAILED(useEXECUTOR_REJECTEDwhen Mollie refuses the action outright). With an earlier ALLOW, the disposition isNO_LONGER_POSSIBLE. - A refund after commit is not an authorization transition; report it so the signed evidence carries the claim (Refund reports).
open,pending(or a still-open checkout): not final; do not commit or cancel yet.- A timeout or lost response: reconcile before deciding (below).
Webhooks
One rule covers both flows in this loop: a notification is a trigger, never the proof. From Mollie. Mollie posts only the paymentid (form-encoded) to the webhookUrl you set on creation; fetch the payment yourself and act on its state. Respond 200 OK immediately, before processing. Mollie retries failed deliveries ten times over about 26 hours.
From Attesso. Attesso delivers signed lifecycle notifications: mandate approvals and revocations, authorization outcomes, and the rest of the journal. Register an endpoint with Webhooks, verify every delivery, then fetch current state and the signed evidence bundle.
Reconcile a lost response
- Retry the identical create call with the same
Idempotency-Key: Mollie returns the original response (Idempotent-Replayed: trueheader); a409 Conflictmeans the first request is still in flight; a reused key with different bytes is a400. - Keys survive for one hour; after that the same key is a new request.
- Find the payment by listing payments and matching your
metadatavalues, or retrieve it directly by itstr_id.
Test mode
Verified against Mollie test mode (Oct 2026):- Selecting paid in the test checkout completes the payment and returns the payer to
redirectUrl. - To exercise a failed payment, pin
"method": "creditcard"at creation and use a documented magic amount from Mollie’s testing reference, for example1007.00->insufficient_funds, then select Failed on the status screen. A payment created without a pinned method bounces non-paid selections back to method selection and staysopen; open test payments are not cancelable via the API (DELETE /payments/{id}-> 422). - On paid test payments, Mollie adds a
changePaymentStatelink for testing refunds and chargebacks.
Rehearsal
mollie-e2e.mjs drives the full loop against this recipe: Mandate create, passkey approval, an over-cap DENY, an in-cap ALLOW executed as a Mollie test payment, then commit (paid) or cancel (failed), with the signed evidence verified locally. Every create is replayed under its idempotency key first, and the replay must return the same resource. Settle each printed checkout URL in a browser; passMOLLIE_WEBHOOK_URL (a public tunnel URL ending in /mollie-webhook) to exercise real webhook delivery, or leave it unset to settle by polling.
node mollie-e2e-drive.mjs --runs 3 completes three full loops without a human at the keyboard. It needs Playwright installed.
