figma guide
Designing gift cards and vouchers UI in Figma: balance, redemption, and handoff
Design gift card purchase, redemption, balance display, and wallet UI in Figma with payment-method states, partial apply rules, and Dev Mode specs for ecommerce checkout.
- Published
- Updated
- Jun 21, 2026
- Read time
- 8 min
- Level
- Beginner
Quick answer
Gift card UI is a payment method, not a discount row—separate it from promo codes with its own entry field, applied-balance row, and wallet surfaces for saved cards. Build GiftCardField (number + PIN optional), AppliedGiftCard with remaining balance, and GiftCardBalanceRow in OrderSummary that reduces amount due rather than showing a negative discount. Model purchase flows (digital delivery, physical card, email recipient), account wallet with multiple cards, and partial apply when balance < order total. Pair with cart/checkout, forms, and price tokens. Start from the Figma guides hub.
Who this is for
- Product designers shipping DTC stores, marketplaces, and omnichannel retail with gift card programs.
- Design system teams aligning gift card display across checkout, account wallet, and marketing landing pages.
- Engineers implementing gift card APIs, partial redemption, fraud checks, and ledger balance updates.
Gift card surfaces
| Surface | Goal | Key components |
|---|---|---|
| Checkout apply field | Redeem at payment | GiftCardField, AppliedGiftCard |
| OrderSummary balance row | Reduce amount due | GiftCardBalanceRow |
| Account wallet | Saved cards + history | GiftCardWalletCard list |
| Purchase flow | Buy new card | GiftCardPurchaseStep wizard |
| PDP / marketing | Promote gift cards | Hero CTA + denomination picker |
| Email / digital delivery | Recipient experience | Static mock + copy spec |
| Order detail | Payment breakdown | PaymentMethodRow gift card line |
Verdict: never reuse PromoCodeField for gift cards—the mental model is wallet balance applied to payment, not a percentage off subtotal. Separate components prevent engineers from routing both through discount logic.
GiftCardField anatomy
| Part | Purpose | Spec tip |
|---|---|---|
| Label | ”Gift card” or “Redeem gift card” | Distinct from “Promo code” label |
| Card number input | 16–19 digit entry | Mask display optional: **** **** **** 1234 |
| PIN field | Security for physical cards | 4–8 digits; separate input |
| Apply button | Validate + attach balance | Loading state during API |
| Helper text | Where to find number | ”On back of card below barcode” |
| Error message | Invalid / zero balance | Below field group |
GiftCardField
├── Variant: layout=inline | stacked
├── Variant: state=empty | focus | loading | error | success | disabled
├── Property: hasPin (boolean)
└── Layers:
├── Label
├── CardNumberInput
├── PinInput (optional)
├── ApplyButton
├── HelperText
└── ErrorMessage
Use form input states for focus and error borders. On mobile, stack card number and PIN full-width—inline PIN fields are hard to tap.
Validation states
| State | Trigger | Visual | Copy examples |
|---|---|---|---|
| Empty | Default | Neutral border | Placeholder: “Card number” |
| Focus | User taps field | Focus ring | — |
| Loading | Apply clicked | Spinner on button | — |
| Invalid number | API 400 | Red border | ”We couldn’t find this card” |
| Expired | Date passed | Red border | ”This gift card expired” |
| Zero balance | Balance $0 | Error message | ”This card has no remaining balance” |
| Already applied | Duplicate | Info message | ”This card is already applied” |
| Success | Valid + balance > 0 | Show AppliedGiftCard | ”Gift card applied — $50.00 available” |
Prototype Apply → loading → success/error with interactive components. Document fraud rate-limit UI: after 3 failures, show inline alert “Try again in 15 minutes.”
AppliedGiftCard component
| Part | Purpose | Spec tip |
|---|---|---|
| Card label | Masked number | Gift card •••• 4821 |
| Available balance | Remaining after apply | $50.00 available |
| Applied amount | What covers this order | −$50.00 applied |
| Remaining after order | If partial | $0.00 remaining on card |
| Remove action | Unapply before pay | ”Remove” link or × icon |
AppliedGiftCard
├── Variant: density=compact | comfortable
├── Variant: coverage=full | partial
├── Property: balance (number)
├── Property: appliedAmount (number)
└── Layers:
├── Icon (gift or card)
├── CardLabel + BalanceText
├── AppliedAmount
└── RemoveButton
Place below promo section if both exist—visual order: discounts first, payment methods second.
OrderSummary gift card rows
| Row type | When | Display |
|---|---|---|
GiftCardBalanceRow | Card applied | Gift card label + −$50.00 |
AmountDueRow | After gift card | Updated total prominently |
RemainingBalanceNote | Partial apply | ”Pay remaining $24.50 with card below” |
Multiple cards | Stacking allowed | Stacked rows per card |
Gift card rows use payment adjustment styling—not green discount styling. Use neutral or text/primary for amounts; reserve green for explicit “You saved” promo lines.
| Scenario | Subtotal | Gift card | Amount due |
|---|---|---|---|
| Full coverage | $45.00 | −$45.00 | $0.00 |
| Partial | $75.00 | −$50.00 | $25.00 |
| Multiple cards | $100.00 | −$30 + −$20 | $50.00 |
Link row math to price display tokens—same decimal rules as cart line items.
Purchase flow (buy a gift card)
| Step | Content | Components |
|---|---|---|
| 1. Amount | Denomination picker | DenominationChip ($25, $50, $100, custom) |
| 2. Delivery | Email vs physical | DeliveryMethodCard |
| 3. Recipient | To, from, message | Form fields |
| 4. Schedule | Send now vs future date | Date picker |
| 5. Review + pay | Summary | Reuse checkout payment block |
DenominationChip
├── Variant: state=default | selected | disabled
├── Property: amount (number)
└── Layers:
├── AmountLabel
└── CustomInput (optional variant)
Physical card shipping adds address step—reuse checkout address components. Digital-only stores skip address entirely.
Account wallet
| Element | Purpose | Spec |
|---|---|---|
GiftCardWalletCard | Saved card tile | Balance + masked number + expiry |
| Add card CTA | Link external card | Opens GiftCardField modal |
| Transaction history | Load / redeem log | Table or list |
| Empty state | No cards saved | Empty state + buy CTA |
GiftCardWalletCard
├── Variant: state=active | expired | zero_balance
├── Property: balance (number)
├── Property: expiresAt (date optional)
└── Layers:
├── CardArt (brand gradient)
├── MaskedNumber
├── BalanceAmount
├── ExpiryLabel
└── ActionLink ("View history")
Show wallet in account sidebar nav under Payments or Wallet—not buried in order history.
Stacking rules with promos
| Rule | UI treatment |
|---|---|
| Gift card + promo allowed | Both sections visible; totals recalc together |
| Mutually exclusive | Error on second apply: “Can’t combine with gift card” |
| Promo on subtotal, gift on remainder | Dev Mode note on calculation order |
| Gift card buys gift card | Block with error |
Document calculation order in handoff—designers often show final total without explaining intermediate steps engineers must implement.
Responsive behavior
| Breakpoint | Apply field | Wallet |
|---|---|---|
| Mobile | Stacked inputs; sticky amount due | Single-column cards |
| Tablet | Inline Apply on wide fields | 2-column grid |
| Desktop | Collapsible “Gift card” section in checkout | 3-column grid |
On mobile checkout, show updated amount due immediately after apply—users shouldn’t scroll to find the new total.
Handoff checklist
| Item | Dev Mode annotation |
|---|---|
| Card number format | Strip spaces; validate length |
| PIN required | Physical vs digital cards |
| Partial apply logic | min(balance, amount_due) |
| Multiple card stacking | Max cards per order |
| Balance API timing | Real-time vs cached |
| Remaining balance storage | On card entity after order |
| Fraud lockout | UI after N failed attempts |
| Email delivery template | Match purchase confirmation UI |
| Analytics | apply_gift_card, purchase_gift_card |
| Currency | Single-currency vs conversion note |
Use Dev Mode checklist and link GiftCardBalanceRow to checkout OrderSummary props.
Common mistakes
| Mistake | Why it hurts | Fix |
|---|---|---|
| Gift card in discount row | Wrong tax + ledger logic | Separate payment adjustment row |
| Same field as promo code | User confusion | Distinct labels and sections |
| No partial apply UI | Abandoned high-value carts | Show remaining balance + amount due |
| Balance not updated after apply | Distrust at payment | Live recalc with loading skeleton |
| No wallet in account | Re-entry every order | Saved cards in account area |
| Purchase flow without delivery spec | Broken recipient emails | Email mock in Figma + copy doc |
Recommended workflow
- Define program rules (denominations, PIN, stacking, expiry) with PM/finance.
- Build
GiftCardField+AppliedGiftCardseparate from promo components. - Add
GiftCardBalanceRowto checkoutOrderSummarywith partial-apply states. - Design purchase wizard if store sells cards—denomination + delivery + recipient.
- Create account wallet with
GiftCardWalletCardand history. - Document stacking rules with promo and payment methods.
- Prototype checkout apply → partial pay → order detail payment breakdown.
- Spec digital delivery email aligned to purchase confirmation UI.
FAQ
Gift card or store credit after return?
Different UI—store credit from returns may auto-apply; label it “Store credit” not “Gift card” unless they share the same backend.
Can users split across gift card + credit card?
Yes—show amount due after gift card with payment method selector below. Hide card form when amount due is $0.
Physical card barcode scan?
Add Scan card camera CTA on mobile GiftCardField—static frame mock + “Opens camera” note for engineers.
Marketplace seller gift cards?
If cards are seller-specific, show seller name on AppliedGiftCard and block cross-seller application—mirror multi-seller returns grouping.
Next steps
- Design coupons and promo codes UI in Figma — discounts vs payment methods
- Design shopping cart and checkout UI in Figma — OrderSummary and payment block
- Design price tags and pricing UI in Figma — amount due and balance display
- Design order history UI in Figma — payment breakdown on order detail
§ Keep reading