Foxpay

Public API docs for Foxpay custom REST integrations.

Public APICustom REST integrationv0.1
Guide

Payment flow

The current Foxpay custom flow is backend init, frontend redirect, and backend reconciliation. This guide reflects the latest contract around `POST /payments/initialize` so merchants understand the runtime split instead of treating the initializer as a standalone HTTP call.

Primary sequence

  1. Merchant backend calls `POST /payments/initialize` with `Authorization: Bearer <apiKey>`, `merchantId`, `orderId`, `amountCents`, buyer context, and optional method controls.
  2. Foxpay resolves the merchant/store, enforces eligibility and payment-method gating, and either creates/reuses a hosted checkout transaction or creates a direct provider session.
  3. Initialization has succeeded when the response is HTTP 2xx and includes `success: true`, `paymentId`, and `paymentUrl`.
  4. Merchant frontend redirects the buyer into `paymentUrl` for hosted checkout, or `redirectUrl`/`sessionUrl` for direct provider sessions.
  5. During checkout, poll `GET /payments/{paymentId}/status` to reflect progress states.
  6. If the buyer needs manual transfer data, fetch `GET /payments/{paymentId}/bank-details` with the `orderId` query parameter.
  7. Merchant backend reconciles final payment state through webhook-style callbacks and internal order updates.

Successful initialization

  • HTTP 2xx means the initializer accepted the request.
  • `success: true` confirms Foxpay created or reused a checkout handoff.
  • `paymentId` is the Foxpay transaction identifier to store with the merchant order.
  • `paymentUrl` is the buyer redirect target for hosted checkout.
  • `redirectUrl` and `sessionUrl` are returned for direct provider handoff such as Calytics OBT.
  • `status: pending` is normal immediately after initialization and does not mean payment completion.

Payment outcome

  • Use polling to update the buyer-facing checkout screen or return page.
  • Use signed webhook delivery to update your backend order record durably.
  • Only mark the merchant order as paid after the later status or webhook indicates a completed payment state.
  • If initialization returns HTTP 4xx or 5xx, do not redirect the buyer because no usable checkout handoff exists.

Bank statement remittance info

The custom REST contract supports merchant-controlled remittanceInfo for the SEPA remittance/payment reference.

  • Send `remittanceInfo` when the merchant wants to control what Foxpay sends as the payment reference to the provider.
  • Allowed characters are letters, numbers, spaces, and `. , - _ / + : #`; the maximum length is 140 characters.
  • If `remittanceInfo` is omitted, Foxpay generates `FP-{orderNumber}-{transactionIdSuffix}`.
  • The response returns `remittanceInfo` and `remittanceInfoSource` so the merchant can persist exactly what was used.
  • `metadata` is still only reconciliation context and does not replace `remittanceInfo`.

Hosted checkout vs direct provider

  • Default hosted checkout: omit `paymentMethod` and `checkoutMode`, then redirect to `paymentUrl`.
  • Direct OBT: send `paymentMethod: open_bank_transfer` and `checkoutMode: direct_provider`.
  • Direct OBT currently uses `provider: calytics` and requires buyer country plus the sender details required by the provider flow.
  • Both modes return a Foxpay `paymentId` and should be reconciled through the same polling and webhook model.

How to answer payment-init questions

  • Successful initialization means Foxpay accepted the session and returned a redirect target.
  • It does not mean the payment is paid, settled, or final.
  • Persist the identifiers, redirect the buyer, then listen for the later status/webhook outcome.

State transitions that matter

  • `pending` is the normal initial state.
  • `paymentId` is the Foxpay-side transaction identifier and should be stored for later polling and reconciliation.
  • Checkout flow statuses collapse some lower-level transaction states into buyer-facing progress labels.
  • Polling and webhooks solve different problems and should usually coexist.
  • The custom initializer is cent-based end to end: `amountCents` is the canonical request field.

Where the docs are still light

  • No dedicated idempotency guidance yet.
  • No explicit retry matrix yet for init, polling, and webhook replay scenarios.
  • No dedicated public webhook reference yet for the custom integration flow.
  • No sequence diagrams yet for payment-method variations.
  • No end-to-end example app yet.