# Payment methods & capabilities

`GET /payments-api/v1/payment-methods` is the first call a server integration should make.
It returns the exact set of instruments, currencies, and payment rails your seller account
has been configured for — the intersection of your account settings and what the active
terminals support. Use this response to drive your checkout UI rather than hard-coding
assumptions.

## Request

| Aspect | Value |
|--------|-------|
| Method | `GET` |
| Path | `/payments-api/v1/payment-methods` |
| Auth | `Authorization: Bearer <token>` |
| Body | None |
| Query params | None |

No `Idempotency-Key` is required — this is a read-only endpoint.

```bash
curl -sS "$FYNEX_API/payments-api/v1/payment-methods" \
  -H "Authorization: Bearer $FYNEX_TOKEN"
```

## Response

**`200 OK`** — returns `dtos.PaymentMethodsResponse`:

```json
{
  "merchantId": "16ddc5f1-39ca-4b7c-9bfa-bf5779b8c117",
  "allowedPaymentMethods": ["card", "google_pay", "apple_pay"],
  "allowedCurrencies": ["GBP", "EUR"],
  "allowedPaymentRails": ["card"]
}
```

### Response fields

| Field | Type | Description |
|-------|------|-------------|
| `merchantId` | `string` (UUID) | The authenticated seller account's UUID. |
| `allowedPaymentMethods` | `string[]` | Payment instruments enabled for this account. See [Payment instruments](#payment-instruments) below. |
| `allowedCurrencies` | `string[]` | ISO 4217 currency codes supported by this account. See [Currencies](#currencies) below. |
| `allowedPaymentRails` | `string[]` | Active payment rails. Omitted (`omitempty`) when no rails are configured. See [Payment rails](#payment-rails) below. |

## Enum values

### Payment instruments

Values from `model.PaymentInstrumentType`:

| Value | Description |
|-------|-------------|
| `card` | Standard card payment (Visa, Mastercard, Amex, etc.) |
| `bank_account` | Bank account / direct debit |
| `google_pay` | Google Pay (tokenised card via Google's wallet) |
| `apple_pay` | Apple Pay (tokenised card via Apple's wallet) |
| `bancontact` | Bancontact (Belgian local scheme, `apm` rail) |
| `multibanco` | Multibanco (Portuguese reference/voucher payment, `apm` rail) |
| `mbway` | MB WAY (Portuguese mobile-app payment, `apm` rail) |
| `wero` | Wero (European account-to-account wallet, `apm` rail) |
| `swish` | Swish (Swedish mobile payment, `apm` rail) |

### Currencies

Values from `model.CurrencyCode`. All 3-letter ISO 4217:

| Code | Currency |
|------|----------|
| `EUR` | Euro |
| `USD` | US Dollar |
| `GBP` | British Pound |
| `DKK` | Danish Krone |
| `NOK` | Norwegian Krone |
| `SEK` | Swedish Krona |

### Payment rails

Values from `model.PaymentRailType`:

| Value | Description | Instruments |
|-------|-------------|-------------|
| `card` | Card network processing | `card`, `google_pay`, `apple_pay` |
| `bank_transfer` | Bank transfer / account-to-account | `bank_account` |
| `apm` | Alternative / local payment methods (redirect-based) | `bancontact`, `multibanco`, `mbway`, `wero`, `swish` |

The instrument-to-rail mapping is enforced by the server: a `card` rail will only accept
`card`, `google_pay`, or `apple_pay` instruments; `bank_transfer` only accepts `bank_account`;
the `apm` rail carries the local-scheme instruments (`bancontact`, `multibanco`, `mbway`,
`wero`, `swish`).

> [!NOTE]
> The `apm` instruments are **redirect-based**: accept them either server-to-server via
> `POST /initialize-payment` with `paymentType: "apm"` (follow the returned redirect action),
> or through Fynex-hosted checkout. See [Alternative payment methods
> (APM)](https://docs.fynex.ai/payments-api/v2/docs#tag/alternative-payment-methods-apm) for both flows and the per-checkout
> availability rules.

## Status codes

| Status | When |
|--------|------|
| `200` | Success |
| `401` | Missing or invalid bearer token |
| `404` | `no payment configuration is set up for this account; contact support` — the account has not been provisioned for payments yet |
| `500` | A dependency is not configured, or loading the payment configuration or terminals failed. The body is a fixed string; the cause is logged server-side, never returned. Retry with backoff |

## Using the response to drive your checkout UI

> [!NOTE]
> Always fetch payment methods at session start and render **only** what the response
> contains. Do not hard-code which instruments or currencies to show — your account
> configuration can change without a code deployment.

1. **Fetch on server startup or per-request**

   Call `GET /payment-methods` when your server starts (and cache for a short period),
   or fetch it once per checkout session before rendering the payment form.

2. **Render only enabled instruments**

   ```js
   const { allowedPaymentMethods, allowedCurrencies } = await getPaymentMethods();

   // Show card form only if enabled
   const showCard = allowedPaymentMethods.includes('card');

   // Show Google Pay button only if enabled and browser supports it
   const showGooglePay =
     allowedPaymentMethods.includes('google_pay') && await isGooglePayReady();

   // Show Apple Pay button only if enabled and browser supports it
   const showApplePay =
     allowedPaymentMethods.includes('apple_pay') && isApplePayAvailable();

   // Populate currency selector from the live list
   renderCurrencySelect(allowedCurrencies);
   ```

3. **Pass the correct instrument and rail when initializing a payment**

   When you call `POST /payments-api/v1/initialize-payment` or
   `POST /payments-api/v1/checkout`, the `paymentType` (rail) and `paymentMethod`
   (instrument) fields must be values the server already told you are allowed.
   Sending a disallowed combination returns `400 Bad Request`.

> [!CAUTION]
> `allowedPaymentRails` uses `omitempty` — it will be absent from the response if no
> rails are configured on the account. Always check for the key's presence before
> reading it; don't assume an empty array.

## See also

- **[Hosted checkout](https://docs.fynex.ai/payments-api/v2/docs#tag/hosted-checkout)** — Accept payments by redirecting customers to a Fynex-hosted page.
- **[Server-to-server payments](https://docs.fynex.ai/payments-api/v2/docs#tag/server-to-server)** — Collect card details in your own UI and call the API directly.
