# Integration Guide

## Partner Integration Flow Concepts

UR acts as the banking infrastructure layer for neobank partners. Partners integrate via a single REST API — UR handles KYC compliance, the user's UR account, and the underlying banking rails. Partners choose from a menu of modular banking services to build their product.

This page introduces the three integration dimensions a Partner needs to choose between:

1. **Account Mode** — *how* the Partner accesses the user's UR account.
2. **Card Mode** — *where* card spend draws funds from when the user taps their card.
3. **KYC Mode** — *how* the user's KYC is performed.

***

#### 1. How UR Supports a Partner

Partners connect to UR as a Banking-as-a-Service provider. UR sits between the Partner's product and the global banking rails — managing identity (URID), the user's UR account, and regulated financial services behind a clean API surface.

**Modular services partners can enable:**

* Multi-currency fiat balance (EUR, CHF, USD, SGD, HKD, JPY, RMB)
* Crypto ⇄ Fiat conversion (On-ramp / Off-ramp)
* Fiat ⇄ Fiat conversion (FX)
* Fiat Pay-in via bank transfer (SEPA / SWIFT)
* Fiat Payout via bank transfer (SEPA / SWIFT)
* Card spending via co-branded Mastercard debit

```mermaid
flowchart TD
    User(["End User"]) -->|Uses| App

    subgraph Partner["Partner Platform"]
        App["Partner App & UX"]
        Backend["Partner Backend"]
        App --> Backend
    end

    Backend -->|REST API| UR

    subgraph UR["UR — Banking Infrastructure"]
        KYC["KYC & Compliance\nAll users verified by UR\nPartners may assist data collection"]

        subgraph Services["Modular Banking Services"]
            direction LR
            Bal["Multi-Currency\nFiat Balance"]
            Conv["On-ramp / Off-ramp / FX"]
            PayIn["Fiat Pay-in"]
            PayOut["Fiat Payout"]
            Cards["Card Spending \n (Co-branded Mastercard)"]
        end

        KYC -->|"User verified — Live"| Services
    end

    subgraph Rails["Banking Rails  (managed by UR)"]
        direction LR
        SEPA["SEPA · SWIFT\nGlobal Transfers"]
        MC["Mastercard Network\nGlobal Acceptance"]
    end

    PayIn <--> SEPA
    PayOut <--> SEPA
    Cards <--> MC
```

***

#### 2. Account Mode — How the Partner Accesses the User's UR Account

In the Partner's system, every user who registered UR has a UR Account, anchored by their URID (an identity NFT on Mantle) and holding the user's tokenized fiat balances. The Account Mode determines whether the user's UR Account is held in a UR-managed wallet, or reuses a wallet the user already has on the Partner platform.

UR supports two Account Modes:

**2.1 External Wallet Access Mode**

The user brings their own wallet — this can be a wallet the user already controls (e.g. MetaMask, Rabby, a smart contract wallet) or a non-custodial wallet that the Partner itself provisions for its users. The URID NFT and the user's fiat token balances live directly inside that external wallet — **no UR-managed wallet is provisioned**.

* **Signing model** — the user signs every banking action with their own wallet (or via EIP-2612 / EIP-712 permits when gasless execution is needed).
* **Onboarding** — the user signs a message to prove wallet ownership; URID is minted to the user's wallet address.
* **Best for** — Web3-native products where users already manage their own keys (DeFi platforms, on-chain wallets, dApp ecosystems).

```mermaid
flowchart LR

  subgraph PartnerScope["Partner Platform"]
    PFE["Partner Frontend / DApp"]
    PBE["Partner Backend"]
  end

  subgraph UserScope["User"]
    ActorUser(("User"))
    UW["External Wallet"]
  end

  subgraph URScope["UR Backend"]
    API["Partner API"]
    VAL["Quote Service / Compliance Engine"]
    WH["Event Listener / Webhooks"]
  end

  subgraph ContractScope["UR Onchain Settlement"]
    SC["Offramp / Onramp / FX / Payin & Payout"]
    UA["Fiat Balance"]
  end

  ActorUser -- Controls --> UW
  UW -- Connects to --> PFE

  PFE -- "1. Request Action" --> PBE
  PBE -- "2. Get Quote / Params" --> API
  API --> VAL
  VAL -- "3. Return Tx Data" --> PBE
  PBE -- "4. Pass Data" --> PFE

  PFE -- "5. Request Signature" --> UW
  UW -- "6. Sign & Submit Tx" --> SC
  SC --> UA

  SC -.-> WH
  WH -. "7. Notify Status" .-> PBE
```

**→ API reference:** [External Wallet Access Mode](/developer-resources/api-reference-external-wallet-access-mode.md) — user-signed REST flows. Common entry points: [Signature & Verify](https://docs.ur.app/getting-started/pages/yEG7tyYvgaB42helZKpJ#id-1.2-signature-and-verify), [MINT URID](https://docs.ur.app/getting-started/pages/yEG7tyYvgaB42helZKpJ#id-2.1.4-mint-create-users-urid), [Off-ramp](/developer-resources/api-reference-external-wallet-access-mode.md#id-4-offramp), [On-ramp](/developer-resources/api-reference-external-wallet-access-mode.md#id-5-onramp), [Bank Transfer](/developer-resources/api-reference-external-wallet-access-mode.md#id-6-bank-transfer), [FX](/developer-resources/api-reference-external-wallet-access-mode.md#id-7-fx), [Card](/developer-resources/api-reference-external-wallet-access-mode.md#id-3-card).

**2.2 Managed Custody Mode**

The Partner accesses the user's UR account **entirely through REST APIs**. UR provides the underlying account infrastructure — wallet security, signing, gas, and on-chain settlement — so neither the user nor the Partner needs to sign any blockchain transactions for routine banking operations.

The user's UR account remains a **fully isolated UR account** with its own URID, IBAN, and balance — separate from any other Partner's user accounts. Access to that account is governed by the Partner's authenticated API key and UR's compliance / risk engine.

* **Signing model** — Partner backend authenticates with a signed REST API call (API key + Ethereum signature on every request). UR validates the request, runs compliance / risk / limit checks, and executes the on-chain operation. The user is not prompted to sign on-chain transactions for routine banking actions.
* **Onboarding** — Partner backend submits the user's KYC bundle via API. URID is minted into a UR-managed embedded wallet.
* **User experience** — the Partner owns the entire UX surface.
* **Best for** — consumer fintechs, exchanges, smart wallets, and neobanks that want to consolidate banking capabilities behind their own product.

```mermaid
flowchart LR

  subgraph Partner["Partner Platform"]
    PFE["Partner Frontend"]
    PBE["Partner Backend"]
  end

  subgraph UR["UR Backend"]
    API["UR API Service"]
    VAL["Quote Service & Compliance Engine"]
    OP["UR Operation Service"]
    WH["Webhook Dispatcher"]
  end


  subgraph ContractScope["UR Onchain Settlement"]
    SC["Offramp / Onramp / FX / Payin & Payout"]
    UA["Fiat Balance"]
  end


  PFE --> PBE
  PBE -- "1. API call" --> API
  API --> VAL --> OP
  OP -- "2. Check quote & submit on-chain op" --> SC
  SC --> UA
  WH -. "3. Lifecycle events" .-> PBE
```

**→ API reference:** [Managed Custody Mode](/developer-resources/api-reference-managed-custody-mode.md) — Partner-signed REST flows (EIP-191). Common entry points: [Partner Auth (EIP-191)](https://docs.ur.app/getting-started/pages/vKjz7ekaylj2VXHMZtAb#id-2.2-authentication-partner-auth-eip-191), [Get BR Profile](https://docs.ur.app/getting-started/pages/vKjz7ekaylj2VXHMZtAb#id-4.1-get-br-profile), [Off-ramp](/developer-resources/api-reference-managed-custody-mode.md#id-6-off-ramp), [On-ramp](/developer-resources/api-reference-managed-custody-mode.md#id-9-on-ramp), [Bank Payout](/developer-resources/api-reference-managed-custody-mode.md#id-8-bank-payout), [FX](/developer-resources/api-reference-managed-custody-mode.md#id-7-fx), [Card](/developer-resources/api-reference-managed-custody-mode.md#id-10-card), [Webhooks](/developer-resources/api-reference-managed-custody-mode.md#id-12-webhooks).

**2.3 Quick Comparison**

| Dimension                   | External Wallet Access Mode                        | Managed Custody Mode                  |
| --------------------------- | -------------------------------------------------- | ------------------------------------- |
| Wallet location             | User's own external wallet                         | UR-managed embedded wallet            |
| Signing for banking actions | User signs each action / permit                    | Partner backend signs REST API calls  |
| Best fit                    | Web3-native products and external wallet providers | Consumer fintech / exchange / neobank |

***

#### 3. Card Mode — Where Card Spend Draws Funds From

After choosing an Account Mode, Partners separately choose a **Card Mode** for their co-branded debit card. The Card Mode answers a single question: when the user taps their card, **which balance is debited**?

**3.1 Card Mode: Fiat Only**

> The card draws exclusively from the user's UR fiat balance.

Card spend is booked against the user's existing UR fiat balance. The user funds that balance through any of the standard channels: bank pay-in, crypto off-ramp into UR, or transfers from another UR user. No Partner-side prefund pool is required.

If the user wants to spend crypto, they first **off-ramp** crypto into their UR fiat balance, then tap the card. The off-ramp and the card swipe are two separate operations.

**Step 1 — Optional: Off-ramp (user-initiated, only if the user is starting from crypto)**

The user converts crypto to fiat. UR executes the conversion at a quoted rate and credits the user's UR fiat balance.

**Step 2 — Card swipe**

The user taps their card. UR authorizes against the available UR fiat balance.

**User experience** — if the user already holds fiat in UR, the swipe is one tap. If they're starting from crypto, they need to off-ramp first.

```mermaid
sequenceDiagram
    participant User as End User
    participant Partner as Partner Platform
    participant UR as UR
    participant MC as Mastercard Network
    participant Merchant

    Note over User, UR: Step 1 — Optional: Convert crypto to fiat (only if needed)
    User->>Partner: Initiate off-ramp (e.g. 500 USDC)
    Partner->>UR: Request conversion quote (USDC → EUR)
    UR-->>Partner: Quote returned (e.g. €431 · valid 30s)
    User->>Partner: Confirm
    Partner->>UR: Execute conversion
    UR-->>User: €431 credited to UR fiat balance

    Note over User, Merchant: Step 2 — Card spending (draws from UR fiat balance)
    User->>Merchant: Tap UR co-branded card
    Merchant->>MC: Authorization request
    MC->>UR: Route: Authorize €50?
    UR->>UR: Verify user fiat balance
    UR-->>MC: Approved
    MC-->>Merchant: Transaction complete
```

**→ API reference:** No additional Partner-side integration surface — UR handles authorization on-chain against the user's tokenized fiat balance. Use the standard Card endpoints in your Account Mode reference ([External Wallet Access](/developer-resources/api-reference-external-wallet-access-mode.md#id-3-card) or [Managed Custody](/developer-resources/api-reference-managed-custody-mode.md#id-10-card)).

**3.2 Card Mode: Crypto Backed**

> The card can settle directly against the user's crypto holdings, with no per-swipe off-ramp required.

This mode is for Partners whose product requires that users be able to spend their crypto directly via the card, without having to manually off-ramp into fiat before each purchase. The Partner does not have to custody the user's crypto for this to work — what matters is that the Partner can reliably debit the user's crypto after a swipe is approved (this can be achieved through centralized custody, a smart contract wallet under the Partner's programmatic control, or any equivalent arrangement).

The mechanism is a **Buffer Pool** (also called the *Prefund channel*): the Partner periodically tops up USDC into a UR-side prefund pool, and card authorizations are settled in real time from that prefunded balance. The Partner then debits the user's crypto asynchronously after the swipe — using UR's swipe-result webhook as the trigger. UR only reports the fiat swipe amount; the Partner decides, based on its own pricing and conversion logic, how much crypto to debit from the user.

**Phase 1 — Prefund (Partner-initiated, scheduled)**

The Partner periodically sends USDC to UR's prefund address on a supported off-ramp chain. UR off-ramps the USDC into USD and credits a Partner-scoped card-management account on UR. UR maintains a configured minimum balance to ensure continuous card authorization capacity.

**Phase 2 — Card spend (user-initiated, real-time)**

When the user taps their card, UR routes the authorization and asks the Partner — via webhook — whether to approve, and which source to use (`CRYPTO` or `FIAT`). The Partner must respond within **500 ms** so UR can return an `APPROVE` / `DECLINE` to Mastercard within the **1.5-second** authorization window.

* If the Partner returns `sourceUsed: CRYPTO` → UR books the spend against the Partner's prefunded card-management account.
* If the Partner returns `sourceUsed: FIAT` → UR books the spend against the user's UR fiat balance (same path as Card Mode: Fiat Only).

After UR returns the result to Mastercard, UR sends a follow-up webhook to the Partner. On a successful `CRYPTO` swipe, the **Partner is responsible** for debiting the equivalent crypto from the user. UR does not move crypto on the Partner's behalf — how the Partner enforces the debit is part of its own business logic, and typically relies on a smart contract wallet under the Partner's programmatic control or a centralized custody arrangement so the user cannot move the crypto between approval and debit.

**User experience** — seamless: the user just taps and pays. No manual conversion step required.

**Refund handling** — any card refund is credited to the user's UR fiat balance, regardless of whether the original spend was settled from digital assets or fiat.

```mermaid
sequenceDiagram
    participant Partner as Partner Platform
    participant UR as UR
    participant Pool as Card Prefund Account<br/>(UR Managed Fiat Account)
    participant MC as Mastercard Network
    participant Merchant

    Note over Partner, Pool: Phase 1 — Prefund (scheduled · daily / weekly)
    Partner->>UR: Send USDC to UR prefund address
    UR->>UR: Off-ramp USDC → USD
    UR-->>Pool: Credit USD to Partner-prefund fiat account
    Note over Pool: Minimum balance maintained<br/>for card spending capacity

    Note over Partner, Merchant: Phase 2 — Card spending (user-initiated)
    Merchant->>MC: Authorization request (user taps card)
    MC->>UR: Route: Authorize €X?
    UR->>Partner: Webhook: "Approve? CRYPTO or FIAT?"<br/>(respond within 500 ms)
    Partner-->>UR: APPROVE, sourceUsed: CRYPTO
    UR->>Pool: Book spend against Partner pool
    UR-->>MC: Approved (within 1.5 s window)
    MC-->>Merchant: Transaction complete
    UR->>Partner: Webhook: authorization.result
    Partner->>Partner: Debit equivalent crypto from user's wallet
```

**Partner prerequisites for Card Mode: Crypto Backed**

* Ability to make an initial USDC prefund to seed card spending capacity.
* Ability to schedule periodic USDC top-ups to UR's prefund address on a supported off-ramp chain.
* Ability to respond to the authorization webhook within 500 ms.
* Ability to reliably debit crypto from the user **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 funds between approval and debit).
* Operational tolerance for working-float management — if the Partner's pool drains below the minimum balance, authorizations begin to decline.

**→ API reference:** [Card Mode — Crypto Backed](/developer-resources/api-reference-card-mode-crypto-backed.md) — plugs into either Account Mode. Three integration surfaces: [Prefund Account](/developer-resources/api-reference-card-mode-crypto-backed.md#id-3-prefund-account), [Card Authorization Callback](/developer-resources/api-reference-card-mode-crypto-backed.md#id-4-card-authorization-callback-ur-greater-than-partner), [Card Mode Webhooks](/developer-resources/api-reference-card-mode-crypto-backed.md#id-5-card-mode-webhooks).

***

#### 4. What Partners Need to Decide Before Integration

Before integration kicks off, Partners confirm:

1. **Account Mode** — External Wallet Access or Managed Custody.
2. **Card Mode** — Fiat Only or Crypto Backed (or no card at all, if card spending is not part of the product).
3. **KYC Mode** — TBD.

Once those three are fixed, the rest of the integration is a standard menu of Core Banking APIs (Pay-in, Payout, On-ramp, Off-ramp, FX, Card) wired against the chosen modes.

**Reference docs:**

Concepts:

* [Core Banking Overview](https://github.com/mantle-xyz/ur-doc/blob/main/getting-started/core-banking-overview.md)
* [Fiat Pay-in (Bank Transfer)](https://github.com/mantle-xyz/ur-doc/blob/main/getting-started/deposits.md)
* [Fiat Payout (Bank Transfer)](https://github.com/mantle-xyz/ur-doc/blob/main/getting-started/withdrawals.md)
* [Crypto-to-Fiat Off-ramp](https://github.com/mantle-xyz/ur-doc/blob/main/getting-started/deposits.md#crypto-to-fiat-conversion-offramp)
* [Card Spending Flow](https://github.com/mantle-xyz/ur-doc/blob/main/getting-started/what-is-ur.md#the-spending-flow-from-fiat-balance-to-a-real-world-purchase)

API references:

* [External Wallet Access Mode](/developer-resources/api-reference-external-wallet-access-mode.md) — user-signed REST flows.
* [Managed Custody Mode](/developer-resources/api-reference-managed-custody-mode.md) — Partner-signed REST flows (EIP-191).
* [Card Mode — Crypto Backed](/developer-resources/api-reference-card-mode-crypto-backed.md) — Prefund Account, authorization callback, card webhooks. Plugs into either Account Mode.

***

## Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.ur.app/concepts/partner-integration-flow-concepts.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language. The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.ur.app/getting-started/integration-guide.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
