У кого-нибудь есть идеи, как я могу настроить конкретную c подписку в полоску с такими особыми требованиями для обновления и понижения? - PullRequest
0 голосов
/ 30 апреля 2020

Я работаю на платформе, способной анализировать данные пользователей. Я хотел бы использовать платежи Stripe, однако у меня есть некоторые проблемы. Сначала я хотел бы описать, как я хотел бы, чтобы мои цены выглядели так, чтобы было яснее понять для вас, чего я хочу достичь. Во время создания учетной записи пользователь может выбрать сумму, например, от 1 до 1000 долларов, которая будет доступна для всех услуг. Эта сумма будет взиматься каждый месяц, так что это будет работать как план подписки. Разница в том, что сумма не используется пропорционально каждый день месяца, как в случае с подписками. Например, пользователь начинает месячный ценовой период 5-го числа месяца с суммы, равной 10 $. В течение первых 10 дней этого периода он не выполняет никаких действий, поэтому у него все еще есть 10 $. На 11-й день он запускает сервис и использует 4 $ в течение 5 часов. С этого времени он не использует никаких инструментов до конца текущего периода, и у него осталось 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 $. Поэтому, когда пользователь выбирает месячный тарифный план, равный 13 $, я отправляю бэкэнду информацию с суммой, равной 13, а затем Django бэкэнд отправляет запрос в Stripe для создания подписки с 13 количествами, что равно 13 $. Исходный код выше отвечает за эту часть. Можете ли вы взглянуть и проверить, правильно ли это сделано? Может быть, есть лучший способ сделать это? Это единственное решение, которое пришло мне в голову, но, похоже, работает. Проблемы начинаются, когда я хочу понизить или обновить свой план. Вот как я бы хотел, чтобы это выглядело. Когда пользователь понижает или обновляет свой тарифный план, я просто рассчитываю, сколько денег он потратил в течение текущего платежного периода, и возвращаю ему всю оставшуюся сумму. Затем я списываю с его счета сумму, которую он выбрал в новом плане, и с этого момента начинаю новый расчетный период. Пример:

3 мая пользователь создает учетную запись с ежемесячной подпиской, равной 20 $. 10 мая он понимает, что ему недостаточно бюджета, поскольку он уже использовал 17 $, и решает обновить свой план. до 50 $. Система возвращает ему 3 $, которые он получил, и списывает с его счета сумму в 50 $. Теперь его расчетный период начинается с 10 мая, а следующий счет, равный 50 $, будет 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)

1 Ответ

1 голос
/ 30 апреля 2020

Разбиваем это на ключевые элементы:

Если вы хотите изменить цикл выставления счетов при обновлении подписки, вы можете использовать параметр billing_cycle_anchor . Это повлияет на будущие счета.

Во-вторых, пока вы можете пропорционально изменять план / количество , логарифмическая пропорция c всегда основана на линейном потреблении времени (и применяется только к Планы на сиденья, не измеряются). Если вы хотите кредитовать другую сумму, вам нужно будет сделать это вручную и отключить пропорциональное распределение Stripe. Вы можете либо:

  • Создать элемент счета-фактуры на клиенте перед обновлением, с отрицательной суммой для представления кредита. Когда для клиента создается следующий счет-фактура, этот элемент будет извлечен, и кредит будет применен к новой сумме подписки.
  • Выдача частичного возврата для платежа по предыдущему счет на сумму, которую вы считаете подлежащим возврату клиенту.
...