如何在Angular5的Stripe支付表单中添加账单信息字段
Ah, I get it—you tried adding {billing_name: true} to your Card Element config and it didn’t work, right? That’s because the pre-built card Element in Stripe doesn’t support that specific option. It only handles the core card fields (card number, expiry, CVC, and optionally postal code) out of the box. To collect billing name, address, and other customer details, you have two reliable approaches:
方案一:手动添加自定义表单字段(灵活可控)
You can build standard HTML form fields for billing details, then pass that data to Stripe when creating a Payment Method. Here’s how to implement this in your Angular component:
1. 更新模板(HTML)
Add custom input fields for billing info alongside the Stripe Card Element:
<!-- 自定义账单信息字段 --> <div class="form-group"> <label>账单姓名</label> <input type="text" [(ngModel)]="billingName" name="billingName" required> </div> <div class="form-group"> <label>账单地址</label> <input type="text" [(ngModel)]="billingAddress" name="billingAddress" required> </div> <div class="form-group"> <label>城市</label> <input type="text" [(ngModel)]="billingCity" name="billingCity" required> </div> <div class="form-group"> <label>州/省</label> <input type="text" [(ngModel)]="billingState" name="billingState" required> </div> <div class="form-group"> <label>邮编</label> <input type="text" [(ngModel)]="billingPostalCode" name="billingPostalCode" required> </div> <!-- Stripe Card Element --> <div #cardElement></div>
2. 更新组件逻辑(TypeScript)
Modify your component to collect the custom field values and pass them to Stripe when creating a Payment Method:
import { Component, ViewChild, ElementRef } from '@angular/core'; import { Stripe } from '@stripe/stripe-js'; @Component({ selector: 'app-payment-form', templateUrl: './payment-form.component.html', styleUrls: ['./payment-form.component.css'] }) export class PaymentFormComponent { @ViewChild('cardElement') cardElement!: ElementRef; card: any; // 绑定自定义字段的值 billingName: string = ''; billingAddress: string = ''; billingCity: string = ''; billingState: string = ''; billingPostalCode: string = ''; stripe: Stripe; constructor() { // 初始化Stripe实例(替换成你的公钥) this.stripe = window.Stripe('your-publishable-api-key'); } ngAfterViewInit() { const elements = this.stripe.elements(); // 创建Card Element,隐藏内置的邮编字段(因为我们自己加了) this.card = elements.create('card', { hidePostalCode: true }); this.card.mount(this.cardElement.nativeElement); } async processPayment() { try { // 创建Payment Method,传入卡片信息和账单详情 const { paymentMethod, error } = await this.stripe.createPaymentMethod({ type: 'card', card: this.card, billing_details: { name: this.billingName, address: { line1: this.billingAddress, city: this.billingCity, state: this.billingState, postal_code: this.billingPostalCode } } }); if (error) { console.error('创建Payment Method失败:', error); // 这里可以添加错误提示给用户 } else { // 将paymentMethod.id发送到你的后端,创建PaymentIntent完成支付 console.log('Payment Method已创建:', paymentMethod); // 调用你的后端API处理支付 } } catch (err) { console.error('支付处理出错:', err); } } }
方案二:使用Stripe Address Element(推荐,自带验证)
If you want Stripe to handle address formatting, validation, and localization, use the official Address Element alongside a custom name field. This is better for international customers.
1. 更新模板(HTML)
Add a name input and the Address Element:
<div class="form-group"> <label>账单姓名</label> <input type="text" [(ngModel)]="billingName" name="billingName" required> </div> <!-- Stripe Address Element --> <div #addressElement></div> <!-- Stripe Card Element --> <div #cardElement></div>
2. 更新组件逻辑(TypeScript)
Initialize the Address Element and fetch its values when processing payment:
import { Component, ViewChild, ElementRef } from '@angular/core'; import { Stripe } from '@stripe/stripe-js'; @Component({ selector: 'app-payment-form', templateUrl: './payment-form.component.html', styleUrls: ['./payment-form.component.css'] }) export class PaymentFormComponent { @ViewChild('cardElement') cardElement!: ElementRef; @ViewChild('addressElement') addressElement!: ElementRef; card: any; addressElementInstance: any; billingName: string = ''; stripe: Stripe; constructor() { this.stripe = window.Stripe('your-publishable-api-key'); } ngAfterViewInit() { const elements = this.stripe.elements({ locale: 'zh', // 设置语言,支持多语言 country: 'CN' // 默认国家 }); // 创建Card Element,隐藏内置邮编 this.card = elements.create('card', { hidePostalCode: true }); this.card.mount(this.cardElement.nativeElement); // 创建Address Element(账单地址模式) this.addressElementInstance = elements.create('address', { mode: 'billing', allowedCountries: ['CN', 'US'] // 限制允许的国家 }); this.addressElementInstance.mount(this.addressElement.nativeElement); } async processPayment() { try { // 从Address Element获取地址数据 const addressData = this.addressElementInstance.getValue(); // 创建Payment Method const { paymentMethod, error } = await this.stripe.createPaymentMethod({ type: 'card', card: this.card, billing_details: { name: this.billingName, address: { line1: addressData.line1, line2: addressData.line2, city: addressData.city, state: addressData.state, postal_code: addressData.postal_code, country: addressData.country } } }); if (error) { console.error('创建Payment Method失败:', error); } else { console.log('Payment Method已创建:', paymentMethod); // 发送到后端完成支付流程 } } catch (err) { console.error('支付处理出错:', err); } } }
为什么你的初始配置无效?
The {billing_name: true} option doesn’t exist for the pre-built card Element. That component is designed only to handle the essential card fields. To collect additional billing info, you need to either add custom fields or use Stripe’s dedicated Address Element, as shown above.
内容的提问来源于stack exchange,提问作者LearnToday

