> ## Documentation Index
> Fetch the complete documentation index at: https://docs.useduro.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Global Cards

> A saved card belongs to the person, not the merchant — captured automatically on any checkout, deduped by token, reusable everywhere.

A card saved on Duro belongs to the **person**, keyed to their [account](/identity/universal-identity), and works at **every merchant** they check out with. Alongside the [wallet](/identity/wallet), it's the second half of the customer's cross-merchant payment identity: pay once anywhere, and the card is on file everywhere.

## Auto-saved on any checkout

There is no separate "save my card" step to remember. Whenever a checkout charges a **new** card — a subscription, a one-off, or a [top-up](/payments/top-up) — the settlement captures the tokenised card onto the customer's account:

```mermaid theme={null}
flowchart TD
    PAY["checkout pays with a card"] --> TOK{"tokenised card<br/>on the payment?"}
    TOK -->|"no"| DONE["nothing to save"]
    TOK -->|"yes"| DEDUP{"token already<br/>on this account?"}
    DEDUP -->|"yes"| KEEP["keep existing card<br/>(no duplicate)"]
    DEDUP -->|"no"| SAVE["save AccountCard<br/>first card → default"]
```

* **Deduped by token.** Cards are `@@unique([accountId, nombaTokenKey])` — paying with the same card ten times yields one `AccountCard`, not ten.
* **First card is the default.** The first card saved on an account becomes its default automatically; later cards are added non-default.
* **Only the safe fields are stored.** An `AccountCard` holds `brand`, `last4`, and expiry — plus the Nomba **token key** used to charge it. The raw PAN never touches Duro, and the token key is never returned over the API; the portal only ever sees brand + last-4.

## "Add a card" is a ₦100 top-up

Duro has no card-validator of its own, so it never stores a card it hasn't successfully charged. **Adding a card** therefore runs a **minimum ₦100 [top-up](/payments/top-up)**: the customer pays ₦100, the card is tokenised and saved on the way through, and the ₦100 lands in their wallet. Nothing is wasted — the customer keeps the ₦100 as balance, and the card is now on file for every merchant.

## Removing a card is guarded

A customer can remove a card from the portal — but not if doing so would strand an active subscription with no way to pay:

```mermaid theme={null}
flowchart LR
    RM["DELETE /cards/:id"] --> CNT{"is this the last<br/>active card?"}
    CNT -->|"no"| DEL["remove it"]
    CNT -->|"yes"| SUB{"any active / trialing /<br/>past-due subscription?"}
    SUB -->|"yes"| BLOCK["blocked — keep at least<br/>one valid card"]
    SUB -->|"no"| DEL
```

If the card being removed is the **last** valid card **and** the customer has a live subscription, the removal is rejected with *"keep at least one valid card while you have an active subscription."* When the removed card was the default, the next card on the account is promoted to default automatically.

<Note>
  The wallet changes the stakes here. A customer with a funded [wallet](/identity/wallet) can renew wallet-first without a card at all — but the guard is deliberately conservative: it protects the fallback rail for the moment the balance runs dry.
</Note>

## Global cards vs. per-merchant payment methods

There are two card-shaped things in Duro, and they are not the same:

|            | `AccountCard` (global)             | `PaymentMethod` (per-merchant)      |
| ---------- | ---------------------------------- | ----------------------------------- |
| Belongs to | the person's account (core schema) | a merchant's customer (data schema) |
| Scope      | every merchant                     | one merchant                        |
| Captured   | on any checkout with a new card    | on that merchant's checkout         |
| Used for   | portal card list, "add a card"     | that subscription's card renewals   |

A single checkout can write **both**: the tokenised card is saved to the merchant's `PaymentMethod` (so the subscription can renew) *and* to the account's `AccountCard` (so it appears in the portal everywhere). Same token, two homes.

Next: the [virtual account](/payments/virtual-account) — funding the wallet by bank transfer instead of a card.
