Payments - As a Service
Last updated
Was this helpful?
Once a user has a verified monetary account, they can send and receive money on the SEPA network. bunq's payments API gives you full programmatic control over both sides of that flow.
Payments in bunq are always scoped to a monetary account. To initiate a payment, you specify the source account, the destination (an IBAN or bunq alias), the amount, and a description. bunq handles the routing — internal transfers between bunq accounts settle instantly; external SEPA payments follow standard rail timelines.
Incoming payments arrive on the account's IBAN. Your integration receives them via callbacks and can query the transaction history at any time.
Key things to understand:
Payment types. The Payment object covers both outgoing and incoming transfers. Filter by type (IDEAL, SEPA, INTERNAL, etc.) to distinguish them.
Draft payments. For flows that require a second approval step (e.g. a human signs off before money moves), use DraftPayment. The payment is created but not executed until explicitly confirmed.
Batch payments. You can send multiple payments in a single API call using PaymentBatch. Useful for payroll runs, mass payouts, or invoice settlements.
Idempotency. Use the X-Bunq-Client-Request-Id header to safely retry failed requests without risk of double payments.
Callbacks. Register a notification filter on the account to receive a webhook whenever a payment arrives or a payment status changes.
Outgoing payment:
Your platform bunq API
───────────── ────────
POST /payment → Validates and queues payment
← Payment object (status: PENDING)
← Callback: PAYMENT_CREATED / PAYMENT_EXECUTEDIncoming payment:
List payments (history)
Get a specific payment
Create a draft payment
Send a batch of payments
Register a payment callback
The payment response includes:
amount — object with value (string decimal) and currency
counterparty_alias — the other party's IBAN or bunq alias
description — the payment reference (appears on the recipient's statement)
type — payment rail used (SEPA_CREDIT_TRANSFER, INTERNAL, etc.)
status — current state (PENDING, EXECUTED, REJECTED, REVERTED)
created / updated — timestamps in YYYY-MM-DD HH:MM:SS.SSSSSS format
Pattern 1 — Instant payouts. Trigger a payment immediately when an event occurs in your platform (e.g. a gig worker completes a task). Use callbacks to confirm execution and update your own records.
Pattern 2 — Scheduled / batch payroll. Collect payment instructions throughout the week, then fire a PaymentBatch on payday. Simpler to manage than individual calls and easier to reconcile.
Pattern 3 — Incoming payment reconciliation. Each account has a unique IBAN. Assign one account per customer or invoice, so incoming payments self-identify by destination. Query the payment's description field for additional reference matching.
Pattern 4 — Two-step approval. Use DraftPayment for high-value transactions that require a human review step before execution. Your platform surfaces the draft, an authorised user confirms it, and you send the confirmation via API.
{% hint style="warning" %} Always store the X-Bunq-Client-Request-Id you send with each payment request. If a request times out, resubmit the same ID — bunq will deduplicate and return the original result rather than creating a second payment. {% endhint %}
Last updated
Was this helpful?
Was this helpful?
External sender bunq API Your platform
─────────────── ──────── ─────────────
Sends SEPA to user's IBAN → Credits account
→ Callback: MUTATION → Your webhook
GET /payment/{id} ← Full transaction detail