# RappiPay Card Management UI in SwiftUI

> By Lawrence Arya, Founder & CEO of VP0. Published 2026-06-07. 5 min read.
> Source: https://vp0.com/blogs/rappipay-card-management-ui-swiftui

Every control is a promise about a real payment instrument. A freeze toggle that lies is a security failure, not a cosmetic bug.

**TL;DR.** RappiPay card management is the controls-first fintech surface inside Rappi's super-app (founded 2015, ~US$800M revenue by 2023): freeze/unfreeze, spending limits, channel toggles, a secure detail reveal, and an enriched transaction list. You build the card-control UI on a licensed card issuer, surfacing controls and reflecting real card state, never issuing cards or moving money yourself. The freeze is the centerpiece and it is state, not intent: reflect the issuer-confirmed locked status, never an optimistic flip, because a user freezing a lost card must trust it is off. Reveal card details behind biometric/PIN auth, never logged, and round-trip every control to the issuer. A free VP0 design supplies the card screens.

## What is RappiPay card management, and what shapes the build?

The screen where a user controls their RappiPay card, freeze it, see transactions, set limits, manage the virtual card, inside the super-app of [Rappi](https://en.wikipedia.org/wiki/Rappi), the Colombian delivery-and-fintech giant (founded 2015, around US$800 million in revenue by 2023). Card management is the fintech surface that sits beside the delivery app, and it is a distinct, high-trust screen: this is where a user does the things traditional banks made you phone for, which is exactly the neobank promise the super-app extends to its card.

The honest framing first: you build the **card-control UI**, and the actual card, the money, and the issuing run through a licensed card issuer (Rappi partners with banks/issuers for this), so the app surfaces controls and reflects real card state, it never issues cards or moves money itself. The controls must reflect the card's true state, because a freeze toggle that lies about whether the card is actually frozen is the worst possible bug on a payment instrument.

## What controls does the card screen need?

The self-service set that defines modern card management:

| Control | What it does | Why it matters |
| --- | --- | --- |
| Freeze / unfreeze | Instantly lock the card | The most-used safety control |
| Card details | Reveal number/CVV (virtual card) | Securely, gated by auth |
| Spending limits | Per-transaction or monthly caps | Control the bank made you call for |
| Online / contactless toggles | Enable or disable channels | Granular security |
| Transactions | Recent activity, enriched | The card's real-time truth |

The freeze is the centerpiece, and it is **state, not intent**: tapping freeze must reflect the card's actual status (frozen confirmed by the issuer), with a clear visual that the card is locked, never an optimistic "frozen" that the backend has not confirmed, because a user who froze a lost card needs to trust it is really off. Revealing the virtual card's number and CVV is the security-sensitive action: it is gated behind [biometric or PIN auth](https://developer.apple.com/documentation/localauthentication), shown briefly, never logged, the same secure-reveal discipline as any [PIN or credential surface](/blogs/face-id-biometric-login-screen-swiftui/). The transaction list is the card's truth, enriched (merchant, category) and updated in real time, with pending distinct from settled.

## Why is honest card state the whole product?

Because every control is a promise about a real payment instrument, and a lie is a security failure. The controls (freeze, limits, channel toggles) must round-trip to the issuer and reflect the confirmed result, so the UI shows pending while a change is applying and the confirmed state after, never a toggle that flips visually but did not take effect. The same pending-not-optimistic rule that governs every money movement applies to every card control, because a user who set a limit or froze a card is relying on it.

Security wraps all of it: card details behind auth, sensitive actions confirmed, nothing sensitive logged or cached (sensitive tokens belong in the [Keychain](https://developer.apple.com/documentation/security/keychain-services)), and biometric unlock for the screen itself where appropriate. This is genuine fintech, so the honest framing throughout, that the licensed issuer holds the card and the app reflects it, is both the legal reality and the trust model, the same render-the-UI, route-through-the-licensed-entity pattern as [the Maya digital bank build](/blogs/maya-digital-bank-ui-clone-react-native/).

## What makes it feel like RappiPay specifically?

The super-app and regional context. RappiPay's card lives inside Rappi, so card management connects to the wider app (paying for orders, cashback, the wallet), and the design is the clean, controls-first neobank language rather than a dense traditional-bank screen. Colombian and Latin American context shapes it: the right currency, Spanish, and the cashback/rewards layer Rappi leans on, with the card as both a spending instrument and a loyalty hook.

The screens, the card hero with freeze, the limits, the secure detail reveal, the transaction list, come as a free [VP0](https://vp0.com) design, so an agent wires the issuer integration onto a UI already shaped for state-not-intent controls and gated detail reveal rather than a static card mockup.

## Key takeaways: a RappiPay card management screen

- **It is a card-control UI on a licensed issuer**: surface controls and reflect real card state; never issue cards or move money yourself.
- **Freeze is the centerpiece and it is state, not intent**: reflect the issuer-confirmed locked status, never an optimistic flip.
- **Reveal card details behind auth**: biometric or PIN gated, shown briefly, never logged, the secure-reveal discipline.
- **Every control round-trips to the issuer**: pending while applying, confirmed after; a toggle that lies is a security failure.
- **Super-app and regional context**: clean controls-first neobank language, connected to the wallet and cashback, in the right currency and language.

## Frequently asked questions

**How do I build a RappiPay-style card management UI in SwiftUI?** Build a controls-first card screen, freeze/unfreeze, spending limits, channel toggles, a biometric-gated detail reveal, and an enriched transaction list, wired to a licensed card issuer so every control reflects the issuer-confirmed state. A free VP0 design supplies the card hero, limits, and transaction screens to wire the integration onto.

**Does the app issue the card or move the money?** No: the card, the money, and issuing run through a licensed card issuer that Rappi partners with, and the app surfaces controls and reflects real card state. It never issues cards or settles funds itself, the same render-the-UI, route-through-the-licensed-entity reality as every fintech build.

**How should the freeze control work?** As state, not intent: tapping freeze must reflect the card's actual issuer-confirmed status with a clear locked visual, showing pending while the change applies and confirmed after, never an optimistic flip the backend has not confirmed. A user freezing a lost card needs to trust the card is genuinely off, so a lying toggle is the worst possible bug.

**How do I securely reveal the virtual card number and CVV?** Behind authentication: gate the reveal with biometric or PIN, show the details briefly, and never log or cache them. Revealing card details is the most security-sensitive action on the screen, so it gets the same treatment as any credential reveal, on-demand, time-limited, and never persisted.

**Why must every card control reflect real state?** Because each control is a promise about a real payment instrument: a freeze, a limit, or a channel toggle that flips visually but did not take effect at the issuer is a security failure, not a cosmetic bug. Controls must round-trip to the issuer and show pending-then-confirmed, because users rely on them to protect real money.

## Frequently asked questions

### How do I build a RappiPay-style card management UI in SwiftUI?

Build a controls-first card screen, freeze/unfreeze, spending limits, channel toggles, a biometric-gated detail reveal, and an enriched transaction list, wired to a licensed card issuer so every control reflects the issuer-confirmed state. A free VP0 design supplies the card hero, limits, and transaction screens to wire the integration onto.

### Does a card management app issue the card or move the money?

No: the card, the money, and issuing run through a licensed card issuer that Rappi partners with, and the app surfaces controls and reflects real card state. It never issues cards or settles funds itself, the same render-the-UI, route-through-the-licensed-entity reality as every fintech build.

### How should the freeze control work?

As state, not intent: tapping freeze must reflect the card's actual issuer-confirmed status with a clear locked visual, showing pending while the change applies and confirmed after, never an optimistic flip the backend has not confirmed. A user freezing a lost card needs to trust the card is genuinely off, so a lying toggle is the worst possible bug.

### How do I securely reveal the virtual card number and CVV?

Behind authentication: gate the reveal with biometric or PIN, show the details briefly, and never log or cache them. Revealing card details is the most security-sensitive action on the screen, so it gets the same treatment as any credential reveal, on-demand, time-limited, and never persisted.

### Why must every card control reflect real state?

Because each control is a promise about a real payment instrument: a freeze, a limit, or a channel toggle that flips visually but did not take effect at the issuer is a security failure, not a cosmetic bug. Controls must round-trip to the issuer and show pending-then-confirmed, because users rely on them to protect real money.

---
*Published on the [VP0 Journal](https://vp0.com/blogs). Free to read, index and cite with attribution.*
