Skip to content
Native Animation
Express Pay Sheet animation preview

This preview uses fictional demo content. See the props below for the customization options available in this component.

npx nativeanimation add express-pay-sheet
Glass

Express Pay Sheet

A payment sheet with a sliding card stack and card-to-receipt finish, with configurable cards, labels, accent color, and fonts.

$9 for this animation

Add to your project

Copy the component and its assets into your app with the Native Animation CLI, or paste the agent prompt into Claude Code, Codex or Cursor once the MCP server is connected.

About this animation

A payment sheet with a sliding card stack and card-to-receipt finish, with configurable cards, labels, accent color, and fonts.

Why this one

An ordinary Pay button skips the feeling of deliberate confirmation. This sheet connects a double tap to a side-button indicator beside the card, away from the sheet header and the viewer close control. Switching uses an interruptible lateral stack with dark material peeking out by 8 pt and a fading ‘Everyday · Debit’ caption. This reads as choosing an account immediately. Labeled 48 pt controls also avoid asking users to tap a narrow card edge. A continuous ring frames authorization; the confirmation flip reveals a real magnetic stripe, signature panel, masked CVV, and wallet wordmark before the sheet contracts into a receipt. The receipt uses the sheet's actual dimensions rather than a cover placed over it.

How it works

  1. Measure the container with onLayout; sheet, card, and side-button placement follow its dimensions.
  2. One UI-thread progress value drives opening, authorization, card flip, contraction, and receipt departure.
  3. A continuous card position drives the interruptible lateral stack and caption opacity independently of payment progress. Both confirmation faces rotate individually with a constant 900 pt perspective, hidden backfaces, and angle-based visibility guards; mirrored text never shows.
  4. Gesture Handler recognizes a deliberate double tap; a labeled single-tap alternative triggers the same finish. Drag the title to dismiss, or tap Cancel.
  5. Skia trims a rounded rectangular path around the card over 800 ms. Lucide supplies all icon paths.
  6. Emit state callbacks and accessibility announcements at milestones. The demo owns and cleans up its autoplay timers; user input cancels the loop.

Install

npx expo install react-native-reanimated react-native-worklets react-native-gesture-handler expo-blur expo-linear-gradient @shopify/react-native-skia

Wrap your application in GestureHandlerRootView. For web, configure Skia's CanvasKit loading as required by your Expo application. No external images, fonts, or network assets are needed by the component. Icons: Lucide (ISC).

Usage

import { useRef } from 'react';
import ExpressPaySheet, { type ExpressPaySheetRef } from './express-pay-sheet';

function Checkout() {
  const payment = useRef<ExpressPaySheetRef>(null);
  return (
    <ExpressPaySheet
      ref={payment}
      merchant="Your store"
      amount="$42.50"
    />
  );
}

Call payment.current?.open() from your checkout button, or use the built-in Open payment sheet action.

<ExpressPaySheet
  merchant="Your store"
  walletName="Wallet"
  shipping="Home · Standard delivery"
  contact="customer@example.com"
  accentColor="#A78BFA"
  confirmationDuration={900}
  springDamping={30}
  cards={[
    { label: 'Everyday', lastFour: '4821', colors: ['#6850B5', '#30264D'] },
    { label: 'Reserve', lastFour: '9064', colors: ['#39335F', '#8B7CBA'] },
  ]}
/>

This is a visual interaction, not a payment SDK, passcode validator, or listener for the physical side button. Connect your production authentication and payment flow separately. onPaid reports visual success.

Props

PropTypeDefaultDescription
childrenReactNode—Background app content.
merchantstringYour storeReceipt merchant.
amountstring$42.50Formatted amount.
shippingstringHome · Standard deliveryShipping summary.
contactstringcustomer@example.comContact summary.
walletNamestringWalletWallet heading and card identity.
cardsreadonly PaymentCard[]Three generic cardsUp to three labels, optional type (default Debit), last-four digits, and gradients; empty lists use defaults.
fontFamilystringSystemUI typeface.
monoFontFamilystringSystemPrice and account digits.
accentColorstring#22D3EERing and success check.
surfaceColorstring#0B0B12Glass sheet tint.
confirmationDurationnumber800Ring duration in ms, minimum 200.
springDampingnumber28Sheet damping, minimum 28 with explicit mass 1 (ζ ≥ 0.86).
confirmationLabelstringDouble-click to payVisible and accessible confirmation label.
alternativeLabelstringPay with passcodeSingle-tap alternative.
securityCodeLabelstringCVV •••Masked code on the real reverse; never provide a real security code.
onPaid() => void—Visual success callback.
onStateChange(state: PaymentState) => void—closed, ready, authorizing, paid.
onCardChange(index: number) => void—Selected card index.
onInteraction() => void—Stops demo autoplay on user input.
styleStyleProp<ViewStyle>—Root styling; defaults to flex: 1.
testIDstring—Root identifier, also used for -confirm, -cancel, -pay, -card-N, and -select-N controls.

Ref methods: open(), close(), reset(), expandCards(), selectCard(index), pay(). Close cancels payment animations. Selection is interruptible before authorization; duplicate payment requests are ignored. Reopening starts a fresh visual checkout.

Compatibility

Targets Expo SDK 58, React Native 0.88.0, Reanimated 4.7.1, worklets 0.13.0, and Skia 2.14.0. Uses installed Expo Go modules. Android blur uses BlurTargetView and dimezisBlurViewSdk31Plus; older Android versions use the native fallback. Supports iOS, Android, and web.

Accessibility

Buttons have roles, labels, 48 pt minimum targets, and selection states. Card-choice buttons provide an explicit touch alternative to the stack. Important transitions announce to assistive technology; the receipt has a polite live region. A single tap on Pay with passcode replaces the double tap. Screen readers can activate the side indicator directly. Cancel replaces dragging to dismiss. Reduced motion removes blur, pulsing, card travel, flips, ring animation, and receipt flight; 200 ms opacity transitions reveal the result with a discrete layout change.

Demo timing

Open at 0.1 s, fan at 0.75 s, select at 1.15 s, confirm at 1.7 s, ring completes at 2.5 s, the real reverse arrives at 2.94 s. Subsequent cycles alternate Everyday and Reserve. The sheet then contracts, holds the receipt, fades, and repeats after reset. Every user touch stops autoplay.

Layout

The host supplies safe-area insets. Card width is capped at 340 pt and leaves space for the side indicator; sheet height reserves the top 72 pt for the catalog viewer. Content scrolls in short containers and landscape rather than shrinking text or hiding payment actions. At 320×694 and 390×844 the checkout content fits in the sheet without scrolling at default text size. The reverse is physical card material, not a success overlay or a block sweeping over text.