Я работаю на платформе, способной анализировать данные пользователей. Я хотел бы использовать платежи 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)