Stripe实现信用卡支付
不做介绍stripe支付介绍,就讲讲逻辑和实现和代码,要看stripe介绍自己百度一大堆。
ssm三层架构实现。小白还望指教,谢谢大佬们。
屁话少说 逻辑
1.讲讲逻辑: 点击商品然后下单创建订单,把订单号封装成自定义参数传给stripe在调起支付,所有东西都有stripe实现。最后使用webhook挂钩实现回调操作拿到自定义参数处理你的业务逻辑;
实现
2.前端实现:初始化页面,找到官网案例图(https://stripe.com/docs/payments/integration-builder)根据下面图下载。这是stripe测试的,如果想调起支付就得把自己key和秘钥换上去。 stripe 官网都实现了前端,样式根据自己需求去调,这里我讲讲js实现。
// 直贴关键代码
var stripe_pk = "pk_livex9FxxxxhI9Yj2";//这是你的pk_key ,去开发模块里面找key和秘钥
var stripe = Stripe(stripe_pk);//初始化stripe
//这个不是调起支付 而是初始化这个页面 ,也可以说你可以不用管调起支付, stripe会帮你调起,用户只要输入卡号就行
fetch("/create-payment-intent", {//打开html 页面就会去请求 你的‘/create-payment-intent’后台
method: "POST",
headers: {
"Content-Type": "application/json"
},
//传过去的参数 price 价格最低0.5美元 单位分 , 邮箱 ,订单号 ,其他
body: JSON.stringify({"price":money,"order_no":order_no,"email":email,"title":title})
})
//支付成功后调取 自己根据需求改
var orderComplete = function(paymentIntentId) {
loading(false);
document
.querySelector(".result-message a")
.setAttribute(
"href",
"./order?paymentIntentId=" + paymentIntentId //成功调取地址
);
document.querySelector(".result-message").classList.remove("hidden");
document.querySelector("button").disabled = true;
};
3.后端实现:初始化页面
//xml 包
// 控制层
@ResponseBody
@RequestMapping(value = {"/create-payment-intent"}, method = RequestMethod.POST)
public String paymentOrder(@RequestBody Map<String, String> map,
HttpServletRequest request, HttpServletResponse response) throws StripeException {
return service.payments(map,request,response);
}
//service业务处理
public String payments(Map<String, String> map,HttpServletRequest request, HttpServletResponse response) throws StripeException {
staticFiles.externalLocation(Paths.get("").toAbsolutePath().toString());
Stripe.apiKey = "sk_live_51HZCAR00sBFiQi4h";//自己sk_key 开发里面有自己找
PaymentIntentCreateParams createParams = new PaymentIntentCreateParams.Builder()
.setAmount(Long.decode(map.get("price")))//设置金额
.setCurrency("twd")//设置货币
.setDescription("购买"+map.get("title")+",订单号:"+ map.get("order_no"))//描述
.putMetadata("order_id", map.get("order_no"))//自定义参数
.putMetadata("money", map.get("price"))//自定义参数
.addPaymentMethodType("card")
.setReceiptEmail(map.get("email"))//通知这个邮箱
.build();//还有很多参数 自己看中文文档去
PaymentIntent intent = PaymentIntent.create(createParams);
CreatePaymentResponse paymentResponse = new CreatePaymentResponse(intent.getClientSecret());
return gson.toJson(paymentResponse);
}
4.webhook挂钩回调
首先你要在stripe找到开发者下面webhook 配置你的回调地址
我这里已经加过了还是给你们添加端点。看图二
保存后点击去里面有个密钥签名点击显示复制回调要用到。
//控制层 回调不用返回 能走得通就是成功
@ResponseBody
@RequestMapping(value = {"/stripe_events"}, method = RequestMethod.POST)
public void stripe_events(HttpServletRequest request, HttpServletResponse response) {
service.stripe_events(request,response);
}
//service
public void stripe_events(HttpServletRequest request, HttpServletResponse response) {
try {
String endpointSecret = "whsec_xxxgx92OjXdBf1lc2c";//webhook秘钥签名
InputStream inputStream = request.getInputStream();
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buffer = new byte[1024*4];
int n = 0;
while (-1 != (n = inputStream.read(buffer))) {
output.write(buffer, 0, n);
}
byte[] bytes = output.toByteArray();
String payload = new String(bytes, "UTF-8");
String sigHeader = request.getHeader("Stripe-Signature");
Event event = Webhook.constructEvent(payload, sigHeader, endpointSecret);//验签,并获取事件
PaymentIntent intent = (PaymentIntent) event
.getDataObjectDeserializer()
.getObject()
.get();
switch(event.getType()) {
case "payment_intent.created"://创建订单 这里事件就是图二选着的事件
break;
case "payment_intent.canceled"://取消订单
break;
case "payment_intent.succeeded"://支付成功
if(intent.getStatus().equals("succeeded")) {
Map<String,String> metaData = intent.getMetadata();//自定义传入的参数
String order_id = metaData.get("order_id");//自定义订单号
/*********** 根据订单号从数据库中找到订单,并将状态置为成功 *********/
}
break;
case "payment_intent.payment_failed"://支付失败
System.out.println("Failed: " + intent.getId());
break;
default:
break;
}
} catch (Exception e) {
System.out.println("stripe异步通知(webhook事件)"+e);
}
}
stripe 我也是头次接触也不太懂,错了还望大家指出错误。
最后讲讲:遇到的bug
1.stripe 需要安全支付,就是如果你用域名或者发布到线上,必须是https否则报错调不起来当时我也找了半天。无赖把改成http改成https,在配置完https安全证书的访问一直访问不了,也不是访问不行,讲域名和证书不匹配,我又找半天,心态爆炸。最后发现是sdn多配置 了点东西,比如 xxx.cn,被解析成 xxx.cn.tw.com这样,把这个删掉就ok。
2.回调那一块犯了个不小心错误:我是找错了回调事件,如果配置了多个回调地址,别的回调地址也会走你的回调地址,所以当时还以为自定义的参数会变,当场懵逼,最后发现找错事件 害。
3.java 案例demo地址:https://pan.baidu.com/s/11iXLX1sR3hVn1Jd1-XkrPw 提取:ynpy
demo案例切勿商用,仅供参考。切记!切记!切记!