Docs

Get started

Quickstart

Sign up a payer, register a payee, sign a mandate, get a decision, and send a simulated payout. About five minutes, no real money.

Before you start

The sandbox is shared, and each payer email and funding IBAN can be used once, so these snippets generate fresh ones on every run. Add X-API-Key (or api_key= in Python) if your sandbox has authentication on.

Install and connect
# pip install "whire>=0.2"      (Python 3.11+, async)
# Run the snippets below in `python -m asyncio`, or inside an async function.
import random, uuid
from whire import WhireClient

client = WhireClient(environment="sandbox")
run = uuid.uuid4().hex[:8]

def random_iban() -> str:  # a valid throw-away NL IBAN
    bban = "ABNA" + "".join(random.choices("0123456789", k=10))
    check = 98 - int("".join(str(int(c, 36)) for c in bban + "NL00")) % 97
    return f"NL{check:02d}{bban}"

Check what the deployment can do. No key needed:

Sign up and verify a payer

The payer is the customer whose money moves. It opens pending_verification; a person records the verification.

payer = await client.payers.create(
    legal_name=f"Merchant {run} B.V.",
    account_type="business",
    contact_first_name="Eva",
    contact_last_name="Jansen",
    email=f"eva.{run}@example.com",
    phone="+31612345678",
    funding_sources=[{"type": "sepa", "destination": random_iban()}],
)
payer = await client.payers.activate(
    payer.payer_id, verified_by="Compliance Officer"
)
print(payer.status)  # active
Register a payee and sign a mandate

The mandate lets this payer pay this payee up to 100 EUR per payment and 250 EUR in total. See Mandates.

payee = await client.beneficiaries.create(
    full_name="Acme Supplies BV",
    iban="DE89370400440532013000",
    reference=f"acme-{run}",
)
mandate = await client.mandates.create(
    beneficiary_id=payee.beneficiary_id,
    payer_id=payer.payer_id,
    mandate_reference=f"SHOP-{run}",
    signed_by="Finance",
    max_amount=100,
    max_total_amount=250,
)
Ask for a decision

Nothing moves yet. The answer is a signed receipt that says yes or no, and which checks failed.

receipt = await client.authorizations.create(
    mandate_id=mandate.mandate_id,
    beneficiary_id=payee.beneficiary_id,
    amount=50,
)
print(receipt.decision, receipt.failed_checks)  # approved []

refused = await client.authorizations.create(
    mandate_id=mandate.mandate_id,
    beneficiary_id=payee.beneficiary_id,
    amount=150,
)
print(refused.decision, refused.failed_checks)  # refused ['per_payment_limit']
Send a payout

Create a draft under the mandate, submit it for KYC review, wait for the decision, execute. The sandbox decides KYC after about three seconds.

payout = await client.payouts.create(
    beneficiary_id=payee.beneficiary_id,
    mandate_id=mandate.mandate_id,
    amount="20.00",
    reason="Invoice 2026-091",
)
await client.payouts.submit(payout.payout_id)
payout = await client.payouts.wait_for_kyc(payout.payout_id, timeout=30)
print(payout.status)  # approved

execution = await client.payouts.execute(payout.payout_id)
print(execution.status, execution.provider_reference)  # paid SIM-...
await client.close()

What next#