Skip to main content
Issued cards are in beta. Everything on this page, including issued checkout and the card.issue, card.retrieve, card.close and card.reveal endpoints, is enabled per account and may change. To request access, email support@henrylabs.ai. Until access is enabled, these endpoints return 403.

What it is

With issued cards, a checkout doesn’t send your buyer’s card to the merchant. Henry Labs charges your buyer’s tokenized card (collect it with the Card Element), issues a virtual card for that amount, and checks out on the virtual card instead.
  • The buyer is charged once, by Henry Labs. Their statement reads HENRY* <MERCHANT>, for example HENRY* ZARA.
  • The buyer doesn’t need to be present. The charge uses the card saved when it was tokenized, so no CVC is needed, even days later.
  • The merchant never sees your buyer’s card. Each issued card has a hard spending limit and locks to the merchant that charges it.
  • Unspent money goes back automatically. When the card settles, the buyer is refunded whatever it didn’t spend, and later merchant refunds on returns are passed back too.
There are two ways to use it:

Issued checkout

Recommended. Henry Labs sizes, charges and issues the card for you inside cart.checkout.purchase, from a checkout quote.

Issue a card yourself

Call card.issue with an amount you choose, then pay with the returned card token.
Get your buyer’s permission for future charges. Both flows charge the buyer’s card without them present, which card networks treat as a merchant-initiated charge. When your buyer enters their card, tell them it may be charged later for their orders, and keep a record that they agreed.

Issued checkout

For apps using issued checkout, every headless purchase pays with an issued card. It takes one extra field: the checkout quote the card is sized from.
1

Quote the cart

Run checkout details for the buyer’s shipping address. You get one refId per merchant in the cart.
Show your buyer the total before you charge them.
2

Purchase with the quote

Pass every refId as checkoutDetailsRefIds, within 30 minutes of the quote, with the same items and shipping address.
Henry Labs charges buyerCardToken, issues the card and starts the checkout on it. Poll or use webhooks as for any purchase.

What the buyer is charged

Each merchant’s quoted total, plus padding, rounded up to the whole dollar. Padding absorbs small changes between the quote and the merchant’s final total, such as tax recalculated at the last step. The default is $5 per merchant; email support@henrylabs.ai to change it for your app. Whatever the merchants don’t take is refunded to the buyer when the card settles (see Refunds). For a single-merchant cart you can set the amount yourself with capCents, as long as it covers the quoted total.

When a quote is refused

Nothing is charged in any of these cases. Fix the quote and retry. Retrying a purchase with the same checkoutDetailsRefIds is safe: it returns the same order and never charges twice.
Issued checkout currently applies to headless purchases. Hosted checkout orders pay with the buyer’s card directly, as before.

Issue a card yourself

Use card.issue when you want to choose the amount, or use the card outside a Henry cart.
1

Issue

  • capCents is a lifetime limit: the most the card can ever be charged in total. It’s rounded up to the whole dollar (30.40becomes30.40 becomes 31). Size it to cover tax and shipping.
  • The buyer is charged the rounded amount before the card exists.
  • Send an idempotency key. Retrying with the same key returns the same card and never charges twice.
2

Pay with it

Use the token anywhere a tokenized card works.
Issued cards don’t need CVC re-collection: their security code stays valid until the card expires.
3

Check on it

card.retrieve(cardToken) returns the card’s limit, expiry, live state, and what has been charged to it.
4

Close it

card.close(cardToken) once the purchase has fully completed. The card then settles within about 15 minutes. Closing is optional: a card you leave alone settles when it expires.

Reveal the card number

If you run the checkout yourself instead of through cart.checkout.purchase, card.reveal returns an issued card’s full number, expiry and security code.
Receiving a full card number puts your systems in PCI DSS scope (typically SAQ D). Don’t log, store or display it. If you can, pay with cart.checkout.purchase and the cardToken instead: that never exposes the number.
  • Separate beta access. Reveal is enabled on its own, separately from card issuance. Email support@henrylabs.ai to request it; until then it returns 403.
  • Issued cards only. Only cards issued to your app can be revealed. A tokenized buyer card never can (404).
  • Open cards only. A card that’s closed or expired returns 409, as does a card whose state couldn’t be confirmed (safe to retry).
  • Rate limited. 30 reveals per minute per app (429 above that). Every reveal is recorded with the app and card.

Refunds

A card settles when it’s closed or expires. At settlement, the buyer is refunded the difference between what they were charged and what the merchant actually took, usually within 15 minutes.
Don’t close a card the merchant may still charge. A merchant that charges at shipping can’t capture on a closed card. If you’re unsure, leave the card open and let it settle when it expires.

Limits

Henry Labs sets these for your app during the beta; email support@henrylabs.ai to change them. A request over either limit returns 402 and charges nothing.