Form Elements
The Easy React Native SDK provides secure form elements for PCI-compliant payment data collection. These elements ensure your application never touches sensitive payment information.
Available Elements
import {
CardNumberElement, // Card number only
CardExpirationDateElement, // Expiration date only
CardVerificationCodeElement, // CVV only
TextElement, // Bank account numbers, routing numbers
} from "@easylabs/react-native";
React Native SDK uses separate card elements. There is no combined CardElement like in the web SDK.
CardNumberElement
Secure input for card numbers with automatic formatting and validation.
Usage
import { CardNumberElement } from "@easylabs/react-native";
import { useRef } from "react";
import { View, Text, StyleSheet } from "react-native";
function PaymentForm() {
const cardNumberRef = useRef(null);
return (
<View>
<Text style={styles.label}>Card Number</Text>
<CardNumberElement
btRef={cardNumberRef}
placeholder="4242 4242 4242 4242"
style={styles.input}
/>
</View>
);
}
const styles = StyleSheet.create({
label: {
fontSize: 16,
fontWeight: "600",
marginBottom: 8,
},
input: {
borderWidth: 1,
borderColor: "#ccc",
borderRadius: 8,
padding: 12,
fontSize: 16,
backgroundColor: "#fff",
},
});
Props
btRef(required) - React ref to access the element (note: usebtRef, notref)placeholder- Placeholder textstyle- React Native StyleSheet objecteditable- Whether the input is editable (default:true)
CardExpirationDateElement
Secure input for card expiration dates with automatic formatting.
Usage
import { CardExpirationDateElement } from "@easylabs/react-native";
import { useRef } from "react";
import { View, Text, StyleSheet } from "react-native";
function PaymentForm() {
const expiryRef = useRef(null);
return (
<View>
<Text style={styles.label}>Expiration Date</Text>
<CardExpirationDateElement
btRef={expiryRef}
placeholder="MM/YY"
style={styles.input}
/>
</View>
);
}
const styles = StyleSheet.create({
label: {
fontSize: 16,
fontWeight: "600",
marginBottom: 8,
},
input: {
borderWidth: 1,
borderColor: "#ccc",
borderRadius: 8,
padding: 12,
fontSize: 16,
backgroundColor: "#fff",
},
});
CardVerificationCodeElement
Secure input for CVV/CVC codes.
Usage
import { CardVerificationCodeElement } from "@easylabs/react-native";
import { useRef } from "react";
import { View, Text, StyleSheet } from "react-native";
function PaymentForm() {
const cvcRef = useRef(null);
return (
<View>
<Text style={styles.label}>CVC</Text>
<CardVerificationCodeElement
btRef={cvcRef}
placeholder="123"
style={styles.input}
/>
</View>
);
}
const styles = StyleSheet.create({
label: {
fontSize: 16,
fontWeight: "600",
marginBottom: 8,
},
input: {
borderWidth: 1,
borderColor: "#ccc",
borderRadius: 8,
padding: 12,
fontSize: 16,
backgroundColor: "#fff",
},
});
TextElement
General purpose secure text input for sensitive data like bank account numbers.
Usage
import { TextElement } from "@easylabs/react-native";
import { useRef } from "react";
import { View, Text, StyleSheet } from "react-native";
function BankAccountForm() {
const accountRef = useRef(null);
const routingRef = useRef(null);
return (
<View>
<Text style={styles.label}>Routing Number</Text>
<TextElement
btRef={routingRef}
placeholder="123456789"
style={styles.input}
/>
<Text style={styles.label}>Account Number</Text>
<TextElement
btRef={accountRef}
placeholder="0123456789"
style={styles.input}
/>
</View>
);
}
const styles = StyleSheet.create({
label: {
fontSize: 16,
fontWeight: "600",
marginBottom: 8,
marginTop: 16,
},
input: {
borderWidth: 1,
borderColor: "#ccc",
borderRadius: 8,
padding: 12,
fontSize: 16,
backgroundColor: "#fff",
},
});
Complete Payment Form
Example with all card elements together:
import {
CardNumberElement,
CardExpirationDateElement,
CardVerificationCodeElement,
useEasy,
} from "@easylabs/react-native";
import { useRef, useState } from "react";
import { View, Text, Button, StyleSheet, ScrollView } from "react-native";
function CompletePaymentForm() {
const { checkout } = useEasy();
const cardNumberRef = useRef(null);
const expiryRef = useRef(null);
const cvcRef = useRef(null);
const [loading, setLoading] = useState(false);
const handleSubmit = async () => {
setLoading(true);
try {
const result = await checkout({
customer_creation: true,
customer_details: {
first_name: "John",
last_name: "Doe",
email: "[email protected]",
},
source: {
type: "PAYMENT_CARD",
cardNumberElement: cardNumberRef,
cardExpirationDateElement: expiryRef,
cardVerificationCodeElement: cvcRef,
name: "Primary Card",
},
line_items: [{ price_id: "price_123", quantity: 1 }],
});
console.log("Payment successful!", result);
} catch (err) {
console.error("Payment failed:", err);
} finally {
setLoading(false);
}
};
return (
<ScrollView style={styles.container}>
<Text style={styles.title}>Payment Information</Text>
<Text style={styles.label}>Card Number</Text>
<CardNumberElement
btRef={cardNumberRef}
placeholder="4242 4242 4242 4242"
style={styles.input}
/>
<View style={styles.row}>
<View style={styles.column}>
<Text style={styles.label}>Expiration</Text>
<CardExpirationDateElement
btRef={expiryRef}
placeholder="MM/YY"
style={styles.input}
/>
</View>
<View style={styles.column}>
<Text style={styles.label}>CVC</Text>
<CardVerificationCodeElement
btRef={cvcRef}
placeholder="123"
style={styles.input}
/>
</View>
</View>
<Button
title={loading ? "Processing..." : "Pay Now"}
onPress={handleSubmit}
disabled={loading}
/>
</ScrollView>
);
}
const styles = StyleSheet.create({
container: {
padding: 20,
},
title: {
fontSize: 24,
fontWeight: "bold",
marginBottom: 24,
},
label: {
fontSize: 16,
fontWeight: "600",
marginBottom: 8,
marginTop: 16,
},
input: {
borderWidth: 1,
borderColor: "#ccc",
borderRadius: 8,
padding: 12,
fontSize: 16,
backgroundColor: "#fff",
},
row: {
flexDirection: "row",
gap: 12,
},
column: {
flex: 1,
},
});
Styling
Basic Styling
Apply styles using React Native StyleSheet:
const styles = StyleSheet.create({
input: {
borderWidth: 1,
borderColor: "#e0e0e0",
borderRadius: 8,
padding: 12,
fontSize: 16,
backgroundColor: "#ffffff",
},
});
<CardNumberElement btRef={cardRef} style={styles.input} />;
Focus States
Handle focus states manually:
import { useState } from "react";
function PaymentForm() {
const [isFocused, setIsFocused] = useState(false);
return (
<CardNumberElement
btRef={cardRef}
style={[styles.input, isFocused && styles.inputFocused]}
onFocus={() => setIsFocused(true)}
onBlur={() => setIsFocused(false)}
/>
);
}
const styles = StyleSheet.create({
input: {
borderWidth: 1,
borderColor: "#e0e0e0",
},
inputFocused: {
borderColor: "#007AFF",
borderWidth: 2,
},
});
Dark Mode
Support dark mode:
import { useColorScheme } from "react-native";
function PaymentForm() {
const colorScheme = useColorScheme();
const isDark = colorScheme === "dark";
return (
<CardNumberElement
btRef={cardRef}
style={[styles.input, isDark ? styles.inputDark : styles.inputLight]}
/>
);
}
const styles = StyleSheet.create({
input: {
borderWidth: 1,
borderRadius: 8,
padding: 12,
fontSize: 16,
},
inputLight: {
backgroundColor: "#ffffff",
borderColor: "#e0e0e0",
color: "#000000",
},
inputDark: {
backgroundColor: "#1c1c1e",
borderColor: "#38383a",
color: "#ffffff",
},
});
Best Practices
1. Always Use btRef
Use btRef prop instead of ref for secure form elements:
// ✅ Correct
<CardNumberElement btRef={cardRef} />
// ❌ Wrong
<CardNumberElement ref={cardRef} />
2. Validate Before Submission
Check that refs are set before processing:
const handleSubmit = async () => {
if (!cardNumberRef.current || !expiryRef.current || !cvcRef.current) {
Alert.alert("Error", "Please fill in all card details");
return;
}
await checkout({...});
};
3. Provide Clear Labels
Always label your form elements:
<Text style={styles.label}>Card Number</Text>
<CardNumberElement btRef={cardRef} />
4. Handle Keyboard
Manage keyboard behavior:
import { KeyboardAvoidingView, Platform } from "react-native";
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : "height"}
style={styles.container}
>
{/* Form elements */}
</KeyboardAvoidingView>;
5. Accessibility
Add accessibility props:
<Text style={styles.label} accessibilityLabel="Card number input">
Card Number
</Text>
<CardNumberElement
btRef={cardRef}
accessibilityLabel="Enter your card number"
accessibilityHint="16 digit card number"
/>