Как получить доступ к метаданным сессии оформления заказа в веб-хуке Stripe для методов оплаты в режиме подписки
Я интегрирую Stripe Checkout в Django-приложение и обрабатываю webhooks для обновления информации о пользователе на основе событий оплаты. Однако я сталкиваюсь с проблемами доступа к метаданным, связанным с Checkout Session
, когда работаю с payment_method
объектами.
Контекст:
У меня следующая настройка для Stripe Checkout:
StripeCheckoutMonthlyView
иStripeCheckoutYearlyView
: оба создаютCheckout Session
с метаданными (например,user_id
,plan_type
).- Webhook Handler (
stripe_webhook
): Обрабатывает различные типы событий от Stripe.
Проблема:
В событии payment_method.attached
мне нужно получить доступ к метаданным, которые были включены в Checkout Session
. Однако объект payment_method
не включает метаданные и не ссылается непосредственно на Checkout Session
.
Вот как выглядит мой обработчик вебхука:
@csrf_exempt
def stripe_webhook(request):
payload = request.body
event = None
print('Stripe Webhook Received!')
try:
event = stripe.Event.construct_from(
json.loads(payload), stripe.api_key
)
except ValueError as e:
# Invalid payload
return HttpResponse(status=400)
if event.type == 'payment_intent.succeeded':
# Handle payment_intent.succeeded event
pass
elif event.type == 'payment_method.attached':
payment_method = event.data.object
# Issue: Payment method does not include metadata or session_id
pass
elif event.type == 'checkout.session.completed':
session = event.data.object
# Retrieve session metadata here
pass
else:
print('Unhandled event type {}'.format(event.type))
return HttpResponse(status=200)
Что мне нужно:
Мне нужно обновить информацию о пользователе на основе метаданных, которые были включены в Checkout Session
. А именно:
- Получить метаданные в
payment_method.attached
событии. - Получение метаданных из
Checkout Session
при обработкеpayment_method
событий.
Попытка решения:
Я пытался использовать payment_intent_data
:
class StripeCheckoutMonthlyView(APIView):
def post(self, request, *args, **kwargs):
# try:
checkout_session = stripe.checkout.Session.create(
line_items=[
{
'price': settings.STRIPE_PRICE_ID_MONTHLY,
'quantity': 1,
},
],
payment_method_types=['card'],
mode='subscription',
success_url=settings.SITE_URL + '/pagamento/?success=true&session_id={CHECKOUT_SESSION_ID}',
cancel_url=settings.SITE_URL + '/?canceled=true',
metadata={'user_id': request.user.id,
'plan_type': 'monthly'},
payment_intent_data={
'metadata': {
'user_id': request.user.id,
}
}
)
return Response({'url': checkout_session.url,
'id': checkout_session.id,
}, status=status.HTTP_200_OK)
и затем используйте его в соответствующей функции:
def add_info_card(payment_method):
"""
Update the user's card details and payment date based on the payment intent.
Args:
payment_method: The payment intent object from Stripe containing card and charge details.
user: The user object retrieved from the database.
"""
print('Payment Method: ', payment_method)
user = get_object_or_404(User, id=payment_method.metadata.user_id)
last4 = payment_method['card']['last4']
payment_date = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
brand_card = payment_method['card']['brand']
print('Last 4: ', last4)
print('Payment Date: ', payment_date)
# Update the user with card details and payment date
user.card_last4 = last4
user.brand_card = brand_card
user.payment_date = payment_date
user.save()
print(f"User {user.id} updated with card details and payment date.")
но получил ошибку:
stripe._error.InvalidRequestError: Request req_td3acLmE4ziQqi: You can not pass `payment_intent_data` in `subscription` mode.
Вопросы:
- Как я могу получить доступ к
Checkout Session
метаданным при обработкеpayment_method
событий? - Каким образом лучше всего связать
payment_method
сCheckout Session
метаданными в веб-хуке?
Для кассовой сессии с режимом subscription
метаданные должны быть установлены в разделе subscription_data.metadata
.
Метаданные будут доступны в следующих местах:
- Объект подписки в
customer.subscription.*
событиях subscription_details.metadata
вinvoice.*
событиях
Метаданные не будут доступны для объектов Payment Method или Payment Intent.