1
  • 堆栈:Nodejs/Vue/Stripe
  • 注意:逻辑适用于标准卡 (4242424242424242),当不存在试用版时,即使 3D 卡也可以使用。
  • 此卡用于此测试:4000002500003155

https://stripe.com/docs/testing#regulatory-cards

大家好,所以标题几乎说明了一切,试用期结束时我遇到了 3d 安全卡的问题。

重现步骤:节点(服务器):

  1. 创建客户
const customer = await this.getInstance().customers.create({
      email: userData.email,
      name: userData.fullname,
    });
  1. 创建订阅
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,
});
  1. 返回数据到客户端
 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 方面:

  1. 获取响应:
 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;
  1. 根据意图的类型:
 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 },
          });
        }
  1. 确认触发 3d 安全模式,确认后,支付 0 美元的发票。

一切正常,直到下一点。

为了尽可能快地测试跟踪模式,我制作了 API 以从订阅中删除试用版

 const subscription = await this.getInstance().subscriptions.update(subscriptionId, {
      trial_end: 'now',
    });

之后,发票过期,订阅失败(切换到待处理)。我注意到 default_payment_method 不存在,所以我什至从前端返回了设置意图付款方式,并附加到客户,甚至发票设置。但无论我修改了什么,新的发票和付款意图都不会使用该信息。

这种预期行为是由于某些规定还是我遗漏了什么?

发票

///////////////////// 订阅 _ 活动

4

1 回答 1

2

默认情况下,创建和更新订阅都被视为会话请求,因此卡需要身份验证。

如果这纯粹是为了测试目的,您可以包括off_session=true.

 const subscription = await this.getInstance().subscriptions.update(subscriptionId, {
    trial_end: 'now',
    off_session : true
 });

如果您让订阅的试用结束并自然进行(没有进行 API 调用来更新订阅),您会看到不会请求 3DS(使用以 3155 结尾的卡)。

trial_end您可以通过创建一个设置为最近可能时间的订阅来尝试此操作。如果您不想等待 1 小时自动完成发票,您可以调用 API 来完成支付发票。

const subscription = await stripe.subscriptions.create({
  customer: 'cus_FfkjLYmWcepurw',
  items: [
    {price: 'price_1JXgRCJQtHgRImA7fDIHY4B2'},
  ],
  trial_end : 1634536700
});
于 2021-10-18T07:04:11.937 回答