Two ways to get a token

The SDK behaves identically once a token exists. What differs is who calls POST /api/v1/checkout/init — and therefore where the merchant API key lives.

Backend-mintedSDK-minted
You passwidgetTokenorder + customerEmail
Calls /checkout/initYour serverThe app
Merchant API key livesOn your serverIn the app binary
Needs a backendYesNo
Fit for a public consumer appYesNo — see below

The merchant API key is a merchant-wide credential. Anything holding it can mint tokens for any amount, create checkouts, and read every payment of the merchant — including other shoppers' payment history from their email alone, via GET /api/v1/payments?customer_email=…. An app binary is not a secret store: it can be unzipped, and the header read off the wire on a device the reader controls. Compiling the key into a shipped app publishes it, and rotating it afterwards breaks every installed copy until users update.

Choose SDK-minting for an internal or single-tenant app, a prototype, or a build whose key is restricted server-side. For a public consumer app, mint on a backend and pass widgetToken.

Supply exactly one of widgetToken or order — the widget asserts on both or neither, and customerEmail is required with order because a mint without one is rejected. Only /checkout/init ever carries the credentials: the lookup, the checkout and the status poll are authenticated by the widget token and the payment client token, so the key never travels on them. RezolvePayCardPaymentController.activeWidgetToken reports whichever token the checkout is actually running on.

A widget token is single-use either way, and only one may be ACTIVE per merchant/order pair — so a retry needs a fresh order_id, not a repeat of the spent one.

Backend-minted

// Your server holds the merchant API key and mints the token.
// The app never sees a merchant credential.
RezolvePay.configure(baseUrl: 'https://pay.rezolve.com');

final String widgetToken = await fetchWidgetToken(orderId);  // your endpoint

RezolvePayCardForm(
  widgetToken: widgetToken,
  customerEmail: email,
  onSuccess: ..., onFailure: ...,
);

SDK-minted

// No backend: the SDK calls /checkout/init itself.
//
// WARNING: merchantApiKey is a MERCHANT-WIDE credential and an app binary
// cannot keep it secret. Anyone who downloads the app can extract it and
// then mint tokens, create checkouts, and read every payment of this
// merchant - including other shoppers' history by email. Use this only
// for an internal/single-tenant app, a prototype, or a restricted key.
RezolvePay.configure(
  baseUrl: 'https://pay.rezolve.com',
  merchantId: 'acme',
  merchantApiKey: '...',
);

RezolvePayCardForm(
  // Instead of a token: the SDK mints one for this order on start().
  order: const RezolvePayOrder(
    amount: 1499,          // minor units
    currency: 'GBP',
    orderId: 'ORD-4421',   // fresh per attempt - a token is single use
  ),
  // Required here: a mint without a shopper email is rejected.
  customerEmail: email,
  onSuccess: ..., onFailure: ...,
);

Did this page help you?