Payment lifecycle
Payment lifecycle
Service discovery
Start with GET /payment-services to discover available providers, currencies, methods, and channels. Do not hard-code a provider without consulting the service catalog. The select endpoint can return the required next_action, such as collecting additional input, redirecting, or waiting for confirmation.
Initiation
POST /payments/initiate requires amount, currency, payment method, and payment channel, and uses the Idempotency-Key header. Do not send business_id; it comes from authenticated context. A new payment returns 201, while a recognized duplicate replay can return 200 with the original result.
Confirmation and status
Some flows require confirm with metadata, while others advance through a webhook. Use GET /payments/{uuid}/status when polling is necessary, but apply backoff and a time limit. The authoritative state must come from LuxPay, not only from a provider UI outcome.
Cancellation and refund
Cancellation is allowed only in compatible states. A refund can be full when amount is omitted or partial when an amount is supplied. Use a separate idempotency key for each refund intent and record the reason internally. A refund is a linked financial movement, not an edit to the original transaction.
Reconciliation
Map your local order ID to the LuxPay payment identifier, provider reference, and request ID. If UI state, webhook delivery, and status query disagree, do not make a financial decision based only on the last message received; apply state-transition and reconciliation rules.