200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > 微信公众号 关联网页支付功能(公众号支付)的实现

微信公众号 关联网页支付功能(公众号支付)的实现

时间:2021-08-08 16:06:08

相关推荐

微信公众号 关联网页支付功能(公众号支付)的实现

公众号支付是用户在微信中打开商户的H5页面,商户在H5页面通过调用微信支付提供的JSAPI接口调起微信支付模块完成支付。应用场景有:

1、 用户在微信公众账号内进入商家公众号,打开某个主页面,完成支付

2、用户的好友在朋友圈、聊天窗口等分享商家页面连接,用户点击链接打开商家页面,完成支付

3、将商户页面转换成二维码,用户扫描二维码后在微信浏览器中打开页面后完成支付

公众号支付具体实现步骤见官方文档《微信支付开发文档境内普通商户》,官方链接地址:https://pay./wiki/doc/api/jsapi.php?chapter=3_1

一、申请支付账户

商户在微信公众平台(申请扫码支付、公众号支付)或开放平台(申请APP支付)按照相应提示,申请相应微信支付模式。微信支付工作人员审核资料无误后开通相应的微信支付权限。微信支付申请审核通过后,商户在申请资料填写的邮箱中收取到由微信支付小助手发送的邮件,此邮件包含开发时需要使用的支付账户信息,见图3.1所示。

二、配置支付目录和授权域名

设置支付目录

请确保实际支付时的请求目录与后台配置的目录一致,否则将无法成功唤起微信支付。

在微信商户平台(pay.)设置您的公众号支付支付目录,设置路径:商户平台-->产品中心-->开发配置,如图7.7所示。公众号支付在请求支付的时候会校验请求来源是否有在商户平台做了配置,所以必须确保支付目录已经正确的被配置,否则将验证失败,请求支付不成功。

设置授权域名

开发公众号支付时,在统一下单接口中要求必传用户openid,而获取openid则需要您在公众平台设置获取openid的域名,只有被设置过的域名才是一个有效的获取openid的域名,否则将获取失败。具体界面如图7.8所示:

三、支付业务流程

四、示例代码:

StringUtil

/*** 按指定长度生成随机字符串* @param length* @return*/public static String getRandomString(int length) { //length表示生成字符串的长度String base = "abcdefghijklmnopqrstuvwxyz0123456789"; Random random = new Random(); StringBuffer sb = new StringBuffer(); for (int i = 0; i < length; i++) { int number = random.nextInt(base.length()); sb.append(base.charAt(number)); } return sb.toString(); }

UnifiedOrderRequest

package mon.entity;public class UnifiedOrderRequest extends BaseEntity {private String appid;// 公众账号IDprivate String mch_id;// 微信支付分配的商户号private String nonce_str;// 随机字符串private String sign;// 签名private String body;// 商品简单描述private String out_trade_no;// 商户订单号private String total_fee;// 标价金额private String spbill_create_ip;// 终端IPprivate String notify_url;// 通知地址private String trade_type = "JSAPI";// 交易类型// JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付// 其他不必填参数private String device_info;// 设备号private String sign_type;// 签名类型 默认为MD5private String detail;// 商品详情private String attach;// 附加数据private String fee_type;// 标价币种private String time_start;// 交易起始时间private String time_expire;// 交易结束时间private String goods_tag;// 商品标记private String product_id;// 商品IDprivate String limit_pay;// 指定支付方式private String openid;// 用户标识public String getAppid() {return appid;}public void setAppid(String appid) {this.appid = appid;}public String getMch_id() {return mch_id;}public void setMch_id(String mch_id) {this.mch_id = mch_id;}public String getNonce_str() {return nonce_str;}public void setNonce_str(String nonce_str) {this.nonce_str = nonce_str;}public String getSign() {return sign;}public void setSign(String sign) {this.sign = sign;}public String getBody() {return body;}public void setBody(String body) {this.body = body;}public String getOut_trade_no() {return out_trade_no;}public void setOut_trade_no(String out_trade_no) {this.out_trade_no = out_trade_no;}public String getTotal_fee() {return total_fee;}public void setTotal_fee(String total_fee) {this.total_fee = total_fee;}public String getSpbill_create_ip() {return spbill_create_ip;}public void setSpbill_create_ip(String spbill_create_ip) {this.spbill_create_ip = spbill_create_ip;}public String getNotify_url() {return notify_url;}public void setNotify_url(String notify_url) {this.notify_url = notify_url;}public String getTrade_type() {return trade_type;}public void setTrade_type(String trade_type) {this.trade_type = trade_type;}public String getDevice_info() {return device_info;}public void setDevice_info(String device_info) {this.device_info = device_info;}public String getSign_type() {return sign_type;}public void setSign_type(String sign_type) {this.sign_type = sign_type;}public String getDetail() {return detail;}public void setDetail(String detail) {this.detail = detail;}public String getAttach() {return attach;}public void setAttach(String attach) {this.attach = attach;}public String getFee_type() {return fee_type;}public void setFee_type(String fee_type) {this.fee_type = fee_type;}public String getTime_start() {return time_start;}public void setTime_start(String time_start) {this.time_start = time_start;}public String getTime_expire() {return time_expire;}public void setTime_expire(String time_expire) {this.time_expire = time_expire;}public String getGoods_tag() {return goods_tag;}public void setGoods_tag(String goods_tag) {this.goods_tag = goods_tag;}public String getProduct_id() {return product_id;}public void setProduct_id(String product_id) {this.product_id = product_id;}public String getLimit_pay() {return limit_pay;}public void setLimit_pay(String limit_pay) {this.limit_pay = limit_pay;}public String getOpenid() {return openid;}public void setOpenid(String openid) {this.openid = openid;}}

后台

@RequestMapping(value = "/charge")public Map<String, Object> charge(HttpServletRequest req) throws Exception {super.pageLoad(req);String total_fee = (String) super.parameterMap.get("total_fee");// 金额// 将元转换为分BigDecimal tf = new BigDecimal(total_fee);BigDecimal real_total_fee = tf.multiply(new BigDecimal(100));Map<String, Object> dataMap = new LinkedHashMap<String, Object>();long timeStamp = System.currentTimeMillis() / 1000;// 时间戳(毫秒转换为秒)String nonceStr = StringUtil.getRandomString(32);// 随机串// 获取prepay_id,即获取微信生成的订单号,需要我们调用统一订单接口来获取UnifiedOrderRequest uniOrder = new UnifiedOrderRequest();uniOrder.setAppid(AppString.getAppid());uniOrder.setMch_id(PublicConstants.MCH_ID);uniOrder.setNonce_str(nonceStr);uniOrder.setBody("xx充值");uniOrder.setOut_trade_no(Utils.createTradeNo("O"));// 订单号生成uniOrder.setTotal_fee(String.valueOf(real_total_fee.longValue()));uniOrder.setOpenid((String) super.session.getAttribute("openId"));uniOrder.setSpbill_create_ip(getIpAddr(req));uniOrder.setNotify_url(req.getScheme() + "://" + req.getServerName() + req.getContextPath() + "/wxpay/payNotify");uniOrder.setSign(Utils.createSign(Utils.convertBeanToMap(uniOrder)));// 调用微信接口获取prepay_idString result = httpSender.sendPost("https://api.mch./pay/unifiedorder",Utils.reqObjectToXml(uniOrder));logger.info(result);UnifiedOrderResult uniOrderResult = (UnifiedOrderResult) Utils.getMsgResultEntity(result,UnifiedOrderResult.class.getName());if (!uniOrderResult.getReturn_code().equals("SUCCESS")) {dataMap.put("success", false);dataMap.put("msg", "调用微信统一下单接口失败,原因:" + uniOrderResult.getReturn_msg());return dataMap;}dataMap.put("appId", AppString.getAppid());dataMap.put("nonceStr", nonceStr);dataMap.put("package", "prepay_id=" + uniOrderResult.getPrepay_id());dataMap.put("signType", PublicConstants.SIGN_TYPE);dataMap.put("timeStamp", String.valueOf(timeStamp));dataMap.put("paySign", Utils.createSign(dataMap));return dataMap;}@RequestMapping(value = "/payNotify")public void payNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {Map<String, String> returnMap = new HashMap<>();// 读取请求头,获取参数StringBuilder requestSb = new StringBuilder();BufferedReader reader = request.getReader();String line = null;while (null != (line = reader.readLine())) {requestSb.append(line);}logger.info("payNotify支付回调通知结果:" + requestSb.toString());Map<String, String> wxResultMap = WXPayUtil.xmlToMap(requestSb.toString());// 判断通知中的sign是否有效WXPay wxPay = new WXPay(new WXPayConfig() {@Overridepublic String getMchID() {return PublicConstants.MCH_ID;}@Overridepublic String getAppID() {return AppString.getAppid();}@Overridepublic String getKey() {return PublicConstants.API_KEY;}@Overridepublic int getHttpReadTimeoutMs() {return 5000;}@Overridepublic int getHttpConnectTimeoutMs() {return 5000;}@Overridepublic InputStream getCertStream() {return null;}});boolean signValid = wxPay.isPayResultNotifySignatureValid(wxResultMap);if (signValid) {if ("SUCCESS".equals(wxResultMap.get("return_code")) && "SUCCESS".equals(wxResultMap.get("result_code"))) {String guid = wxResultMap.get("openid");// 用户标识Integer total_fee = Integer.valueOf(wxResultMap.get("openid"));// 订单金额,单位为分String transaction_id = wxResultMap.get("transaction_id");// 微信支付订单号/* 支付成功处理 写入交易记录 */// 1、微信订单号处理过了不再处理 2.通过guid查找用户手机号 3、将充值记录写入数据库Map<String, Object> paramMap = new HashMap<>();paramMap.put("wxTransactionId", transaction_id);List<TransactionRecord> transactionRecordList = this.transactionRecordService.findByParams(paramMap);if (!CollectionUtils.isEmpty(transactionRecordList)) {// 微信支付订单号已存在则不进行处理returnMap.put("return_code", "SUCCESS");returnMap.put("return_msg", "OK");logger.info("payNotify支付回调返回微信参数【" + transaction_id + "已处理直接返回】:" + returnMap);response.getWriter().write(WXPayUtil.mapToXml(returnMap));return;}paramMap.put("guid", guid);List<Account> userList = this.accountService.findByParams(paramMap);String tellphone = userList.get(0).getTellphone();// 用户手机号this.transactionRecordService.add(new TransactionRecord(tellphone, guid,new BigDecimal(total_fee / 100), transaction_id, TransactionTypeEnum.RECHARGE.getValue()));// 保存充值记录returnMap.put("return_code", "SUCCESS");returnMap.put("return_msg", "OK");} else {returnMap.put("return_code", "FAIL");returnMap.put("return_msg", wxResultMap.get("return_msg"));}} else {returnMap.put("return_code", "FAIL");returnMap.put("return_msg", "签名失败");}logger.info("payNotify支付回调返回微信参数:" + returnMap);response.getWriter().write(WXPayUtil.mapToXml(returnMap));}

jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" /><title>公众号支付</title><link href="<%=request.getContextPath()%>/css/app_comm.css" rel="stylesheet" type="text/css" /><link href="<%=request.getContextPath()%>/css/app_style.css" rel="stylesheet" type="text/css" /><script type="text/javascript" src="<%=request.getContextPath()%>/js/jquery.min.js"></script><script type="text/javascript" src="<%=request.getContextPath()%>/js/app_comm.js"></script><script type="text/javascript" src="<%=request.getContextPath()%>/js/common.js"></script><script src="http://res./open/js/jweixin-1.0.0.js"></script><script language="javascript" type="text/javascript">//全局变量//可退金额var refundAmount = 0;$(document).ready(function(){//隐藏弹窗hideWin();//充值金额切换$(".div_ul>li").click(function(){$(".div_ul>li").removeClass("ar_rci");$(this).addClass("ar_rci");//显示或者隐藏输入框if($(this).attr("id")==("other_amount")){$("#input_amount").show();$("#input_amount").val("其他金额(元)");$("#charge_amount").val("");}else{$("#input_amount").hide();var str = $(this).text();$("#charge_amount").val(str.substring(0,str.length - 1));}});$("#input_amount").hide();//设置按钮点击样式$("#chgbtn").click(function(){$(this).css("background","#ddd");var that = $(this);setTimeout(function() { that.css("background",""); }, 50);});//获取用户金额ajaxSyncRequest("wx/amount",{},function(data){if(data.success){$("#balance").text(data.amount);}else{alert(data.msg);}});});//输入框获得焦点function inputOnFocus(){$("#input_amount").attr('type','number');if($("#input_amount").val()=='其他金额(元)'){$("#input_amount").val("");}}//输入框失去焦点function inputBlur(){$("#input_amount").attr('type','text');$("#charge_amount").val($("#input_amount").val());if($("#input_amount").val()==''){$("#input_amount").val('其他金额(元)');}}//隐藏弹窗function hideWin(){$(".app_rec").hide();$(".lock").hide();}//显示弹窗function showWin(){$(".lock").show();$(".app_rec").show();}//充值function charge(){//调用微信支付接口进行充值wxPay();}//确定判断有无注册之后,在执行支付操作function wxPay(){var text = $("#charge_amount").val();if(text == ""){alert("请输入充值金额!"); }else if(!/^[0-9](([0-9]*\.[0-9]{2})|([0-9]*\.[0-9]{1})|([0-9]*))$/.test(text)){alert("请正确输入充值金额!最多两位小数");}else{var value = Number(text);ajaxSyncRequest("wxpay/charge",{"total_fee": value},function(data){if(typeof data.success != 'undefined' && !data.success){alert(data.msg);return;}var onBridgeReady = function(){WeixinJSBridge.invoke('getBrandWCPayRequest', {"appId": data.appId, //公众号名称,由商户传入"timeStamp": data.timeStamp,//时间戳,自1970年以来的秒数"nonceStr": data.nonceStr, //随机串"package": data.package, //微信生成的订单号 "signType": data.signType, //微信签名方式:"paySign": data.paySign //微信签名 },function(res){if(res.err_msg == "get_brand_wcpay_request:ok" ) {//alert("充值成功!");//充值成功,写入数据库(总金额,充值记录)ajaxSyncRequest("wx/chargeRecord",{"amount":value},function(data){if(data.success){window.location.reload(); }else{alert(data.msg);}});}}); }//调用微信支付接口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(); } });}}</script></head><body><div class="w_all app_main"><div class="app_rech"><div class="app_rech_ra"><i id="balance">0.00</i><b>钱包余额(元)</b></div><div class="app_rech_ras"><div class="app_rech_rast">充值金额</div><ul class="div_ul" style="display:block;"><li class="ar_rc">300元</li><li class="ar_rc">200元</li><li class="ar_rc ar_rci">100元</li><li class="ar_rc">50元</li><li class="ar_rc" id="other_amount">其他</li></ul><input name="" id="charge_amount" type="hidden" value="100"/><div class="app_rech_rasi"><input name="" id="input_amount" type="text" οnfοcus="inputOnFocus();" οnblur="inputBlur();" οnkeyup="findConcerns()" value="其他金额(元)"/></div></div><div class="app_info_but"><a class="app_cont_but" id="chgbtn" οnclick="charge()">充值</a></div></div><div class="app_menu"><ul></ul></div></div></body></html>

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