Docs

Concepts

Simulation

The sandbox settles against simulated money. Nothing real moves, every response says simulated: true, and every outcome a bank can produce is available on demand, so you can build your failure handling before you have a bank.

note

These triggers mean nothing on a deployment that moves real money. Check GET /api/capabilities first: simulated: true means they apply.

Choose the outcome#

You pick it with the cents of the amount, or with two designated IBANs.

Trigger Outcome Status after execute → after the delay
any other amount settled at once paid
ends in .01 insufficient funds (AM04) failed
ends in .02 payee account closed (AC04) failed
ends in .03 no confirmation, then settled processing (unresolved) → paid
ends in .04 no confirmation, then rejected processing (unresolved) → failed
ends in .05 accepted, settles later processing → paid
ends in .06 settled, then returned by the bank (AC01) paid → returned
ends in .07 rail unavailable, nothing sent failed
debtor IBAN NL56SIML0000000001 source account frozen, refused before sending stays approved
payee IBAN NL29SIML0000000002 KYC rejected kyc_rejected
any other payee KYC approved approved

For example, a payout of 20.03 is accepted without confirmation and settles a moment later:

payout = await client.payouts.create(
    beneficiary_id=payee.beneficiary_id,
    mandate_id=mandate.mandate_id,
    amount="20.03",
)
await client.payouts.submit(payout.payout_id)
await client.payouts.wait_for_kyc(payout.payout_id, timeout=30)

execution = await client.payouts.execute(payout.payout_id)
print(execution.status, execution.unresolved)  # processing True: do not resend

payout = await client.payouts.wait_for_settlement(payout.payout_id, timeout=60)
print(payout.status)                              # paid

Timing and balances#

  • KYC is decided by the service after a delay, three seconds by default. After submit, poll the payout until it leaves pending_kyc. Do not record the decision yourself.
  • Every debtor account opens with 1000.00 EUR. A balance below the amount is insufficient funds.
  • A returned payout still counts against the mandate's total. failed and kyc_rejected do not.
  • There are no webhooks yet. Poll.

Inspect and reset#

GET /api/simulation returns this table, the delay, and every simulated account with its balance. In Python, await client.simulation.get().

POST /api/reset empties the store and the simulated ledger. The store is shared, so reset only when you mean it. The Python SDK refuses unless the deployment is a simulated sandbox.