前端:
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0"> <title>支付首页</title> <link rel="stylesheet" href="//cdn.bootcss.com/weui/1.1.1/style/weui.min.css"> <link rel="stylesheet" href="//cdn.bootcss.com/jquery-weui/1.0.1/css/jquery-weui.min.css"> <link rel="stylesheet" href="#(ctxPath)/static/css/demos.css"> </head> <body> <body ontouchstart> <header > <h1 class="demos-title">支付Demo</h1> </header> <div class="weui-cells weui-cells_form"> <div class="weui-cell"> <div class="weui-cell__hd"><label class="weui-label">产品ID</label></div> <div class="weui-cell__bd"> <input class="weui-input" type="number" id="product_id" placeholder="请输入产品ID"> </div> </div> <div class="weui-cell"> <div class="weui-cell__hd"> <label class="weui-label">金额(¥)</label> </div> <div class="weui-cell__bd"> <input class="weui-input" type="number" id="total_fee" placeholder="请输入数字金额,单位分"> </div> </div> <div class="weui-cell"> <div class="weui-cell__hd"> <label class="weui-label">条形码</label> </div> <div class="weui-cell__bd"> <input class="weui-input" type="number" id="auth_code" placeholder="请输入条形码"> </div> </div> <div class="weui-tab"> <div class="weui-navbar"> <a class="weui-navbar__item weui-bar__item--on" href="#tab1"> 微信支付 </a> <a class="weui-navbar__item" href="#tab2"> 支付宝支付 </a> <a class="weui-navbar__item" href="#tab3"> 银联支付 </a> <a class="weui-navbar__item" href="#tab4"> Ping++ </a> </div> <div class="weui-tab__bd"> <div id="tab1" class="weui-tab__bd-item weui-tab__bd-item--active"> <div class="weui-cells weui-cells_radio"> <label class="weui-cell weui-check__label" for="w1"> <div class="weui-cell__bd"> <p>扫码支付模式一:用户输入金额</p> </div> <div class="weui-cell__ft"> <input type="radio" class="weui-check" name="radio1" id="w1" value="scancode1" checked="checked"> <span class="weui-icon-checked"></span> </div> </label> <label class="weui-cell weui-check__label" for="w2"> <div class="weui-cell__bd"> <p>扫码支付模式二:确定支付金额</p> </div> <div class="weui-cell__ft"> <input type="radio" name="radio1" class="weui-check" id="w2" value="scancode2"> <span class="weui-icon-checked"></span> </div> </label> <label class="weui-cell weui-check__label" for="w3"> <div class="weui-cell__bd"> <p>刷卡支付</p> </div> <div class="weui-cell__ft"> <input type="radio" name="radio1" class="weui-check" id="w3" value="micropay"> <span class="weui-icon-checked"></span> </div> </label> <label class="weui-cell weui-check__label" for="w4"> <div class="weui-cell__bd"> <p>公众号支付</p> </div> <div class="weui-cell__ft"> <input type="radio" name="radio1" class="weui-check" id="w4" value="webpay"> <span class="weui-icon-checked"></span> </div> </label> <label class="weui-cell weui-check__label" for="w5"> <div class="weui-cell__bd"> <p>H5支付</p> </div> <div class="weui-cell__ft"> <input type="radio" name="radio1" class="weui-check" id="w5" value="h5pay"> <span class="weui-icon-checked"></span> </div> </label> <label class="weui-cell weui-check__label" for="w6"> <div class="weui-cell__bd"> <p>APP支付</p> </div> <div class="weui-cell__ft"> <input type="radio" name="radio1" class="weui-check" id="w6" value="wxapppay"> <span class="weui-icon-checked"></span> </div> </label> </div> </div> <div id="tab2" class="weui-tab__bd-item"> <div class="weui-cells weui-cells_radio"> <label class="weui-cell weui-check__label" for="z1"> <div class="weui-cell__bd"> <p>手机网站支付</p> </div> <div class="weui-cell__ft"> <input type="radio" class="weui-check" name="radio1" id="z1" value="wappay"> <span class="weui-icon-checked"></span> </div> </label> <label class="weui-cell weui-check__label" for="z2"> <div class="weui-cell__bd"> <p>电脑网站支付</p> </div> <div class="weui-cell__ft"> <input type="radio" class="weui-check" name="radio1" id="z2" value="pcpay"> <span class="weui-icon-checked"></span> </div> </label> <label class="weui-cell weui-check__label" for="z3"> <div class="weui-cell__bd"> <p>当面付:条码支付</p> </div> <div class="weui-cell__ft"> <input type="radio" class="weui-check" name="radio1" id="z3" value="tradepay"> <span class="weui-icon-checked"></span> </div> </label> <label class="weui-cell weui-check__label" for="z4"> <div class="weui-cell__bd"> <p>当面付:扫码支付</p> </div> <div class="weui-cell__ft"> <input type="radio" class="weui-check" name="radio1" id="z4" value="tradeprepay"> <span class="weui-icon-checked"></span> </div> </label> <label class="weui-cell weui-check__label" for="z5"> <div class="weui-cell__bd"> <p>APP支付</p> </div> <div class="weui-cell__ft"> <input type="radio" class="weui-check" name="radio1" id="z5" value="aliapppay"> <span class="weui-icon-checked"></span> </div> </label> </div> </div> <div id="tab3" class="weui-tab__bd-item"> 对接中... </div> <div id="tab4" class="weui-tab__bd-item"> 对接中... </div> </div> </div> </div> <div style="text-align: center;"> <img id="qrcode1" alt="" src=""> </div> <div class="weui-btn-area" style="margin-top: -400px;"> <a href="javascript:pay();" class="weui-btn weui-btn_primary">确定支付</a> <a href="#(ctxPath)/toOauth?state=wxpay" class="weui-btn weui-btn_primary">获取微信openId</a> </div> </body> <script src="//cdn.bootcss.com/jquery/1.11.0/jquery.min.js"></script> <script src="//cdn.bootcss.com/jquery-weui/1.0.1/js/jquery-weui.min.js"></script> <script src="#(ctxPath)/static/layer/layer.js"></script> <script type="text/javascript" src="#(ctxPath)/static/js/jquery.qrcode.min.js"></script> <script type="text/javascript"> function pay(){ var product_id = $.trim($("#product_id").val()); var total_fee = $.trim($("#total_fee").val()); var auth_code = $.trim($("#auth_code").val()); var pay_mode = $("input[name='radio1']:checked").val(); if(pay_mode=="scancode1"){//微信 scancode1(product_id,total_fee,auth_code); }else if(pay_mode=="scancode2"){ scancode2(product_id,total_fee,auth_code); }else if(pay_mode=="micropay"){ micropay(product_id,total_fee,auth_code); }else if(pay_mode=="webpay"){ webpay(product_id,total_fee,auth_code); }else if(pay_mode=="h5pay"){ h5pay(product_id,total_fee,auth_code); }else if(pay_mode=="wxapppay"){ wxapppay(product_id,total_fee,auth_code); }else if(pay_mode=="wappay"){//支付宝 wappay(product_id,total_fee,auth_code); }else if(pay_mode=="pcpay"){ pcpay(product_id,total_fee,auth_code); }else if(pay_mode=="tradepay"){ tradepay(product_id,total_fee,auth_code); }else if(pay_mode=="tradeprepay"){ tradeprepay(product_id,total_fee,auth_code); }else if(pay_mode=="aliapppay"){ aliapppay(product_id,total_fee,auth_code); } } /* 微信扫码支付 */ function scancode1(product_id,total_fee,auth_code) { alert("微信扫码支付模式一"); $.showLoading("正在加载..."); $.post("#(ctxPath)/wxpay/scancode1", { productId : product_id, }, function(res) { $.hideLoading(); if (res.code == 0) { var name = res.data; console.log(name); showScanCode('#qrcode1', name); } else { if (res.code == 2) { layer.alert(res.message); } else { layer.msg("error:" + res.message, { shift : 6 }); } } }); } function scancode2(product_id,total_fee,auth_code) { alert("微信扫码支付模式二"); $.showLoading("正在加载..."); $.post("#(ctxPath)/wxpay/scancode2", { total_fee : total_fee, }, function(res) { $.hideLoading(); if (res.code == 0) { var name = res.data; console.log(name); showScanCode('#qrcode1', name); } else { if (res.code == 2) { layer.alert(res.message); } else { layer.msg("error:" + res.message, { shift : 6 }); } } }); } function showScanCode(id, name) { $(id).attr("src", "#(ctxPath)/" + name); } /* 微信扫码支付 END*/ /* 微信刷卡支付 */ function micropay(product_id,total_fee,auth_code) { $.showLoading("正在加载..."); $.post("#(ctxPath)/wxpay/micropay", { total_fee : total_fee, auth_code : auth_code, }, function(res) { $.hideLoading(); if (res.code == 0) { layer.msg("支付成功", { shift : 6 }); self.location = "#(ctxPath)/success"; } else { if (res.code == 2) { layer.alert(res.message); } else { layer.msg("error:" + res.message, { shift : 6 }); } } }); } /* 微信刷卡支付 END*/ /* 微信公众号支付支付 */ function webpay(product_id,total_fee,auth_code) { alert("公众号支付记得传OpenId"); $.showLoading("正在加载..."); var total_fee = total_fee; $.post("#(ctxPath)/wxpay/webpay", { total_fee : total_fee, }, function(res) { $.hideLoading(); if (res.code == 0) { var data = $.parseJSON(res.data); if (typeof WeixinJSBridge == "undefined") { if (document.addEventListener) { document.addEventListener('WeixinJSBridgeReady', onBridgeReady(data), false); } else if (document.attachEvent) { document.attachEvent('WeixinJSBridgeReady', onBridgeReady(data)); document.attachEvent('onWeixinJSBridgeReady', onBridgeReady(data)); } } else { onBridgeReady(data); } } else { if (res.code == 2) { layer.alert(res.message); } else { layer.msg("error:" + res.message, { shift : 6 }); } } }); } function onBridgeReady(json) { WeixinJSBridge.invoke('getBrandWCPayRequest', json, function(res) { // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回 ok,但并不保证它绝对可靠。 if (res.err_msg == "get_brand_wcpay_request:ok") { layer.msg("支付成功", { shift : 6 }); self.location = "#(ctxPath)/success"; } else { layer.msg("支付失败", { shift : 6 }); } }); } /* 微信公众号支付支付 END */ function h5pay(product_id,total_fee,auth_code){ window.open("#(ctxPath)/wxpay/h5pay?total_fee="+total_fee); } function wxapppay(product_id,total_fee,auth_code){ window.open("#(ctxPath)/wxpay/apppay?total_fee="+total_fee); } /*支付宝*/ function wappay(product_id,total_fee,auth_code){ window.open("#(ctxPath)/alipay/wapPay?total_fee="+total_fee); } function pcpay(product_id,total_fee,auth_code){ window.open("#(ctxPath)/alipay/pcPay?total_fee="+total_fee); } function tradepay(product_id,total_fee,auth_code){ window.open("#(ctxPath)/alipay/tradePay?total_fee="+total_fee+"&auth_code="+auth_code); } function tradeprepay(product_id,total_fee,auth_code){ window.open("#(ctxPath)/alipay/tradePrePay?total_fee="+total_fee+"&auth_code="+auth_code); } function aliapppay(product_id,total_fee,auth_code) { window.open("#(ctxPath)/alipay/appPay?total_fee="+total_fee+"&auth_code="+auth_code); } </script> </body> </html>后台核心代码:
package com.anssy.pay.controller.weixin; import com.alibaba.fastjson.JSONObject; import com.anssy.pay.PayApi; import com.anssy.pay.ext.kit.IpKit; import com.anssy.pay.ext.kit.PaymentKit; import com.anssy.pay.ext.kit.ZxingKit; import com.anssy.pay.vo.AjaxResult; import com.anssy.pay.vo.PayResponse; import com.anssy.pay.vo.WxPayRequest; import com.anssy.pay.weixin.api.WxPayApi; import com.anssy.pay.weixin.api.WxPayApiConfigKit; import com.anssy.pay.weixin.entity.H5ScencInfo; import com.anssy.pay.weixin.entity.H5ScencInfo.H5; import com.google.zxing.BarcodeFormat; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; import com.jfinal.core.Controller; import com.jfinal.kit.*; import com.jfinal.log.Log; import java.io.File; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; /** * 商户模式下微信支付 */ public class WxPayController extends Controller { static Log log=Log.getLog(WxPayController.class); private AjaxResult ajax = new AjaxResult(); private static final Prop prop = PropKit.use("wxpay.properties"); //商户相关资料 String appId = prop.get("appId"); String mchId = prop.get("mchId"); String key = prop.get("key"); String notify_url = prop.get("domain")+"/wxpay/pay_notify"; /** * 生成支付二维码(模式一)并在页面上显示 * * 注:系统后台正在维护,这个立即重复提交也是没有办法提交成功的,需要等待维护结束之后,再进行提交 */ public void scancode1(){ try { String product_id = getPara("productId"); if (StrKit.isBlank(product_id)) { ajax.addError("productId is null"); renderJson(ajax); return; } //获取扫码支付(模式一)url WxPayRequest request = new WxPayRequest(); request.setPayChannel(PayApi.PayChannel.WX.name()); request.setPayMode(WxPayApi.PayMode.scancode1.name()); request.setAppid(appId); request.setMch_id(mchId); request.setProduct_id(product_id); request.setKey(key); //调用支付接口 String requestJson = JSONObject.toJSONString(request); log.info("requestJson>"+requestJson); PayResponse response = PayApi.pay(requestJson); log.info("responseJson>"+JsonKit.toJson(response)); Map<String,String> data = response.getData(); String qrCodeUrl = data.get("qrCodeUrl"); log.info(qrCodeUrl); //生成二维码保存的路径 String name = "payQRCode1.png"; Boolean encode = ZxingKit.encode(qrCodeUrl, BarcodeFormat.QR_CODE, 3, ErrorCorrectionLevel.H, "png", 200, 200, PathKit.getWebRootPath()+File.separator+name ); if (encode) { //在页面上显示 ajax.success(name); renderJson(ajax); } } catch (Exception e) { ajax.addError("系统异常:"+e.getMessage()); renderJson(ajax); e.printStackTrace(); } } /** * 扫码支付模式二 * 注:可以正常操作的支付模式 */ public void scancode2() { String openId = (String) getSession().getAttribute("openId"); String total_fee=getPara("total_fee"); if (StrKit.isBlank(total_fee)) { ajax.addError("支付金额不能为空"); renderJson(ajax); return; } String ip = IpKit.getRealIp(getRequest()); if (StrKit.isBlank(ip)) { ip = "127.0.0.1"; } //支付请求参数 WxPayRequest request = new WxPayRequest(); request.setPayChannel(PayApi.PayChannel.WX.name()); request.setPayMode(WxPayApi.PayMode.scancode2.name()); request.setAppid(appId); request.setMch_id(mchId); request.setKey(key); request.setAttach("支付测试Attach"); request.setBody("支付测试Body"); request.setOpenid(openId); request.setSpbill_create_ip(ip); request.setTotal_fee(total_fee); request.setNotify_url(notify_url); request.setOut_trade_no(String.valueOf(System.currentTimeMillis())); //调用支付接口 String requestJson = JSONObject.toJSONString(request); log.info("requestJson>"+requestJson); PayResponse response = PayApi.pay(requestJson); log.info("responseJson>"+JsonKit.toJson(response)); if(response.getCode().equalsIgnoreCase("SUCCESS")){ Map<String, String> result = response.getData(); //生成预付订单success String qrCodeUrl = result.get("code_url"); String name = "payQRCode2.png"; Boolean encode = ZxingKit.encode(qrCodeUrl, BarcodeFormat.QR_CODE, 3, ErrorCorrectionLevel.H, "png", 200, 200, PathKit.getWebRootPath()+File.separator+name); if (encode) { //在页面上显示 ajax.success(name); renderJson(ajax); } }else{ renderText(response.getMsg()); return; } } /** * 刷卡支付 */ public void micropay(){ String auth_code = getPara("auth_code"); String total_fee = getPara("total_fee"); if (StrKit.isBlank(total_fee)) { ajax.addError("支付金额不能为空"); renderJson(ajax); return; } if (StrKit.isBlank(auth_code)) { ajax.addError("auth_code参数错误"); renderJson(ajax); return; } String ip = IpKit.getRealIp(getRequest()); if (StrKit.isBlank(ip)) { ip = "127.0.0.1"; } //支付请求参数 WxPayRequest request = new WxPayRequest(); request.setPayChannel(PayApi.PayChannel.WX.name()); request.setPayMode(WxPayApi.PayMode.micropay.name()); request.setAppid(appId); request.setMch_id(mchId); request.setKey(key); request.setAttach("支付测试Attach"); request.setBody("支付测试Body"); request.setSpbill_create_ip(ip); request.setTotal_fee(total_fee); request.setAuth_code(auth_code); request.setNotify_url(notify_url); request.setOut_trade_no(String.valueOf(System.currentTimeMillis())); //调用支付接口 String requestJson = JSONObject.toJSONString(request); log.info("requestJson>"+requestJson); PayResponse response = PayApi.pay(requestJson); log.info("responseJson>"+JsonKit.toJson(response)); if(response.getCode().equalsIgnoreCase("SUCCESS")){ Map<String, String> result = response.getData(); ajax.success(result); renderJson(ajax); }else{ ajax.addError(response.getMsg()); renderJson(ajax); } } /** * 公众号支付 */ public void webpay() { String openId = (String) getSession().getAttribute("openId"); String total_fee=getPara("total_fee"); if (StrKit.isBlank(total_fee)) { ajax.addError("请输入数字金额"); renderJson(ajax); return; } String ip = IpKit.getRealIp(getRequest()); if (StrKit.isBlank(ip)) { ip = "127.0.0.1"; } WxPayRequest request = new WxPayRequest(); request.setPayChannel(PayApi.PayChannel.WX.name()); request.setPayMode(WxPayApi.PayMode.webpay.name()); request.setAppid(appId); request.setMch_id(mchId); request.setKey(key); request.setAttach("支付测试Attach"); request.setBody("支付测试Body"); request.setOpenid(openId); request.setSpbill_create_ip(ip); request.setTotal_fee(total_fee); request.setNotify_url(notify_url); request.setOut_trade_no(String.valueOf(System.currentTimeMillis())); //调用支付接口 String requestJson = JSONObject.toJSONString(request); log.info("requestJson>"+requestJson); PayResponse response = PayApi.pay(requestJson); log.info("responseJson>"+JsonKit.toJson(response)); if(response.getCode().equalsIgnoreCase("SUCCESS")){ Map<String, String> result = response.getData(); String prepay_id = result.get("prepay_id"); Map<String, String> packageParams = PaymentKit.prepayIdCreateSign(prepay_id,appId,key); String jsonStr = JsonKit.toJson(packageParams); ajax.success(jsonStr); renderJson(ajax); }else{ ajax.addError(response.getMsg()); renderJson(ajax); } } /** * 微信H5 支付 * 注意:必须再web页面中发起支付且域名已添加到开发配置中 */ public void h5pay(){ String total_fee=getPara("total_fee"); if (StrKit.isBlank(total_fee)) { ajax.addError("请输入数字金额"); renderJson(ajax); return; } String ip = IpKit.getRealIp(getRequest()); if (StrKit.isBlank(ip)) { ip = "127.0.0.1"; } H5ScencInfo sceneInfo = new H5ScencInfo(); H5 h5_info = new H5(); h5_info.setType("Wap"); h5_info.setWap_url("https://pay.qq.com"); h5_info.setWap_name("支付测试"); sceneInfo.setH5_info(h5_info); //支付请求 WxPayRequest request = new WxPayRequest(); request.setPayChannel(PayApi.PayChannel.WX.name()); request.setPayMode(WxPayApi.PayMode.h5pay.name()); request.setAppid(appId); request.setMch_id(mchId); request.setKey(key); request.setAttach("支付测试Attach"); request.setBody("支付测试Body"); request.setSpbill_create_ip(ip); request.setTotal_fee(total_fee); request.setNotify_url(notify_url); request.setOut_trade_no(String.valueOf(System.currentTimeMillis())); request.setScene_info(h5_info.toString()); //调用支付接口 String requestJson = JSONObject.toJSONString(request); log.info("requestJson>"+requestJson); PayResponse response = PayApi.pay(requestJson); log.info("responseJson>"+JsonKit.toJson(response)); if(response.getCode().equalsIgnoreCase("SUCCESS")){ Map<String, String> result = response.getData(); // 以下字段在return_code 和result_code都为SUCCESS的时候有返回 String prepay_id = result.get("prepay_id"); String mweb_url = result.get("mweb_url"); System.out.println("prepay_id:"+prepay_id+" mweb_url:"+mweb_url); redirect(mweb_url); }else{ ajax.addError(response.getMsg()); renderJson(ajax); } } /** * 微信APP支付 */ public void apppay(){ String total_fee=getPara("total_fee"); if (StrKit.isBlank(total_fee)) { ajax.addError("请输入数字金额"); renderJson(ajax); return; } String ip = IpKit.getRealIp(getRequest()); if (StrKit.isBlank(ip)) { ip = "127.0.0.1"; } WxPayRequest request = new WxPayRequest(); request.setPayChannel(PayApi.PayChannel.WX.name()); request.setPayMode(WxPayApi.PayMode.apppay.name()); request.setAppid(appId); request.setMch_id(mchId); request.setKey(key); request.setAttach("支付测试Attach"); request.setBody("支付测试Body"); request.setSpbill_create_ip(ip); request.setTotal_fee(total_fee); request.setNotify_url(notify_url); request.setOut_trade_no(String.valueOf(System.currentTimeMillis())); //提交支付请求 String requestJson = JSONObject.toJSONString(request); log.info("requestJson>"+requestJson); PayResponse response = PayApi.pay(requestJson); log.info("responseJson>"+JsonKit.toJson(response)); if(response.getCode().equalsIgnoreCase("SUCCESS")){ Map<String, String> result = response.getData(); // 以下字段在return_code 和result_code都为SUCCESS的时候有返回 String prepay_id = result.get("prepay_id"); //封装调起微信支付的参数 https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_12 Map<String, String> packageParams = new HashMap<String, String>(); packageParams.put("appid", WxPayApiConfigKit.getWxPayApiConfig().getAppId()); packageParams.put("mch_id", WxPayApiConfigKit.getWxPayApiConfig().getMchId()); packageParams.put("prepayid", prepay_id); packageParams.put("package", "Sign=WXPay"); packageParams.put("noncestr", System.currentTimeMillis() + ""); packageParams.put("timestamp", System.currentTimeMillis() / 1000 + ""); String packageSign = PaymentKit.createSign(packageParams, WxPayApiConfigKit.getWxPayApiConfig().getPaternerKey()); packageParams.put("sign", packageSign); String jsonStr = JsonKit.toJson(packageParams); log.info("最新返回apk的参数:"+jsonStr); renderJson(jsonStr); }else{ ajax.addError(response.getMsg()); renderJson(ajax); } } /** * 支付通知 */ public void pay_notify() { //获取所有的参数 StringBuffer sbf=new StringBuffer(); Enumeration<String> en=getParaNames(); while (en.hasMoreElements()) { Object o= en.nextElement(); sbf.append(o.toString()+"="+getPara(o.toString())); } log.error("支付通知参数:"+sbf.toString()); // 支付结果通用通知文档: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7 String xmlMsg = HttpKit.readData(getRequest()); System.out.println("支付通知="+xmlMsg); Map<String, String> params = PaymentKit.xmlToMap(xmlMsg); String result_code = params.get("result_code"); /以下是附加参数/// String attach = params.get("attach"); if(PaymentKit.verifyNotify(params, WxPayApiConfigKit.getWxPayApiConfig().getPaternerKey())){ if (("SUCCESS").equals(result_code)) { //更新订单信息 log.warn("更新订单信息:"+attach); //发送通知等 Map<String, String> xml = new HashMap<String, String>(); xml.put("return_code", "SUCCESS"); xml.put("return_msg", "OK"); renderText(PaymentKit.toXml(xml)); return; } } renderText(""); } }