Skip to main content

Payment Processing Requirements

This section outlines the requirements for implementing payment processing endpoints.

Idempotency

All payment operations must be idempotent. Flex uses the flex_payment_id as an idempotency key.

Requirements

  • If Flex sends a payment request with a flex_payment_id that already exists, return the existing payment (do not create a duplicate)
  • The flex_payment_id is unique across all payments, not just per account
  • Store the flex_payment_id permanently and use it for deduplication

Example Scenario

Request 1: PUT /payment/flex_pay_123 → Creates payment, returns 200
Request 2: PUT /payment/flex_pay_123 → Returns existing payment, 200 (no duplicate)
Request 3: PUT /payment/flex_pay_456 → Creates new payment, returns 200

Payment Lifecycle

Payments progress through the following statuses:

┌─────────────┐
│ processing │ ← Initial state when payment accepted
└──────┬──────┘

├─────────────────┬─────────────────┐
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ succeeded │ │ failed │ │ canceled │
└─────────────┘ └─────────────┘ └─────────────┘

Status Definitions

StatusDescription
processingPayment has been accepted and is being processed
succeededPayment was successfully applied to the account
failedPayment failed (see failure_reason for details)
canceledPayment was canceled before completion

Status Transition Rules

  • Payments start in processing status
  • From processing, a payment can transition to succeeded, failed, or canceled
  • Terminal states (succeeded, failed, canceled) are final and cannot change

Timestamps

initiated_at

  • Set when the payment is first accepted by the partner's system
  • Required for all payments
  • Format: ISO 8601 with timezone (e.g., 2025-11-15T14:22:10Z)

posted_at

  • Set when the payment is successfully posted to the account ledger
  • null while payment is processing
  • Required when status is succeeded
  • Format: ISO 8601 with timezone

Batch Processing

Flex groups payments into batches for reconciliation purposes.

flex_batch_id

  • Provided by Flex on every payment request
  • Partners should store this value for reconciliation
  • Multiple payments may share the same flex_batch_id
  • Format: String (e.g., BATCH-20251115)

Error Handling

failure_reason

When a payment fails, include a human-readable error message:

{
"payment_id": "partner_123",
"flex_payment_id": "flex_pay_abc",
"status": "failed",
"failure_reason": "Account is closed and not accepting payments."
}

Common Failure Reasons

  • Account not found or inactive
  • Payment amount exceeds maximum allowed
  • Duplicate payment detected (different from idempotent retry)

Payment Amount

amount_in_cents

  • All monetary amounts are in cents (integer)
  • Example: $157.50 is represented as 15750
  • Must match the amount in the original request

Polling for Status

Flex polls the Get Account Payment endpoint to check payment status.

Expected Behavior

  • Partners should update payment status as soon as it changes
  • Flex may poll frequently while payment is processing
  • Once a terminal status is reached, Flex stops polling