Crypto Backed Card
Prefund operations, card authorization callback, and card webhooks for Crypto Backed mode.
This document is the Partner-facing API reference for Card Mode: Crypto Backed. It covers the three integration surfaces a Partner must implement on top of their chosen Account Mode: Prefund Account operations, the Card Authorization callback (UR → Partner, synchronous), and the Card Mode webhooks (post-swipe and Prefund balance alerts).
For the conceptual definition of Card Mode and how it relates to Account Mode, see Integration Guide. For the Account Mode API surfaces this mode plugs into, see API Reference: Managed Custody Mode or API Reference: External Wallet Access Mode.
1. Mode context
1.1 What Card Mode: Crypto Backed is
Card Mode answers a single question: when the user taps the card, which balance is debited?
Card Mode: Fiat Only: the card draws exclusively from the user's UR fiat balance. UR runs the authorization on-chain; the Partner is not in the authorization path.
Card Mode: Crypto Backed (this document): the card can settle directly against the user's crypto holdings via a Partner-funded Prefund Account, with no per-swipe off-ramp required. UR synchronously consults the Partner at authorization time; the Partner asynchronously debits the user's crypto after a successful swipe.
Card Mode is orthogonal to Account Mode; a Partner can pair Crypto Backed with either External Wallet Access Mode or Managed Custody Mode.
1.2 The two phases
Crypto Backed runs in two phases that operate on different timescales:
1. Prefund
Partner
Scheduled (recurring, or on alert)
Partner calls the UR off-ramp contract with USDC, targeting its own Prefund Account. The Prefund Account is credited in the Partner's settlement currency.
2. Card spend
User (tap)
Real-time
Mastercard routes the auth to UR → UR calls the Partner webhook → Partner returns a decision → UR settles against the Prefund Account (APPROVE) or the user's UR fiat balance (PASS) → after Mastercard finalizes, UR sends a post-swipe webhook to the Partner → on an APPROVE, the Partner debits the user's crypto.
The Prefund Account exists to absorb real-time card authorizations: Partners cannot bridge user crypto fast enough to meet UR's 1 s total authorization window, so UR is pre-funded and the Partner reconciles asynchronously.
1.3 What this document covers vs. doesn't
This document covers Partner-facing surfaces that exist only in Card Mode: Crypto Backed:
§3 Prefund Account funding flow + balance API
§5 Card Mode webhooks (post-swipe transaction + Prefund balance alert)
This document does NOT cover endpoints that are common to both Card Modes (Create Card, Get Card Info, Set Default Currency, Card history). Those live in the Account Mode API reference under the Card section:
Managed Custody Partners → API Reference: Managed Custody Mode §11
External Wallet Access Partners → API Reference: External Wallet Access Mode
1.4 Partner prerequisites
Before integrating Card Mode: Crypto Backed, the Partner must have:
An Account Mode chosen and operational (External Wallet Access or Managed Custody).
KYB (Know Your Business) completed with UR. UR requires KYB before it provisions your Prefund Account.
The ability to make an initial USDC off-ramp into the Prefund Account to seed card spending capacity.
The ability to schedule recurring off-ramp calls that top up the Prefund Account on a supported chain.
The ability to respond to the Card Authorization callback within 500 ms with valid Partner Auth signatures.
The ability to reliably debit user crypto after the swipe is approved, typically via a smart contract wallet under the Partner's programmatic control, or centralized custody, so the user cannot move the crypto between approval and debit. UR does not enforce this on the Partner's behalf.
Operational tolerance for working-float management; if the Prefund Account drains below the minimum balance, authorizations begin to decline.
2. API foundation
This document inherits the API foundation defined in the Account Mode reference: base URLs, Partner Auth (EIP-191) headers, response envelope, idempotency rules. See:
Managed Custody Partners → API Reference: Managed Custody Mode §2
External Wallet Access Partners → API Reference: External Wallet Access Mode
Two header-block shorthands are used below:
Partner-Scoped Partner Auth Headers:
X-Api-Signature+X-Api-Deadline+X-Api-PublicKey, no user identity. Used for Prefund Account endpoints (§3).
3. Prefund Account
Scope: Partner-scoped (not user-scoped). One Prefund Account per Partner, regardless of how many users the Partner has onboarded. A single Prefund Account can hold a balance in more than one settlement currency.
3.1 What the Prefund Account is
The Prefund Account is a Partner-level operational funding account used to settle card swipes that the Partner approves with decision: APPROVE. The Partner funds it; UR debits it during card settlement; the Partner asynchronously debits the user's crypto to replenish its own books.
It is not:
A user balance; users cannot see it, cannot deposit to it, and cannot withdraw from it.
A real-time authorization gate the Partner queries per swipe. Use it for operational monitoring only; UR performs Prefund availability checks inside the Card Authorization flow (§4).
3.2 Funding the Prefund Account
You fund the Prefund Account yourself, by calling the UR off-ramp contract with your Prefund Account as the off-ramp target account. UR does not run an operator-mediated deposit step, and there is no separate deposit address to send crypto to.
Currently supported:
Off-ramp USDC on supported chains: call the off-ramp contract with USDC on any UR Supported Chain. USDC is the only deposit currency today.
Settlement currency: the currency your Prefund Account is held in, on Mantle, as a tokenized fiat balance. It defaults to
USD. To use a different settlement currency, agree it with UR before onboarding; the settlement currency you pick affects your off-ramp pricing.Minimum balance: agreed with UR during onboarding, per settlement currency. UR emits
prefund.balance.alert(§5.5) when a currency's balance reaches or falls below its threshold.
Operational constraints:
Off-ramp to your own Prefund Account, never to a user account. Confirm your Prefund Account details with UR before your first production top-up, and use them as the off-ramp target account.
Maintain a buffer above the minimum balance. Each
prefund.balance.alertindicates the Partner is now exposed to authorization decline risk on the next swipe. Plan top-up SLA accordingly.
3.3 Get Prefund balance
Method
GET
Path
/api/fma/v1/prefund-balance
Headers
Partner-Scoped Partner Auth Headers
This endpoint is partner-scoped, not user-scoped. It returns the current state of the Partner's Prefund Account.
Request body: none. Query parameters: none.
Response example:
The response is a flat, single-currency object describing the Prefund Account's settlement currency (defaults to USD):
Response fields:
partnerId
Partner identifier registered with UR.
account
On-chain address of the Prefund Account (Mantle).
currency
The settlement currency, agreed with UR (defaults to USD, see §3.2).
balance
Current balance, decimal string.
minBalance
Minimum balance threshold. prefund.balance.alert fires when the balance reaches or falls below it.
level
Balance level relative to minBalance. This endpoint emits "normal" (balance > minBalance) or "warning" (balance ≤ minBalance) only.
allowance
The card-spend contract allowance for this account, as a human-readable amount.
updatedAt
Unix seconds, last balance update.
This endpoint returns a single currency and does not include a
settleModefield. Record your configured settlement mode from onboarding; it is not read back from this response.
Usage recommendations:
Polling cadence: operational dashboard cadence, e.g. no more frequently than once per minute unless UR advises otherwise.
Authoritative source: treat this endpoint as the source of truth for
balanceandminBalance. Webhook payloads are eventually consistent.Reactive pattern: use
prefund.balance.alert(§5.5) as a passive trigger; call this endpoint to confirm current state before initiating a top-up.Not for authorization decisions: do not call this endpoint from inside the Card Authorization callback (§4). UR already performs Prefund availability checks before approving. Adding a Partner-side check increases your 500 ms callback latency for no benefit.
4. Card authorization callback (UR → Partner)
Scope: Required only for Card Mode: Crypto Backed. Card Mode: Fiat Only Partners are not in the authorization path at all.
When the user taps the card, UR synchronously calls a Partner-hosted authorization endpoint. The Partner returns an approval decision and the currency to settle in; UR then performs final balance, limit, compliance, and Prefund checks before responding to Mastercard.
4.1 Settlement modes
Partners configure one of two settlement modes during onboarding. The mode determines what UR sends in the authorization request and what the Partner is expected to return.
Mode
settleMode
Description
Fixed
fixed (default)
UR pre-computes the exact amount it will debit from the Prefund Account, in the Partner's configured settlement currency, including FX spread and interchange. UR sends that amount in the settlement field of the authorization request. The Partner approves or declines against that pre-calculated amount, and does not choose the debit currency.
Partner Controlled
partner_controlled
The Partner chooses which Prefund settlement currency to debit on each swipe. UR sends the raw Mastercard transaction and settlement details, and the Partner returns the chosen currency in paidCurrency. Because UR does not know the currency in advance, it cannot pre-compute the debit amount; the Partner sizes it.
Fixed mode is designed for Partners who hold a single-currency Prefund Account and want UR to handle all FX conversion. The Partner does not need to perform any currency conversion; the settlement.amount in the request is the exact amount that will be debited from the Prefund Account.
4.2 Endpoint contract
The Partner hosts an endpoint at a URL registered with UR during onboarding (e.g. https://api.partner.example/ur/card-authorizations). UR calls it on every card authorization for users whose accounts are configured with Card Mode: Crypto Backed.
Method
POST
Path
Partner-hosted (registered with UR during onboarding)
Direction
UR → Partner
Auth
Mutual EIP-191: UR signs the request body; Partner signs the response body. Both parties verify the other's signature against pinned addresses.
Latency budget
≤ 500 ms Partner response time. The Partner's 500 ms sits inside UR's 1 s total authorization window; UR uses the remaining ~500 ms for internal checks.
Failure mode
Timeout / 5xx / signature-verification failure / invalid response → UR treats as DECLINE for this swipe.
The Partner's authorization endpoint should be low-latency, idempotent, auditable, and fail-safe. Treat the 500 ms budget as a hard ceiling; design for p99 well under it.
4.3 Flow
4.4 Request signing (UR → Partner)
UR signs every authorization request body with EIP-191 using UR's server private key. The signature and signer address are sent in HTTP headers:
X-Api-Signature
EIP-191 signature over the raw JSON request body (0x-prefixed hex, 65 bytes).
X-Api-PublicKey
UR's signer Ethereum address. The Partner must verify this matches the address pinned during onboarding.
X-Request-Id
Matches data.requestId in the body. Convenience header for logging.
Verification: recover the signer address from EIP191(body) using X-Api-Signature, then assert it equals the pinned UR public key. Reject if it doesn't match.
4.5 Request body (UR → Partner)
Field reference:
event
string
Always "card_authorization".
timestamp
number
Unix seconds when the request was built.
data.version
string
Protocol version. Currently "1".
data.requestId
string
UR-generated idempotency key. The Partner must echo this back in the response and respond identically to retries with the same requestId.
data.expiresAt
number
Unix milliseconds. The Partner should reject requests where expiresAt < now.
data.action
string
"AUTHORIZE" for initial authorization, "INCREMENT" for an incremental auth on the same transaction.
data.partnerId
string
Partner identifier.
data.userId
string
User's UR ID.
data.authorizationToken
string
Card network authorization token.
data.transaction.currency
string
Merchant's transaction currency (ISO 4217 alpha code, e.g. "SGD").
data.transaction.amount
string
Transaction amount in the transaction currency (integer string in the token's smallest unit).
data.settlement.currency
string
Settlement currency symbol (e.g. "USD", "EUR"). In fixed mode, this is always the Partner's configured settleCurrency. In partner_controlled mode, this is the Mastercard network settlement currency.
data.settlement.amount
string
Settlement amount. Its meaning depends on your settleMode; read it accordingly. In fixed mode, this is the pre-computed Prefund debit amount, including FX spread and interchange. It is the exact amount UR debits from your Prefund Account if you approve, so you can check it against your balance directly. In partner_controlled mode, this is the Mastercard network settlement amount. It is not your Prefund debit; UR applies FX and interchange at execution, so convert it yourself before you size the debit.
data.merchant.*
object
Merchant details from the card network.
4.6 Response body (Partner → UR)
The Partner must sign the response body with EIP-191 and include signature headers:
X-Api-Signature
EIP-191 signature over body + " " + deadline (the response body bytes, a space, and the deadline string).
X-Api-Deadline
Unix seconds expiry for the response signature (e.g. 60 s from now).
X-Api-PublicKey
Partner's signer Ethereum address.
Approval:
Decline:
Pass (fall back to user's own balance):
Response field reference:
requestId
Yes
Must match data.requestId from the request. UR rejects mismatches.
decisionId
Yes
Partner-generated unique ID for this decision. Used for audit trail and reconciliation.
decision
Yes
"APPROVE", "DECLINE", or "PASS". Any other value is treated as an error (UR declines).
paidCurrency
On APPROVE
The currency to debit from the funding source that decision selected (ISO symbol, e.g. "USD", "EUR"). On APPROVE, it names a currency in your Prefund Account. On PASS, it names a currency in the user's UR fiat balance; leave it empty to let UR select the currency for you. Not used on DECLINE. See the mode tables in §4.6 examples for every valid combination.
Decision semantics
decision
Effect
APPROVE
Settle against the Prefund Account in paidCurrency. UR still performs final checks and may override to DECLINE.
DECLINE
Reject the authorization entirely. The card swipe is declined.
PASS
Skip double booking for this swipe. UR falls back to the user's own UR fiat balance; the swipe behaves as if the user were on Card Mode: Fiat Only. No Prefund debit occurs; no Partner-side crypto debit is needed.
PASS is useful when the Partner wants to selectively route certain transactions to the user's own balance; for example, small transactions below a threshold, or when the user has sufficient fiat balance and the Partner prefers not to consume Prefund capacity.
Important behavior:
UR retains final authority: even after an
APPROVE, UR performs balance / limit / compliance / Prefund availability checks and can still decline.Increment consistency: for
action: INCREMENT, the Partner must return the samedecisionandpaidCurrencyas the originalAUTHORIZEfor the same transaction. UR rejects currency changes mid-transaction. If the original wasPASS, the increment must also bePASS.Fixed mode simplification: in fixed mode, the
settlement.amountin the request already includes FX fees. The Partner only needs to check if the Prefund Account can absorb that amount and approve or decline.PASSis also available in fixed mode if the Partner wants to route specific transactions to the user's balance.
Examples by settlement mode
Your settleMode changes only what you may return on APPROVE. PASS and DECLINE behave identically in both modes. The following tables list every valid combination.
Fixed mode. UR pre-computes the debit, so you never run a currency conversion:
decision
paidCurrency
What UR does
APPROVE
Equal to settlement.currency from the request
Debits settlement.amount from your Prefund Account. That amount already includes FX spread and interchange.
APPROVE
Any other currency
Declines the swipe. In fixed mode you cannot choose the debit currency.
APPROVE
Empty
Declines the swipe. paidCurrency is required on APPROVE.
PASS
Empty
Settles from the user's UR fiat balance and selects the currency for you. Your Prefund Account is untouched.
PASS
A currency the user holds
Settles from that currency of the user's UR fiat balance. Declines if that balance is short.
DECLINE
Empty
Declines the swipe.
Partner controlled mode. You choose the Prefund currency, so UR cannot pre-compute the debit:
decision
paidCurrency
What UR does
APPROVE
Any currency your Prefund Account holds
Debits that currency from your Prefund Account. UR applies FX spread and interchange at execution.
APPROVE
A currency your Prefund Account does not hold
Declines the swipe.
APPROVE
Empty
Declines the swipe. paidCurrency is required on APPROVE.
PASS
Empty
Settles from the user's UR fiat balance and selects the currency for you. Your Prefund Account is untouched.
PASS
A currency the user holds
Settles from that currency of the user's UR fiat balance. Declines if that balance is short.
DECLINE
Empty
Declines the swipe.
4.7 Fail-safe semantics
UR treats the following as DECLINE (the Partner's authorization endpoint is considered unavailable):
HTTP timeout (no response within 500 ms)
Decline with internal reason partner_timeout
HTTP 5xx
Decline with internal reason partner_5xx
HTTP 4xx
Decline with internal reason partner_4xx (likely Partner config error; investigate)
Invalid or missing signature on response
Decline with internal reason partner_sig_invalid
requestId mismatch
Decline with internal reason partner_invalid_response
Missing decisionId
Decline with internal reason partner_invalid_response
Invalid decision value
Decline with internal reason partner_invalid_response
decision: APPROVE but paidCurrency missing
Decline with internal reason partner_invalid_response
Unsupported paidCurrency
Decline with internal reason partner_invalid_response
Response body exceeds 64 KB
Decline with internal reason partner_invalid_response
Partner signature deadline expired or too far in the future (> 5 min)
Decline with internal reason partner_sig_invalid
UR exposes the internal decline reason on the post-swipe transaction webhook (§5.4) for reconciliation.
Operational note on the authorization URL. The Partner-hosted authorization URL is registered with UR during onboarding. To update it (e.g. environment migration), coordinate the change with UR; there is no self-serve endpoint for this.
4.8 Recommended reason codes
For Partners who include a
reasonfield in their response (optional, for reconciliation/analytics).
reason
When to use
ok
Approve.
insufficient_user_crypto
User does not have enough crypto on the Partner side.
insufficient_partner_prefund
Partner's Prefund Account is too low.
user_blocked
Partner-side compliance block.
merchant_blocked
Partner-side MCC / merchant block.
card_disabled
Card is locked or frozen on the Partner side.
internal_error
Catch-all decline; treat as transient.
4.9 Fixed mode: FX quote details
In fixed mode, UR pre-calculates the settlement.amount using on-chain FX rates from the card authorization contract. The calculation mirrors the contract's actual debit logic to ensure the quoted amount matches the on-chain settlement:
Same-currency (e.g. Prefund is USD, settlement is USD):
settlement.amount= network settlement amount, no FX.Cross-currency (e.g. Prefund is EUR, settlement is USD): UR calls the contract's
getRateandgetSpreadview functions to compute the exact amount including FX spread and interchange fees.
The quoted amount is deterministic at the time of the authorization request. Between the quote and the on-chain settlement (typically < 1 second), exchange rates may shift marginally. This is operationally acceptable for the card authorization use case.
Partners in fixed mode do not need to perform any FX calculation; the settlement.amount is ready to use for balance checks and ledger entries.
5. Card Mode webhooks
UR delivers Card Mode events via the standard webhook envelope. The Partner must verify every webhook signature before acting on it.
5.1 Webhook envelope
5.2 Signature verification
UR signs webhook bodies with EIP-191. Verification steps:
Read the exact raw request body string (do not re-serialize).
Recover the signer address using the body and
X-Api-Signature.Accept the event only if the signer address matches the UR public key provided out of band.
See Signature and Verification for the canonical recovery algorithm.
5.3 Retry and idempotency
The Partner should return
HTTP 200within 10 seconds.UR retries non-200 / timed-out webhook deliveries up to 3 times, with a 5-minute interval.
Use
data.idas the idempotency key for card paymenttransaction_v2events.
5.4 Card payment transaction (event: "transaction_v2")
UR sends transaction_v2 when a card payment transaction reaches a terminal state. Card payment records use data.type = "MARQETA_AUTHORIZE". The same event covers successful and failed card payments.
Confirmed payment example:
Failed payment example:
Key fields for Crypto Backed reconciliation:
id
UR transaction record ID. Use this field as the idempotency key for transaction_v2 delivery.
type
Card payment transactions use MARQETA_AUTHORIZE.
status
Terminal transaction status, such as CONFIRMED or FAILED.
direction
OUT for card spend.
amount / currency
Amount and currency recorded on the transaction row.
txHash
On-chain transaction hash when available.
detailsJson
Stringified JSON with card payment details. Parse this value before reading nested fields.
detailsJson may include the following card payment fields:
authorizationId
Card authorization identifier.
balance
Balance value recorded with the card payment.
cardCurrency
Card currency.
cardId
Card identifier.
city
Merchant city.
country
Merchant country.
mcc
Merchant category code.
merchant
Merchant display name.
merchantId
Merchant identifier.
settlementAmount
Settlement amount recorded for the card payment.
settlementCurrency
Settlement currency recorded for the card payment.
transactionAmount
Merchant transaction amount.
transactionCurrency
Merchant transaction currency.
reason
Failure reason. This field appears only when the card payment record includes a reason.
Partner crypto-debit responsibility. When a Crypto Backed card payment succeeds, the partner is responsible for computing and debiting the corresponding user crypto amount in its own system. UR reports the card payment transaction data; UR does not move user crypto on the partner's behalf.
Use transaction_v2 records with data.type = "MARQETA_AUTHORIZE" and data.status = "FAILED" for failed card payments. The failure reason is in detailsJson.reason when UR has one.
5.5 Prefund balance alert (event: "prefund.balance.alert")
UR emits prefund.balance.alert when the balance of one settlement currency in your Prefund Account crosses a threshold. Use it as a passive trigger to top up before authorizations start to decline.
The alert is per currency, not per account. If two currencies cross a threshold, UR sends two events.
Example:
Fields:
partnerId
Partner identifier registered with UR.
account
On-chain address of the Prefund Account (Mantle).
currency
The settlement currency this alert is about.
balance
Balance in that currency at the moment the level changed.
minBalance
The threshold configured for that currency.
previousLevel
The level before this change.
level
The level after this change: "normal", "warning", or "critical".
updatedAt
Unix seconds, the balance update that triggered the alert.
When UR sends it. The alert is edge-triggered: UR sends it only when level changes for a currency, not repeatedly while the balance sits below the threshold. You therefore receive an alert on the way down (normal to warning, warning to critical) and again on recovery (back to normal), and nothing in between.
How to handle it:
Treat the alert as a trigger, not as truth. Call Get Prefund balance to confirm the current state before you top up; webhook payloads are eventually consistent.
Top up that currency. A
warningon one currency says nothing about the others.Idempotency key:
account+currency+updatedAt. Retry and delivery semantics follow §5.3.A
criticallevel means the next swipe in that currency is at real risk of declining. Treat it as a page, not a ticket.
6. Implementation checklist
Before going live with Card Mode: Crypto Backed:
Prefund operations
Confirm the off-ramp chain, the deposit currency, your settlement currency, and the minimum balance (all agreed during onboarding).
Confirm your Prefund Account details with UR, and use them as the off-ramp target account.
Implement recurring off-ramp automation with an SLA aligned to your minimum-balance buffer.
Build an operational dashboard that polls
GET /prefund-balanceand surfacesleveltransitions.Subscribe to
prefund.balance.alert(§5.5) and route it to your ops channel. Alerts are per currency.
Card Authorization callback
Host the authorization endpoint at the URL registered with UR (see the operational note in §4.7).
Verify every inbound request's EIP-191 signature against UR's public key before doing any business logic.
Implement the handler with a p99 < 500 ms budget. Pre-compute everything you can; avoid cross-region database calls in the hot path.
Decide
decisiondeterministically. ReturnAPPROVEto settle from your Prefund Account,PASSto fall back to the user's own UR fiat balance, orDECLINEto reject the swipe. See Examples by settlement mode for every validdecisionandpaidCurrencycombination.Make the handler idempotent on
requestId. UR may retry on transient network errors, and you must return the same decision for the samerequestId.Build a fail-safe path: if any internal dependency fails, return
decision: "DECLINE"with areasonrather than a 5xx. UR treats a 5xx as a decline anyway, but an explicit decline preserves thereasonfor reconciliation.
Post-swipe + reconciliation
Subscribe to the
transaction_v2webhook (§5.4) and verify its signature.When you returned
APPROVEand the swipe settled against your Prefund Account, perform the user-side crypto debit once thetransaction_v2webhook reportsstatus: CONFIRMED. Record it against the samerequestId.Handle the override case: you returned
decision: APPROVE, but UR still declined the swipe. Clean up any speculative Partner-side state.Decide your refund policy and document it for end users.
Operational
Treat webhook delivery as at-least-once and implement idempotency on
data.id(transactions) andaccount + currency + updatedAt(Prefund alerts).Maintain monitoring on Partner-side authorization handler latency, success rate, and decline reason distribution.
7. Reference docs
Integration Guide: Account Mode × Card Mode framing.
API Reference: Managed Custody Mode: common card endpoints (Create Card, Get Card Info, Set Default Currency, history) and the Account Mode this plugs into.
API Reference: External Wallet Access Mode: the alternative Account Mode this can pair with.
Signature and Verification: EIP-191 signing and verification for Partner Auth and webhook signatures.
Last updated