失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 微信支付二:微信公众号支付(jsapi支付)

微信支付二:微信公众号支付(jsapi支付)

时间:2022-05-10 22:46:16

相关推荐

微信支付二:微信公众号支付(jsapi支付)

SpringBoot 实现微信公众号支付(jsapi支付)

一、背景

在开发一个捐赠项目时须在pc端接入微信扫码支付(Native 扫码支付),在微信端接入微信公众号支付(Jsapi 支付)。后端使用的是Spring Boot框架,前台采用HTML+css+js 编写。

微信支付一:微信支付一

二、微信公众号支付流程

1、微信支付开发文档:微信支付开发文档

2、Jsapi 支付业务流程

三、配置

jsapi支付所需要的工具类与微信扫码支付的配置类相同,还可使用微信官方提供的sdk,本文以SDK为例。

1、Jsapi支付基本信息配置

public interface JsapiConfig {String APP_ID="";//微信公众号idString MCH_ID="";//商户idString API_KEY="";//API密钥String UFDOOER_URL="https://api.mch./pay/unifiedorder";//微信统一下单地址String NOTIFY_URL="";//回调地址String CREATE_IP="";//发起ip}

四、除SDK外的工具类

JsapiPayCommonUtil

/*** @author wxc* @date 07月31日 16:02* @description JSAPI支付*/@Slf4jpublic class JsapiPayCommonUtil implements JsapiConfig{/**** @author wxc* @date /7/31/031 16:33* @param order_price* @param body* @param out_trade_no* @param openid* @return java.lang.String* @description 获取prepay_id*/public static String jsapiPay(String order_price,String body,String out_trade_no,Object openid){String appid=JsapiConfig.APP_ID; //账号信息String mch_id=JsapiConfig.MCH_ID; //商家号String key=JsapiConfig.API_KEY; //密钥String currTime=PayCommonUtil.getCurrTime();String strTime = currTime.substring(8, currTime.length());String strRandom = PayCommonUtil.buildRandom(4) + "";String nonce_str=strTime+strRandom; //随机字符串String spbill_create_ip=JsapiConfig.CREATE_IP;//获取发起电脑ipString notify_url=JsapiConfig.NOTIFY_URL;//回调接口String trade_type="JSAPI";SortedMap<Object,Object> packageParams=new TreeMap<>();packageParams.put("appid",appid);packageParams.put("mch_id",mch_id);packageParams.put("nonce_str",nonce_str);packageParams.put("body",body);packageParams.put("out_trade_no",out_trade_no);packageParams.put("total_fee",order_price);packageParams.put("spbill_create_ip",spbill_create_ip);packageParams.put("notify_url",notify_url);packageParams.put("trade_type",trade_type);packageParams.put("openid",openid);//根据前10个参数创建签名String sign = PayCommonUtil.createSign("UTF-8",packageParams,key);packageParams.put("sign",sign); //将第11个参数放入map中//请求前,将有11个参数的map转成XML格式String requestXML = PayCommonUtil.getRequestXml(packageParams);log.info(requestXML);//请求微信统一下单接口String resXml= WxHttpUtil.postData(JsapiConfig.UFDOOER_URL,requestXML);log.info(resXml);//解析微信返回的xml数据Map map = XMLUtil.doXMLParse(resXml);//取出prepay_idString prepayId=(String) map.get("prepay_id");return prepayId;}}

五、具体实现

Controller层,具体需要的前台传的参数根据个人业务需要决定,但下面六个参数是必传的。

try{String prepayId = JsapiPayCommonUtil.jsapiPay(order_price,body,out_trade_no,openId);Map<String, String> payMap = new HashMap<String, String>();payMap.put("appId", JsapiConfig.APP_ID);payMap.put("timeStamp", WXPayUtil.getCurrentTimestamp() + "");payMap.put("nonceStr", WXPayUtil.generateNonceStr());payMap.put("signType", "MD5");payMap.put("package", "prepay_id=" + prepayId);//根据前五个参数生成标签String paySign = WXPayUtil.generateSignature(payMap,JsapiConfig.API_KEY);payMap.put("paySign", paySign);return payMap;} catch(Exception e){e.printStackTrace();}

回调接口

@RequestMapping("notify")public void weixin_notify(HttpServletRequest request, HttpServletResponse response) throws IOException {//读取参数InputStream inputStream;StringBuffer sb = new StringBuffer();inputStream=request.getInputStream();String s;BufferedReader in = new BufferedReader(new InputStreamReader(inputStream,"UTF-8"));while ((s=in.readLine())!=null){sb.append(s);}in.close();inputStream.close();//解析xml成mapMap<String,String> m=new HashMap<String,String>();m= XMLUtil.doXMLParse(sb.toString());//过滤空 设置TreeMapSortedMap<Object,Object> packageParams=new TreeMap<Object,Object>();Iterator it=m.keySet().iterator();while (it.hasNext()){String paramter = (String)it.next();String parameterValue=m.get(paramter);String v="";if(null!=parameterValue){v=parameterValue.trim();}packageParams.put(paramter,v);}//账号信息String key= JsapiConfig.API_KEY;String out_trade_no=(String)packageParams.get("out_trade_no");//判断签名是否正确if(PayCommonUtil.isTenpaySign("UTF-8",packageParams,key)){//处理业务开始String resXml="";if("SUCCESS".equals((String)packageParams.get("result_code"))){//支付成功,下面执行自己的业务log.info("支付成功");log.info("========================================================================");resXml="<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";}else {log.info("订单"+out_trade_no+"支付失败");resXml="<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文为空]]></return_msg></xml>";}//业务处理完毕BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());out.write(resXml.getBytes());out.flush();out.close();}else{log.info("通知签名验证失败");}}

前端js

var appId,timeStamp,nonceStr,package,signType,paySign;function pay(){var url = "/wx/jsapi/wxJsapiPay";$.ajax({url:url,type: "get",data: {projectName:$("#projectNameH").val(),payMoney:$("#payMoneyH").val(),sysOrderId:$("#sysOrderIdH").val(),id:$("#id").val(),projectId:$("#projectId").val(),},success:function (data) {appId = data.appId;timeStamp = data.timeStamp;nonceStr = data.nonceStr;package = data.package;signType = data.signType;paySign = data.paySign;if (typeof WeixinJSBridge == "undefined") {if (document.addEventListener) {document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);} else if (document.attachEvent) {document.attachEvent('WeixinJSBridgeReady', onBridgeReady);document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);}} else {onBridgeReady();}}})}function onBridgeReady(){WeixinJSBridge.invoke( 'getBrandWCPayRequest', {"appId":appId, //公众号名称,由商户传入"timeStamp":timeStamp, //时间戳,自1970年以来的秒数"nonceStr":nonceStr, //随机串"package":package,"signType":signType, //微信签名方式:"paySign":paySign //微信签名}, function(res){if(res.err_msg == "get_brand_wcpay_request:ok" ) {console.log('支付成功');layer.msg("支付成功");//支付成功后跳转的页面window.location.href = "/wx/prePay/toWxMainHome";}else if(res.err_msg == "get_brand_wcpay_request:cancel"){console.log('支付取消');layer.msg("支付取消");}else if(res.err_msg == "get_brand_wcpay_request:fail"){console.log('支付失败');layer.msg("支付失败");WeixinJSBridge.call('closeWindow');} //使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。});}$(function () {//确认支付$("#pay").on("click",function (){pay();});})

如果觉得《微信支付二:微信公众号支付(jsapi支付)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。