260 lines
7.1 KiB
Markdown
260 lines
7.1 KiB
Markdown
# Stripe支付数据流程详解
|
||
|
||
## 1. 价格传递机制
|
||
|
||
### 1.1 基本价格传递
|
||
|
||
StripePaymentForm组件通过props接收基本价格信息:
|
||
|
||
```javascript
|
||
const props = defineProps({
|
||
amount: {
|
||
type: Number,
|
||
required: true // 金额(分)
|
||
},
|
||
currency: {
|
||
type: String,
|
||
default: 'usd' // 货币类型
|
||
},
|
||
// 其他props...
|
||
})
|
||
```
|
||
|
||
**关键说明**:
|
||
- `amount` 以**分**为单位(例如:100表示1美元或100日元)
|
||
- `currency` 默认为'usd',支持Stripe支持的所有货币
|
||
|
||
### 1.2 费用计算逻辑
|
||
|
||
组件内部会根据基础金额计算税费和运费:
|
||
|
||
```javascript
|
||
// 计算税费和运费
|
||
const calculateFees = () => {
|
||
// 模拟税费计算(8%)
|
||
taxAmount.value = Math.round(props.amount * 0.08)
|
||
|
||
// 模拟运费计算(满99免费)
|
||
shippingAmount.value = props.amount >= 9900 ? 0 : 1000
|
||
}
|
||
```
|
||
|
||
### 1.3 优惠券处理
|
||
|
||
组件支持优惠券折扣,会从最终金额中扣除:
|
||
|
||
```javascript
|
||
// 优惠券应用逻辑
|
||
if (discount < 1) {
|
||
// 百分比折扣
|
||
discountAmount.value = Math.round(props.amount * discount)
|
||
} else {
|
||
// 固定金额折扣
|
||
discountAmount.value = Math.min(discount, props.amount)
|
||
}
|
||
```
|
||
|
||
### 1.4 最终金额计算
|
||
|
||
通过计算属性`finalAmount`得出最终支付金额:
|
||
|
||
```javascript
|
||
const finalAmount = computed(() => {
|
||
return props.amount + taxAmount.value + shippingAmount.value - discountAmount.value
|
||
})
|
||
```
|
||
|
||
## 2. Stripe订单数据格式
|
||
|
||
### 2.1 支付方式创建数据
|
||
|
||
在`processPayment`函数中,创建支付方式时使用的数据格式:
|
||
|
||
```javascript
|
||
const { error, paymentMethod: pm } = await stripe.value.createPaymentMethod({
|
||
type: 'card',
|
||
card: cardElement.value,
|
||
billing_details: { email: props.customerEmail }
|
||
})
|
||
```
|
||
|
||
**参数说明**:
|
||
- `type`: 支付方式类型,这里固定为'card'
|
||
- `card`: Stripe卡片元素实例
|
||
- `billing_details`: 账单详情,包含客户邮箱
|
||
|
||
### 2.2 支付方式返回数据结构
|
||
|
||
Stripe返回的支付方式数据结构示例:
|
||
|
||
```javascript
|
||
{
|
||
id: 'pm_1234567890',
|
||
object: 'payment_method',
|
||
billing_details: {
|
||
address: {
|
||
city: null,
|
||
country: null,
|
||
line1: null,
|
||
line2: null,
|
||
postal_code: null,
|
||
state: null
|
||
},
|
||
email: 'customer@example.com',
|
||
name: null,
|
||
phone: null
|
||
},
|
||
card: {
|
||
brand: 'visa',
|
||
checks: {
|
||
address_line1_check: null,
|
||
address_postal_code_check: null,
|
||
cvc_check: 'pass'
|
||
},
|
||
country: 'US',
|
||
exp_month: 12,
|
||
exp_year: 2025,
|
||
fingerprint: 'abcdef1234567890',
|
||
funding: 'credit',
|
||
last4: '4242',
|
||
networks: {
|
||
available: ['visa'],
|
||
preferred: null
|
||
},
|
||
three_d_secure_usage: {
|
||
supported: true
|
||
},
|
||
wallet: null
|
||
},
|
||
created: 1678901234,
|
||
customer: null,
|
||
livemode: false,
|
||
type: 'card'
|
||
}
|
||
```
|
||
|
||
### 2.3 支付成功事件数据
|
||
|
||
支付成功后,组件通过`payment-success`事件返回的数据格式:
|
||
|
||
```javascript
|
||
emit('payment-success', {
|
||
paymentMethodId: paymentMethod?.id,
|
||
orderId: props.orderId,
|
||
amount: finalAmount.value,
|
||
currency: props.currency
|
||
})
|
||
```
|
||
|
||
**返回数据说明**:
|
||
- `paymentMethodId`: Stripe支付方式ID
|
||
- `orderId`: 订单ID(从props接收)
|
||
- `amount`: 最终支付金额(分)
|
||
- `currency`: 货币类型
|
||
|
||
### 2.4 与后端交互的数据格式
|
||
|
||
在实际项目中,前端需要将支付信息发送到后端,后端再与Stripe API交互。典型的数据格式:
|
||
|
||
```javascript
|
||
// 前端发送给后端的数据
|
||
const paymentData = {
|
||
orderId: props.orderId,
|
||
paymentMethodId: paymentMethod.id,
|
||
amount: finalAmount.value,
|
||
currency: props.currency,
|
||
customerEmail: props.customerEmail,
|
||
// 其他订单相关信息
|
||
}
|
||
|
||
// 后端返回的数据
|
||
const response = {
|
||
success: true,
|
||
paymentIntentId: 'pi_1234567890',
|
||
chargeId: 'ch_1234567890',
|
||
orderStatus: 'paid'
|
||
}
|
||
```
|
||
|
||
## 3. 数据流向图
|
||
|
||
```
|
||
父组件
|
||
│
|
||
├─── 传递基本价格信息 ───► StripePaymentForm组件
|
||
│ │
|
||
│ ├─── 计算税费和运费
|
||
│ │
|
||
│ ├─── 应用优惠券折扣
|
||
│ │
|
||
│ ├─── 创建支付方式 ───► Stripe API
|
||
│ │ │
|
||
│ │ └─── 返回支付方式数据
|
||
│ │
|
||
│ ├─── 发送支付数据 ───► 后端API
|
||
│ │ │
|
||
│ │ └─── 返回支付结果
|
||
│ │
|
||
│ └─── 触发支付事件 ───► 父组件
|
||
│
|
||
└─── 处理支付结果
|
||
```
|
||
|
||
## 4. 实际使用示例
|
||
|
||
### 4.1 父组件传递价格
|
||
|
||
```vue
|
||
<template>
|
||
<StripePaymentForm
|
||
:amount="10000" <!-- 100.00 元 -->
|
||
:currency="'cny'"
|
||
:order-id="'ORDER-20250101-001'"
|
||
:customer-email="'user@example.com'"
|
||
@payment-success="handlePaymentSuccess"
|
||
@payment-error="handlePaymentError"
|
||
/>
|
||
</template>
|
||
```
|
||
|
||
### 4.2 支付成功处理
|
||
|
||
```javascript
|
||
const handlePaymentSuccess = (paymentResult) => {
|
||
console.log('Payment successful:', paymentResult)
|
||
// 输出示例:
|
||
// {
|
||
// paymentMethodId: 'pm_1234567890',
|
||
// orderId: 'ORDER-20250101-001',
|
||
// amount: 10800, // 108.00 元(含8%税费)
|
||
// currency: 'cny'
|
||
// }
|
||
|
||
// 跳转到支付成功页面或更新订单状态
|
||
}
|
||
```
|
||
|
||
## 5. 注意事项
|
||
|
||
1. **金额单位**:始终使用分作为金额单位,避免浮点数精度问题
|
||
2. **货币一致性**:确保前端和后端使用相同的货币类型
|
||
3. **税费计算**:实际项目中应根据地区和法规调整税费计算逻辑
|
||
4. **运费规则**:根据实际业务需求调整运费计算规则
|
||
5. **优惠券验证**:生产环境中应通过后端API验证优惠券有效性
|
||
6. **支付结果处理**:必须处理支付成功和失败的情况
|
||
7. **幂等性设计**:确保重复支付请求不会导致多次扣款
|
||
|
||
## 6. 扩展建议
|
||
|
||
1. **支持多种货币**:根据用户地区自动切换货币
|
||
2. **动态税费计算**:根据不同地区和商品类型计算税费
|
||
3. **灵活运费规则**:支持多种运费模板和免运费条件
|
||
4. **优惠券系统集成**:与后端优惠券系统深度集成
|
||
5. **支付方式扩展**:支持Apple Pay、Google Pay等多种支付方式
|
||
6. **支付意图创建**:在后端创建Payment Intent,提高支付安全性
|
||
|
||
## 7. 总结
|
||
|
||
StripePaymentForm组件通过props接收基本价格信息,内部计算税费、运费和优惠券折扣,最终生成支付金额。支付过程中,组件与Stripe API交互创建支付方式,然后将支付信息发送到后端处理。支付结果通过事件通知父组件,完成整个支付流程。
|
||
|
||
了解数据流向和格式对于集成和扩展Stripe支付功能至关重要,可以帮助开发人员更好地理解和调试支付流程,确保支付系统的安全性和可靠性。 |