MAXFIMAXFIdeveloper hub
DocsPayment methods

Payment methods

MAXFI exposes one universal checkout flow that supports all eight canonical payment methods. The hosted checkout page decides at runtime which methods to show based on your Merchant Connector Account (MCA) — you do not ship connector-specific UI.

The same catalog is also available to the Widget SDK and to direct-API integrations that want to render their own method picker.

Canonical 8 methods

Every method_code returned by our APIs is one of these:

cardinline_form
Card (Visa / Mastercard / Mir)
PCI SAQ A-EP. 3DS2 when required. Supports recurring tokenisation.
sbpqr_code + deeplink
SBP (NSPK)
QR for desktop, bank deeplink on mobile. Poll /status until succeeded.
sberpayredirect
SberPay
Customer confirms in Sberbank Online. Returns via success_url.
tpayredirect
T-Pay (Tinkoff Pay)
Customer confirms in Tinkoff app. Returns via success_url.
yoomoneyredirect
YooMoney wallet
Optional wallet_id pre-fill. Balance or linked card.
apple_paymodal
Apple Pay
Safari / iOS only. Tokenised payload, no PAN on your server.
google_paymodal
Google Pay
Chrome / Android. Tokenised payload, no PAN on your server.
recurrentinline_form
Saved method (MIT)
Merchant-initiated off-session charge using saved_payment_method_id.

Effective catalog · MCA ∩ CMC ∩ MCS

What a given customer actually sees on the checkout page is computed from three layers, resolved server-side:

  1. MCAMerchant Connector Account. The set of methods the acquirer (Bank131, ATB, E-Xezine…) has switched on for this merchant.
  2. CMCConnector Method Capability. The global whitelist of what each connector can technically do at the platform level (managed by MAXFI operations).
  3. MCSMerchant Connector Setting. Per-merchant toggles the merchant controls from the Merchant Portal (“Способы оплаты” tab).

The effective catalog is the intersection: a method must be allowed at all three layers to appear. If any layer removes it, the checkout page hides the tab. Reordering is driven by MCS display_order.

Fetching the catalog

The hosted checkout page fetches this itself on load — you usually don't need to call it. But if you're rendering your own picker (direct API, a custom widget embed, a mobile SDK), hit it first:

curl https://maxfi-api.exezine.az/checkout/cs_abc123/methods \
  -H "Accept: application/json"

# Response
{
  "methods": [
    {
      "method_code":    "card",
      "display_order":  10,
      "render_mode":    "inline_form",
      "is_enabled":     true,
      "supports_recurring": true,
      "supports_refund":    true,
      "allowed_currencies": ["RUB", "USD", "EUR"]
    },
    {
      "method_code":    "sbp",
      "display_order":  20,
      "render_mode":    "qr_code",
      "is_enabled":     true,
      "supports_refund": true,
      "allowed_currencies": ["RUB"]
    }
  ]
}

This endpoint fails open: if the catalog lookup errors, we return { methods: [{ method_code: "card", … }], fallback: true }so the customer can still pay by card.

Submitting a non-card method

Card payments go through POST /checkout/{sessionId}/pay(PCI SAQ A-EP, 2-phase 3DS). All other methods submit to the shared endpoint:

curl https://maxfi-api.exezine.az/checkout/cs_abc123/submit-method \
  -H "Content-Type: application/json" \
  -d '{
    "method_code": "sbp"
  }'

# Response — browser must render the QR + poll for settlement
{
  "session_id": "cs_abc123",
  "status":     "requires_action",
  "next_action": {
    "type":           "show_qr",
    "qr_raw_payload": "https://qr.nspk.ru/AS1000…",
    "deeplink":       "bank100000000111://qr.nspk.ru/AS1000…"
  }
}

next_action shapes

The next_action object tells the browser what to do next. Four discriminated shapes:

SBP bank picker · NSPK whitelist

SBP (Система Быстрых Платежей / Faster Payments System) in Russia is run by NSPK — the National Payment Card System. Every bank connected to SBP has a stable 12-digit identifier called nspkId. When a customer picks their bank on the checkout page before generating the QR, the QR payload is routed directly to that bank's mobile application via a deeplink, skipping the manual «open my banking app and scan» step.

MAXFI mirrors the public NSPK dictionary at qr.nspk.ru/proxyapp/c2bmembers.json into our database and exposes it through three endpoints. All three validate the supplied member_id against the active whitelist before a payment is even sent to the acquirer — unknown / stale identifiers return an error straight from Gateway.

Public
GET /sbp/members

Full active whitelist (~200+ banks). No auth. Ideal for server-side validation or a «всё SBP-сообщество» picker.

Public
GET /sbp/members/popular?limit=12

Only top-N banks (curated by MAXFI Ops), sorted by display_order. Used by the hosted checkout grid.

Per-session
GET /checkout/{sessionId}/sbp-members

Same list but tied to a checkout session. Returns an empty array if the session currency ≠ RUB (SBP only supports rubles).

Widget SDK
GET /widget/v1/sbp-members

Authenticated with your publishable key. Used by the embedded Widget modal to render the same grid on your site.

Each member is returned as:

curl https://maxfi-api.exezine.az/sbp/members/popular?limit= class="tok-number">4

# Response
{
  "data": [
    {
      "member_id":        "100000000111",
      "name":             { "en": "Sberbank", "ru": "Сбербанк", "az": "Sberbank" },
      "logo_url":         "https://qr.nspk.ru/logos/bank100000000111.png",
      "deeplink_ios":     "bank100000000111://",
      "deeplink_android": "ru.sberbankmobile",
      "is_popular":       true,
      "display_order":    1
    },
    { "member_id": "100000000004", "name": { "en": "T-Bank", … }, "display_order": 2, … },
    { "member_id": "100000000005", "name": { "en": "VTB",    … }, "display_order": 3, … },
    { "member_id": "100000000008", "name": { "en": "Alfa-Bank", … }, "display_order": 4, … }
  ],
  "count": 4
}

Submit the chosen bank by adding extra.memberId to the SBP method payload:

curl https://maxfi-api.exezine.az/checkout/cs_abc123/submit-method \
  -H "Content-Type: application/json" \
  -d '{
    "method_code": "sbp",
    "payload": {
      "dynamic": true,
      "extra":   { "memberId": "100000000111" }
    }
  }'

# Response — payload routed to Sberbank deeplink, QR still shown as fallback
{
  "status": "requires_action",
  "next_action": {
    "type":     "show_qr",
    "deeplink": "bank100000000111://qr.nspk.ru/AS1000…",
    "qr_raw_payload": "https://qr.nspk.ru/AS1000…"
  }
}
Why we validate on the Gateway side

A bogus memberId (typo, bot traffic, custom SDK bug) would still reach the acquirer and come back as an opaque invalid_member_bank error after a 500–800 ms round trip. By keeping an in-memory mirror of the NSPK whitelist (10-minute TTL, refreshed nightly by a cron job) we reject unknown IDs in under 1 ms, keep payment_audit_log clean, and can present a localised error message without leaking the acquirer's dictionary.

Apple Pay / Google Pay activation

Unlike card, sbp, or sberpay, wallet methods require extra setup on the acquirer side and on the merchant's own domain before they become toggleable. Until your MAXFI account manager completes verification, these methods are visible in Merchant Portal → Payment methods but the toggle is disabled with a “Awaiting verification” pill.

Apple Pay — checklist

  1. Register an Apple Merchant ID in your Apple Developer account (e.g. merchant.com.yourshop).
  2. Generate the Merchant Identity Certificate and the Payment Processing Certificate signed by your acquirer (ATB SmartVista, Bank131, …).
  3. Upload the domain association file Apple gives you to MAXFI. Once saved on the Merchant Connector Account (MCA), MAXFI serves it at https://<your-domain>/.well-known/apple-developer-merchantid-domain-association automatically — one endpoint per verified domain, no extra deploy on your side.
  4. Sign the Apple Pay Web merchant agreement with your acquirer.

When all four are in place, MAXFI Ops flips payment_methods.apple_pay on your MCA and the toggle in Merchant Portal → Payment methods becomes active — no deploy required on your side.

Google Pay — checklist

  1. Register a Google Pay Merchant ID in Google Pay & Wallet Console.
  2. Configure your gateway in the console pointing at your acquirer (e.g. smartvista for ATB). Google will issue a gateway_merchant_id that MAXFI stores on your MCA.
  3. Sign the Google Pay API for Web agreement with your acquirer.
  4. (Optional, production launch) submit your website to Google for the Google Pay Web production review.

Same unlock mechanism as Apple Pay — MAXFI Ops adds google_pay to your MCA, the Merchant Portal toggle becomes active, and the hosted checkout starts advertising the Google Pay button on supported browsers.

Tokenisation, not PAN

Both wallets send MAXFI an encrypted device-specific token, not the customer's real PAN. From your server's point of view nothing changes — you still call POST /checkout/{sessionId}/submit-method with method_code: "apple_pay" or "google_pay". The hosted checkout handles the Apple Pay sheet / Google Pay button, sends the token server-to-server, and returns a standard succeeded / failed status.

Widget SDK

The Widget SDK (/widget/v1/maxfi.js) wraps all of this. Drop a button on your page, the SDK shows the method picker in a modal, creates the session, and mounts the checkout iframe. Card data never crosses your front-end — the iframe handles it.

If you want to pre-select a tab, pass initial_method:

<script src="https://maxfi-api.exezine.az/widget/v1/maxfi.js"></script>
<script>
  const maxfi = new Maxfi({
    publishableKey: "pk_live_…",
    amount:   4900,
    currency: "USD",
    initial_method: "sbp", // pre-selects the SBP tab
  });
  maxfi.mount("#pay-button");
</script>
Where methods are configured

Enable / reorder methods for your account in Merchant Portal → Способы оплаты. What your customers see on the hosted page reflects that setting within a minute.