1业务需求 公司的电商项目最近开展到了支付环节,所以老板给了一个第三方支付文档,让我完成支付功能。
2支付文档 先上支付文档url https://open.swiftpass.cn/openapi
必填参数:①body 商品描述 ②total_fee 消费金额,这里是以分为单位,即数值为1就是1分,且不能有再小的单位,不能写成带小数的数值 ③sub_openid 这个是用户微信的openid,如果用户关注了公众号,那么用户在该微信公众号理论上会存取一个唯一的openid,当然不关注也可以通过微信提供的接口获取openid ④out_trade_no 唯一订单编号,我这里是根据时间来的,本来还想加入用户openid,可是发现长度过了,个人建议别仅仅使用时间,万一同一时间2个人同时付款,会出问题,因为订单号会重复
⑤mch_create_ip 终端IP地址 ⑥service 接口类型,我这里是公众号支付类型pay.weixin.jspay ⑦version 版本号,version默认值是2.0 ⑧is_raw 原生JS,值为1 ⑨mch_id 商户号,由平台分配 ⑩notify_url 接收平台通知的URL,需给绝对路径,255字符内格式如:http://wap.tenpay.com/tenpay.asp,确保平台能通过互联网访问该地址 ⑪nonce_str 随机字符串,不长于 32 位
⑫sign MD5签名结果,详见“安全规范”
public Map<String, String> payment(TransactionEntity transactionEntity, HttpServletResponse resp) throws ServletException, IOException {
if (null == transactionEntity) {
throw new RuntimeException("对象为空");
}
SortedMap<String, String> map = new TreeMap();
map.put("body", "购买商品");
map.put("attach", transactionEntity.attach);
map.put("total_fee", transactionEntity.totalFee);
map.put("sub_openid", transactionEntity.subOpenid);
map.put("out_trade_no", System.currentTimeMillis()+"");
map.put("mch_create_ip", "36.99.168.154");
map.put("service", "pay.weixin.jspay");
map.put("version", "2.0");
map.put("charset", "UTF-8");
map.put("sign_type", "MD5");
map.put("is_raw", "1");
map.put("mch_id", SwiftpassConfig.mch_id);
map.put("notify_url", SwiftpassConfig.notify_url);
map.put("nonce_str", String.valueOf(new Date().getTime()));
map.put("callback_url", "http://yinji.sharey-ad.com/wechat/pay_success.html");
Map<String, String> params = SignUtils.paraFilter(map);
System.err.println(params);
StringBuilder buf = new StringBuilder((params.size() + 1) * 10);
SignUtils.buildPayParams(buf, params, false);
String preStr = buf.toString();
String sign = MD5.sign(preStr, "&key=" + SwiftpassConfig.key, "utf-8");
map.put("sign", sign);
String reqUrl = SwiftpassConfig.req_url;
logger.debug("reqUrl:" + reqUrl);
logger.debug("reqParams:" + XmlUtils.parseXML(map));
CloseableHttpResponse response = null;
CloseableHttpClient client = null;
String res = null;
Map<String, String> resultMap = null;
try {
HttpPost httpPost = new HttpPost(reqUrl);
StringEntity entityParams = new StringEntity(XmlUtils.parseXML(map), "utf-8");
httpPost.setEntity(entityParams);
httpPost.setHeader("Content-Type", "text/xml;utf-8");
client = HttpClients.createDefault();
response = client.execute(httpPost);
if (response != null && response.getEntity() != null) {
resultMap = XmlUtils.toMap(EntityUtils.toByteArray(response.getEntity()), "utf-8");
logger.info("请求的结果:" + resultMap);
res = XmlUtils.toXml(resultMap);
logger.debug("请求结果:" + res);
System.err.println(res);
if (!SignUtils.checkParam(resultMap, SwiftpassConfig.key)) {
res = "验证签名不通过";
} else {
if ("0".equals(resultMap.get("status")) && "0".equals(resultMap.get("result_code"))) {
String pay_info = resultMap.get("pay_info");
logger.debug("pay_info : " + pay_info);
res = "ok";
}
}
} else {
res = "操作失败";
}
} catch (Exception e) {
logger.error("操作失败,原因:", e);
res = "系统异常";
} finally {
if (response != null) {
response.close();
}
if (client != null) {
client.close();
}
}
Map<String, String> result = new HashMap<String, String>();
if ("ok".equals(res)) {
result = resultMap;
} else {
result.put("status", "500");
result.put("msg", res);
}
//resp.getWriter().write(new Gson().toJson(resultMap));
//}
return resultMap;
}
2根据resultmap返回的数据调用微信js,这里要记住,需要在手机微信才能支付,否则不行,res.err_msg == "get_brand_wcpay_request:ok"表示支付成功
$.ajax({ //请求支付
type:"post",
url:"/test-api/pay/transact-pay",
data:JSON.stringify(json),
contentType: "application/json; charset=utf-8",
dataType: "json",
success:function(data){
if(data.code==0){
WeixinJSBridge.invoke('getBrandWCPayRequest',{
"appId" : data.appId, //动态获取初始化请求中返回的pay_info参数中appId值
"timeStamp":data.timeStamp, //动态获取初始化请求中返回的pay_info参数中timeStamp值
"nonceStr" : data.nonceStr, //动态获取初始化请求中返回的pay_info参数中nonceStr值
"package" : data.package,//动态获取初始化请求中返回的pay_info参数中package值
"signType" : data.signType, //动态获取初始化请求中返回的pay_info参数中signType值
"paySign" : data.paySign //动态获取初始化请求中返回的pay_info参数中paySign值
},function(res){
if(res.err_msg == "get_brand_wcpay_request:ok" ) {
//alert(res.err_msg);
//console.log(data);
$("#bg").css("display","block");
$('#layerBox').fadeIn(300);
}
});
}else{
alert(data.code);
console.log(data);
}
}
})