如何从Stripe session_id中解析获取交易信息?
Stripe Checkout 回调获取交易数据的ColdFusion实现示例
一、处理当前GET回调链接的场景
你收到的/checkoutcomplete.cfm?session_id=xxx是Stripe Checkout的成功跳转链接,要获取交易数据,需通过这个session_id调用Stripe API拉取会话详情,再提取所需信息。以下是完整CFML代码示例:
<!--- 建议将密钥存到应用配置或环境变量,不要硬编码 ---> <cfset stripeSecretKey = application.stripeSecretKey /> <cfset sessionId = url.session_id /> <!--- 调用Stripe API获取Checkout Session详情 ---> <cfhttp method="GET" url="https://api.stripe.com/v1/checkout/sessions/#sessionId#" result="stripeResponse"> <cfhttpparam type="header" name="Authorization" value="Basic #toBase64(stripeSecretKey & ':')#" /> </cfhttp> <!--- 解析API响应 ---> <cfset sessionData = deserializeJSON(stripeResponse.fileContent) /> <cfif stripeResponse.statusCode eq 200> <!--- 提取核心交易数据(根据你的需求调整字段) ---> <cfset donationAmount = sessionData.amount_total / 100> <!--- Stripe金额以"分"为单位,转换为元/美元 ---> <cfset currency = sessionData.currency> <cfset donorEmail = sessionData.customer_details.email> <cfset paymentStatus = sessionData.payment_status> <cfset paymentIntentId = sessionData.payment_intent> <!--- 将数据保存到数据库(替换成你的数据源和表结构) ---> <cfquery name="saveDonationRecord" datasource="CharityDB"> INSERT INTO donations ( amount, currency, donor_email, payment_status, payment_intent_id, stripe_session_id, created_at ) VALUES ( ?, ?, ?, ?, ?, ?, NOW() ) </cfquery> <cfqueryparam cfsqltype="CF_SQL_FLOAT" value="#donationAmount#"> <cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#currency#"> <cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#donorEmail#"> <cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#paymentStatus#"> <cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#paymentIntentId#"> <cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#sessionId#"> <!--- 给捐赠者显示感谢页面 ---> <h1>感谢你的慷慨捐赠!</h1> <p>捐赠金额:#donationAmount# #currency#</p> <p>我们已收到你的付款,收据将发送至:#donorEmail#</p> <cfelse> <!--- 处理API请求失败的情况 ---> <h1>处理失败</h1> <p>无法获取交易信息:#sessionData.error.message#</p> </cfif>
二、更安全的Webhook回调方案(推荐)
GET跳转链接容易被伪造,Stripe官方推荐使用Webhook POST请求来接收交易完成事件,通过签名验证确保请求来自Stripe。以下是Webhook实现示例(stripe-webhook.cfm):
<!--- 替换为你的Stripe Webhook密钥 ---> <cfset stripeWebhookSecret = application.stripeWebhookSecret /> <!--- 获取请求体和签名头 ---> <cfset requestBody = getHttpRequestData().content /> <cfset stripeSignature = getHttpRequestData().headers["Stripe-Signature"] /> <!--- 拆分签名中的时间戳和签名值 ---> <cfset timestampPart = listFirst(stripeSignature, ",") /> <cfset timestamp = listLast(timestampPart, "=") /> <cfset actualSignature = listLast(listGetAt(stripeSignature, 2, ","), "=") /> <!--- 计算签名并验证 ---> <cfset signedPayload = timestamp & "." & requestBody /> <cfset computedSignature = hmac(signedPayload, stripeWebhookSecret, "HMACSHA256", "base64") /> <cfif computedSignature eq actualSignature> <!--- 签名验证通过,解析事件数据 ---> <cfset event = deserializeJSON(requestBody) /> <!--- 只处理checkout.session.completed事件(交易完成) ---> <cfif event.type eq "checkout.session.completed"> <cfset sessionData = event.data.object /> <!--- 提取数据并保存(逻辑和GET场景一致) ---> <cfset donationAmount = sessionData.amount_total / 100> <cfset currency = sessionData.currency> <cfset donorEmail = sessionData.customer_details.email> <cfset paymentStatus = sessionData.payment_status> <cfset paymentIntentId = sessionData.payment_intent> <cfquery name="saveDonationRecord" datasource="CharityDB"> INSERT INTO donations ( amount, currency, donor_email, payment_status, payment_intent_id, stripe_session_id, created_at ) VALUES ( ?, ?, ?, ?, ?, ?, NOW() ) </cfquery> <cfqueryparam cfsqltype="CF_SQL_FLOAT" value="#donationAmount#"> <cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#currency#"> <cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#donorEmail#"> <cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#paymentStatus#"> <cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#paymentIntentId#"> <cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#sessionData.id#"> </cfif> <!--- 必须返回200给Stripe,否则Stripe会重复发送事件 ---> <cfheader statuscode="200" statustext="OK" /> <cfelse> <!--- 签名验证失败,拒绝请求 ---> <cfheader statuscode="403" statustext="Forbidden" /> <cfoutput>Invalid request signature</cfoutput> </cfif>
关键注意事项
- 密钥管理:Stripe的Secret Key和Webhook密钥要妥善保存,不要硬编码到代码中,建议存到ColdFusion的
application变量或服务器环境变量里。 - 金额单位:Stripe返回的金额是以最小货币单位(如分、便士)为整数,需要除以100转换为常规金额格式。
- Webhook配置:在Stripe后台的Webhook设置中,添加
checkout.session.completed事件,并指向你的stripe-webhook.cfm公网地址,同时设置Webhook密钥。
内容的提问来源于stack exchange,提问作者Thomas Nichols
相关产品推荐
相关产品推荐

