STRIPE - 通过试用创建订阅,在试用结束后对 3D 安全卡实施 one-time 身份验证失败
STRIPE - Creating Subscription with trial, implementing one-time authentication fails for 3D secure cards after trial ends
- 堆栈:Nodejs/Vue/Stripe
- 注意:逻辑适用于标准卡 (4242424242424242),当
即使 3D 卡有效,试用版也不存在。
- 本次测试使用的卡号:4000002500003155
大家好,
所以标题几乎说明了一切,我在试用结束时遇到 3d 安全卡问题。
重现步骤:
节点(服务器):
- 创建客户
const customer = await this.getInstance().customers.create({
email: userData.email,
name: userData.fullname,
});
- 创建订阅
const subscription = await this.getInstance().subscriptions.create({
customer,
items: [
{
price: priceId,
},
],
off_session: true,
promotion_code,
payment_behavior: 'default_incomplete',
expand: ['latest_invoice.payment_intent', 'pending_setup_intent'],
metadata,
trial_from_plan: true,
});
- return数据到客户端
const invoice = subscription.latest_invoice as Stripe.Invoice;
const intentType = subscription.pending_setup_intent ? 'setup' : 'payment';
const intent = intentType === 'payment'
? (invoice.payment_intent as Stripe.PaymentIntent)
: (subscription.pending_setup_intent as Stripe.SetupIntent);
const formattedSubscription = pick(subscription,['cancel_at_period_end','cancel_at','canceled_at']);
return {
intentType,
...pick(intent, ['id', 'client_secret', 'status']),
...formattedSubscription,
};
从 CLINET 端:
- 正在获取响应:
const response = await this.$pricesService.buyPlan(this.selectedPlan.id, {
fullname: this.nameOnTheCard,
email: this.email,
hash: this.couponApplied?.hash,
});
if (response.error) {
throw new Error(response.error);
}
const { intentSecret, intentID, intentType, ...restOfBuyResponse } = response;
- 取决于意图的类型:
if (intentType === 'payment') {
stripeResponse = await StripeInstance.confirmCardPayment(intentSecret, {
payment_method: { card: this.$refs.cardElement.$refs.element._element },
});
} else {
stripeResponse = await StripeInstance.confirmCardSetup(intentSecret, {
payment_method: { card: this.$refs.cardElement.$refs.element._element },
});
}
- 确认触发 3d 安全模式,确认后,支付 0 美元的发票。
在下一点之前一切正常。
为了尽可能快地测试跟踪模式,我已经API从订阅中删除试用
const subscription = await this.getInstance().subscriptions.update(subscriptionId, {
trial_end: 'now',
});
之后,Invoice OverDue,订阅失败(切换到pending)。
我注意到 default_payment_method 不存在,所以我什至从前面 returned 设置意向付款方式,并附加到客户,甚至是发票设置。
但无论我修改了什么,新的发票和付款意向从未使用过该信息。
这是由于某些规定导致的预期行为还是我遗漏了什么?
///////////
////////////
默认情况下,创建和更新订阅都被视为 on-session 请求,因此卡需要身份验证。
如果这纯粹是为了测试目的,您可以包括 off_session=true
。
const subscription = await this.getInstance().subscriptions.update(subscriptionId, {
trial_end: 'now',
off_session : true
});
如果您让订阅试用自然结束并继续进行(无需调用 API 更新订阅),您会看到不会请求 3DS(使用以 3155 结尾的卡) .
您可以通过将 trial_end
设置为最接近的时间来创建订阅来进行尝试。如果您不想等待 1 小时自动完成,您可以 API 调用 finalize and pay 发票。
const subscription = await stripe.subscriptions.create({
customer: 'cus_FfkjLYmWcepurw',
items: [
{price: 'price_1JXgRCJQtHgRImA7fDIHY4B2'},
],
trial_end : 1634536700
});
- 堆栈:Nodejs/Vue/Stripe
- 注意:逻辑适用于标准卡 (4242424242424242),当 即使 3D 卡有效,试用版也不存在。
- 本次测试使用的卡号:4000002500003155
大家好, 所以标题几乎说明了一切,我在试用结束时遇到 3d 安全卡问题。
重现步骤: 节点(服务器):
- 创建客户
const customer = await this.getInstance().customers.create({ email: userData.email, name: userData.fullname, });
- 创建订阅
const subscription = await this.getInstance().subscriptions.create({ customer, items: [ { price: priceId, }, ], off_session: true, promotion_code, payment_behavior: 'default_incomplete', expand: ['latest_invoice.payment_intent', 'pending_setup_intent'], metadata, trial_from_plan: true, });
- return数据到客户端
const invoice = subscription.latest_invoice as Stripe.Invoice; const intentType = subscription.pending_setup_intent ? 'setup' : 'payment'; const intent = intentType === 'payment' ? (invoice.payment_intent as Stripe.PaymentIntent) : (subscription.pending_setup_intent as Stripe.SetupIntent); const formattedSubscription = pick(subscription,['cancel_at_period_end','cancel_at','canceled_at']); return { intentType, ...pick(intent, ['id', 'client_secret', 'status']), ...formattedSubscription, };
从 CLINET 端:
- 正在获取响应:
const response = await this.$pricesService.buyPlan(this.selectedPlan.id, { fullname: this.nameOnTheCard, email: this.email, hash: this.couponApplied?.hash, }); if (response.error) { throw new Error(response.error); }
const { intentSecret, intentID, intentType, ...restOfBuyResponse } = response;
- 取决于意图的类型:
if (intentType === 'payment') { stripeResponse = await StripeInstance.confirmCardPayment(intentSecret, { payment_method: { card: this.$refs.cardElement.$refs.element._element }, }); } else { stripeResponse = await StripeInstance.confirmCardSetup(intentSecret, { payment_method: { card: this.$refs.cardElement.$refs.element._element }, }); }
- 确认触发 3d 安全模式,确认后,支付 0 美元的发票。
在下一点之前一切正常。
为了尽可能快地测试跟踪模式,我已经API从订阅中删除试用
const subscription = await this.getInstance().subscriptions.update(subscriptionId, { trial_end: 'now', });
之后,Invoice OverDue,订阅失败(切换到pending)。 我注意到 default_payment_method 不存在,所以我什至从前面 returned 设置意向付款方式,并附加到客户,甚至是发票设置。 但无论我修改了什么,新的发票和付款意向从未使用过该信息。
这是由于某些规定导致的预期行为还是我遗漏了什么?
///////////
默认情况下,创建和更新订阅都被视为 on-session 请求,因此卡需要身份验证。
如果这纯粹是为了测试目的,您可以包括 off_session=true
。
const subscription = await this.getInstance().subscriptions.update(subscriptionId, {
trial_end: 'now',
off_session : true
});
如果您让订阅试用自然结束并继续进行(无需调用 API 更新订阅),您会看到不会请求 3DS(使用以 3155 结尾的卡) .
您可以通过将 trial_end
设置为最接近的时间来创建订阅来进行尝试。如果您不想等待 1 小时自动完成,您可以 API 调用 finalize and pay 发票。
const subscription = await stripe.subscriptions.create({
customer: 'cus_FfkjLYmWcepurw',
items: [
{price: 'price_1JXgRCJQtHgRImA7fDIHY4B2'},
],
trial_end : 1634536700
});