如何在payment_intent.succeeded中获取Checkout Session的client_reference_id?
Stripe Payment Intent获取client_reference_id及会话关联逻辑
一、Checkout Session与Payment Intent的关联逻辑
当创建mode=payment的Checkout Session时,Stripe会自动生成对应的Payment Intent,二者是绑定的支付流程上下游关系:
- Checkout Session负责前端支付页面展示、用户交互流程;
- Payment Intent负责后端支付授权、资金划转等核心支付操作;
- 双向关联标识:
- Checkout Session对象的
payment_intent字段存储对应Payment Intent的ID; - Payment Intent对象的
checkout_session字段存储对应Checkout Session的ID(仅当该Payment Intent由Checkout创建时存在)。
- Checkout Session对象的
二、在payment_intent.succeeded事件中获取client_reference_id的两种方案
方案1:创建Checkout Session时同步数据到Payment Intent的metadata
直接在创建Checkout Session时,通过payment_intent_data字段将client_reference_id传入关联Payment Intent的metadata中,后续可直接从Payment Intent事件中读取。
修改你的generate_payment_link函数:
def generate_payment_link(sender_id, selected_option_title, email_address): #genrating payment link try: # Create a Checkout Session session = stripe.checkout.Session.create( payment_method_types=['card'], line_items=[{ 'price_data': { 'currency': 'inr', 'product_data': { 'name': f'{selected_option_title}', }, 'unit_amount': 10000, }, 'quantity': 1, "adjustable_quantity": { "enabled": True, # 修正为布尔值,原字符串写法会触发Stripe参数错误 "maximum": 100, # 修正为数值类型,原字符串写法无效 "minimum": 1 }, }], customer_email = email_address, client_reference_id = sender_id, # 新增:将client_reference_id同步到Payment Intent的metadata payment_intent_data={ 'metadata': { 'client_reference_id': sender_id } }, mode='payment', success_url='https://example.com/success', cancel_url='https://example.com/cancel', ) payment_link = session.get('url') return payment_link except Exception as e: print(f"Error generating payment link: {e}")
然后在webhook中读取:
@app.post("/stripe-webhook") async def webhook(request: Request): """ other code(需确保包含Stripe事件签名验证逻辑)""" if event['type'] == 'checkout.session.completed': session = event['data']['object'] print(session) elif event['type'] == 'payment_intent.succeeded': payment_intent = event['data']['object'] # 直接从metadata中获取client_reference_id client_reference_id = payment_intent['metadata'].get('client_reference_id') if client_reference_id: send_success_payment_message(client_reference_id) # 传入sender_id进行后续处理
方案2:通过Payment Intent关联的Checkout Session ID查询获取
若不想修改Checkout Session创建逻辑,可在webhook中通过Payment Intent的checkout_session字段获取关联的会话ID,再调用Stripe API查询该会话以拿到client_reference_id:
修改webhook代码:
@app.post("/stripe-webhook") async def webhook(request: Request): """ other code(需确保包含Stripe事件签名验证逻辑)""" if event['type'] == 'checkout.session.completed': session = event['data']['object'] print(session) elif event['type'] == 'payment_intent.succeeded': payment_intent = event['data']['object'] checkout_session_id = payment_intent.get('checkout_session') if checkout_session_id: try: # 查询关联的Checkout Session checkout_session = stripe.checkout.Session.retrieve(checkout_session_id) client_reference_id = checkout_session.get('client_reference_id') if client_reference_id: send_success_payment_message(client_reference_id) except Exception as e: print(f"Error retrieving checkout session: {e}")
三、之前传递metadata失败的原因
你之前可能直接在Checkout Session的根节点添加了metadata字段,但该metadata仅属于Checkout Session本身,不会自动同步到关联的Payment Intent中。只有通过payment_intent_data.metadata设置的内容,才会被传递到对应的Payment Intent对象里。
内容的提问来源于stack exchange,提问作者Shaheen Ansari
相关产品推荐
相关产品推荐

