You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Stripe订阅模式Webhook中访问Checkout Session元数据的问题

Django集成Stripe Checkout:Webhook中关联Payment Method与Checkout Session元数据的问题

上下文

我的Stripe Checkout配置如下:

  • StripeCheckoutMonthlyView 和 StripeCheckoutYearlyView:两个视图都会创建携带元数据(如user_id、plan_type)的Checkout Session。
  • Webhook处理器(stripe_webhook):负责处理Stripe发送的各类事件。

问题

在处理payment_method.attached事件时,我需要获取Checkout Session里的元数据,但Payment Method对象既不包含元数据,也没有直接关联到Checkout Session的字段。

我的Webhook处理器代码如下:

@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:
        # 无效的请求体
        return HttpResponse(status=400)

    if event.type == 'payment_intent.succeeded':
        # 处理payment_intent.succeeded事件
        pass
    elif event.type == 'payment_method.attached':
        payment_method = event.data.object
        # 问题:Payment method不包含元数据或session_id
        pass
    elif event.type == 'checkout.session.completed':
        session = event.data.object
        # 这里可以获取Session元数据
        pass
    else:
        print('未处理的事件类型 {}'.format(event.type))

    return HttpResponse(status=200)

需求

  1. 在payment_method.attached事件中访问Checkout Session的元数据。
  2. 处理Payment Method事件时,从关联的Checkout Session中获取元数据。

已尝试的方案

我尝试在创建Checkout Session时添加payment_intent_data:

class StripeCheckoutMonthlyView(APIView):
   def post(self, request, *args, **kwargs):
        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)

并在处理函数中尝试通过Payment Method的元数据获取用户:

def add_info_card(payment_method):
    """
    根据支付意图更新用户的卡片信息和支付日期。
    
    参数:
        payment_method: Stripe返回的支付意图对象,包含卡片和收费详情。
        user: 从数据库获取的用户对象。
    """
    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)
    
    # 更新用户的卡片信息和支付日期
    user.card_last4 = last4
    user.brand_card = brand_card
    user.payment_date = payment_date
    user.save()
    print(f"用户 {user.id} 的卡片信息和支付日期已更新。")

但运行后报错:

stripe._error.InvalidRequestError: Request req_td3acLmE4ziQqi: You can not pass `payment_intent_data` in `subscription` mode.

核心疑问

  1. 处理payment_method.attached事件时,如何访问Checkout Session的元数据?
  2. 在Webhook中,将Payment Method与Checkout Session元数据关联的最佳实践是什么?

内容的提问来源于stack exchange,提问作者Lucas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 06:28:14