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

# Payment API Reference

> Reference for the GoPay C2B payment initiation API

# Payment API Reference

This reference documents the C2B (customer-to-business) payment initiation API.

## Base URL

Use the base URL provided during onboarding for each environment (sandbox and production are separate hosts). Because the host is part of the signed canonical string, signatures are environment-specific by construction.

## Authentication

Requests are authenticated with a detached Ed25519 signature over the [v1 canonical string](/getting-started/authentication#the-canonical-string-v1), sent via the `X-Public-Key`, `X-Signature`, `X-Timestamp`, and `X-Request-ID` headers. Your API key must carry the **`c2b` permission**. The C2B API additionally accepts an optional `Idempotency-Key` header for safe retries.

See [Authentication](/getting-started/authentication) for the full scheme, signing helpers, and the replay/rate-limit rules that apply to every request.

## Initiate Payment

Creates a payment session and returns a hosted checkout URL.

**Endpoint**

```
POST /api/v1/initiate-payment
```

### Request Body

| Parameter     | Type   | Required | Description                                                     |
| ------------- | ------ | -------- | --------------------------------------------------------------- |
| `merchantId`  | string | Yes      | Your merchant ID                                                |
| `amount`      | number | Yes      | Payment amount; must be > 0 and at most 10,000,000              |
| `currency`    | string | Yes      | One of the supported currency codes: `KES`, `USD`, `EUR`, `GBP` |
| `phoneNumber` | string | Yes      | Customer phone number: 10–15 digits, optional leading `+`       |
| `successUrl`  | string | Yes      | Absolute HTTPS URL for redirect after successful payment        |
| `failUrl`     | string | Yes      | Absolute HTTPS URL for redirect after failed payment            |
| `notifyUrl`   | string | Yes      | Absolute HTTPS URL that receives the settlement webhook         |

Validation failures are accumulated — the error message lists every failing field, not just the first one. All URLs must be `https`; `http` and other schemes are rejected.

### Response

<Tabs>
  <Tab title="Success (200 OK)">
    ```json theme={null}
    {
        "checkoutUrl": "https://checkout.gopay.example.com/?token=eyJhbGciOi...",
        "sessionId": 12345
    }
    ```

    Redirect your customer to `checkoutUrl`. The token embedded in the URL is minted by GoPay and expires; do not cache checkout URLs.
  </Tab>

  <Tab title="Error (non-2xx)">
    All errors share the standard shape — see [Errors](/getting-started/errors) for the full code taxonomy:

    ```json theme={null}
    {
        "error": {
            "code": "VALIDATION_FAILED",
            "message": "amount must be greater than 0; notifyUrl must use https",
            "requestId": "req_..."
        }
    }
    ```
  </Tab>
</Tabs>

<Note>
  When retrying after `UPSTREAM_UNAVAILABLE` (503) or `UPSTREAM_TIMEOUT` (504), generate a fresh `X-Request-ID` and signature (the old ID may already be consumed), and send the same `Idempotency-Key` so the payment is not created twice.
</Note>

### Payment Statuses

Settlement status is delivered via webhook (see [C2B Callbacks](/webhooks/c2b-callbacks)):

| Status      | Description                               |
| ----------- | ----------------------------------------- |
| `completed` | Payment settled successfully              |
| `failed`    | Payment failed                            |
| `expired`   | Payment session expired before completion |
| `cancelled` | Payment was cancelled by the customer     |
