@reevit/react
v0.8.1
Published
Reevit React SDK - Unified Payment Widget
Downloads
687
Maintainers
Readme
@reevit/react
Unified Payment Widget for React Applications. Accept card and mobile money payments with a single integration.
Installation
npm install @reevit/reactQuick Start
The simplest way to integrate Reevit is using the ReevitCheckout component.
import { ReevitCheckout } from '@reevit/react';
import '@reevit/react/styles.css';
function App() {
return (
<ReevitCheckout
publicKey="pfk_test_your_key"
amount={10000} // Amount in smallest unit (e.g., pesewas for GHS)
currency="GHS"
email="[email protected]"
idempotencyKey={`order_${Date.now()}`}
onSuccess={(result) => {
console.log('Payment success!', result);
alert(`Payment of ${result.currency} ${result.amount/100} successful!`);
}}
onError={(error) => {
console.error('Payment failed:', error.message);
}}
>
<button className="my-pay-button">Pay GHS 100.00</button>
</ReevitCheckout>
);
}Idempotency
Provide an idempotencyKey tied to your order/cart to avoid duplicate intent creation and enable safe retries.
<ReevitCheckout
publicKey="pfk_test_your_key"
amount={10000}
currency="GHS"
idempotencyKey="order_12345"
/>Payment Links
If you have a hosted payment link, pass the link code. The widget will create the payment intent from the public link endpoint.
<ReevitCheckout
paymentLinkCode="plink_123"
amount={25000}
currency="GHS"
email="[email protected]"
customerName="Ada Lovelace"
/>Controlled Modal
You can control the open state yourself.
const [open, setOpen] = useState(false);
<ReevitCheckout
publicKey="pfk_test_your_key"
amount={10000}
currency="GHS"
isOpen={open}
onOpenChange={setOpen}
/>Success Screen Delay
By default, the checkout shows a success screen for 5 seconds before calling onSuccess and closing. Override with successDelayMs (set to 0 for immediate close).
<ReevitCheckout successDelayMs={0} /* ... */ />Custom Theme
You can customize the look and feel of the checkout widget to match your brand.
<ReevitCheckout
theme={{
primaryColor: '#0EA5E9',
primaryForegroundColor: '#FFFFFF',
backgroundColor: '#F8FAFC',
borderColor: '#E2E8F0',
borderRadius: '12px',
companyName: 'Acme',
logoUrl: 'https://example.com/logo.png',
selectedBackgroundColor: '#E8F5F0',
selectedTextColor: '#0B1120',
selectedDescriptionColor: '#64748B',
selectedBorderColor: '#E2E8F0',
}}
// ...other props
>
<button>Secure Checkout</button>
</ReevitCheckout>Advanced Usage: useReevit Hook
For full control over the payment flow, use the useReevit hook. This allows you to build your own custom UI while Reevit handles the state management and API communication.
import { useReevit } from '@reevit/react';
function CustomCheckout() {
const {
status, // 'idle' | 'loading' | 'ready' | 'method_selected' | 'processing' | 'success' | 'failed'
initialize, // Start the process
selectMethod, // Pick 'card' or 'mobile_money'
processPayment, // Confirm payment
error,
isLoading
} = useReevit({
config: {
publicKey: 'pfk_test_xxx',
amount: 5000,
currency: 'GHS',
},
onSuccess: (res) => console.log('Done!', res),
});
if (status === 'loading') return <Spinner />;
return (
<div>
<button onClick={() => initialize()}>Start Checkout</button>
{status === 'ready' && (
<>
<button onClick={() => selectMethod('card')}>Card</button>
<button onClick={() => selectMethod('mobile_money')}>Mobile Money</button>
</>
)}
</div>
);
}Browser Support
- Chrome, Firefox, Safari, Edge (latest 2 versions)
- Mobile Safari and Chrome on Android/iOS
Props Reference
| Prop | Type | Description |
|------|------|-------------|
| publicKey | string | Your project's public key (required for API-created intents; optional when using paymentLinkCode) |
| amount | number | Required. Amount in the smallest unit (e.g., 500 for 5.00) |
| currency | string | Required. 3-letter ISO currency code (GHS, NGN, USD, etc.) |
| email | string | Customer's email address |
| phone | string | Customer's phone number (recommended for Mobile Money) |
| customerName | string | Customer name (used in payment links and some PSPs) |
| reference | string | Your own unique transaction reference |
| metadata | object | Key-value pairs to store with the transaction |
| customFields | object | Custom fields for payment links |
| paymentLinkCode | string | Hosted payment link code (uses the public link checkout flow) |
| paymentMethods | PaymentMethod[] | Enabled methods: card, mobile_money, bank_transfer, apple_pay, google_pay (PSP/country dependent) |
| initialPaymentIntent | PaymentIntent | Use an existing intent instead of creating a new one |
| children | ReactNode | Custom trigger element |
| autoOpen | boolean | Open automatically on mount |
| isOpen | boolean | Controlled open state |
| onOpenChange | (open: boolean) => void | Controlled open state handler |
| theme | ReevitTheme | Customization options for the widget |
| apiBaseUrl | string | Override API base URL (self-hosted/testing) |
| successDelayMs | number | Delay before calling onSuccess and closing (default 5000) |
| onSuccess | function | Called when the payment is successfully processed |
| onError | function | Called when an error occurs |
| onClose | function | Called when the user dismisses the widget |
| onStateChange | function | Called when checkout state changes |
Theme Reference
| Field | Description |
|-------|-------------|
| primaryColor | Primary text/brand color |
| primaryForegroundColor | Text color on primary brand surfaces |
| backgroundColor | Background color for the modal |
| borderColor | Border and divider color |
| borderRadius | Border radius for inputs and buttons |
| darkMode | Force dark mode when true |
| logoUrl | Logo URL shown in the header |
| companyName | Brand name shown in the header |
| selectedBackgroundColor | Background color for selected provider/methods |
| selectedTextColor | Primary text color for selected items |
| selectedDescriptionColor | Description/muted text color for selected items |
| selectedBorderColor | Border color for selected items |
| pspSelectorBgColor | PSP selector background color (where supported) |
| pspSelectorTextColor | PSP selector text color (where supported) |
| pspSelectorBorderColor | PSP selector border color (where supported) |
| pspSelectorUseBorder | Use border-only PSP selector styling |
PSP Bridges
For advanced use cases, you can use individual PSP bridges directly. These provide React components for each payment processor.
Stripe
import { StripeBridge } from '@reevit/react';
<StripeBridge
publishableKey="pk_test_xxx"
clientSecret="pi_xxx_secret_xxx" // From your backend
amount={5000}
currency="USD"
onSuccess={(result) => console.log('Paid:', result.paymentIntentId)}
onError={(err) => console.error(err.message)}
/>Monnify (Nigeria)
import { MonnifyBridge } from '@reevit/react';
<MonnifyBridge
apiKey="MK_TEST_xxx"
contractCode="1234567890"
amount={5000}
currency="NGN"
reference="TXN_12345"
customerName="John Doe"
customerEmail="[email protected]"
isTestMode={true}
onSuccess={(result) => console.log('Paid:', result.transactionReference)}
onError={(err) => console.error(err.message)}
/>M-Pesa (Kenya/Tanzania)
M-Pesa uses STK Push - the customer receives a prompt on their phone to authorize the payment.
import { MPesaBridge, useMPesaStatusPolling } from '@reevit/react';
function MpesaPayment() {
const [checkoutId, setCheckoutId] = useState(null);
const { startPolling } = useMPesaStatusPolling(
'/api/mpesa/status',
checkoutId,
{
onSuccess: (result) => console.log('Paid:', result.transactionId),
onFailed: (err) => console.error(err.message),
onTimeout: () => console.log('Timed out'),
}
);
return (
<MPesaBridge
apiEndpoint="/api/mpesa/stk-push"
phoneNumber="254712345678"
amount={500}
currency="KES"
reference="TXN_12345"
onInitiated={(id) => {
setCheckoutId(id);
startPolling();
}}
onSuccess={(result) => console.log('Paid!')}
onError={(err) => console.error(err.message)}
/>
);
}Supported PSPs
| Paystack | NG, GH, ZA, KE | Card, Mobile Money, Bank Transfer | | Flutterwave | NG, GH, KE, ZA + | Card, Mobile Money, Bank Transfer | | Hubtel | GH | Mobile Money | | Stripe | Global (50+) | Card, Apple Pay, Google Pay | | Monnify | NG | Card, Bank Transfer, USSD | | M-Pesa | KE, TZ | Mobile Money (STK Push) |
Release Notes
v0.7.0
- Redesigned checkout UI with premium visual polish
- New typography system: Grato Classic for body, ABC Repro Mono for amounts
- Layered shadow system for natural depth
- Replaced emoji icons with inline SVG icons (consistent cross-platform rendering)
- New loading animation (three-dot pulse), success glow effect, and countdown bar
- Improved dark mode contrast and surfaces
- Mobile bottom-sheet pattern with touch-friendly targets (44px+)
- Smoother animations with cubic-bezier easing curves
- Removed external Google Fonts dependency (zero network requests for fonts)
License
MIT © Reevit
