@nmipayments/nmi-pay-react
v1.0.0-beta.3
Published
NMI Embedded Component for Payments in React
Readme
@nmipayments/nmi-pay-react
React components for NMI Embedded Payments
Overview
React wrapper components for NMI payment processing, providing seamless integration of payment forms and 3D Secure authentication in React applications. Built on top of @nmipayments/nmi-pay with React-specific optimizations and hooks.
Features
- 🎯 React Components: Native React components with hooks integration
- 🔒 3D Secure Support: Dedicated component for 3D Secure authentication
- 💳 Express Checkout: Apple Pay and Google Pay support
- 🎨 TypeScript: Full TypeScript support with comprehensive type definitions
- ⚡ Performance: Optimized rendering and minimal re-renders
- 🔧 Ref Support: Imperative API access through React refs
- 📱 Responsive: Mobile-first responsive design
Installation
npm install @nmipayments/nmi-pay-reactPeer Dependencies:
react>= 16.8.0react-dom>= 16.8.0
Required CSP Directives
Content-Security-Policy:
frame-src 'self' https://secure.nmi.com https://secure.networkmerchants.com;
connect-src 'self' https://secure.nmi.com https://secure.networkmerchants.com;Usage
Basic Payment Form
import React from 'react';
import { NmiPayments } from '@nmipayments/nmi-pay-react';
function CheckoutPage() {
const handlePayment = async (token) => {
try {
// Process the payment with your backend
const response = await fetch('/api/process-payment', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ token, amount: 1000 })
});
if (response.ok) {
return true; // Payment successful
} else {
return 'Payment failed. Please try again.'; // Error message
}
} catch (error) {
return 'Network error. Please check your connection.';
}
};
return (
<div style={{ maxWidth: '500px', margin: '0 auto' }}>
<h1>Checkout</h1>
<NmiPayments
tokenizationKey="your-tokenization-key"
layout="multiLine"
paymentMethods={['card', 'ach', 'apple-pay', 'google-pay']}
appearance={{
theme: 'light',
layoutSpacing: 'default',
primaryColor: '#4c51bf'
}}
expressCheckoutConfig={{
applePay: {
merchantId: 'your-apple-merchant-id',
displayName: 'Your Business Name'
},
googlePay: {
merchantId: 'your-google-merchant-id',
environment: 'TEST'
}
}}
onPay={handlePayment}
onChange={(state) => {
console.log('Payment state:', state);
}}
onFieldsAvailable={() => {
console.log('Payment fields ready');
}}
/>
</div>
);
}
export default CheckoutPage;3D Secure Authentication
import React from 'react';
import { NmiThreeDSecure } from '@nmipayments/nmi-pay-react';
function ThreeDSecurePage() {
const handleAuthentication = (result) => {
console.log('3D Secure authentication completed:', result);
// Process the authenticated payment
};
const handleError = (error) => {
console.error('3D Secure error:', error);
// Handle authentication failure
};
return (
<div>
<h2>Secure Payment Verification</h2>
<NmiThreeDSecure
tokenizationKey="your-tokenization-key"
paymentInformation={{
amount: '10.00',
currency: 'USD',
orderId: 'order-123',
customerEmail: '[email protected]'
}}
onAuthenticated={handleAuthentication}
onError={handleError}
/>
</div>
);
}Using Refs for Imperative Control
import React, { useRef } from 'react';
import { NmiPayments } from '@nmipayments/nmi-pay-react';
function PaymentFormWithReset() {
const paymentRef = useRef();
const resetForm = () => {
if (paymentRef.current) {
paymentRef.current.resetFields();
}
};
return (
<div>
<NmiPayments
ref={paymentRef}
tokenizationKey="your-tokenization-key"
onPay={async (token) => {
// Handle payment
return true;
}}
/>
<button onClick={resetForm}>
Reset Form
</button>
</div>
);
}API Reference
NmiPayments Component
Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| tokenizationKey | string | - | Required. Your NMI tokenization key |
| layout | 'singleLine' \| 'multiLine' \| 'stacked' | 'multiLine' | Layout style for the payment form |
| paymentMethods | Array<PaymentMethod> | ['card', 'ach', 'apple-pay', 'google-pay'] | Available payment methods |
| paymentMethodLayout | 'singleLine' \| 'stacked' | 'singleLine' | Layout for payment method selector |
| appearance | Appearance | {} | Styling and theming configuration |
| expressCheckoutConfig | ExpressCheckoutConfig | {} | Apple Pay and Google Pay settings |
| showDivider | boolean | false | Show dividers between sections |
| payButtonText | string | 'Pay' | Text for the payment button |
| onPay | (token: string) => Promise<true \| string> | - | Required. Payment submission handler |
| onChange | (state: PaymentState) => void | - | Payment state change handler |
| onFieldsAvailable | () => void | - | Called when fields are ready |
Ref Methods
| Method | Description |
|--------|-------------|
| resetFields() | Clears all payment form fields |
PaymentMethod Type
type PaymentMethod = 'card' | 'ach' | 'apple-pay' | 'google-pay';Appearance Interface
interface Appearance {
theme?: 'light' | 'dark';
layoutSpacing?: 'compact' | 'default' | 'spacious';
textSize?: 'small' | 'default' | 'large';
radiusSize?: 'none' | 'small' | 'default' | 'large';
primaryColor?: string;
backgroundColor?: string;
borderColor?: string;
textColor?: string;
}ExpressCheckoutConfig Interface
interface ExpressCheckoutConfig {
applePay?: {
merchantId: string;
displayName: string;
countryCode?: string;
currencyCode?: string;
};
googlePay?: {
merchantId: string;
environment: 'TEST' | 'PRODUCTION';
countryCode?: string;
currencyCode?: string;
};
}NmiThreeDSecure Component
Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| tokenizationKey | string | - | Required. Your NMI tokenization key |
| paymentInformation | PaymentInformation | - | Required. Payment details for authentication |
| onAuthenticated | (result: any) => void | - | Required. Authentication success handler |
| onError | (error: string) => void | - | Required. Authentication error handler |
PaymentInformation Interface
interface PaymentInformation {
amount: string;
currency: string;
orderId?: string;
customerEmail?: string;
// Additional fields as needed
}Event Handling
Payment Events
The onPay callback receives a payment token and must return a Promise that resolves to:
truefor successful payment processingstringcontaining an error message for failed processing
const handlePayment = async (token) => {
try {
const result = await processPayment(token);
return result.success ? true : result.errorMessage;
} catch (error) {
return 'Payment processing failed';
}
};State Changes
The onChange callback provides real-time payment state updates:
const handleStateChange = (state) => {
console.log('Current state:', state);
// State includes field validation, payment method selection, etc.
};Error Handling
function PaymentWithErrorHandling() {
const [error, setError] = useState(null);
const handlePayment = async (token) => {
try {
setError(null);
const response = await processPayment(token);
if (response.success) {
return true;
} else {
const errorMessage = response.error || 'Payment failed';
setError(errorMessage);
return errorMessage;
}
} catch (err) {
const errorMessage = 'Network error occurred';
setError(errorMessage);
return errorMessage;
}
};
return (
<div>
{error && (
<div style={{ color: 'red', marginBottom: '1rem' }}>
{error}
</div>
)}
<NmiPayments
tokenizationKey="your-key"
onPay={handlePayment}
/>
</div>
);
}TypeScript Support
Full TypeScript definitions are included. Import types as needed:
import type {
PaymentWidgetProps,
PaymentState,
NmiPaymentsRef,
Appearance,
ExpressCheckoutConfig
} from '@nmipayments/nmi-pay-react';Testing
The package includes Cypress component tests. To run tests:
# Run component tests
npm run test
# Open Cypress test runner
npm run cy:open-unitBrowser Support
- Modern browsers with ES2020 support
- Safari 14+
- Chrome 84+
- Firefox 90+
- Edge 84+
License
MIT
