figma guide

Designing payment methods UI in Figma: cards, wallets, BNPL, and handoff

Design credit card forms, saved payment methods, digital wallets, and BNPL options in Figma with PCI-safe patterns, validation states, and Dev Mode specs for checkout.

Published
Updated
Jun 22, 2026
Read time
8 min
Level
Beginner

Quick answer

Payment UI is a checkout step, not a generic form—separate saved-method pickers, new card entry, wallet express buttons, and BNPL tiles into distinct components with explicit security copy. Build PaymentMethodCard (radio list for saved cards), CardEntryForm with brand detection and field-level validation, WalletButtonRow for Apple Pay / Google Pay / PayPal, and BNPLOptionTile with installment breakdown. Never design raw card numbers in high-fidelity mocks engineers will screenshot—use tokenized field placeholders and note “Stripe/Payment Element slot.” Pair with checkout, gift cards, and forms. Start from the Figma guides hub.


Who this is for

  • Product designers shipping DTC checkout, marketplaces, and B2B invoicing with multiple payment rails.
  • Design system teams standardizing payment display across web, mobile web, and embedded checkout.
  • Engineers integrating payment processors, tokenization iframes, 3-D Secure modals, and saved instrument APIs.

Payment surfaces

SurfaceGoalKey components
Checkout payment stepCollect or select paymentPaymentMethodPicker, CardEntryForm
Saved methods (account)Manage cards on filePaymentMethodCard list, Add new
Express checkoutSkip steps with walletWalletButtonRow above stepper
BNPL selectionInstallment choiceBNPLOptionTile, schedule breakdown
Order confirmationReceipt payment linePaymentMethodSummary read-only
Failed payment retryRecover from declinePaymentErrorBanner, retry CTA

Verdict: one PaymentMethodCard reused in checkout radio list and account wallet—same last-four, brand icon, and expiry layout everywhere.


PaymentMethodCard anatomy

PartPurposeSpec tip
Radio / selectChoose at checkoutSingle-select only on payment step
Brand iconVisa, MC, Amex, etc.32×20px SVG set; unknown = generic card
Masked numberLast four digits”•••• 4242” never full PAN
ExpiryCard validity”Exp 08/27” localized format
Default badgePrimary on fileBadge “Default”
Edit / RemoveAccount contextRemove opens confirm modal
PaymentMethodCard
├── Variant: context=checkout | account | readonly
├── Variant: type=card | wallet | bnpl | gift_card
├── Variant: state=default | selected | expired | disabled
├── Property: brand (visa | mastercard | amex | unknown)
├── Property: lastFour (string)
├── Property: isDefault (boolean)
└── Layers:
    ├── SelectIndicator (radio)
    ├── BrandIcon
    ├── MaskedDetails (number + expiry)
    ├── DefaultBadge (optional)
    └── ActionRow (Edit | Remove)

Expired cards show inline alert on card: “This card expired—update or choose another method.”


CardEntryForm fields

FieldLabelValidation states
Card numberCard numberempty, focus, valid brand detected, invalid Luhn, unsupported brand
ExpiryMM / YYempty, invalid date, expired
CVCSecurity codeempty, invalid length (3 vs 4 for Amex)
Name on cardName on cardempty, invalid characters
Billing ZIP (US)ZIP codeoptional if collected elsewhere; AVS note for eng

Design rule: show a dashed placeholder box labeled “Payment Element — card fields rendered by processor” when your team uses Stripe Elements or similar—designers specify spacing, label copy, and error placement; engineers drop the iframe inside your frame bounds.

StateBorderHelper text
Defaultneutral”All transactions are secure and encrypted”
Focusbrand accent
Errorred”Card number is invalid” under field
Successgreen check on brand iconAuto-advance to next field optional

Use segmented layout only if you offer “Credit card” vs “PayPal” as top-level tabs—otherwise wallets sit above the card form as express options.


Digital wallet express checkout

WalletButton specPlacement
Apple PayBlack pill, Apple logo + “Pay”Top of payment step; full width mobile
Google PayWhite/dark per themeSame row as Apple Pay on supported browsers
PayPalGold branded buttonOften alternate path—may skip address if account has it
Shop PayPurple brandedShopify ecosystems
WalletButtonRow
├── Layout: vertical stack mobile | horizontal row desktop max 2-up
├── Spacing: 12px between buttons
├── Divider: "— or pay with card —" text between express and form
└── States: default | loading | unavailable (hidden)

When to hide wallets: if cart contains subscription + one-time mix incompatible with wallet, show tooltip on disabled wallet: “Apple Pay unavailable for this order.”

Prototype wallet buttons as interactive components with pressed state only—actual wallet sheets are OS-native.


BNPL (buy now, pay later)

ElementContentNotes
TileKlarna / Affirm / Afterpay logo + “Pay in 4”Radio select like payment method
Schedule breakdown4 × $24.99 datesShow after tile selected
Legal microcopy”Subject to approval”Link to provider terms
OrderSummary rowNo change until selectedBNPL replaces card charge semantics

Model BNPLOptionTile with expanded variant showing installment table—collapsed on mobile, expandable accordion for schedule detail.

Verdict: BNPL is a payment method, not a promo discount—do not show negative discount rows when BNPL selected.


Checkout payment step layout

CheckoutPaymentStep
├── CheckoutStepper (Shipping ✓ | Payment | Review)
├── WalletButtonRow (optional express)
├── Divider
├── PaymentMethodPicker (saved cards radio list)
├── Link: "+ Add new card" → expands CardEntryForm inline
├── CardEntryForm (when adding new OR no saved methods)
├── Checkbox: "Save card for future purchases"
├── BNPLOptionSection (optional)
├── GiftCardSection → link [gift card guide](/designing-gift-cards-and-vouchers-ui-in-figma/)
├── OrderSummary (sticky desktop)
└── Primary CTA: "Pay $XX.XX" | "Continue to review"

On mobile, stack OrderSummary collapsed accordion above pay button so total is visible before charge.


Security and trust patterns

PatternCopy examplePlacement
Lock icon + SSL”Secure checkout”Near pay button
Processor badgesVisa Secure, Mastercard ID CheckFooter of payment step
No storage disclaimer”We don’t store your full card number”Under save-card checkbox
3DS note for eng”SCA modal — out of scope for Figma; link Figma frame for loading overlay”Dev Mode comment

Avoid designing fake card numbers that look real (e.g., valid-looking test PANs in marketing screenshots)—use obviously fake “4111 1111 1111 1111” with watermark “Sample.”


Error and retry flows

ErrorUIRecovery
Card declinedToast + inline on card field”Try another card”
Insufficient fundsSameSuggest BNPL if available
3DS failedModal skeleton frameReturn to payment step
Processor timeoutEmpty-state style alertRetry button, preserve form
AVS mismatchWarning not hard error”Billing ZIP doesn’t match—confirm or update”

Show PaymentErrorBanner below stepper with order ID reference for support on persistent failures.


Dev Mode handoff checklist

SpecValue to document
Component namesPaymentMethodCard, CardEntryForm, WalletButtonRow
Tokenized field boundsWidth, height, label-to-field gap for iframe
Brand icon setLink SVG export or icon plugin roundup
Error copy stringsAll validation messages as text styles
Analytics eventspayment_method_selected, wallet_clicked, bnpl_expanded
A11yRadio group label “Payment method”; wallet buttons need accessible names

Link Dev Mode checklist for inspect workflow with engineers.


Common mistakes

MistakeWhy it hurtsFix
Full card number in mockupsPCI confusion, screenshot leaksMasked last-four only
Separate drawer vs page card UIInconsistent saved methodsOne PaymentMethodCard
BNPL shown as discount rowWrong ledger logicSeparate payment method tile
No expired card stateFailed renewalsstate=expired variant
Wallet + card form same hierarchyCluttered payment stepExpress on top, divider, then card
Missing “save card” defaultUnexpected vault behaviorExplicit opt-in checkbox

  1. Confirm processor (Stripe, Adyen, Braintree) and whether Payment Element or custom fields.
  2. Build PaymentMethodCard with brand icons and masked display.
  3. Design CardEntryForm with all validation states and placeholder for tokenized iframe.
  4. Add WalletButtonRow and divider pattern for express checkout.
  5. Layer BNPL tiles if product supports installments—expanded schedule variant.
  6. Wire checkout payment step with saved list, add new, gift card slot, sticky summary.
  7. Design account payment methods page reusing same card component.
  8. Prototype decline error, expired card, and wallet-unavailable paths.

FAQ

Should billing address live on payment step or shipping?

Usually shipping step—payment step shows “Billing same as shipping” toggle with expandable billing address form when off.

Design Apple Pay sheet in Figma?

No—note “Native OS sheet” in Dev Mode; design only the trigger button and post-success confirmation redirect.

Multiple gift cards + credit card split?

Show gift card balance rows in OrderSummary first; CardEntryForm charges remaining amount due only—label CTA “Pay remaining $XX.XX.”

Corporate PO / invoice payment?

Add PaymentMethodCard variant type=invoice with PO number field—B2B checkout extension, not consumer card form.

Subscription vs one-time card?

Saved methods on subscription need default for renewals badge separate from checkout default—two boolean properties on same card component.


Next steps

Share on X

§ Keep reading

Related guides.