Accept a payment: cards, APMs and 3-D Secure 2

One object covers a Visa card in Berlin, an iDEAL debit in Rotterdam and a BLIK code in Kraków. What changes between them is the method, the refund window and who carries the chargeback risk.

  • Reviewed
  • 14 min read
  • API version 2026-04-01

The payment lifecycle

A payment moves through a small state machine. Only two states are final, and only one of them means you have money. Everything your order system does should be driven by these transitions rather than by the response to the call that created the object.

Statuses, what they mean and what you should do
Status Meaning Your move
requires_action The payer must authenticate or approve in their bank. Redirect to next_action.url. Hold the basket.
processing Submitted to the rail, outcome not yet known. Wait for the event. Never treat this as a failure.
requires_capture Authorised, funds held, nothing taken yet. Capture on dispatch, or cancel to release the hold.
succeeded Final. Funds are captured and scheduled to settle. Fulfil the order. This is the only status that means paid.
failed Final. The issuer or the bank refused. Show the reason, offer another method. See declines.
canceled Final. Abandoned by the payer, or released by you. Free any reserved stock.
The one rule

Fulfil on payment.succeeded, delivered to your webhook endpoint. Not on the browser returning to your return_url, and not on a status you polled. The redirect can be lost to a closed laptop, and a poll can race the rail — the event cannot.

Creating a payment

The same POST /v1/payments creates every kind of charge. Below is a card authorisation held for later capture, which is the shape most physical-goods merchants want.

POST /v1/payments · card, manual capture
# card charge, authorise now and capture on dispatchcurl -X POST https://api.bazpay.com/v1/payments \  -H "Authorization: Bearer sk_test_9f2c…" \  -H "Idempotency-Key: ord_10482" \  -d '{        "amount": 8990,        "currency": "EUR",        "method": "card",        "token": "tok_1Hq8Vc4nRs",        "capture": "manual",        "reference": "ORDER-10482",        "customer": { "email": "[email protected]" },        "return_url": "https://shop.example/thanks"      }'

token comes from hosted fields in the browser; your server never sees the PAN. Omit capture to take the money immediately.

The fields that change behaviour

  • amount Integer, minor units. 8990 with EUR is 89.90 euro. Currency decides the exponent — JPY has none, so 8990 there is 8,990 yen.
  • capture automatic takes the money at authorisation. manual holds it, which is correct whenever you might not ship.
  • reference Your order id. It travels onto the payer's statement where the scheme allows, onto every event, and onto the settlement line — which is what makes reconciliation cheap.
  • customer.email Optional but strongly advised: it feeds the risk score and is one of the data points that earns a transaction risk analysis exemption.
  • return_url Required for any method that redirects. It must be HTTPS and must tolerate being opened twice.

Where the card form lives

This is the decision that fixes your PCI scope, so make it before you write checkout code. All three options keep you at SAQ A because the card number never reaches your systems in any of them — what changes is how much of the interface you own.

Three surfaces, compared on the things that differ
Surface You build Effort Best when
Hosted checkout A redirect and a webhook handler. One day You want method selection, localisation and retry logic maintained for you.
Hosted fields Your own checkout; our iframe supplies the inputs. 2–5 days Brand control matters and you want one page rather than a hand-off.
CMS plugin Nothing. Install and paste two keys. Hours You are on WooCommerce, Magento 2, PrestaShop, Shopware or OpenCart.
On PCI scope

SAQ A applies when all cardholder data functions are outsourced to a validated third party and your page does not touch the PAN. Hosted fields satisfy this because the inputs belong to our origin, not yours. The moment you copy a card number into your own form field — even to reformat it — you leave SAQ A and enter SAQ A-EP. There is no partial version of this rule.

The EU method matrix

Every method below is created through the same call and reports the same events. They differ in three ways that affect your business rather than your code: how fast money settles, whether a partial refund is possible, and who carries the risk if the payer disputes it.

Methods, coverage and dispute exposure
Method Markets Refunds Dispute risk
Card — Visa, Mastercard All EU/EEA Full and partial, up to 180 days Chargebacks apply. Liability shifts on a 3-D Secure challenge.
iDEAL Netherlands Full and partial, to the same IBAN None. A completed iDEAL payment is final.
Bancontact Belgium Full and partial Very low. No cardholder-initiated chargeback path.
BLIK Poland Full and partial None on the code flow.
EPS Austria Full and partial None.
Open banking debit SEPA-wide under PSD2 Full and partial, same rail None for a payer-approved push. See open banking.
SEPA Direct Debit SEPA-wide Full and partial High: 8 weeks no-questions, 13 months if unauthorised.
Apple Pay · Google Pay All EU/EEA As the funding card As cards, but authentication is on-device so challenges are rare.

Show methods by the payer's country, not by your own. A Dutch checkout without iDEAL loses conversion no card optimisation will recover, and a Polish one without BLIK looks foreign. If you would rather not maintain that mapping, the hosted checkout does it from the payer's billing country and IP.

Pricing per method, including interchange++ breakdowns: pricing · method-level product detail: card and APM processing.

3-D Secure 2 and exemptions

Under PSD2, an electronic payment in the EEA needs strong customer authentication unless an exemption applies. We run 3-D Secure 2.2 for you: the authentication request is built, submitted and interpreted on the gateway, and you get the outcome on the payment object.

Frictionless is the normal case

Most authentications never show the payer anything. The issuer receives around 150 data points about the transaction, scores it, and returns an approval without a challenge. A challenge — a banking-app prompt or a one-time code — is the exception, and each one costs conversion.

Asking for an exemption

Where the rules allow it, you can ask to skip authentication. The issuer decides; a request is never a guarantee, and the response tells you what actually happened.

sca request and result
# ask for an exemption; the issuer may still force a challenge"sca": {  "request": "exemption",  "reason": "transaction_risk_analysis"}# what came back on the completed payment"sca": {  "applied": "exemption",  "reason": "transaction_risk_analysis",  "liability_shift": false,  "version": "2.2.0"}
Exemptions we can request, and the catch in each
Exemption Applies when The catch
Low value Under 30 EUR. Counters reset after five uses or 100 EUR cumulative — the issuer tracks this, you cannot.
Transaction risk analysis Acquirer fraud rate is under the band for the amount. Our rate, our call. Available up to 500 EUR at current performance.
Trusted beneficiary The payer added you to their allow-list at their bank. You cannot initiate it. Prompt on a challenge screen and the payer may opt in.
Merchant initiated Subscription renewals after an authenticated first payment. Needs the mandate from that first payment. See recurring billing.
Exemptions cost you the liability shift

A completed challenge moves fraud-chargeback liability to the issuer. An exemption keeps it with you. On a low-value digital order that trade is usually worth it; on a high-value physical one it rarely is. Set the threshold per product category rather than site-wide, and read anti-fraud before you set it low.

Capture, cancel, refund

An authorisation is a hold, not a payment. Three calls resolve it, and choosing the right one is the difference between a clean ledger and a support queue.

resolving an authorisation
# capture less than you authorised — the rest is releasedPOST /v1/payments/pay_3fJ2Qk8vTn/capture  { "amount": 7490 }→ 200  { "status": "succeeded", "amount_captured": 7490 }# nothing shipped — release the hold instead of refundingPOST /v1/payments/pay_3fJ2Qk8vTn/cancel→ 200  { "status": "canceled", "amount_captured": 0 }
  • capture Takes the money, in full or in part. Capturing less releases the remainder to the payer's available balance straight away.
  • cancel Releases an uncaptured hold. Use this — not a refund — when nothing shipped: it costs nothing and never appears on the payer's statement.
  • refund Returns captured money over the original rail. Full or partial, and repeatable up to the captured amount.

The windows that matter

  • A card authorisation expires after 7 days, or 30 for travel and lodging categories. Capture before then or it lapses.
  • Card refunds are possible for 180 days after capture. Beyond that the money has to move as a payout.
  • Bank-rail refunds have no scheme deadline but need the original payment to still be on file — we hold that for 7 years.
  • A partial capture cannot be topped up. If you may ship more later, authorise the larger amount and capture down.

Reading a decline

A failed payment carries two codes: ours, which is stable and safe to branch on, and the issuer's raw reason, which is more specific but varies by bank. Show the payer a plain sentence, log both, and let the pair drive your retry policy.

The declines that account for most volume
Code What happened Retry?
insufficient_funds The account cannot cover it right now. Yes, after a few days. This is the classic dunning case.
do_not_honor A generic issuer refusal with no stated reason. Once, later. Then offer a different method.
expired_card The stored card is past its date. No. Ask for new details, or use the updater on subscriptions.
authentication_failed The payer abandoned or failed the challenge. Yes, immediately, in the same session.
card_not_supported The product cannot be used for this transaction type. No. Offer an APM instead.
fraud_suspected Blocked by the issuer or by our rules. Never automatically. Repeat attempts raise your fraud ratio.
Retry etiquette

Scheme rules cap retries of a declined card at four attempts in 30 days for the same transaction, and a hard decline may not be retried at all. Exceeding this earns fees and, eventually, scrutiny. Decline-reason distribution over time is on real-time analytics, which is the fastest way to see whether a drop in approvals is your rules, your traffic mix or one issuer having a bad day.

Forcing each of these codes on demand in test mode: sandbox behaviour and test data.