API reference: 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 (daily / weekly / on-alert)
Partner tops up crypto into UR's prefund address. UR Ops converts to fiat and credits the Partner's Prefund Account.
2. Card spend
User (tap)
Real-time
Mastercard routes the auth to UR → UR calls Partner webhook → Partner returns approve + source → UR settles against Prefund Account (CRYPTO path) or user's UR fiat balance (FIAT path) → after Mastercard finalizes, UR sends a post-swipe webhook to the Partner → Partner debits user crypto.
The Prefund Account exists to absorb real-time card authorizations: Partners cannot bridge user crypto fast enough to meet Mastercard's 1.5 s 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).
The ability to make an initial crypto prefund to seed card spending capacity.
The ability to schedule periodic crypto top-ups to UR's prefund address 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.
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 has marked as sourceUsed: CRYPTO. 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
Currently supported:
Prefund USDC on supported chains: You can deposit USDC on any UR Supported Chains
Settlement currency:
USD— the Prefund Account is held on Mantle as aUSD-denominated tokenized fiat balance.Minimum balance: agreed with UR during onboarding. UR emits
prefund.balance.alert(§5.5) whenbalance ≤ minBalance.
Operational constraints:
Confirm the deposit address with UR before every production funding setup. UR may rotate addresses; sending to a stale address can result in funds being held in operations.
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:
Response fields:
partnerId
Partner identifier registered with UR.
account
On-chain address of the Prefund Account (Mantle).
currency
Prefund settlement currency: USD (see §3.2).
balance
Current balance in settlement currency, decimal string.
minBalance
Minimum balance threshold; prefund.balance.alert fires at or below this value.
level
"normal" | "warning" (≤ minBalance) | "critical" (severely below minBalance).
updatedAt
Unix seconds, last balance update.
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 a settlement-source recommendation; UR then performs final balance, limit, compliance, and Prefund checks before responding to Mastercard.
4.1 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
UR-Signed Inbound (EIP-191; verify against UR's public key)
Latency budget
≤ 500 ms Partner response time. UR allocates the remaining ~1 s for internal checks within Mastercard's ~1.5 s authorization window.
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.2 Flow
4.3 Request Body (UR → Partner)
UR sends the following JSON body when calling the Partner's authorization endpoint:
Field reference:
eventId
string
UR-generated idempotency key for this authorization attempt. The Partner must respond identically to retries with the same eventId.
urId
number
User's URID.
externalUserId
string
Partner's user ID mapped during onboarding.
amount
string (decimal)
Authorization amount, denominated in currency.
currency
string (ISO 4217)
Transaction currency requested by the merchant.
merchant.name
string
Merchant name from the Mastercard message.
merchant.mcc
number
Merchant category code.
merchant.country
string (ISO 3166-1 alpha-2)
Merchant country.
cardTokenId
string
UR token ID identifying the card.
timestamp
number
Unix seconds when UR received the authorization from Mastercard.
4.4 Response Body (Partner → UR)
The Partner returns one of two response shapes.
Approval:
Decline:
Response field reference:
approve
Yes
true to approve, false to decline.
sourceUsed
On approve
"CRYPTO" → settle via the Prefund Account (Partner will debit user crypto post-swipe). "FIAT" → settle from the user's UR fiat balance directly.
settleCurrency
On approve
Fiat ISO code for the settlement currency. For sourceUsed: CRYPTO, this must be USD (the Prefund Account currency; see §3.2). For sourceUsed: FIAT, this must be a currency the user holds in their UR fiat balance.
Important behavior:
The Partner decides only
approve+sourceUsed+settleCurrency+reason. UR retains final authority — UR still performs balance / limit / compliance / Prefund availability checks after the Partner response and can decline an approved swipe if any of those fail.The Partner cannot use
sourceUsed: CRYPTOto overdraft the Prefund Account — UR's Prefund availability check will decline if the swipe would take the Prefund Account below operational minimums.If the Partner responds with
sourceUsed: FIAT, the swipe behaves exactly like a Card Mode: Fiat Only swipe — UR debits the user's tokenized fiat balance directly, and no post-swipe Partner crypto debit is required.
4.5 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 signature on response
Decline with internal reason partner_sig_invalid
Response body fails schema validation
Decline with internal reason partner_invalid_response
Partner returns approve: true but sourceUsed is missing or unknown
Decline with internal reason partner_invalid_source
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. UR will reject calls that fail signature verification, so URL changes must be paired with key/cert validation on the Partner side.
4.6 Recommended reason Codes
reason CodesThe reason field is a free-form short code used for reconciliation and analytics. UR recommends the following standard set; Partners may add custom codes for internal categorization but should not overload the standard codes' meanings.
reason
When to use
ok
Approve (approve: true).
insufficient_user_crypto
User does not have enough crypto on the Partner side to cover a CRYPTO settlement.
insufficient_partner_prefund
Partner's Prefund Account is too low to safely cover this swipe. (UR will also decline on its own check; this code is for Partner-side optimization.)
insufficient_user_fiat
User has insufficient tokenized fiat for a FIAT settlement.
user_blocked
Partner-side compliance block on this user.
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.
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.txHashordata.id(for transaction events) anddata.account+data.updatedAt(for Prefund alerts) as idempotency keys.
5.4 Transaction Event — Post-Swipe (event: "transaction", data.type: "CRD")
event: "transaction", data.type: "CRD")This is the follow-up that closes the loop after the Card Authorization callback (§4). It carries the final settlement state of the swipe — including any UR-side decline that overrode the Partner's approve: true response.
Payload example:
Key fields for Crypto Backed reconciliation:
eventId
The same eventId UR sent in the Card Authorization callback (§4.3) — primary idempotency key.
status
"completed" | "declined" | "reversed".
sourceUsed
The actual source UR used. For declines, may be null.
settleCurrency / settleAmount
The settlement currency UR booked the swipe in, and the amount in that currency (after FX from amount / currency). For sourceUsed: CRYPTO, this is the Prefund Account debit amount; the Partner should use it to compute how much crypto to debit from the user.
declineReason
Populated when status: "declined". Values include UR-internal decline codes (partner_timeout, insufficient_prefund, etc.) and Partner-supplied reason from §4.6.
Partner crypto-debit responsibility. When status: completed and sourceUsed: CRYPTO, the Partner is responsible for:
Computing the crypto amount to debit from the user based on its own pricing / conversion logic. UR reports the fiat
settleAmount; UR does not prescribe the crypto-to-fiat conversion rate the Partner uses.Performing the on-chain (or custody-side) crypto debit. UR does not move crypto on the Partner's behalf.
Recording the debit against the same
eventIdfor reconciliation.
How the Partner enforces the debit (smart-contract-wallet pre-authorization, centralized custody freeze + debit, etc.) is part of the Partner's own business logic and is out of scope for this document.
5.5 Prefund Balance Alert (event: "prefund.balance.alert")
event: "prefund.balance.alert")UR emits this event when the Prefund Account reaches warning conditions.
Trigger behavior:
UR sends
level = "warning"whenbalance ≤ minBalance.While the balance remains at or below
minBalance, UR may resend the alert after every Prefund debit (i.e. after every CRYPTO-path card swipe).Alerts stop after the balance returns above
minBalance.
Payload example:
Recommended handling:
Store the alert idempotently (key on
account+updatedAt).Confirm with the authoritative API — call
GET /api/fma/v1/prefund-balance(§3.3) before acting; webhook payloads are eventually consistent.Notify the Partner operations channel if
level = "warning"or"critical".Trigger top-up workflows — at
warning, schedule a top-up; atcritical, escalate.
6. Refund Handling
Any card refund is credited to the user's UR fiat balance, regardless of whether the original swipe was settled from the Prefund Account (
sourceUsed: CRYPTO) or from the user's fiat balance (sourceUsed: FIAT).
Implications for Crypto Backed Partners:
A refund for a CRYPTO-path swipe does not automatically reverse the Partner's user-side crypto debit. The Partner must decide its own policy — credit equivalent crypto back to the user, leave the fiat refund as a UR fiat balance, or surface the choice to the user.
The refund is delivered as a
transactionevent withdata.type = "CRD",direction = "IN", and aoriginalEventIdfield linking to the original swipe.
Payload sketch:
7. Implementation Checklist
Before going live with Card Mode: Crypto Backed:
Prefund operations
Confirm the deposit chain, deposit currency and the minimum balance (agreed during onboarding) for your integration.
Confirm the current production deposit address with UR.
Implement scheduled top-up automation with 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 to your ops channel.
Card Authorization callback
Host the authorization endpoint at the URL registered with UR (see operational note in §4.5).
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
sourceUseddeterministically — typically check user crypto balance first, fall back to user fiat balance, otherwise decline.Make the handler idempotent on
eventId— UR may retry on transient network errors.Build a fail-safe path: if any internal dependency fails, return
approve: falsewithreason: "internal_error"rather than 5xx — UR treats 5xx as decline anyway, but explicit declines preservereasonfor reconciliation.
Post-swipe + reconciliation
Subscribe to
transactionwebhooks (§5.4); verify signatures.For
sourceUsed: CRYPTO, status: completed, perform the user-side crypto debit and record it against the sameeventId.Handle the override case: Partner returned
approve: truebut UR returnedstatus: declined— clean up any speculative Partner-side state.Decide your refund policy (§6) and document it for end users.
Operational
Treat webhook delivery as at-least-once and implement idempotency on
eventId(transactions) andaccount + updatedAt(Prefund alerts).Maintain monitoring on Partner-side authorization handler latency, success rate, and decline reason distribution.
8. 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