About this animation
A payment confirmation with a drawn ring, rolling amount, and receipt reveal, with configurable amount, recipient details, success color, and fonts.
Why this one
Most payment confirmations replace the whole screen or drop a generic checkmark into place. This version preserves spatial continuity: the action itself contracts, processes, rises, and becomes the success symbol. The celebration combines a continuous ring, a traced Lucide check, deterministic physical particles, and a rolling amount without placing opaque effect blocks over the interface. The receipt remains useful after the wow moment, with readable details and interruptible reverse motion.
How it works
- One Reanimated shared value drives the receipt from idle (
0) to complete (1); crossing the check threshold starts a separate linear celebration clock. - The send pill springs into a processing circle, then moves to the success position and expands.
- Skia draws the progress ring and Lucide check from their path
endvalues. - Sixteen curated particles rendered in Reanimated views burst upward and sideways from the check over 1.4 seconds on web and native (animated Skia props are static in this SDK's web renderer), staying visible for more than 0.8 seconds regardless of the receipt easing or reveal duration. Analytic air resistance slows their travel and rotation, soft gravity bends the upper fan, and a smooth fade removes every particle above the launch center before it can fall onto the receipt.
- The supplied amount slides into clipped one-line masks without placeholder digits while the glass receipt rises and reveals rows at 50 ms intervals.
- Calling
reset()clears the burst and animates the receipt progress backward, so every transition can be interrupted.
Install
npx expo install expo-blur expo-linear-gradient @shopify/react-native-skia react-native-reanimated react-native-workletsUsage
import { useRef } from 'react';
import {
PaymentSuccessBurst,
type PaymentSuccessBurstRef,
} from './PaymentSuccessBurst';
const ref = useRef<PaymentSuccessBurstRef>(null);
<PaymentSuccessBurst ref={ref} amount="$84.00" recipientName="Alex Rivera" />;<PaymentSuccessBurst
ref={ref}
brandName="Aster"
amount="$240.00"
recipientName="Maya Reyes"
recipientInitials="MR"
recipientHandle="@mayareyes"
note="Dinner + concert tickets"
successColor="#34D399"
brandColor="#A78BFA"
sourceAccount="Checking ···· 8210"
arrival="Instantly"
reference="PAY-48213-K"
date="10/10/2026, 6:42 PM"
onShare={shareReceipt}
/>The forwarded ref exposes send() and reset().
Props
| Prop | Type | Default | Description |
|---|---|---|---|
brandName | string | 'Payments' | Product brand shown in the header. |
recipientInitials | string | 'AR' | Recipient initials. |
recipientName | string | 'Alex Rivera' | Recipient display name. |
recipientHandle | string | '@alexrivera' | Recipient handle. |
amount | string | '$240.00' | Formatted payment amount. |
note | string | 'Dinner and tickets' | Payment note shown on the form. |
sourceAccount | string | 'Checking ···· 8210' | Source account detail. |
arrival | string | 'Instantly' | Arrival detail. |
reference | string | 'PAY-48213-K' | Receipt reference. |
date | string | '10/10/2026, 6:42 PM' | Localized receipt date. |
backgroundColor | string | '#07060B' | Background color. |
successColor | string | '#34D399' | Success accent color. |
brandColor | string | '#A78BFA' | Brand accent color. |
fontFamily | string | undefined | Interface font family. |
mediumFontFamily | string | undefined | Medium interface font family. |
titleFontFamily | string | undefined | Editorial success-title font family. |
monoFontFamily | string | undefined | Monospaced receipt-reference font family. |
onSuccess | () => void | undefined | Called after the complete success sequence settles. |
onShare | () => void | undefined | Called when Share receipt is pressed. |
onDone | () => void | undefined | Called when Done is pressed after reset begins. |
sendAccessibilityLabel | string | undefined | Accessible label for the send action. |
style | StyleProp<ViewStyle> | undefined | Optional outer-container style. |
testID | string | undefined | Optional test identifier. |
duration | number | 1120 | Success receipt reveal duration in milliseconds. The 1.4-second particle burst, spring physics, and reduced-motion timing are unchanged. |
Icons: Lucide (ISC).
Compatibility
Built for Expo SDK 58, React Native 0.88, Reanimated 4.7, Worklets 0.13, and React Native Skia 2.14. Supports iOS, Android, and web. The installed modules work in Expo Go for the matching SDK.
Accessibility
Send, Share receipt, Done, and Replay expose button roles and descriptive labels with touch targets of at least 44 pt. The success result uses a polite live region. Reduced Motion replaces travel, rotation, particles, and spring celebration with a direct 190 ms state fade while preserving the complete receipt.




