Take a check's card payment on an Adyen terminal
const url = 'https://api.aerandil.com/v1/fnb/checks/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/card-payment';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"amount":{"amount":"example","currency":"example"},"device_id":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","tip_mode":"none"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.aerandil.com/v1/fnb/checks/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/card-payment \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "amount": { "amount": "example", "currency": "example" }, "device_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "tip_mode": "none" }'Sends a registered Adyen terminal a Terminal API PaymentRequest for part of an open check’s balance — with tip_mode = on_terminal, the terminal asks the guest for a tip (tenderOption=AskGratuity) — and records the approval as the check’s payment through add_check_payment under the caller’s own identity: tender = card, amount = the authorised total less the terminal’s TipAmount, tip, psp_reference, terminal_transaction_id, poiid, external_ref = the pspReference. Authorised before the terminal is touched: the caller’s add_check_payment scope, the house and (for a till) outlet gate, the check open and owing at least amount, and a dry run of the payment the kernel will record. Idempotency-Key is required: a lost answer is asked after (TransactionStatusRequest), and one the terminal still will not give answers 504 card_outcome_unknown — check the terminal, then retry with the same key, which resumes the question rather than charging again. A terminal approval the kernel then refuses is reversed on the terminal (ReversalRequest) and answered 409. 501 unless AERANDIL_ADYEN_ENABLED=1.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”The open hospitality.guest_check the card pays.
Header Parameters
Section titled “Header Parameters”Opaque idempotency token (Stripe-shape). Repeated POSTs with the same key replay the original response within the cache TTL rather than creating a duplicate object.
Request Bodyrequired
Section titled “Request Bodyrequired”object
The part of the check’s balance this card pays, tip excluded: more than zero, at most balance_due, in the check’s currency.
object
Exact decimal as a string. Money is never a float — binary floating point cannot hold 0.10.
The registered hospitality.device the guest pays on. Must be active and carry the Adyen POIID in vendor_device_ref.
on_terminal asks the guest for a tip on the terminal (tenderOption=AskGratuity); the tip comes back in AmountsResp.TipAmount and is recorded as the payment’s tip.
Responses
Section titled “Responses”The card was approved and the payment recorded on the check.
object
object
Exact decimal as a string. Money is never a float — binary floating point cannot hold 0.10.
object
object
Exact decimal as a string. Money is never a float — binary floating point cannot hold 0.10.
true on a cached Idempotency-Key replay.
The hospitality.check_payment recorded.
Adyen’s pspReference for the payment.
object
Exact decimal as a string. Money is never a float — binary floating point cannot hold 0.10.
Example
{ "check": { "status": "open" }}Headers
Section titled “Headers”Always no-store. Object and link state is live data and is never cacheable.
The bearer authenticated but does not hold the scope this operation requires.
Structured error wrapper. Every non-2xx response from any Aerandil endpoint serialises to this shape; the HTTP status carries the failure class (4xx/5xx), the body adds a stable code for programmatic dispatch plus a human-readable message.
object
object
Stable, programmatic error code (e.g. unauthorized, forbidden, not_found, invalid_body, invalid_url, precondition_failed, no_secondary_key). Clients dispatch on code, not on the message (which may be localised or contextualised in future versions).
Request-id correlation handle echoed on the request-id response header — support teams correlate without scraping logs.
Human-readable explanation of the failure.
Per-error structured detail. The shape varies by code (e.g. forbidden_action carries {"action": "..."}; precondition_failed carries {"current_version": N}).
Examplegenerated
{ "error": { "code": "example", "instance_id": "example", "message": "example", "parameters": "example" }}No such object in the caller’s tenant — which is also the answer when it exists in another tenant, by design.
Structured error wrapper. Every non-2xx response from any Aerandil endpoint serialises to this shape; the HTTP status carries the failure class (4xx/5xx), the body adds a stable code for programmatic dispatch plus a human-readable message.
object
object
Stable, programmatic error code (e.g. unauthorized, forbidden, not_found, invalid_body, invalid_url, precondition_failed, no_secondary_key). Clients dispatch on code, not on the message (which may be localised or contextualised in future versions).
Request-id correlation handle echoed on the request-id response header — support teams correlate without scraping logs.
Human-readable explanation of the failure.
Per-error structured detail. The shape varies by code (e.g. forbidden_action carries {"action": "..."}; precondition_failed carries {"current_version": N}).
Examplegenerated
{ "error": { "code": "example", "instance_id": "example", "message": "example", "parameters": "example" }}Nothing recorded: check_not_open, amount_exceeds_balance; card_declined, card_cancelled, terminal_busy (nothing charged); card_reversed — the terminal approved, the kernel refused (its reason in the message, its code in parameters.kernel_code) and the payment was reversed; card_reversal_failed — the same, but the reversal failed: the card was charged, refund parameters.psp_reference by hand or retry with the same key; idempotency_in_flight.
Structured error wrapper. Every non-2xx response from any Aerandil endpoint serialises to this shape; the HTTP status carries the failure class (4xx/5xx), the body adds a stable code for programmatic dispatch plus a human-readable message.
object
object
Stable, programmatic error code (e.g. unauthorized, forbidden, not_found, invalid_body, invalid_url, precondition_failed, no_secondary_key). Clients dispatch on code, not on the message (which may be localised or contextualised in future versions).
Request-id correlation handle echoed on the request-id response header — support teams correlate without scraping logs.
Human-readable explanation of the failure.
Per-error structured detail. The shape varies by code (e.g. forbidden_action carries {"action": "..."}; precondition_failed carries {"current_version": N}).
Examplegenerated
{ "error": { "code": "example", "instance_id": "example", "message": "example", "parameters": "example" }}idempotency_key_required, invalid_body, invalid_amount, currency_mismatch, device_not_active, device_missing_vendor_ref, terminal_rejected (Adyen never delivered the message — e.g. an unknown POIID), idempotency_key_mismatch, or the kernel’s refusal of the dry run (invalid_action).
Structured error wrapper. Every non-2xx response from any Aerandil endpoint serialises to this shape; the HTTP status carries the failure class (4xx/5xx), the body adds a stable code for programmatic dispatch plus a human-readable message.
object
object
Stable, programmatic error code (e.g. unauthorized, forbidden, not_found, invalid_body, invalid_url, precondition_failed, no_secondary_key). Clients dispatch on code, not on the message (which may be localised or contextualised in future versions).
Request-id correlation handle echoed on the request-id response header — support teams correlate without scraping logs.
Human-readable explanation of the failure.
Per-error structured detail. The shape varies by code (e.g. forbidden_action carries {"action": "..."}; precondition_failed carries {"current_version": N}).
Examplegenerated
{ "error": { "code": "example", "instance_id": "example", "message": "example", "parameters": "example" }}The Adyen bridge is not enabled on this deployment.
Structured error wrapper. Every non-2xx response from any Aerandil endpoint serialises to this shape; the HTTP status carries the failure class (4xx/5xx), the body adds a stable code for programmatic dispatch plus a human-readable message.
object
object
Stable, programmatic error code (e.g. unauthorized, forbidden, not_found, invalid_body, invalid_url, precondition_failed, no_secondary_key). Clients dispatch on code, not on the message (which may be localised or contextualised in future versions).
Request-id correlation handle echoed on the request-id response header — support teams correlate without scraping logs.
Human-readable explanation of the failure.
Per-error structured detail. The shape varies by code (e.g. forbidden_action carries {"action": "..."}; precondition_failed carries {"current_version": N}).
Examplegenerated
{ "error": { "code": "example", "instance_id": "example", "message": "example", "parameters": "example" }}terminal_unreachable — the payment never reached the terminal, nothing was charged; terminal_gateway_error — the terminal refused the request itself.
Structured error wrapper. Every non-2xx response from any Aerandil endpoint serialises to this shape; the HTTP status carries the failure class (4xx/5xx), the body adds a stable code for programmatic dispatch plus a human-readable message.
object
object
Stable, programmatic error code (e.g. unauthorized, forbidden, not_found, invalid_body, invalid_url, precondition_failed, no_secondary_key). Clients dispatch on code, not on the message (which may be localised or contextualised in future versions).
Request-id correlation handle echoed on the request-id response header — support teams correlate without scraping logs.
Human-readable explanation of the failure.
Per-error structured detail. The shape varies by code (e.g. forbidden_action carries {"action": "..."}; precondition_failed carries {"current_version": N}).
Examplegenerated
{ "error": { "code": "example", "instance_id": "example", "message": "example", "parameters": "example" }}card_outcome_unknown — the terminal has not said whether the card was charged. Check the terminal; a retry with the same Idempotency-Key asks again and records the payment if it was approved, never sending a second one.
Structured error wrapper. Every non-2xx response from any Aerandil endpoint serialises to this shape; the HTTP status carries the failure class (4xx/5xx), the body adds a stable code for programmatic dispatch plus a human-readable message.
object
object
Stable, programmatic error code (e.g. unauthorized, forbidden, not_found, invalid_body, invalid_url, precondition_failed, no_secondary_key). Clients dispatch on code, not on the message (which may be localised or contextualised in future versions).
Request-id correlation handle echoed on the request-id response header — support teams correlate without scraping logs.
Human-readable explanation of the failure.
Per-error structured detail. The shape varies by code (e.g. forbidden_action carries {"action": "..."}; precondition_failed carries {"current_version": N}).
Examplegenerated
{ "error": { "code": "example", "instance_id": "example", "message": "example", "parameters": "example" }}