Skip to main content
A card saved on Duro belongs to the person, keyed to their account, and works at every merchant they check out with. Alongside the 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 — the settlement captures the tokenised card onto the customer’s account:
  • 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: 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: 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.
The wallet changes the stakes here. A customer with a funded 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.

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 tothe person’s account (core schema)a merchant’s customer (data schema)
Scopeevery merchantone merchant
Capturedon any checkout with a new cardon that merchant’s checkout
Used forportal 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 — funding the wallet by bank transfer instead of a card.