Unlike notification webhooks, authorisation request webhooks ask you a question and wait for your answer. When a cardholder taps, swipes, or enters their card details, Orenda runs its own checks first — balance, spending limits, merchant category, and country restrictions. If those checks pass, we forward the authorisation to your endpoint. You then have the final say: approve it, or decline it based on your own business rules.
This feature is available by application only. It is not enabled by default — contact the team to request it for your program.
The card network is holding the transaction open while it waits for your answer. Your endpoint has a maximum of 2.5 seconds to respond — if you miss the deadline, the response is ignored and the transaction is treated as unanswered (see failure modes below).

Two events

Enabling CARD_AUTHORIZATION_REQUESTED automatically enables both — you will always be consulted on incremental authorisations for transactions you already approved. Both events share the same transaction.transaction_link_id, so you can match an incremental request back to the original authorisation.

Example payload

Fields worth reading twice

Optional fields are omitted when unknown — they will not appear in the payload at all, rather than being sent as null. Do not assume every field is always present.

Refunds

Refunds arrive through the same events — there is no separate refund event. You can tell them apart by the amount: negative for a purchase (money leaving the cardholder), positive for a refund (money coming back).
Be careful with refunds. If your program uses failureMode: "closed" and your endpoint goes down, refunds will be declined too — blocking the cardholder from receiving their money back. To avoid this, always approve requests where amount is positive.

Expected response

Respond with 200 and a JSON body containing a decision field: Approve:
Decline:

reason is required on a decline

reason must be one of the values below, and nothing else. It is not a note for our support team — it selects the response code the card network returns, which is what the terminal prints and what the cardholder is told. A decline for an expired card and a decline on your own risk rule should not read the same at the till. Matching ignores case and surrounding whitespace. Nothing else is guessed at: we will not read card-expired or Insufficient Balance as anything but unrecognised.
Your decline is always honoured. An unrecognised or missing reason never turns a decline into an approval and never causes an error — only the code we return changes. Anything outside the list, and an absent reason, is read as unknown and returns 119.That is exactly what every decline returned before this list existed, so a receiver written against the earlier free-text contract keeps working unchanged. It just gives the cardholder the least useful message we have, on every decline. Send a real reason.
system_error is for when you could not decide — your rules engine was down, a dependency timed out. Do not use it to describe the cardholder’s situation. If you would rather we fell back to our own verdict when your side is broken, that is failureMode below, not a reason. We also keep the raw string you sent, for support and investigation: trimmed and truncated at 200 characters. That text is never relayed to the network and never shown to the cardholder — only the code it selects is.
Only 200 with "decision": "approve" approves a transaction. Any other response is treated as no answer — this includes:
  • Non-200 status codes (3xx, 4xx, 5xx)
  • Unparseable or empty body
  • An unrecognised decision value
  • A timeout
  • 200 {"ok": true} (a common mistake if you reuse a notification webhook handler)

What happens when you do not answer

Configured per programme as failureMode:

Rolling out safely

Rollout happens in two stages:
  1. Shadow mode (default) — We call your endpoint and record your response, but your decisions have no effect. Transactions are approved or declined based on Orenda’s own checks only. We use this to verify your endpoint responds correctly and within the timeout.
  2. Enforcement — When you are ready, contact the team to enable enforceDecision. From that point, your approve/decline responses directly control whether card transactions go through.
Do not skip shadow mode. If your endpoint returns an unexpected response (e.g. 200 {"ok": true}), enforcement would decline every transaction on your program.
enforceDecision, failureMode, the callback URL, and the timeout are all configured by Orenda — contact the team to set them up.

Verifying the signature

Authorisation request webhooks use a different signature format to notification webhooks. Notification webhooks sign the raw body only. Authorisation requests sign <timestamp>.<body> — you cannot reuse the same verification logic for both.

How to identify an authorisation request

Every delivery includes these headers: If Orenda-Signature-Timestamp is present, this is an authorisation request webhook. You must verify the signature using <timestamp>.<body> as the signing base — not the body alone. If the header is absent, this is a notification webhook and you verify using the body only (see notification webhook signature verification).

Redeliveries

If the card network does not receive a response in time, it retries the authorisation and we forward it to your endpoint again. You may receive the same authorisation multiple times. Always deduplicate on event_id, which stays the same across retries. Orenda-Delivery-Id changes with each attempt and should not be used for deduplication.

Other requirements

  • HTTPS only. Plain HTTP is rejected before the call is made.
  • Redirects are not followed. A 3xx is treated as no answer — publish the final URL.
  • Keep the response small. A response over 64 KiB is no answer — we stop reading and, under failureMode: "closed", decline. Answering {"decision":"approve"} followed by 65 KiB of rule context declines the card.
  • Be quick. Our timeout covers DNS, TLS, your processing and the response body.