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

# Resolve Bank Selection Before a Purchase

> Check whether a bank-redirect method (PSE, FPX, iDEAL) needs a bank chosen before you call purchase, and fetch the bank list plus the connection it's locked to.

Some redirect-to-bank methods need the shopper's bank chosen **before** you call `POST /payment/purchase` — the bank code has to be pinned to the exact connection it was resolved against, since a bank/issuer code is not a shared namespace across providers. `POST /payment/bank-options` runs routing ahead of time so your checkout UI knows whether (and how strongly) to render a bank picker.

<Warning>
  Whatever `connectionCode` this endpoint returns **must** be echoed back on the actual `purchase` call, regardless of `bankSelectionMode` — this was empirically confirmed, not just theorized: PayU's own PSE bank codes were cross-checked against an independent Colombia bank-code reference and several diverged outright. Routing to a different connection between this call and the purchase call would make the chosen bank code meaningless.
</Warning>

## `bankSelectionMode`

| Value | Meaning |
| - | - |
| `required` | The purchase call will fail without a chosen bank. Currently `pse` (via PayU) and `fpx` (via Adyen). |
| `optional` | A picker is available and skips the provider's own hosted picker, but purchase works fine without one. Currently `ideal` (via Adyen) — omit the bank and Adyen shows its own bank-selection page instead. |
| `none` | Nothing to pick, or no bank list is available yet for this provider/method combination. Render no picker. |

<Note>
  Coverage today is `pse`, `fpx`, and `ideal` only. Other bank-redirect methods return `bankSelectionMode: "none"` — this is not necessarily proof they never need one, only that Therius doesn't source a bank list for them yet.
</Note>

### Check before rendering a picker

```bash theme={"dark"}
curl -X POST https://api.therius.io/v1/payment/bank-options \
  -H "Authorization: Bearer prv_production_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "key": "MERCHANT_001",
    "paymentMethod": "pse",
    "currency": "COP",
    "amount": 500000
  }'
```

```json theme={"dark"}
{
  "bankSelectionMode": "required",
  "connectionCode": "conn_a1b2c3d4",
  "banks": [
    { "code": "1007", "name": "BANCOLOMBIA" },
    { "code": "1051", "name": "BANCO DAVIVIENDA" },
    { "code": "1023", "name": "BANCO DE OCCIDENTE" }
  ]
}
```

### Use the result on the purchase call

```json theme={"dark"}
{
  "merchantCode": "MERCHANT_001",
  "orderCode": "ORDER-001",
  "amount": { "currency": "COP", "value": 500000, "exponent": 2 },
  "connectionCode": "conn_a1b2c3d4",
  "paymentMethod": {
    "type": "pse",
    "pse": {
      "payerName": "Ada Lovelace",
      "issuerId": "1007",
      "payerTaxId": "1234567890"
    }
  }
}
```

<Note>
  The JS SDK's Checkout Widget calls this automatically for `pse`, `fpx`, and `ideal` panels the first time they're submitted, and caches both the result and the `connectionCode` per method — you don't need to call it directly if you're using the widget.
</Note>


## OpenAPI

````yaml POST /payment/bank-options
openapi: 3.1.0
info:
  title: Therius API
  description: REST API for payments, subscriptions, and billing plans.
  version: 1.0.0
servers:
  - url: https://api.therius.io/v1
    description: Production
  - url: https://api-sandbox.therius.io/v1
    description: Sandbox
security:
  - bearerAuth: []
paths:
  /payment/bank-options:
    post:
      tags:
        - Payments
      summary: Resolve bank-selection requirements before a bank-redirect purchase
      description: >-
        Some connections require the customer's bank to be chosen before the
        purchase call. This endpoint runs routing ahead of time so the checkout
        UI knows whether to render a bank picker (and how strongly -- see
        bankSelectionMode), and which connection it's locked to. Currently
        covers pse (PayU, required), fpx (Adyen, required), and ideal (Adyen,
        optional). Echo the returned connectionCode back as connectionCode on
        the purchase call regardless of mode.
      operationId: bankOptions
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - key
                - paymentMethod
                - currency
                - amount
              properties:
                key:
                  type: string
                  description: Your merchant code.
                paymentMethod:
                  type: string
                  description: The APM method code to check, e.g. pse, fpx, ideal.
                currency:
                  type: string
                amount:
                  type: integer
                  description: Minor units.
      responses:
        '200':
          description: Bank selection requirements for this provider/method combination
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BankOptionsResponse'
        '400':
          description: Invalid request
        '401':
          description: Unauthorized
      security:
        - ApiKeyAuth: []
        - SdkTokenAuth: []
components:
  schemas:
    BankOptionsResponse:
      type: object
      properties:
        bankSelectionMode:
          type: string
          enum:
            - required
            - optional
            - none
          description: >-
            required: purchase will fail without a chosen bank (pse via PayU,
            fpx via Adyen). optional: a picker is available and skips the
            provider's own hosted picker, but purchase works fine without one
            (ideal via Adyen). none: nothing to pick, or no bank list is
            available yet for this provider/method.
        connectionCode:
          type: string
          description: >-
            Echo this back as connectionCode on the actual purchase call,
            regardless of bankSelectionMode -- bank/issuer codes are not a
            shared namespace across providers.
        banks:
          type: array
          items:
            $ref: '#/components/schemas/BankOptionsBank'
    BankOptionsBank:
      type: object
      properties:
        code:
          type: string
          description: >-
            Bank/issuer code -- only valid for the connectionCode returned
            alongside it. Not a shared namespace across providers.
        name:
          type: string
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        Your secret API key: `Bearer prv_production_xxx` (production) or `Bearer
        prv_sandbox_xxx` (sandbox).

````