> ## Documentation Index
> Fetch the complete documentation index at: https://docs.inflowafrica.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Collect a payment

> Create a cross-currency payment request, send the payer to checkout, and verify the result.

# Collect a payment

The normal payment flow is: create a customer, create a payment request, send the payer to the returned checkout link, then confirm the final status from your server.

```mermaid theme={null}
sequenceDiagram
  participant App as Your server
  participant API as Inflow API
  participant Payer
  App->>API: Create customer (once)
  App->>API: Create payment request
  API-->>App: Payment ID and payment link
  App->>Payer: Redirect or send payment link
  Payer->>API: Completes checkout
  App->>API: Get payment by ID
  API-->>App: Current payment status
```

## 1. Preview the exchange rate

Use the quote endpoint when you need to display the source amount before checkout. `amount` is the amount you want to receive in `targetCurrency`; `sourceCurrency` is the payer's currency.

```bash theme={null}
curl "$INFLOW_BASE_URL/v1/payments/exchange-rate?amount=35000&sourceCurrency=EUR&targetCurrency=NGN" \
  --header "Authorization: Bearer $INFLOW_API_KEY"
```

```json theme={null}
{
  "data": {
    "sourceAmount": 21.5,
    "sourceCurrency": "EUR",
    "targetAmount": 35000,
    "targetCurrency": "NGN",
    "exchangeRate": 1627.91
  }
}
```

<Tip>
  The exchange-rate response is useful for display. Create the payment promptly after quoting so the payer sees a current amount.
</Tip>

## 2. Create a payment request

`reference` must be unique for your organization. Generate it on your server and persist it with your order or invoice so retries never accidentally create a second payment.

```bash theme={null}
curl --request POST "$INFLOW_BASE_URL/v1/payments" \
  --header "Authorization: Bearer $INFLOW_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "targetAmount": 35000,
    "sourceCurrency": "EUR",
    "targetCurrency": "NGN",
    "reference": "order_20260724_000184",
    "description": "July subscription",
    "customerId": "4b2a49b2-526c-4c08-b342-f8b1f409c091",
    "payerName": "Ada Okafor",
    "payerEmail": "ada.okafor@example.com",
    "redirectUrl": "https://merchant.example.com/payments/complete",
    "metadata": {
      "orderId": "order_000184"
    }
  }'
```

The response includes a payment ID for reconciliation and a payer-facing link. Use `paymentLink` when it is present; it is the normalized hosted checkout URL across supported providers.

```json theme={null}
{
  "data": {
    "id": "9b06c6dd-98e8-42d9-97d4-35a80644c7e7",
    "reference": "order_20260724_000184",
    "sourceAmount": 21.5,
    "sourceCurrency": "EUR",
    "targetAmount": 35000,
    "targetCurrency": "NGN",
    "status": "pending",
    "paymentLink": "https://sandbox.inflowafrica.com/checkout/9b06c6dd-98e8-42d9-97d4-35a80644c7e7",
    "expiresAt": "2026-07-24T10:16:00.000Z"
  }
}
```

Depending on the configured payment provider, the response can also contain a `linkToken` for a client-side authorization integration or a `checkoutUrl`. Do not assume every provider returns the same provider-specific field; use the payer-facing `paymentLink` when available.

## 3. Send the payer to checkout

Redirect the payer in the same browser tab, or present the link in an in-app browser on mobile. Keep the payment creation request on your server so your API key remains private.

```ts theme={null}
// Server-generated data supplied to your browser only after payment creation.
window.location.assign(payment.data.paymentLink);
```

The `redirectUrl` returns the payer to your application after authorization. Treat that redirect as a user-experience signal—not as proof that the payment settled.

## 4. Verify the payment server-side

Look up the payment with its Inflow ID before fulfilling an order. This endpoint refreshes live payments from the provider where applicable.

```bash theme={null}
curl "$INFLOW_BASE_URL/v1/payments/9b06c6dd-98e8-42d9-97d4-35a80644c7e7" \
  --header "Authorization: Bearer $INFLOW_API_KEY"
```

```json theme={null}
{
  "data": {
    "id": "9b06c6dd-98e8-42d9-97d4-35a80644c7e7",
    "reference": "order_20260724_000184",
    "status": "settled",
    "targetAmount": 35000,
    "targetCurrency": "NGN",
    "paidAt": "2026-07-24T09:23:41.000Z",
    "metadata": {
      "orderId": "order_000184"
    }
  }
}
```

Fulfil only after the status your business requires—typically `executed` (when provider confirms receipt of funds) or `settled` (when funds clear into your wallet). Note that automated payouts or withdrawals can only be triggered once the payment is `settled`. Handle `failed`, `cancelled`, and `expired` by letting the customer try again with a new payment request.

## Recover a payment link

If an eligible pending payment's link expires, request a replacement rather than creating a duplicate reference:

```bash theme={null}
curl --request POST "$INFLOW_BASE_URL/v1/payments/9b06c6dd-98e8-42d9-97d4-35a80644c7e7/refresh-link" \
  --header "Authorization: Bearer $INFLOW_API_KEY"
```

Only payments in `created` or `pending` state can be refreshed or cancelled. See the [payment API reference](/api-reference/external-api--payments/create-a-payment-request) for every request field and provider response.
