Skip to main content
Push to card is an off-ramp whose destination is the user’s own debit card instead of a bank account. Funds land on the card in minutes, around the clock. Everything about the quote, the on-chain payment, and the fiat leg is the same as the bank-account flow — this guide covers only what differs: collecting the card safely and choosing the push_to_card rail. Push to card is available to verified US users, in USD, for Visa and Mastercard debit cards. Credit cards are not eligible, and the card network has the final say on whether a given card can receive a push.

How card data stays out of scope

Spritz never accepts a raw card number, and neither should you. Card entry runs inside an Evervault Card component: an iframe served from Evervault’s domain that encrypts the card number in the user’s browser before your code ever sees it. What comes out is an opaque ev: token plus the plaintext metadata Spritz needs (expiry, last four, BIN, brand). You forward those to POST /v1/debit-cards; only Spritz’s infrastructure can decrypt the token, and only to hand the card to the payout network. The component needs two identifiers to initialise: an Evervault team ID and an app ID. They are public-key material, not credentials — anyone holding them can only encrypt to Spritz, never decrypt — but they are environment-specific, so a card encrypted for sandbox cannot be used in production and vice versa.
Spritz provides the Evervault team ID and the app IDs for sandbox and production during onboarding. If you do not have them, ask your Spritz contact.

Before you start

  • Authenticate as an integrator acting for a user. See Authentication.
  • The user’s capabilities on GET /v1/users/me include the pair product: "crypto_to_fiat" and method: "push_to_card" with status: "active". See Onboarding. Adding a card without it returns 403.
  • You have the Evervault team ID and the app ID for the environment you are calling.

Step 1 — Collect the card in the browser

Install the Evervault SDK for your stack (@evervault/react, @evervault/js, or the mobile SDKs) and render the Card component with number and expiry fields. Spritz does not need the CVC — leave it out.
The onChange payload carries everything the API needs: Collect the cardholder’s first and last name and their US billing address in your own form. The name must be the name printed on the card — Spritz checks it against the user’s verified identity — and the card network requires the billing address to accept pushes.

Step 2 — Add the card

Send the captured values from your backend, signed with your integrator key, on behalf of the user. Your backend only ever handles the encrypted token, which keeps it outside PCI scope.
A 201 returns the card, ready to use:
Card statuses: List a user’s cards with GET /v1/debit-cards ({ "data": [...], "hasMore": false } — no pagination, users hold few cards), read one with GET /v1/debit-cards/{id}, and remove one with DELETE /v1/debit-cards/{id}. A deleted card reads back as 404.

Errors when adding a card

Step 3 — Quote, pay, and track

From here the off-ramp guide applies unchanged. Pass the card’s id as accountId and choose the push_to_card rail:
  • Timing: minutes, seven days a week. The off-ramp usually moves in_flightcompleted within a few minutes of the on-chain confirmation. See Settlement timing.
  • Pricing: the crypto-to-fiat base rate plus the push_to_card adjustment, with a weekend and US-bank-holiday surcharge. See End-user pricing.
  • Failure: if the network declines the push after the crypto has been paid, the off-ramp reaches failed and the refund flow applies. A decline that is a verdict on the card itself (expired, inactive, cannot receive pushes) also flips the card to rejected — collect a different card before offering a reissue.
Webhooks are the same payment.* and offramp.* events as any off-ramp. See Webhooks.

Sandbox testing

Sandbox has its own Evervault app ID. Initialise the Card component with it when targeting https://sandbox.spritz.finance; a token encrypted for the production app is refused there, and the other way round. Card entry accepts any Luhn-valid Visa or Mastercard number with a future expiry, and the add flow runs against a sandbox card registration, so the 201, 403, 422, and 400 paths above are all reachable. As with every sandbox off-ramp, the fiat leg parks at queued — no push is submitted, so completed, failed, and the rejected card state are contract-tested from this guide, not end-to-end tested. Exercise your handling of them with fixtures. See Sandbox for the environment as a whole.

Integration checklist

  • Card number is captured only inside the Evervault Card component, with the team ID and the app ID for the environment you are calling
  • Your backend forwards the encrypted token and never logs it, and your frontend never posts it to Spritz directly (that would expose your integrator key)
  • expiryMonth and expiryYear are forwarded as the component returns them, not re-formatted
  • Cardholder name is collected as first and last name, as printed on the card
  • 403 and 422 on card add produce specific user guidance, and 503 offers “try a different card” rather than a retry
  • Quotes use rail: "push_to_card" with the card id as accountId
  • A rejected card is hidden from the destination picker and the user is prompted to add another

Off-ramp: crypto to bank

The full off-ramp lifecycle this guide builds on.

Onboarding

Reading capabilities to know when push to card is active.

End-user pricing

Fee tiers by rail, including push to card.

Sandbox

Test users, bypasses, and what the sandbox can and cannot simulate.