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

# Payment setup config

> The runtime payment configuration: method × provider shape, how to discover what a merchant has enabled, and how to use it to render the right buttons.

# Payment setup config

The `paymentSetupConfig` is the **runtime** payment configuration for a store. It tells your client code:

* Which payment methods are enabled for this merchant
* How each method is wired (which processor handles it)
* What metadata your browser code needs to render the right UI

It’s the data structure your client code branches on. Get it wrong and you render an Apple Pay button that fails to open. Get it right and your UI just works across every processor combination.

***

## Discover what a merchant has enabled

```ts theme={null}
const setup = await tagada.paymentSetup.get('store_xxx');
```

The `setup` is a flat object keyed by `"{method}"` or `"{method}:{provider}"`:

```jsonc theme={null}
{
  "card": {
    "enabled": true,
    "method": "card",
    "provider": "tagada",
    "paymentFlowId": "pf_eu_cascade"
  },
  "apple_pay": {
    "enabled": true,
    "method": "apple_pay",
    "provider": "apple_pay",
    "type": "apple_pay",
    "express": true,
    "processorId": "proc_native_apple",
    "metadata": { "country": "FR" }
  },
  "klarna:stripe": {
    "enabled": true,
    "method": "klarna",
    "provider": "stripe",
    "type": "apm",
    "processorId": "proc_stripe_eu"
  },
  "express_checkout:proc_stripe_eu": {
    "enabled": true,
    "method": "express_checkout",
    "provider": "stripe",
    "publishableKey": "pk_live_xxx",
    "methods": {
      "apple_pay":  { "enabled": true },
      "google_pay": { "enabled": true },
      "link":       { "enabled": true }
    }
  }
}
```

***

## The two-dimensional shape

Every entry has two coordinates:

| Field          | Question it answers              | Examples                                                                                              |
| -------------- | -------------------------------- | ----------------------------------------------------------------------------------------------------- |
| **`method`**   | What does the customer see?      | `card`, `apple_pay`, `google_pay`, `klarna`, `ideal`, `bancontact`, `twint`, `paypal`                 |
| **`provider`** | Which infrastructure handles it? | `tagada`, `apple_pay` (native), `google_pay` (native), `stripe`, `airwallex`, `adyen`, `oceanpayment` |

The same `method` can ship through different `provider`s. This is intentional — merchants legitimately need Klarna through Stripe in EU and Klarna through Airwallex in APAC, for example.

The key naming convention:

| Pattern                       | Meaning                                                        |
| ----------------------------- | -------------------------------------------------------------- |
| `"card"`                      | The default card flow (provider implicit)                      |
| `"apple_pay"`                 | Native wallet path (provider = `apple_pay`)                    |
| `"apple_pay:stripe"`          | Wallet routed through Stripe Payment Request                   |
| `"klarna:stripe"`             | Klarna routed through Stripe                                   |
| `"klarna:airwallex"`          | Klarna routed through Airwallex                                |
| `"express_checkout:proc_xxx"` | Stripe Express Checkout Element (one widget, multiple methods) |

***

## Field reference

```ts theme={null}
interface PaymentMethodConfig {
  enabled: boolean;
  method: string;          // 'apple_pay', 'klarna', 'card', 'express_checkout', ...
  provider: string;        // 'tagada', 'stripe', 'airwallex', 'apple_pay', 'google_pay', ...
  type?: string;           // 'apm' | 'card' | 'apple_pay' | 'google_pay' — UI hint
  label?: string;          // Display label
  logoUrl?: string;        // Logo URL
  description?: string;    // Customer-facing description
  express?: boolean;       // True = render as express button above the form
  paymentFlowId?: string;  // Card-routing payment flow (cascade, fraud, processor selection)
  processorId?: string;    // Direct processor routing (for APMs, express)
  integrationId?: string;  // Tagada integration record id (for native integrations)
  supportedCountries?: string[];   // ISO 3166-1 alpha-2
  presentmentCurrencies?: string[];// ISO 4217
  recurring?: boolean;
  publishableKey?: string; // Stripe publishable key (express_checkout entries)
  methods?: Record<string, { enabled: boolean }>;  // For express_checkout:proc_xxx — bundled methods
  metadata?: Record<string, any>;  // Provider-specific metadata
  settings?: Record<string, any>;  // Integration settings
}
```

***

## Common patterns

### Render the right buttons

```ts theme={null}
const setup = await tagada.paymentSetup.get('store_xxx');

const buttons = [];

// Card form
if (setup.card?.enabled) {
  buttons.push({ type: 'card-form' });
}

// Apple Pay — native or Stripe?
if (setup.apple_pay?.enabled && setup.apple_pay.provider === 'apple_pay') {
  buttons.push({ type: 'apple-pay-native', config: setup.apple_pay });
} else if (setup['apple_pay:stripe']?.enabled) {
  buttons.push({ type: 'stripe-express', config: setup['apple_pay:stripe'] });
}

// Google Pay
if (setup.google_pay?.enabled && setup.google_pay.provider === 'google_pay') {
  buttons.push({ type: 'google-pay-native', config: setup.google_pay });
}

// Stripe Express (bundled)
const expressKey = Object.keys(setup).find(k => k.startsWith('express_checkout:'));
if (expressKey && setup[expressKey].enabled) {
  buttons.push({ type: 'stripe-express-bundled', config: setup[expressKey] });
}

// Redirect APMs (radio list)
const apms = Object.entries(setup)
  .filter(([_, e]) => e.enabled && e.type === 'apm')
  .map(([key, e]) => ({ key, label: e.label, processorId: e.processorId, method: e.method }));
```

### Filter by currency

```ts theme={null}
const eligibleApms = Object.entries(setup)
  .filter(([_, e]) => e.enabled && e.type === 'apm')
  .filter(([_, e]) => !e.presentmentCurrencies || e.presentmentCurrencies.includes('EUR'));
```

### Filter by country

```ts theme={null}
const eligibleForCountry = (entry, country) =>
  !entry.supportedCountries || entry.supportedCountries.includes(country);
```

***

## Provider catalog

| Provider       | Methods commonly available                                                                                                            | Browser SDK loaded                                                 |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
| `tagada`       | `card`, `paypal` (native), redirect APMs via Tagada-managed processors                                                                | None                                                               |
| `apple_pay`    | `apple_pay` only                                                                                                                      | Apple Pay JS SDK                                                   |
| `google_pay`   | `google_pay` only                                                                                                                     | Google Pay JS SDK                                                  |
| `stripe`       | `card` (cascade), `apple_pay`, `google_pay`, `link`, `klarna`, `ideal`, `bancontact`, `twint`, `blik`, `affirm`, `paypal`, `afterpay` | Stripe.js (only if you render `express_checkout` or `card:stripe`) |
| `airwallex`    | `card`, `klarna`, `afterpay`, `ideal`, `bancontact`, `twint`, `paypal`, `skrill`                                                      | Airwallex SDK (when needed)                                        |
| `adyen`        | `card`, redirect APMs                                                                                                                 | Adyen Web Components (when needed)                                 |
| `oceanpayment` | `card`, regional APMs                                                                                                                 | None                                                               |
| `hipay`        | `card`, `oney`                                                                                                                        | HiPay SDK (when needed)                                            |
| `ngenius`      | `card`, regional MENA APMs                                                                                                            | None                                                               |
| `mastercard`   | `card`                                                                                                                                | None                                                               |

***

## What changes after the call?

`paymentSetup.get(storeId)` is a snapshot. It can change:

* A merchant turns on a new payment method via your dashboard
* An operator adjusts processor routing
* A KYB review unlocks an additional capability

Treat the result as cacheable for \~1 minute on the client. Re-fetch on:

* Page reload
* Currency change (some methods filter by `presentmentCurrencies`)
* Country change (some filter by `supportedCountries`)

***

## Versioning

The `paymentSetupConfig` shape is **stable** — new fields are added in a backwards-compatible way. We don’t remove or rename fields without a major version bump of the API.

If you see an unfamiliar key (e.g. a new method), the safe behavior is to ignore it. Your existing code keeps working until you opt into rendering the new method.
