Mintcash
Guides

Accept with a saved card

Once a customer has paid once, you have a card token you can reuse — no hosted page, no redirect, just a server-to-server charge.

After a customer completes their first successful payment, MintCash returns a card token in subsequent payment lookups. The token represents that saved card on that provider. Use it to charge the same customer again without redirecting them anywhere.

When to use it

  • One-tap re-orders for returning customers
  • Upgrades or upsells from inside your product
  • Programmatic charges (no human in the loop)
  • Pre-authorisations and post-auth captures

If the customer needs to see and confirm a card, use the HPP flow instead.

The flow

Rendering diagram…

No redirect. The customer doesn't see anything until you tell them about it.

Implementation

The request shape is almost identical to the HPP flow — but you include cardToken and omit returnUrl:

const r = await fetch("https://sandbox.mintcash.me/payments", {
  method: "POST",
  headers: {
    Authorization: `Basic ${btoa(`${publicKey}:${secretKey}`)}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    externalId: orderId,
    amount: 1499,
    currency: "USD",
    cardToken: savedCardToken, // from a previous successful payment
    customer: {
      externalId: customerId,
    },
  }),
});

const { payment } = await r.json();

payment.redirectUrl will be null. The payment proceeds directly to either succeeded or failed (sometimes via pending if the provider needs reconciliation).

Where the token comes from

Every payment that succeeds via the HPP flow returns a cardToken field on the resulting payment record:

{
  "id": "pmt_...",
  "status": "succeeded",
  "amount": 49.99,
  "currency": "USD",
  "cardToken": "tok_01HXX...",
  "card": {
    "brand": "mastercard",
    "last4": "0000"
  }
}

Store the token alongside your customer record. Card metadata (brand, last4, expiry) is non-sensitive — safe to display in your dashboard so the customer recognises which card you'll charge.

Tokens are merchant-scoped

A cardToken belongs to the merchant who created it. Trying to use another merchant's token returns invalid_argument with code invalidCardToken. The provider never returns the raw card details — that's by design.

What to test

  • Charge with a valid token — should hit payment.succeeded directly
  • Charge with an unknown token — 400 invalid_argument (invalidCardToken)
  • Charge with an inactive/expired token — same error
  • Provider network failure — should hit 503 unavailable (providerUnreachable)
  • Idempotent retry on the same externalId — second call returns the original payment