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

# Method restrictions

> Narrow the payment methods a single payment may use, whichever surface collects it.

By default a payment can use anything your project routes for the payer's country and currency. A restriction narrows that set for one payment only, without touching your routing rules.

Declare it at creation, on either surface:

```
POST /payment/checkouts
POST /payment/intents
```

It cannot be changed afterwards. A payment is created with the restriction it will keep.

## Shape

Two independent axes, each with an allow and a deny list:

```json theme={null}
{
  "restriction": {
    "payment_methods": { "allow": ["momo_mtn"], "deny": ["card"] },
    "payment_method_categories": { "allow": ["mobile_money"], "deny": ["crypto"] }
  }
}
```

`payment_methods` names individual method codes — the same codes the [methods endpoint](/payments/custom-checkout) returns. `payment_method_categories` names families, and a family covers every method inside it, including ones added to the catalogue later.

On a hosted checkout, these keys sit alongside `country_code` and `phone` in the same `restriction` object and are independent of them.

## How it resolves

1. A denied value wins, on either axis. Nothing overrides a deny.
2. With no allow list on either axis, everything that is not denied stays usable.
3. Otherwise the method must appear on one of the two allow lists — the axes are a union, not an intersection.

So `payment_methods.allow: ["card"]` together with `payment_method_categories.allow: ["mobile_money"]` offers cards **and** all mobile money, not their overlap.

Rule 1 means a contradiction resolves to a refusal: allowing `momo_mtn` while denying the `mobile_money` category leaves MTN unusable. That case is caught at creation rather than at payment time — see [Rejected at creation](#rejected-at-creation).

## Refusing one thing

The common case is excluding a family. Deny the category, not the code:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.orqex.com/v1/payment/checkouts \
    -H "Authorization: Bearer sk_live_..." \
    -H "Content-Type: application/json" \
    -d '{
      "amount": 50,
      "currency": "USD",
      "description": "Order #1042",
      "return_url": "https://example.com/thanks",
      "customer": {
        "email": "ada@example.com",
        "first_name": "Ada",
        "last_name": "Lovelace"
      },
      "restriction": {
        "payment_method_categories": { "deny": ["card"] }
      }
    }'
  ```

  ```json Body theme={null}
  {
    "restriction": {
      "payment_method_categories": { "deny": ["card"] }
    }
  }
  ```
</CodeGroup>

Denying the `card` **code** would only exclude one of the card methods; `card_cb` and `card_kr` would still be offered wherever they are routed. The category covers all three.

<Warning>
  Digital wallets are their own category. Apple Pay, Google Pay, Link and Cash App are `wallet`, not `card`, even though a card funds them. Denying `card` does not stop a card-funded wallet payment.

  Note that `wallet` also holds Wave, Djamo and other account-based wallets that have nothing to do with cards. If you need "no card anywhere", an allow list is more honest than stacking denies:

  ```json theme={null}
  {
    "restriction": {
      "payment_method_categories": { "allow": ["mobile_money"] },
      "payment_methods": { "allow": ["wallet_wave", "wallet_djamo"] }
    }
  }
  ```
</Warning>

## Categories

| Category        | Holds                                                                                              |
| --------------- | -------------------------------------------------------------------------------------------------- |
| `card`          | `card`, `card_cb`, `card_kr`                                                                       |
| `mobile_money`  | Every operator wallet: MTN, Orange, Moov, M-Pesa, Airtel, and the rest                             |
| `bank_transfer` | Bank transfers and account debits, Pix, Bancontact, Multibanco                                     |
| `wallet`        | Apple Pay, Google Pay, Samsung Pay, Link, Cash App, Alipay, Wave, Djamo, and other account wallets |
| `ussd`          | USSD                                                                                               |
| `qr_code`       | QR code                                                                                            |
| `crypto`        | BTC, ETH, USDT, USDC                                                                               |
| `other`         | Anything not in the families above                                                                 |

Do not hard-code the membership of a category. It is the catalogue's business, and it grows.

## What it affects

A restriction is applied everywhere a method could be chosen, not only at the point of payment:

| Surface                                                 | Effect                                                              |
| ------------------------------------------------------- | ------------------------------------------------------------------- |
| Hosted checkout page                                    | Only allowed methods are offered                                    |
| `GET /payment/intents/{id}/countries/{country}/methods` | Excluded methods are absent from the list                           |
| `GET /payment/intents/{id}/countries`                   | A country left with no allowed method disappears from the catalogue |
| `POST /payment/intents/{id}/attempts`                   | A forbidden method is rejected with `422`                           |

The last row is the one that matters for correctness. The catalogues are a convenience; the attempt check is the guarantee. A stale page or a hand-written request cannot get around it.

```json theme={null}
{
  "message": "Payment method Card is not allowed on this payment."
}
```

## Rejected at creation

A restriction your project cannot honour is refused with `422` and no payment is created:

```json theme={null}
{
  "message": "No payment method is available for this payment under the requested restriction."
}
```

That covers the two ways of getting it wrong: restricting to a method you have not routed, and contradicting yourself across the two axes. Both would otherwise surface as an empty checkout in front of a payer.

Listing the same value in `allow` and `deny` on the same axis is a validation error rather than a silent resolution:

```json theme={null}
{
  "message": "The given data was invalid.",
  "errors": {
    "restriction.payment_methods": [
      "The same value cannot be both allowed and denied: card."
    ]
  }
}
```

<Note>
  Satisfiability is checked against your whole routing configuration, not against one country. `allow: ["card"]` passes creation if cards are routed anywhere in your project — a payer landing in a country where they are not routed still sees nothing. Restrict by category rather than by code when the payer's country is not known upfront.
</Note>

## Reading it back

The restriction is echoed on the payment, and on the checkout when you used one. Only the keys you set are present:

```json theme={null}
{
  "data": {
    "id": "pi_9x2k4m7q1w8e",
    "status": "pending",
    "restriction": {
      "payment_method_categories": { "deny": ["card"] }
    }
  }
}
```

On a hosted checkout, `checkout.restriction` carries the method lists next to the country and the obfuscated phone number.
