@xsolla/xui-input-payment
v0.106.0
Published
A cross-platform React payment card input that automatically detects the card type from the entered number and displays relevant payment icons.
Readme
Input Payment
A cross-platform React payment card input that automatically detects the card type from the entered number and displays relevant payment icons.
Installation
npm install @xsolla/xui-input-payment
# or
yarn add @xsolla/xui-input-paymentDemo
Basic Payment Input
import * as React from 'react';
import { InputPayment } from '@xsolla/xui-input-payment';
export default function BasicPayment() {
const [cardNumber, setCardNumber] = React.useState('');
return (
<InputPayment
value={cardNumber}
onChangeText={setCardNumber}
placeholder="Card number"
/>
);
}With Auto-Detection Callback
import * as React from 'react';
import { InputPayment } from '@xsolla/xui-input-payment';
export default function WithDetection() {
const [cardNumber, setCardNumber] = React.useState('');
const [cardType, setCardType] = React.useState<string | null>(null);
return (
<div>
<InputPayment
value={cardNumber}
onChangeText={setCardNumber}
onRecognizedPaymentChange={(type) => setCardType(type)}
/>
{cardType && <p>Detected: {cardType}</p>}
</div>
);
}Different Sizes
import * as React from 'react';
import { InputPayment } from '@xsolla/xui-input-payment';
export default function Sizes() {
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
<InputPayment size="sm" placeholder="Small" />
<InputPayment size="md" placeholder="Medium" />
<InputPayment size="lg" placeholder="Large" />
</div>
);
}Anatomy
import { InputPayment } from '@xsolla/xui-input-payment';
<InputPayment
value={cardNumber} // Card number value
onChangeText={setCardNumber} // Change handler
size="md" // Input size
placeholder="Card number" // Placeholder text
possiblePayments={['visa', 'mastercard']} // Accepted cards
maxVisiblePossiblePayments={5} // Max icons shown
recognizedPayment="visa" // Force recognized type
autoDetect={true} // Enable auto-detection
errorMessage="Invalid card" // Error message
disabled={false} // Disabled state
/>Examples
Custom Accepted Cards
import * as React from 'react';
import { InputPayment } from '@xsolla/xui-input-payment';
export default function CustomCards() {
return (
<InputPayment
possiblePayments={['visa', 'mastercard', 'amex']}
maxVisiblePossiblePayments={3}
placeholder="We accept Visa, Mastercard, Amex"
/>
);
}With Error State
import * as React from 'react';
import { InputPayment } from '@xsolla/xui-input-payment';
export default function WithError() {
const [cardNumber, setCardNumber] = React.useState('');
const [error, setError] = React.useState('');
const validate = (value: string) => {
if (value.length > 0 && value.length < 13) {
setError('Card number too short');
} else {
setError('');
}
};
return (
<InputPayment
value={cardNumber}
onChangeText={(text) => {
setCardNumber(text);
validate(text);
}}
errorMessage={error}
/>
);
}Controlled Recognition
import * as React from 'react';
import { InputPayment } from '@xsolla/xui-input-payment';
export default function ControlledRecognition() {
const [cardNumber, setCardNumber] = React.useState('');
return (
<InputPayment
value={cardNumber}
onChangeText={setCardNumber}
autoDetect={false}
recognizedPayment={cardNumber.startsWith('4') ? 'visa' : undefined}
/>
);
}With Icon
import * as React from 'react';
import { InputPayment } from '@xsolla/xui-input-payment';
import { CreditCard } from '@xsolla/xui-icons-base';
export default function WithIcon() {
return (
<InputPayment
icon={<CreditCard />}
placeholder="Enter card number"
/>
);
}In Payment Form
import * as React from 'react';
import { InputPayment } from '@xsolla/xui-input-payment';
import { Input } from '@xsolla/xui-input';
import { Button } from '@xsolla/xui-button';
export default function PaymentForm() {
const [cardNumber, setCardNumber] = React.useState('');
const [cardType, setCardType] = React.useState<string | null>(null);
return (
<form style={{ display: 'flex', flexDirection: 'column', gap: 16, maxWidth: 400 }}>
<InputPayment
value={cardNumber}
onChangeText={setCardNumber}
onRecognizedPaymentChange={setCardType}
placeholder="Card number"
/>
<div style={{ display: 'flex', gap: 16 }}>
<Input placeholder="MM/YY" style={{ flex: 1 }} />
<Input placeholder="CVV" style={{ width: 100 }} />
</div>
<Input placeholder="Cardholder name" />
<Button onPress={() => console.log('Submit', { cardNumber, cardType })}>
Pay Now
</Button>
</form>
);
}API Reference
InputPayment
InputPaymentProps:
| Prop | Type | Default | Description |
| :--- | :--- | :------ | :---------- |
| value | string | - | Card number value. |
| onChange | (e: ChangeEvent) => void | - | Standard change event handler. |
| onChangeText | (text: string) => void | - | Text change handler. |
| size | "xs" \| "sm" \| "md" \| "lg" \| "xl" | "md" | Input size variant. |
| placeholder | string | "Card number" | Placeholder text. |
| icon | ReactNode | - | Left icon. |
| disabled | boolean | false | Disabled state. |
| error | boolean | - | Error state indicator. |
| errorMessage | string | - | Error message text. |
| possiblePayments | PaymentSystemKey[] | See below | Accepted payment types. |
| maxVisiblePossiblePayments | number | 5 | Max payment icons shown. |
| recognizedPayment | PaymentSystemKey | - | Force recognized payment type. |
| onRecognizedPaymentChange | (type: PaymentSystemKey \| null) => void | - | Detection callback. |
| autoDetect | boolean | true | Enable auto-detection. |
| aria-label | string | "Card number" | Accessible label. |
| testID | string | - | Test identifier. |
Default possiblePayments:
['mastercard', 'visa', 'maestro', 'diners', 'amex', 'discover', 'jcb', 'unionpay']PaymentSystemKey:
type PaymentSystemKey =
| 'visa'
| 'mastercard'
| 'amex'
| 'diners'
| 'maestro'
| 'unionpay'
| 'discover'
| 'jcb'
| 'aura'
| 'cartesbancaires'
| 'cirrus'
| 'dankort'
| 'elo'
| 'hipercard'
| 'mir'
| 'naranja'
| 'paypal'
| 'sodexo'
| 'uatp';Card Detection
The component automatically detects card types based on BIN (Bank Identification Number) ranges:
| Card Type | BIN Pattern | | :-------- | :---------- | | Visa | Starts with 4 | | Mastercard | 51-55 or 2221-2720 | | American Express | 34, 37 | | Discover | 6011, 644-649, 65 | | JCB | 3528-3589 | | Diners Club | 300-305, 36, 38 | | UnionPay | 62 (except Discover range) | | Maestro | 50, 56-69 | | Mir | 2200-2204 |
Icon Animation
- Payment icons cycle through when multiple are available
- When a card type is detected, other icons slide out
- The recognized card icon remains visible
- Animation is smooth with 300ms transitions
Accessibility
- Input has
aria-labelfor screen readers - Error messages are linked via
aria-describedby - Payment icons have descriptive
aria-label - Disabled state is announced with
aria-disabled inputMode="numeric"shows numeric keyboard on mobile
