Payment methods catalog

Mercentia ships a single canonical method dictionary (payment_methods_catalog) shared across every payment provider, plus an eligibility table (payment_method_eligibility) that says exactly which (provider × method × country × currency) tuples are valid.

The non-negotiable rule:

The shopper sees ONLY the methods they can actually pay with. A US shopper never sees UPI. An Indian shopper never sees Affirm. The eligibility filter is non-negotiable.

Browsing the catalog

  • Dashboard — Settings → Methods catalog (/settings/payments/methods). Filter by category or region, expand any method to see every (provider × country × currency) combo that enables it.
  • APIGET /api/v1/payment-providers/catalog returns the same data as JSON.

Schema

payment_methods_catalog

method_key      VARCHAR(40) PRIMARY KEY     -- 'apple_pay', 'pix', 'klarna'
display_name    VARCHAR(80)
category        VARCHAR(20)                 -- 'card', 'wallet', 'bank_redirect',
                                            -- 'bnpl', 'crypto', 'cash_on_delivery',
                                            -- 'invoice', 'direct_debit'
needs_sdk       BOOLEAN                     -- true → renders via Stripe.js / Adyen Web Drop-in
region_label    VARCHAR(20)                 -- 'global', 'eu', 'us', 'uk', 'india',
                                            -- 'sea', 'latam', 'au'

payment_method_eligibility

provider           VARCHAR(40)              -- 'stripe', 'razorpay', 'adyen',
                                            -- 'square', 'paypal', 'klarna'
method_key         VARCHAR(40)              -- FK → payment_methods_catalog
customer_country   VARCHAR(2)               -- ISO-2 or '*' for any
currency           VARCHAR(3)               -- ISO-4217
min_amount_minor   INTEGER                  -- e.g. 3500 = £35 Klarna floor
max_amount_minor   INTEGER
provider_method_code VARCHAR(40)            -- 'klarna', 'scheme', 'directEbanking_DE' etc.
is_active          BOOLEAN
UNIQUE(provider, method_key, customer_country, currency)

How a method ends up on a shopper’s checkout

The routePaymentMethods() function (apps/gateway/src/services/payments/methodRouter.ts) applies four filters in order:

  1. Installation enabled + connected — provider exists for the store with status='connected'.
  2. Currency supported — the installation’s supported_currencies array contains the cart currency.
  3. Eligibility — at least one (provider, method_key, customer_country, currency) row exists; customer_country='*' is a wildcard.
  4. Merchant config — the installation’s enabled_methods array contains the method.

The router then groups by installation (provider) and sorts within each block: local-region methods first, then card → wallet → bank_redirect → bnpl → direct_debit → cash_on_delivery, then alphabetical.

Methods that are shadowed by a higher-priority installation are emitted in ineligible with the reason — useful for the dashboard’s “test eligibility” tool.

Currently supported methods (2026)

Cards & wallets

Method Providers Region
card stripe, razorpay, adyen, square global
apple_pay stripe, adyen, square global
google_pay stripe, square global
paypal paypal global
cashapp stripe us
revolut_pay stripe uk
wechat_pay stripe global
alipay stripe global
mb_way adyen eu
grabpay adyen sea
dana adyen sea
ovo adyen sea
paytm, phonepe razorpay india

BNPL

Method Providers Region
klarna stripe, adyen global (GB, US, DE, FR, IT, ES, NL, BE, PL, SE, NO, FI, DK, AT, CH, IE, PT)
afterpay_clearpay stripe global (GB, US, AU)
affirm stripe us
zip stripe us / au

Bank redirects

Method Providers Region
ideal stripe, adyen eu (NL)
bancontact stripe, adyen eu (BE)
sofort adyen eu (DE/AT)
giropay adyen eu (DE — note: deprecated by Giropay 2024; rows kept for legacy carts)
blik stripe, adyen eu (PL)
eps stripe, adyen eu (AT)
p24 stripe, adyen eu (PL)
multibanco stripe, adyen eu (PT)
upi razorpay india
netbanking razorpay india
emi razorpay india
fpx adyen sea (MY)
promptpay adyen sea (TH)
pix stripe, adyen latam (BR)
webpay latam (placeholder; provider integration pending)
payid adyen au
interac square us (CA)

Direct debit

Method Providers Region
sepa_debit stripe eu
ach_debit stripe us
becs_debit stripe au

Cash & invoice

Method Providers Region
boleto stripe, adyen latam (BR)
oxxo stripe, adyen latam (MX)
cash_on_delivery global (off-platform; merchant flips order to “paid on delivery”)

Adding a new method

  1. Add a migration that inserts the row into payment_methods_catalog.
  2. In the same migration, insert every (provider, method_key, customer_country, currency) eligibility row.
  3. If the method has a regionLabel not in ['global','eu','us','uk','india','sea','latam','au'], update regionsFor() in methodRouter.ts so the local-method sort still works.
  4. If the method needs an SDK (Stripe.js Payment Element, Adyen Drop-in), confirm needs_sdk = TRUE and verify the storefront dispatcher in apps/storefront/components/checkout/PaymentMethods.vue already routes the method key to the right SDK mount.
  5. Add a test case to methodRouter.test.ts covering at least one (country, currency) combination.
  6. Update the table above in this doc.

Adding a new provider

Adding a brand-new provider (not just a method) is a bigger lift:

  1. Extend the PaymentProviderName enum in both the schema and methodRouter.ts.
  2. Implement the provider’s adapter (apps/gateway/src/services/payments/providers/<provider>.ts) covering: connect, charge, refund, webhook verify, webhook dispatch.
  3. Add a row to the provider enum in payment_provider_installations.
  4. Seed eligibility rows in a new migration.
  5. Add a dashboard provider tile (apps/dashboard/pages/settings/payments/providers.vue).
  6. Wire the webhook dispatcher in apps/gateway/src/routes/payment-providers.ts.

Migration history

  • 0070 — initial 22-method catalog (Stripe global + Razorpay India + Adyen EU + Square US + PayPal).
  • 0107 — 2026 international expansion: 20 new method keys (Pix, Boleto, OXXO, Cash App, Zip, Revolut Pay, GrabPay, FPX, PromptPay, DANA, OVO, WeChat Pay, Alipay, RuPay, Multibanco, MB Way, BECS Direct Debit, PayID, Interac), 70+ new eligibility rows, Klarna eligibility expanded from 3 countries (GB/US/DE) to 13.

Related