API errors
| HTTP | Code | Meaning | Recovery |
|---|
| 400 | bad_body / bad_params | Request shape rejected by Zod. | Fix payload; details has the violations. |
| 400 | permit_expired | Permit2 deadline past at checkout submit. | Refresh quote, re-sign. |
| 401 | missing_api_key | X-Arcora-Api-Key header missing. | Add the header. |
| 401 | invalid_api_key | Header present but unrecognised. | Rotate key at /m/settings. |
| 401 | unauthorized | SIWE session missing or expired (merchant routes). | Re-auth at /m/login. |
| 403 | MERCHANT_PAYOUT_BLOCKED | Merchant's payout address flagged sanctions/high in Plan-5 screen. | Resolve via compliance@arcorapay.xyz. |
| 404 | invoice_not_found | invoiceId not in DB. | Check id; create the invoice first. |
| 409 | invoice_not_payable | Status is paid, expired, refunded, or failed. | Don't retry. Refund needs a different path. |
| 410 | invoice_expired | expiresAt past at submit. | Create a new invoice. |
| 412 | delegate_not_authorized | Server hot wallet's authorization expired. Ops must re-authorize. | Contact ops. |
| 502 | chain_error | On-chain tx reverted. | Read detail for the short revert reason. |
| 503 | compliance_unavailable / PROVIDER_UNAVAILABLE | Provider returned 5xx, fail-closed config. | Wait, retry. |
Compliance decisions (/api/checkout/authorize)
| Decision | Code | UI behavior |
|---|
allow | n/a | Pay button enabled |
review | n/a | Pay button disabled, show review banner with ticketId |
reject | SANCTIONED_WALLET | Pay button disabled, neutral copy |
reject | HIGH_RISK_WALLET | Pay button disabled, neutral copy |
reject | PROVIDER_UNAVAILABLE | Treated as transient — UI shows "try again shortly" |
On-chain errors (gateway reverts)
These show up in chain_error.detail and in the explorer. ABI-decoded names:
| Selector | Trigger |
|---|
MerchantAlreadyRegistered | registerMerchant called twice from the same wallet. |
MerchantInactive | Merchant deactivated; new invoices reject. |
InvalidPayoutToken | Token not in supportedTokens. |
InvalidPayoutAddress | Zero address in registerMerchant / constructor. |
InvalidPayInToken | Token not whitelisted; createInvoice reverts. |
InvoiceAlreadyExists(globalId) | Duplicate merchantInvoiceId for the same merchant. |
InvoiceAlreadyPaid(globalId) | settleInvoice re-attempted after settlement. |
InvoiceExpired(globalId) | settleInvoice past expiresAt. |
InvoiceNotFound(globalId) | Invoice doesn't exist. |
InvoiceNotInCreatedState(globalId) | recordPayerRefund after settle. |
InvoiceNotRefundable(globalId) | refundInvoice on a non-Paid invoice. |
PayoutShortfall(supplied, required) | App Kit returned less than amountOut. |
DelegateNotAuthorized | createInvoiceFor from an unauthorized address. |
InsufficientFeesForRefund(required, accrued) | Fee bucket drained before refund. |