Card provisioning — business rules

The constraints, state-machine rules, and validation logic governing card provisioning to a wallet.

These rules govern the Card Provisioning API. For the operations themselves and sample requests, see Card Provisioning.


LINKED vs COSMETIC

The state parameter on /register controls how strictly the card is bound to the wallet:

StateBehaviour
LINKED (default)Hard binding. The PAN / account number can't be registered to any other MSISDN until it's delinked from this one. Use for cards a customer has confirmed they own.
COSMETICSoft binding. The card appears in the wallet, but the same PAN can still be registered to other MSISDNs. Auto-promoted to LINKED after the first successful transaction. Use when you want to display a card before validation is complete.

If you don't specify state, it defaults to LINKED.


Validation methods

The validationMethod parameter controls how the customer confirms ownership of the card when registering:

MethodBehaviour
(not sent)No validation. Card is linked immediately and silently. The simplest path — use when the wallet has already authenticated the cardholder elsewhere (e.g. a bank app authenticating from its own session).
SIMPLECustomer is prompted with a yes/no confirmation. "Yes" → card moves to LINKED. "No" → card is delinked, and the PAN becomes available for other wallets.
DOBCustomer is prompted to enter their date of birth. Compared against the dateOfBirth supplied on /register. Match → LINKED. Mismatch → delinked.

If you send validationMethod: DOB, you must supply dateOfBirth on the same request. Sending DOB without dateOfBirth is rejected.


Already-linked behaviour

The platform distinguishes between three "already exists" cases:

ScenarioResult returned
Same accountNumber + same msisdnCARD LINKED TO PROFILE — idempotent no-op
Same accountNumber + different msisdn, current state LINKEDALREADY LINKED — registration rejected
Same accountNumber + different msisdn, current state COSMETICAllowed — the new registration overrides if its state is LINKED

This means a customer can't add a card that's hard-linked to someone else's wallet, but COSMETIC placeholders don't block legitimate ownership claims.


Update constraints

FieldUpdatable via /update?
expiryDateYes
imageIdYes
cardholderNameYes
nodeNo — register-time only
validationMethodNo — register-time only
stateNo — use /block//unblock to transition
accountNumberNo — delink and re-register
msisdnNo — delink and re-register under the new MSISDN

The update request must supply at least one of expiryDate, imageId, or cardholderName. A request with none of these is rejected.


State transitions

The card-state machine has four states. Only certain transitions are allowed:

FromToTrigger
(new)LINKED/register with state: LINKED or no state
(new)COSMETIC/register with state: COSMETIC
COSMETICLINKEDFirst successful transaction on the card
LINKEDBLOCKED/block
BLOCKEDLINKED/unblock
LINKEDDELINKED/delink
BLOCKEDDELINKED/delink
DELINKED(any)Re-/register (creates a fresh link)

/update on a BLOCKED card returns SUCCESS but the card remains BLOCKED. The mutation is applied; the state isn't changed.

/update on a DELINKED card returns CARD DELINKED — no mutation. Re-register first.


Account-type requirements

Some BINs (typically debit cards) require an account type at register-time. The behaviour is:

account supplied?BIN requires it?Behaviour
Yes, valid (10/20/30)YesHonoured
Yes, validNoStored but ignored
Yes, invalid valueYesDefaults to 30 (Credit)
NoYesReturns MISSING ACCOUNT
NoNoCard registered without an account type

Use /binLookup (on the Remote API) to discover whether a BIN requires an account type before calling /register.


Brand indicators (card art)

RuleDetail
ScopeEach imageId is scoped to your wallet provider. Other wallets can't see yours.
ReusableOne imageId can be referenced by many /register calls — typically one image per card product / tier.
Description limit30 characters max. Anything longer is rejected.
Recommended dimensions300×190 px, PNG, < 100 KB
FormatBase64-encoded byte array on the wire

Once registered, an imageId can be referenced for the life of your wallet provider profile. There's no expiry, but you can replace the underlying image by uploading a new indicator with the same description (a new imageId is generated).


Node assignment

The node parameter tells the platform which acquirer / bank scheme the card should route through.

RuleDetail
OptionalIf not sent, the platform infers a node from the BIN.
Auto-createIf the supplied node doesn't exist, it's created dynamically on the MRA backend.
Consult your service providerDon't guess node names. Speak to your account manager before using a node value that isn't in your existing config.
Common valuesSBSA (Standard Bank), ABSA, NEDBANK, FNB, CAPITEC

Once a card is registered with a node, it can't be changed via /update. To move a card to a different node, delink and re-register.


Limits and quotas

LimitDefault
Cards per wallet (MSISDN)Set per-wallet-brand by Operations. Typical default: 5
Brand indicators per providerNo hard cap, but practical recommendation: < 100
Concurrent registration requests for same MSISDNSerial — second request blocks until first completes

If a customer hits the cards-per-wallet limit, MAX CARDS LINKED is returned. The wallet UI should offer to delink an existing card before registering another.


PII and data handling

RuleDetail
PAN is stored hashed and BIN-taggedScan to Pay vaults the PAN. Your wallet only needs to keep the last 4 digits client-side for display.
No CVV at provisioningCVV is not collected by Card Provisioning. The wallet supplies CVV at purchase time (if the BIN requires it).
PCI scopeTreat any handling of accountNumber in your wallet as PCI-relevant. Use a PCI-compliant SDK / tokenisation flow if you don't want PCI scope.
Cardholder nameTreated as PII. Don't log on the client.
Date of birthWhen used with validationMethod: DOB, store as transient — discard after the validation flow completes.

Sharing card details with the support team for debugging must follow the PII restrictions documented in Query resolution — business rules.


What's next