# Reusing a stored payment method with payment tokens

Capture the reusable payment token returned when a card is saved, then charge the stored card again without handling card data, declaring whether the customer is present for each charge.

**Category:** Integration

**Last reviewed:** 4 September 2026

# Reusing a stored payment method with payment tokens

When a customer saves their card during a payment (for example, a Hosted Payment Page or Virtual Terminal sale with save-card enabled), Syntch vaults the card and returns a reusable **payment token**. You can charge that token later without ever collecting or storing the card number yourself, which keeps the reorder and card-on-file flows out of your PCI scope.

The token you use for this is the **public reference**: a single opaque handle that's both what you receive and what you charge with.

## Where the token appears

The public reference is surfaced in two places whenever a transaction tokenizes a card:

- **The synchronous transaction response** at `responseData.tokenResult.publicReference`.
- **The transaction-completed webhook** at `data.responseData.tokenResult.publicReference` (see the Webhook Integration guide for the envelope and signature scheme).

Both carry the same value. It's present only when the transaction actually saved a card; on a non-tokenizing transaction the `tokenResult` object is omitted.

```json
{
  "responseData": {
    "resultCode": 1,
    "resultMessage": "Approved",
    "tokenResult": {
      "publicReference": "pt_9fKq2ZmB7tLxW3aH5nR8cV1s"
    }
  }
}
```

## What the token is

- **Opaque and self-describing.** It always begins with the `pt_` prefix followed by a random string safe for use in a web address. Treat the whole value as an opaque handle: store it and send it back verbatim. Don't parse, split, or infer anything from its contents.
- **Not a card number and not an internal id.** By design, the public reference isn't shaped like a card number, and it's not the gateway's internal vault identifier. It's the only token identifier Syntch emits to you; the internal identifier never leaves the gateway.
- **Stable.** The same stored payment method keeps the same public reference, so you can store it against your customer record and reuse it across orders.

## Charge with the token

To charge a stored payment method, send the public reference in the payment token field of a sale or authorization request instead of raw card data:

```json
{
  "tokenData": {
    "token": "pt_9fKq2ZmB7tLxW3aH5nR8cV1s"
  },
  "invoiceData": {
    "amounts": { "base": 49.00 }
  }
}
```

Syntch resolves the token to the stored card, runs the charge, and returns the usual transaction response.

**Send the amount as `base`, not `total`.** `total` is calculated by Syntch as `base + tip + tax + shipping + convenience`. It's returned on the response; it's not a way to set the amount charged, and a `total` that disagrees with the components you sent doesn't change what's charged. If you do send `total`, it's treated as an integrity check on those components. Once checksum enforcement is switched on for your environment, a disagreement is rejected with an error naming both values; until then it's recorded for review and the charge proceeds for the component sum. Either way, send a `total` only if you want that check. Always read the `total` on the response as the authoritative amount charged: fees the gateway adds after accepting your request, such as a surcharge or a convenience fee it computes, are outside the check and appear only there.

## Say who initiated the charge

Card network rules require every charge against a stored payment method to say who initiated it, and Syntch reports that to the processor from one field on the request: `initiationType`. The rule is about the customer's presence at the moment of the charge. It isn't about which system sends the request (your platform sends every request), and it isn't about what's being sold.

- The customer is present and agreeing to this charge right now, at a counter, on a kiosk, on a checkout page in front of them, or on a phone call: a **cardholder-initiated (CIT)** charge.
- The customer isn't present and you're charging on their behalf, for a subscription, an unpaid balance, a no-show fee, or an order you fulfill later: a **merchant-initiated (MIT)** charge.

The same stored payment method can be charged both ways. Decide per charge, not per integration.

### When the customer is present (CIT)

Send `initiationType` as `CardholderInitiated`, or leave it out; an omitted value is treated as cardholder-initiated. Don't send a `mitReason`.

```json
{
  "initiationType": "CardholderInitiated",
  "tokenData": {
    "token": "pt_9fKq2ZmB7tLxW3aH5nR8cV1s"
  },
  "invoiceData": {
    "customerId": "3f2a6c1e-8d4b-4f0a-9b7e-2c5d1a8e6f30",
    "amounts": { "base": 49.00 }
  }
}
```

Syntch recognizes a cardholder-initiated charge that pays with a stored token as a later use of a stored payment method and reports it to the processor as one, referencing the network transaction that stored the card. No consent is consulted, so this works for any active stored payment method, including one saved without consent. `invoiceData.customerId` isn't enforced on a cardholder-initiated charge, but send it so the token resolves scoped to the customer who owns it.

### When the customer isn't present (MIT)

Send `initiationType` as `MerchantInitiated`, a `mitReason`, and the owning customer in `invoiceData.customerId`. All three are required. A merchant-initiated token charge without `customerId` is rejected before any consent is checked.

```json
{
  "initiationType": "MerchantInitiated",
  "mitReason": "UnscheduledCOF",
  "tokenData": {
    "token": "pt_9fKq2ZmB7tLxW3aH5nR8cV1s"
  },
  "invoiceData": {
    "customerId": "3f2a6c1e-8d4b-4f0a-9b7e-2c5d1a8e6f30",
    "amounts": { "base": 49.00 }
  }
}
```

A merchant-initiated charge also needs a captured **stored-credential consent** that permits the reason: `Recurring` for a fixed schedule, `Installment` for a known total split into payments, and `UnscheduledCOF` for anything with no fixed schedule (it also covers `DelayedCharge`, `NoShow`, and `IncrementalAuth`). Syntch resolves the active consent from the token and customer for you, so don't look up or send a consent id. A merchant-initiated charge with no consent that permits its reason is declined with `stored_credential_consent_required`.

Consent is captured when the card is saved, on a hosted payment page with save-card enabled or in the Virtual Terminal; the direct API can't record it. Ask for every usage you expect to need at that moment, because a later merchant-initiated charge can't add one. [Setting up a hosted payment page](/help/guides/hosted-payment-page-setup) covers the save-card purposes and the session-level consent settings.

Sending `MerchantInitiated` for a purchase the customer is making in front of you isn't rejected, but it misreports the charge to the networks, which price and dispute the two kinds differently. Sending a cardholder-initiated charge for one the customer never saw is the same mistake in the other direction.

### Charge with a companion `cardData`

A token charge doesn't need a `cardData` object at all: the token is the tender, and Syntch resolves the card number and expiration from the vault. You may still send one to carry **address-verification fields**, which is the only reason to include it:

```json
{
  "tokenData": {
    "token": "pt_9fKq2ZmB7tLxW3aH5nR8cV1s"
  },
  "cardData": {
    "billingAddress": {
      "address1": "1 Market Street",
      "postalCode": "94105"
    }
  },
  "invoiceData": {
    "amounts": { "base": 49.00 }
  }
}
```

Two things to know about that companion object:

- **Send AVS fields only.** A `cardData` on a token charge should carry the billing address, and optionally the cardholder name, email, or phone. Don't put a card number, track data, or a reader payload in it: the token already identifies the card, and a request that supplies both a token and raw card data is rejected as ambiguous about which one to charge.
- **You don't need to set `isStoredPayment`.** Syntch stamps that flag itself while resolving the token. It's an output of token resolution, not something the caller declares, so leave it out and let the gateway set it.

Don't declare a card-present `entryMode` (a magnetic-stripe, chip, or contactless value) on a companion object. Those values assert that a physical card was read on a device, so the request is then held to carrying the reader payload that read produced. Omit `entryMode` on a token charge.

## Treat the token as a credential

Making the public reference chargeable means anyone who holds it can attempt a charge, subject to two protections that always apply: the token is scoped to your merchant account, and merchant-initiated reuse still requires stored-credential consent. The token's shape isn't a secret in itself, so:

- Keep the token server-side. Don't embed it in browser code, query strings, or client-visible URLs.
- Store it with the same care you give any reusable credential, and only alongside the customer it belongs to.
- Log it sparingly. It's not card data, but it's a live charging handle.

## What not to rely on

Charge only with the `publicReference` value. Don't attempt to charge using identifiers scraped from a transaction's history or from internal fields: those aren't resolvable for charging and aren't a supported integration surface. The public reference in the response and webhook is the one supported reusable handle.

## See also

- [All documentation](https://devportal-simpay-sbx.winkpg.io/llms.txt): the machine-readable index of every public page on this site.
