Delphi 10.3 FMX应用中Stripe Payment Intent确认方案求助
问题描述
我用Delphi 10.3开发了一款FMX应用,通过REST组件与API交互。流程是先从后端及Stripe的api.stripe.com获取payment_intents得到client_secret,接着调用接口/v1/payment_intents/'+GlobalData.bookings[0].ClientSecretpi+'/confirm确认Intent,但直接发送信用卡信息每次都会报错。我知道网页端可以用stripe.js和Elements组件处理信用卡输入,但Delphi里没法这么做,求问怎么完成Intent确认。
当前代码
// 拆分月份和年份 delimiterPos := Pos('/', editExpires.Text); monthStr := copy(editExpires.text, 1, delimiterPOS - 1); yearStr := copy(editExpires.text, delimiterpos +1, length(editExpires.text) - delimiterPos); // 移除Secret部分得到pi_订单号 Globaldata.bookings[0].clientSecretPi := RemoveSecret(GlobalData.bookings[0].clientSecret); RESTClient := TRESTClient.Create('https://api.stripe.com'); RESTRequest := TRESTRequest.Create(nil); RESTResponse := TRESTResponse.Create(nil); RESTRequest.Params.AddHeader('Authorization', 'bearer '+GlobalData.bookings[0].Key).Options := [poDoNotEncode]; RESTRequest.Params.AddHeader('client_secret', GlobalData.bookings[0].clientSecret).Options := [poDoNotEncode]; RESTRequest.Params.AddHeader('Content-Type', 'application/x-www-form-urlencoded'); RestRequest.params.AddItem('return_url','https://example.com',pkQUERY); RestRequest.params.additem('payment_method_data[type]','card',pkQUERY); RestRequest.params.additem('payment_method_data[card][number]',CreditCardNumber,pkQUERY); RestRequest.params.addItem('payment_method_data[card][cvc]',SecurityCode,pkQUERY); RestRequest.params.addItem('payment_method_data[card][exp_year]',yearStr,pkQUERY); RestRequest.params.addItem('payment_method_data[card][exp_month]',monthStr,PKQUERY); RESTRequest.Method := TRESTRequestMethod.rmPOST; RESTRequest.Resource := '/v1/payment_intents/'+GlobalData.bookings[0].ClientSecretpi+'/confirm'; // 创建令牌的端点 RESTRequest.Client := RESTClient; RESTRequest.Response := RESTResponse; RESTRequest.Execute; ResponseContent := RESTResponse.Content; JsonResponse := TJSONObject.parseJSONValue(RESTResponse.Content) as TJSONObject; Contentstring := RESTResponse.Content;
错误响应信息
"error": { "message": "直接向Stripe API发送信用卡卡号通常是不安全的。建议使用对应测试卡的测试令牌,相关内容可参考Stripe测试文档。如需在测试模式下启用原始卡数据API,请查看Stripe支持文档。" }
解决方案
Stripe禁止直接传输原始信用卡信息,这是合规和安全的硬性要求。针对Delphi FMX应用,有两种可行的合规方案:
方案一:嵌入WebView加载Stripe Payment Element
在FMX应用中使用TWebBrowser组件,加载一个集成了Stripe Payment Element的简易网页。网页端通过stripe.js安全收集信用卡信息并生成支付方法ID,再通过JS桥接(比如Delphi的ExecuteScript方法、监听浏览器回调事件)把支付方法ID传递给Delphi应用,最后应用调用确认接口时只传支付方法ID和client_secret,不再碰原始卡数据。
方案二:绑定Stripe原生移动SDK(推荐)
Stripe提供了iOS和Android官方SDK,可以通过Delphi FireMonkey的原生绑定功能调用这些SDK,直接在原生界面中安全收集信用卡信息,生成支付方法或令牌后,再用于确认Payment Intent。这种方式体验更原生,也更符合移动应用的交互逻辑。
临时测试方案(仅测试环境可用)
如果只是做测试,可在Stripe后台申请启用测试模式下的原始卡数据访问权限,这样当前代码能暂时跑通,但生产环境绝对不能用这种方式,会违反PCI合规要求。
内容的提问来源于stack exchange,提问作者Glen Morse

