Bank redirects

The customer leaves your checkout, authenticates at their own bank, approves the payment, and comes back. Strong bank authentication means the money is guaranteed once approved — and there is no chargeback rail. In markets like the Netherlands and Belgium, these methods outsell cards.

The redirect methods

Methodpayment_methodRegion
iDEALidealNetherlands
BancontactbancontactBelgium
EPSepsAustria
Przelewy24p24Poland
FPXfpxMalaysia
TrustlytrustlyEurope + Nordics

All six are account-to-account push payments dressed in a scheme: the customer instructs their own bank to pay you. Trustly is the multi-market one — a single method id covering bank login across much of Europe and the Nordics. Currencies per method are in the catalog.

The redirect round-trip

Customer Your server Finscale Customer's bank POST /v1/payments — ideal requires_action + next_action.url redirect to next_action.url picks their bank on the hosted page authenticates & approves in online banking payment confirmed webhook: payment.succeeded returns to return_url Render the confirmation page from webhook-established state — the redirect back can be lost, replayed, or arrive before the webhook.

Two properties of this flow shape your integration:

  • The webhook is the source of truth. The customer's browser coming back to return_url proves nothing — they can close the tab at the bank, the redirect can be lost, or it can arrive before the bank's confirmation. Fulfill on payment.succeeded, and make the return page read state your webhook handler wrote. The API integration guide shows the pattern.
  • Approval is usually seconds, but not always. Most banks confirm while the customer is still in the flow. A few confirm minutes later — treat requires_actionsucceeded as asynchronous, never as a same-request answer.

Creating a redirect payment

return_url is required — there is always a redirect to come back from:

POST /v1/payments — iDEAL
curl https://api.finscale.dev/v1/payments \
  -H "Authorization: Bearer sk_test_51FinscaleDemo…" \
  -H "Idempotency-Key: idem_ord_9f21_0716" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 4900,
    "currency": "EUR",
    "payment_method": "ideal",
    "reference": "ord_9f21_0716",
    "customer": { "email": "anna@example.com" },
    "return_url": "https://shop.example.com/checkout/return"
  }'
201 Created
{
  "id": "pay_8Q2mX4nT1cVb",
  "object": "payment",
  "amount": 4900,
  "currency": "EUR",
  "status": "requires_action",
  "payment_method": "ideal",
  "reference": "ord_9f21_0716",
  "provider": "prov_eu_acq_01",
  "next_action": {
    "type": "redirect",
    "url": "https://pay.finscale.dev/r/8Q2mX4nT"
  },
  "created_at": "2026-07-16T09:24:31Z",
  "livemode": false
}

Send the customer to next_action.url. Bank selection (for methods that need it, like iDEAL and Przelewy24) happens on the Finscale-hosted page — you don't build a bank picker.

What comes back

After approval, payment_method_details records which bank paid and the tail of the paying account — useful for support and for matching refunds later:

payment_method_details — after approval
{
  "payment_method_details": {
    "ideal": {
      "bank": "demo_bank_nl",
      "iban_last4": "3401"
    }
  }
}

The shape is keyed by method id — ideal: { bank, iban_last4 } here; equivalents for the other five carry the same idea.

Refunds — and no chargebacks

Refunds work the standard way: POST /v1/refunds with the payment id, full or partial. Under the hood the refund travels as a credit transfer back to the account that paid — Finscale captured it during the flow, so there is nothing to collect from the customer. Refunds are pending until the transfer lands, typically one to two business days; subscribe to refund.succeeded. See Refunds.

No chargeback rail The customer authenticated at their bank and pushed the payment themselves, so these schemes have no dispute mechanism — a completed bank redirect cannot be charged back. Your dispute queue only ever contains card-family disputes.

Settlement timing

The bank's approval is a guarantee, not yet cash: the scheme moves the funds to Finscale within a business day, and they join your unified payout on the standard T+2 schedule alongside your card and wallet volume — one payout per currency, one settlement report to reconcile.

Error scenarios

ScenarioWhat the API does
Customer abandons at the bankThe payment stays requires_action until the redirect session expires, then moves to failed and payment.failed fires. Sessions are single-use — a restarted checkout is a new payment.
Bank refuses the paymentpayment.failed with a normalized failure_code — most commonly insufficient_funds. Bank refusals are final: no failover, because the answer came from the customer's bank, not from a provider.
Method/currency mismatch400 invalid_request_error with currency_not_supported — e.g. ideal with a non-EUR currency.
return_url missing400 invalid_request_error at create — redirect methods require it.
Provider degradedRouting happens before the customer is redirected, so a failing provider is skipped transparently — see Provider health & failover.