React Stripe Elements 组件库实战教程
2025-07-10 04:01:20作者:咎岭娴Homer
前言
React Stripe Elements 是一个用于构建 Stripe 支付表单的 React 组件库,它提供了多种支付元素组件,让开发者能够轻松地在 React 应用中集成 Stripe 支付功能。本文将深入解析该库的核心组件和使用方法,帮助开发者快速掌握构建安全支付表单的技巧。
核心组件介绍
React Stripe Elements 提供了多种支付表单组件,每种组件对应不同的支付场景:
- CardElement - 完整的信用卡输入组件
- CardNumberElement - 仅信用卡号输入
- CardExpiryElement - 信用卡有效期输入
- CardCvcElement - 信用卡安全码输入
- PaymentRequestButtonElement - Apple Pay/Google Pay 按钮
- IbanElement - 欧洲银行账号(IBAN)输入
- IdealBankElement - iDEAL 银行选择器
基础架构
使用 React Stripe Elements 需要三个核心高阶组件:
- StripeProvider - 提供 Stripe 上下文
- Elements - 定义一组 Stripe 元素
- injectStripe - 将 Stripe 实例注入到表单组件中
<StripeProvider apiKey="your_publishable_key">
<Elements>
<YourPaymentForm />
</Elements>
</StripeProvider>
支付表单实现详解
1. 完整信用卡表单
CardForm
组件展示了如何使用 CardElement
创建一个完整的信用卡输入表单:
class _CardForm extends React.Component {
handleSubmit = (ev) => {
ev.preventDefault();
this.props.stripe.createToken().then((payload) => {
console.log('[token]', payload);
});
};
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>Card details</label>
<CardElement {...createOptions(this.props.fontSize)} />
<button>Pay</button>
</form>
);
}
}
const CardForm = injectStripe(_CardForm);
关键点:
- 使用
injectStripe
注入 Stripe 实例 - 通过
createToken
方法生成支付令牌 - 自定义样式通过
createOptions
函数实现
2. 分体式信用卡表单
SplitForm
组件展示了如何将信用卡信息拆分成多个独立输入框:
class _SplitForm extends React.Component {
// ...类似提交逻辑
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>Card number</label>
<CardNumberElement {...createOptions(this.props.fontSize)} />
<label>Expiration date</label>
<CardExpiryElement {...createOptions(this.props.fontSize)} />
<label>CVC</label>
<CardCvcElement {...createOptions(this.props.fontSize)} />
<button>Pay</button>
</form>
);
}
}
3. 移动支付表单
PaymentRequestForm
组件实现了 Apple Pay/Google Pay 支付按钮:
class _PaymentRequestForm extends React.Component {
constructor(props) {
super(props);
const paymentRequest = props.stripe.paymentRequest({
country: 'US',
currency: 'usd',
total: { label: 'Demo total', amount: 1000 }
});
this.state = { paymentRequest, canMakePayment: false };
}
componentDidMount() {
this.state.paymentRequest.on('token', ({complete, token}) => {
console.log('Received Stripe token:', token);
complete('success');
});
this.state.paymentRequest.canMakePayment().then(result => {
this.setState({canMakePayment: !!result});
});
}
render() {
return this.state.canMakePayment ? (
<PaymentRequestButtonElement
paymentRequest={this.state.paymentRequest}
style={{
paymentRequestButton: {
theme: 'dark',
height: '64px',
type: 'donate',
},
}}
/>
) : null;
}
}
4. 欧洲银行转账表单
IbanForm
组件实现了 SEPA 直接借记支付:
class _IbanForm extends React.Component {
handleSubmit = (ev) => {
ev.preventDefault();
this.props.stripe.createSource({
type: 'sepa_debit',
currency: 'eur',
owner: {
name: ev.target.name.value,
email: ev.target.email.value,
},
mandate: { notification_method: 'email' }
}).then(payload => console.log('[source]', payload));
};
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>Name<input name="name" type="text" required /></label>
<label>Email<input name="email" type="email" required /></label>
<label>IBAN<IbanElement supportedCountries={['SEPA']} {...createOptions(this.props.fontSize)} /></label>
<button>Pay</button>
</form>
);
}
}
5. iDEAL 银行支付表单
IdealBankForm
组件实现了荷兰 iDEAL 支付方式:
class _IdealBankForm extends React.Component {
handleSubmit = (ev) => {
ev.preventDefault();
this.props.stripe.createSource({
type: 'ideal',
amount: 1099,
currency: 'eur',
owner: { name: ev.target.name.value },
redirect: { return_url: 'https://example.com' }
}).then(payload => console.log('[source]', payload));
};
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>Name<input name="name" type="text" required /></label>
<label>iDEAL Bank<IdealBankElement {...createOptions(this.props.fontSize, '10px 14px')} /></label>
<button>Pay</button>
</form>
);
}
}
样式定制技巧
createOptions
函数提供了自定义元素样式的能力:
const createOptions = (fontSize, padding) => ({
style: {
base: {
fontSize,
color: '#424770',
letterSpacing: '0.025em',
fontFamily: 'Source Code Pro, monospace',
'::placeholder': { color: '#aab7c4' },
...(padding ? {padding} : {}),
},
invalid: { color: '#9e2146' }
}
});
可以自定义的属性包括:
- 字体大小和颜色
- 占位符样式
- 无效状态样式
- 内边距等布局属性
响应式设计实现
Checkout
组件展示了如何根据屏幕尺寸调整支付元素的大小:
class Checkout extends React.Component {
constructor() {
super();
this.state = { elementFontSize: window.innerWidth < 450 ? '14px' : '18px' };
window.addEventListener('resize', this.handleResize);
}
handleResize = () => {
if (window.innerWidth < 450 && this.state.elementFontSize !== '14px') {
this.setState({elementFontSize: '14px'});
} else if (window.innerWidth >= 450 && this.state.elementFontSize !== '18px') {
this.setState({elementFontSize: '18px'});
}
};
render() {
return (
<div className="Checkout">
<Elements><CardForm fontSize={this.state.elementFontSize} /></Elements>
{/* 其他表单... */}
</div>
);
}
}
事件处理
所有 Stripe 元素都支持以下事件处理:
onBlur
- 失去焦点时触发onChange
- 值变化时触发onFocus
- 获得焦点时触发onReady
- 元素初始化完成时触发
const handleBlur = () => console.log('[blur]');
const handleChange = (change) => console.log('[change]', change);
const handleFocus = () => console.log('[focus]');
const handleReady = () => console.log('[ready]');
<CardElement
onBlur={handleBlur}
onChange={handleChange}
onFocus={handleFocus}
onReady={handleReady}
/>
最佳实践
- 安全性:永远在前端使用 publishable key,secret key 必须保存在后端
- 错误处理:妥善处理
createToken
和createSource
的 Promise 拒绝 - 用户体验:提供清晰的错误提示和加载状态
- 移动优化:确保表单在移动设备上易于操作
- 合规性:遵循 PCI DSS 规范处理支付数据
结语
React Stripe Elements 提供了一种安全、便捷的方式在 React 应用中集成 Stripe 支付功能。通过本文的详细解析,开发者可以快速掌握各种支付表单的实现方法,并根据实际需求进行定制开发。记住,支付系统涉及敏感数据,务必遵循安全最佳实践,确保用户支付信息的安全。