有谁知道如何设置具有这种特殊升级和降级要求的特定条带订阅?

Does anyone have an idea how can I set up a specific subscription in stripe with such a special requirements for upgrading and downgrading?

我正在开发一个能够分析用户数据的平台。我想使用 Stripe 付款,但我遇到了一些问题。首先,我想描述一下我希望我的定价如何,以便让您更清楚地了解我想要实现的目标。在创建帐户期间,用户可以 select 一个金额,例如从 1 美元到 1000 美元,该金额将可用于所有服务。这笔金额将每月收取,因此这将作为订阅计划运作。不同之处在于,该金额不会像订阅一样在每​​月的每一天按比例使用。例如,用户从每月 5 日开始一个月的定价期,金额等于 10 美元。在此期间的前 10 天,他没有执行任何操作,因此他仍然有 10 美元。第 11 天,他启动服务并在 5 小时内使用了 4 美元。从此时起,他不使用任何工具,直到当前周期结束,他还剩下 6 美元。我当时决定未使用的资金可能不会转移到下一个计费周期,因此从下个月的 5 日起他将再次获得 10 美元。当然,他的发票每个月都会预收10$。在我看来,到那时我已经找到了解决方案。我的应用程序基于 Angular 前端和 Django 后端。因此,在前端,我在初始订阅创建期间通过设置和帐户执行如下所示的操作:

pay(amount) {
  var self = this;
  var handler = (<any>window).StripeCheckout.configure({
    key: ‘key’,
    locale: 'auto',
    token: (token: any) => {

      this.UserService.sendAccountPricing(token.id, amount).subscribe((data: any) => {
    // some code
        },
        (err: HttpErrorResponse) => {
          console.log(err.error)
          alert(err.error)
        });

    }
  });

  handler.open({
    closed: function () {
      self.UploaderService.displayNewPaymentButton = true;
    },
    name: 'Demo Site',
    description: '2 widgets',
    amount: amount * 100,
    email: this.UploaderService.email
  });
}

在后端:

def post(self, request):

    serializer = AccountSerializer(data=request.data)

    if serializer.is_valid():

        key = request.META.get('HTTP_AUTHORIZATION').split()[1]

        user_id = Token.objects.get(key=key).user_id

        user = User.objects.get(id=user_id)

        customer = stripe.Customer.create(
            email=user.email,
            source=request.data['token']
        )

        subscription = stripe.Subscription.create(
            customer=customer.id,
            items=[
                {
                    'plan': 'plan_H8Kg0c8l8WmaQM',
                    'quantity': request.data['amount'],
                },
            ],
            expand=['latest_invoice.payment_intent'],
        )

        Account.objects.filter(user=user).update(subscription=subscription['id'])
        Account.objects.filter(user=user).update(plan_selected=True)

        return Response(status=status.HTTP_200_OK)

我在订阅设置中配置了每 1 个数量等于 1 美元。因此,当用户 select 的每月定价计划等于 13$ 时,我将金额等于 13 的信息发送到后端,然后 Django 后端向 Stripe 发送请求以创建订阅,数量为 13,等于 13$。上面的源代码负责这部分。你能看一下并检查它是否正确完成了吗?也许有更好的方法来做到这一点?这只是我想到的唯一解决方案,但它似乎有效。当我想降级或升级我的计划时,问题就开始了。这是我希望它看起来的样子。当用户降级或升级他的定价计划时,我只计算他在当前计费周期内花费了多少钱,然后将他剩下的所有金额还给他。然后我用他在新计划中选择的金额收取他的发票,我从这一刻开始一个新的计费周期。示例:

用户在 5 月 3 日创建了一个每月订阅等于 20 美元的帐户。5 月 10 日,他意识到预算不够,因为他已经使用了 17 美元,他决定将他的计划升级到 50 美元.系统 returns 他还剩下 3 美元,并向他的帐户收取相当于 50 美元的金额。现在他的账单期从 5 月 10 日开始,下一张等于 50 美元的发票将在 6 月 10 日。这就是问题所在。我在 Stripe 中找不到允许我这样做的功能。我试图做如下所示的事情,但当然它不起作用。订阅修改是不够的,因为它不能像我想的那样工作,正如我上面描述的那样。有谁知道我该怎么做?我将非常感谢您的帮助。此外,非常感谢关于我可以做得更好的建议和提示。

前端:

  newPlan(amount) {

    var handler = (<any>window).StripeCheckout.configure({
      key: ‘key’,
      locale: 'auto',
      token: (token: any) => {

        alert('Your pricing plan has been changed.');


        this.UserService.sendChangeAccountPricing(token.id, amount).subscribe((data: any) => {
        // some code
          },
          (err: HttpErrorResponse) => {
            console.log(err.error)
            alert(err.error)
          });

      }
    });

    handler.open({
      name: 'Demo Site',
      description: '2 widgets',
      amount: amount * 100
    });

  }

后端:

def put(self, request):

    serializer = AccountSerializer(data=request.data)

    if serializer.is_valid():

        key = request.META.get('HTTP_AUTHORIZATION').split()[1]

        user_id = Token.objects.get(key=key).user_id

        user = User.objects.get(id=user_id)

        account = Account.objects.filter(user=user)

        account = Account.objects.get(user=user)

        subscription = stripe.Subscription.retrieve(account.subscription)

        subscription = stripe.Subscription.modify(
            subscription.id,
            items=[{
                'id': subscription['items']['data'][0].id,
                'plan': ‘myplan',
                'quantity': request.data['amount']
            }],
            billing_cycle_anchor='now',
            proration_behavior='none',
        )

        return Response(status=status.HTTP_200_OK)

将其分解以解决关键问题:

如果你想change the billing cycle when updating the subscription, you can use the billing_cycle_anchor parameter。这将影响以后的发票。

其次,虽然您可以 prorate the plan/quantity changes,但 Stripe 按比例分配逻辑始终基于线性时间消耗(并且仅适用于许可的按席位计划,而非计量)。如果您想记入不同的金额,则需要手动进行,并禁用 Stripe 的按比例分配。您可以:

  • Create an invoice item对升级前的客户,用负数表示信用。当为客户创建下一张发票时,将提取此项目并将信用额度应用于新的订阅金额。
  • 为上一张发票的付款开具 partial refund 您认为应退还给客户的金额。