微信公众号扫码支付 spring mvc
来源:互联网 发布:php objectaccess 编辑:程序博客网 时间:2024/06/05 14:32
package com.common.common.controller;import java.io.IOException;import java.io.PrintWriter;import java.math.BigDecimal;import java.net.URLDecoder;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Date;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;import java.util.SortedMap;import java.util.TreeMap;import javax.annotation.Resource;import javax.servlet.ServletInputStream;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.servlet.ModelAndView;import com.alibaba.fastjson.JSON;import com.cloudpark.dao.ParEntryRecordDao;import com.common.common.service.ISmsVerificationService;import com.common.pay.wechatpay.config.WechatPayConfig;import com.common.pay.wechatpay.entity.WechatPayJsonResult;import com.common.pay.wechatpay.entity.WechatPayResponseData;import com.common.pay.wechatpay.util.WeChartPayUtil2;import com.common.pay.wechatpay.util.WeChatPayPaymentStatusUtils;import com.common.pay.wechatpay.util.WechatPayCollectionUtil;import com.common.pay.wechatpay.util.WechatPayFileUtil;import com.common.pay.wechatpay.util.WechatPayHttpKit;import com.common.pay.wechatpay.util.WechatPayHttpUtils;import com.common.pay.wechatpay.util.WechatPaySHA1;import com.common.pay.wechatpay.util.WechatPaySerializerFeatureUtil;import com.common.pay.wechatpay.util.WechatPaySessionUtil;import com.common.pay.wechatpay.util.WechatPayStringUtil;import com.common.pay.wechatpay.util.WechatPayToolUtils;import com.common.pay.wechatpay.util.WechatPayUtil;import com.common.pay.wechatpay.util.WechatPayWebUtil;import com.common.pay.wechatpay.util.WechatPayXmlUtil;import com.common.uitls.DateUtils;import com.common.uitls.JSONMessage;import com.common.uitls.MD5Util;import com.common.uitls.SecurityCodeUtil;import com.common.uitls.SecurityDateUtil;import com.shop.dao.SettlementCategoryDao;import com.shop.util.HttpUtil;import com.shop.util.MyMd5Util;import com.smart.webService.XcloudwebsMain;import com.village.entity.HomeBillcost;import com.village.entity.HomePaymentRecords;import com.village.service.IHomeBillcostService;import com.village.service.IHomePaymentRecordsService;/** * 微信支付控制层 */@Controller@RequestMapping(value = "/WxPay")public class WechatPayController {// 日志输出类private static Logger logger = LoggerFactory.getLogger(WechatPayController.class);private static final String WXPAY_PAY = "https://api.mch.weixin.qq.com/pay/unifiedorder"; // 统一下单// private static final String WXPAY_PAY_QUERY =// "https://api.mch.weixin.qq.com/pay/WxPayquery"; // 支付订单查询private static final String WXPAY_REFUND = "https://api.mch.weixin.qq.com/secapi/pay/refund"; // 申请退款private static final String WXPAY_REFUND_QUERY = "https://api.mch.weixin.qq.com/pay/refundquery"; // 申请退款// 备注,以下两种方法针对不同场景,都可以实现/** * ------------------------------------微信扫码支付 start * 方法一-------------------------------------------- **//** * 扫码支付 * * @param request * @param response * @return */@RequestMapping(value = "/CloudParking/Pay", method = RequestMethod.GET)public ModelAndView CloudCode(HttpServletRequest request, HttpServletResponse response) {ModelAndView mav = new ModelAndView();String parking = request.getParameter("parking");String box = request.getParameter("box");String codeUrl = "http://resource.wlsq.tv/WlsqResourceApi/WxPay/CloudParking/weixin?parking=" + parking+ "&box=" + box;StringBuffer sbt = new StringBuffer(codeUrl);mav.addObject("codeUrl", sbt.toString());logger.info("云停车扫描支付==" + sbt.toString());mav.setViewName("wechatpay_qrcode/QrCode");// 跳转jsp页面生成二维码return mav;}/** * 支付页面跳转 * * @param request * @param response * @return */@RequestMapping(value = "/CloudParking/weixin", method = RequestMethod.GET)public ModelAndView weixinJum(HttpServletRequest request, HttpServletResponse response) {ModelAndView mav = new ModelAndView();try {String userAgent = request.getHeader("user-agent");logger.info("请求头信息======" + userAgent);if (userAgent.indexOf("MicroMessenger") != -1) {logger.info("微信支付");String state = request.getParameter("state");logger.info("state :" + state);String openId = "";String reqcode = request.getParameter("code");openId = WechatPaySHA1.getOpenId(reqcode);logger.info("============openId:" + openId);Map<String, Object> maps = new HashMap<String, Object>();maps.put("parking_id", state.split(",")[0]);maps.put("stand_id", state.split(",")[1]);maps.put("pre_state", 2);List<Map<String, Object>> recordMaps = parentryrecorddao.selectParEntryRecord(maps);// 查询订单信息Map<String, Object> orderMaps = new HashMap<String, Object>();orderMaps.put("record_id", recordMaps.get(0).get("id"));orderMaps.put("pay_statu", "0");List<Map<String, Object>> orderList = parentryrecorddao.selectCloudOrderList(orderMaps);String parking_log = parkingLog(recordMaps.get(0).get("approach_service_time").toString(),recordMaps.get(0).get("service_time_ison").toString());// 时长String car_no = recordMaps.get(0).get("car_no").toString();//String parking_name = recordMaps.get(0).get("parking_name").toString();//String approach_service_time = recordMaps.get(0).get("approach_service_time").toString();//double cashnum = Double.valueOf(orderList.get(0).get("pay_amount").toString());// 订单金额mav.addObject("total_fee", cashnum);mav.addObject("car_no", car_no);mav.addObject("parking_log", parking_log);mav.addObject("parking_name", parking_name);mav.addObject("approach_service_time",approach_service_time.substring(0, approach_service_time.length() - 2));logger.info("微信JS签名参数start=============================");// 微信JS签名参数String time = WechatPayUtil.payTimestamp();String nonceStr = WechatPayUtil.getNonceStr();String jsapi_ticket = WechatPaySHA1.getTicket();String url = getRequertNowUrl(request);String AppId = WechatPayConfig.APP_PUBLIC_ID;// 票据if (WechatPayStringUtil.isEmpty(jsapi_ticket)) {jsapi_ticket = "jdsahflafalf706709sdfshfdldashflhasf7908780";}SortedMap<String, String> wxMap = new TreeMap<String, String>();wxMap.put("wxAppId", WechatPayConfig.APP_PUBLIC_ID);wxMap.put("wxNonceStr", nonceStr);wxMap.put("wxTimeStamp", time);String str = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonceStr + "×tamp=" + time + "&url=" + url;logger.info("str=======" + str);// sha1加密String signature = WechatPaySHA1.encode(str);mav.addObject("appId", WechatPayConfig.APP_PUBLIC_ID);mav.addObject("timeStamp", time);mav.addObject("nonceStr", nonceStr);mav.addObject("signature", signature);logger.info("微信JS签名参数end=============================");Map<String, String> restmap = null;String total_fee = BigDecimal.valueOf(cashnum).multiply(BigDecimal.valueOf(100)).setScale(0, BigDecimal.ROUND_HALF_UP).toString();SortedMap<String, String> parm = new TreeMap<String, String>();parm.put("appid", WechatPayConfig.APP_PUBLIC_ID);parm.put("mch_id", WechatPayConfig.MCH_PUBLIC_ID);parm.put("device_info", "WEB");parm.put("nonce_str", nonceStr);parm.put("body", "H5扫码支付");parm.put("out_trade_no", orderList.get(0).get("order_no").toString());parm.put("total_fee", total_fee);parm.put("spbill_create_ip", WechatPayUtil.getRemoteAddrIp(request));logger.info("spbill_create_ip========" + WechatPayUtil.getRemoteAddrIp(request));parm.put("notify_url", request.getRequestURL() + "/notify"); // 微信服务器异步通知支付结果地址// 下面的WxPay/notify方法parm.put("trade_type", "JSAPI");parm.put("openid", openId); // trade_type=JSAPI时(即公众号支付),此参数必传parm.put("sign", WeChartPayUtil2.createSign2(parm));logger.info(parm.toString());String restxml = WechatPayHttpUtils.post(WXPAY_PAY, WechatPayXmlUtil.xmlFormat(parm, false));restmap = WechatPayXmlUtil.doXMLParse(restxml);logger.info("restxml======" + restxml);logger.info("restmap=====" + restmap.toString());SortedMap<String, String> payMap = new TreeMap<String, String>();// 下单成功if (WechatPayCollectionUtil.isNotEmpty(restmap) && "SUCCESS".equals(restmap.get("result_code"))) {// 生成一个支付的SignpayMap.put("appId", AppId);payMap.put("timeStamp", time);payMap.put("nonceStr", nonceStr);payMap.put("package", "prepay_id=" + (String) restmap.get("prepay_id"));payMap.put("signType", "MD5");mav.addObject("prepayid", restmap.get("prepay_id"));mav.addObject("timeStamp", time);mav.addObject("nonceStr", nonceStr);mav.addObject("signType", "MD5");mav.addObject("paySign", WeChartPayUtil2.createSign2(payMap));mav.addObject("total_fee", total_fee);mav.addObject("out_trade_no", orderList.get(0).get("order_no").toString());logger.info("生成订单支付签名的参数:" + payMap.toString());}mav.setViewName("wechatpay_qrcode/wxcloudprepay");} else if (userAgent.indexOf("AlipayClient") != -1) {logger.info("支付宝支付");}} catch (Exception e) {logger.error(e.getMessage(), e);}return mav;}/** * 订单支付微信服务器异步通知 * * @param request * @param response */@RequestMapping("/CloudParking/weixin/notify")public @ResponseBody JSONMessage WechatPayAdvanceNotify(HttpServletRequest request, HttpServletResponse response) {JSONMessage jsonMessage = new JSONMessage();try {ServletInputStream in = request.getInputStream();String resxml = WechatPayFileUtil.readInputStream2String(in);logger.info("支付进入微信回调");logger.info("{resxml}" + resxml);logger.info("[/WxPay/pay/notify]");response.setCharacterEncoding("UTF-8");response.setContentType("text/xml");// 获取微信反馈过来的信息Map<String, String> restmap = WechatPayXmlUtil.doXMLParse(resxml);logger.info("微信返回的参数{restmap}" + restmap);// 微信返回的参数double total_fee = Double.parseDouble(restmap.get("total_fee"));double total_fee1 = Double.valueOf(total_fee / 100);BigDecimal total_fee2 = BigDecimal.valueOf(total_fee1);String out_trade_no = restmap.get("out_trade_no");if (!security_code.equals(out_trade_no)) {return new JSONMessage(11, "非法参数");}if ("SUCCESS".equals(restmap.get("return_code"))) {// 订单支付成功 业务处理// 通过商户订单判断是否该订单已经处理 如果处理跳过 如果未处理先校验sign签名 再进行订单业务相关的处理Map<String, Object> orsMap = new HashMap<String, Object>();orsMap.put("order_no", out_trade_no);List<Map<String, Object>> orList = parentryrecorddao.selectCloudOrderList(orsMap);if (orList.size() > 0) {logger.info("orList out_trade_no " + orList.get(0).get("order_no"));restmap.remove("sign");// -------------更新订单,通知设备---------Map<String, Object> maps = new HashMap<String, Object>();// 修改订单状态Double orderMoney = Double.valueOf(orList.get(0).get("parking_amount").toString());BigDecimal bdMoney = BigDecimal.valueOf(orderMoney);if (bdMoney.compareTo(total_fee2) == 0) {// 支付金额是否与实际金额相等maps.put("order_no", out_trade_no);maps.put("pay_amount", total_fee);maps.put("pay_statu", 1);maps.put("pay_method", 1);maps.put("id", orList.get(0).get("id"));parentryrecorddao.updateCloudOrder(maps);// 业务操作,更新订单}// -------------更新订单,通知设备---------// 处理成功后相应给响应xmlMap<String, String> respMap = new HashMap<>();respMap = new HashMap<String, String>();respMap.put("return_code", "SUCCESS"); // 相应给微信服务器respMap.put("return_msg", "OK");String resXml = WechatPayXmlUtil.xmlFormat(restmap, true);response.getWriter().write(resXml);}} else {logger.info("订单支付通知:支付失败," + restmap.get("err_code") + ":" + restmap.get("err_code_des"));}} catch (Exception e) {logger.error(e.getMessage(), e);jsonMessage = new JSONMessage(0, "系统异常");}return jsonMessage;}/** * ------------------------------------微信扫码支付 end * -------------------------------------------- **//** * ------------------------------------微信打开h5,jsp页面输入业务条件查询进行支付 start * 方法二------------------------------------------------ **//** * 扫码支付 * * @param request * @param response * @return */@RequestMapping(value = "/CloudParking/pre", method = RequestMethod.GET)public ModelAndView cloudParkingFee(HttpServletRequest request, HttpServletResponse response) {ModelAndView mav = new ModelAndView();String parking = request.getParameter("parking");String codeUrl = "http://resource.wlsq.tv/WlsqResourceApi/WxPay/cloud/pay?parking=" + parking;StringBuffer sbt = new StringBuffer(codeUrl);mav.addObject("codeUrl", sbt.toString());logger.info("跳转扫描支付页面==" + sbt.toString());mav.setViewName("wechatpay_qrcode/QrCode");return mav;}@RequestMapping(value = "/cloud/pay", method = RequestMethod.GET)public ModelAndView cloudSelectPay(HttpServletRequest request, HttpServletResponse response) {ModelAndView mav = new ModelAndView();String parking = request.getParameter("parking");mav.addObject("parking", 1);mav.setViewName("wechatpay_qrcode/wxparkingfee");return mav;}/** * 支付页面跳转 * * @param request * @param response * @return */@RequestMapping(value = "/CloudParking/Pre", method = RequestMethod.GET)public ModelAndView weixinPrePay(HttpServletRequest request, HttpServletResponse response) {ModelAndView mav = new ModelAndView();try {logger.info("微信预支付");String state = request.getParameter("state");String lastState = URLDecoder.decode(state);logger.info("state :" + lastState);String car_no = state.split(",")[0];// 车牌号String openId = "";String reqcode = request.getParameter("code");openId = WechatPaySHA1.getOpenId(reqcode);logger.info(",car_no:" + state.split(",")[0] + ",parking_id:" + state.split(",")[1]);Map<String, Object> maps = new HashMap<String, Object>();maps.put("parking_id", state.split(",")[1]);maps.put("car_no", car_no);maps.put("pre_state", 1);logger.info("查询结果开始::--------------------------------------");List<Map<String, Object>> recordMaps = parentryrecorddao.selectParEntryRecord(maps);if (recordMaps.size() > 0) {logger.info("查询结果::" + recordMaps.size());String parking_log = parkingLog(recordMaps.get(0).get("approach_service_time").toString(),DateUtils.getDate("yyyy-MM-dd hh:mm:ss"));// 停车时长String parking_name = recordMaps.get(0).get("parking_name").toString();// 停车场String approach_service_time = recordMaps.get(0).get("approach_service_time").toString();// 进场时间mav.addObject("car_no", car_no);mav.addObject("parking_log", parking_log);mav.addObject("parking_name", parking_name);mav.addObject("approach_service_time",approach_service_time.substring(0, approach_service_time.length() - 2));logger.info("微信JS签名参数start=============================");// 微信JS签名参数String time = WechatPayUtil.payTimestamp();String nonceStr = WechatPayUtil.getNonceStr();String jsapi_ticket = WechatPaySHA1.getTicket();String url = getRequertNowUrl(request);String AppId = WechatPayConfig.APP_PUBLIC_ID;// 票据if (WechatPayStringUtil.isEmpty(jsapi_ticket)) {jsapi_ticket = "kgt8ON7yVITDhtdwci0qeQviUa69F3dDOrtGgFxhzJfQo5g3eyu8JL7AEm_i2giXc6NbpitSLPYGzewd142h2w";}SortedMap<String, String> wxMap = new TreeMap<String, String>();wxMap.put("wxAppId", WechatPayConfig.APP_PUBLIC_ID);wxMap.put("wxNonceStr", nonceStr);wxMap.put("wxTimeStamp", time);String str = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonceStr + "×tamp=" + time + "&url=" + url;// sha1加密String signature = WechatPaySHA1.encode(str);mav.addObject("appId", WechatPayConfig.APP_PUBLIC_ID);mav.addObject("timeStamp", time);mav.addObject("nonceStr", nonceStr);mav.addObject("signature", signature);logger.info("微信JS签名参数end=============================");// 查询订单信息Map<String, Object> orderMaps = new HashMap<String, Object>();orderMaps.put("record_id", recordMaps.get(0).get("id"));orderMaps.put("pay_statu", "0");List<Map<String, Object>> orderList = parentryrecorddao.selectCloudOrderList(orderMaps);Map<String, String> restmap = null;String pay_money = orderList.get(0).get("pay_amount").toString();// 支付金额double cashnum = Double.valueOf(pay_money);// 订单金额String total_fee = BigDecimal.valueOf(cashnum).multiply(BigDecimal.valueOf(100)).setScale(0, BigDecimal.ROUND_HALF_UP).toString();mav.addObject("total_fee", pay_money);SortedMap<String, String> parm = new TreeMap<String, String>();parm.put("appid", WechatPayConfig.APP_PUBLIC_ID);parm.put("mch_id", WechatPayConfig.MCH_PUBLIC_ID);parm.put("device_info", "WEB");parm.put("nonce_str", nonceStr);parm.put("body", "预支付");parm.put("out_trade_no", orderList.get(0).get("order_no").toString());parm.put("total_fee", total_fee);parm.put("spbill_create_ip", WechatPayUtil.getRemoteAddrIp(request));logger.info("spbill_create_ip========" + WechatPayUtil.getRemoteAddrIp(request));String notify_url = request.getRequestURL().toString();notify_url = notify_url.replace("Pre", "weixin/notify");parm.put("notify_url", notify_url);parm.put("trade_type", "JSAPI");parm.put("openid", openId); // trade_type=JSAPI时(即公众号支付),此参数必传parm.put("sign", WeChartPayUtil2.createSign2(parm));logger.info(parm.toString());String restxml = WechatPayHttpUtils.post(WXPAY_PAY, WechatPayXmlUtil.xmlFormat(parm, false));restmap = WechatPayXmlUtil.doXMLParse(restxml);logger.info("restxml======" + restxml);logger.info("restmap=====" + restmap.toString());SortedMap<String, String> payMap = new TreeMap<String, String>();// 下单成功if (WechatPayCollectionUtil.isNotEmpty(restmap) && "SUCCESS".equals(restmap.get("result_code"))) {// 生成一个支付的SignpayMap.put("appId", AppId);payMap.put("timeStamp", time);payMap.put("nonceStr", nonceStr);payMap.put("package", "prepay_id=" + (String) restmap.get("prepay_id"));payMap.put("signType", "MD5");mav.addObject("prepayid", restmap.get("prepay_id"));mav.addObject("timeStamp", time);mav.addObject("nonceStr", nonceStr);mav.addObject("signType", "MD5");mav.addObject("paySign", WeChartPayUtil2.createSign2(payMap));mav.addObject("out_trade_no", orderList.get(0).get("order_no"));logger.info("生成订单支付签名的参数:" + payMap.toString());}mav.setViewName("wechatpay_qrcode/wxcloudprepay");} else {mav.setViewName("wechatpay_qrcode/error");}} catch (Exception e) {logger.error(e.getMessage(), e);logger.info("微信支付回调");}return mav;}/** * ------------------------------------微信打开h5,jsp页面输入业务条件查询进行支付 end * -------------------------------------------- **/}package com.common.pay.wechatpay.util;import java.io.IOException;/* * 微信公众平台(JAVA) SDK * * Copyright (c) 2014, Ansitech Network Technology Co.,Ltd All rights reserved. * http://www.ansitech.com/weixin/sdk/ * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.util.SortedMap;import java.util.TreeMap;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import com.alibaba.fastjson.JSON;import com.common.pay.wechatpay.config.WechatPayConfig;/** * <p> * Title: SHA1算法 * </p> * * @author Tidy */public final class WechatPaySHA1 {// 日志输出类private static Logger logger = LoggerFactory.getLogger(WechatPaySHA1.class);private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd','e', 'f' };/** * Takes the raw bytes from the digest and formats them correct. * * @param bytes * the raw bytes from the digest. * @return the formatted bytes. */private static String getFormattedText(byte[] bytes) {int len = bytes.length;StringBuilder buf = new StringBuilder(len * 2);// 把密文转换成十六进制的字符串形式for (int j = 0; j < len; j++) {buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);buf.append(HEX_DIGITS[bytes[j] & 0x0f]);}return buf.toString();}public static String encode(String str) {if (str == null) {return null;}try {MessageDigest messageDigest = MessageDigest.getInstance("SHA1");messageDigest.update(str.getBytes());return getFormattedText(messageDigest.digest());} catch (Exception e) {throw new RuntimeException(e);}}/** * 获取签名 用于页面wx.config注入 * * @param timestamp * Sha1Util.getTimeStamp() * @param nonce_str * Sha1Util.getNonceStr() * @param url * 当前网页的URL不包含#及其后面部分(参数需要带上,必须是完整的URL) * @return "" 表示获取签名出现异常 * @throws Exception */public static String createSignature(String timestamp, String nonce_str, String url) throws Exception {SortedMap<String, String> signParams = new TreeMap<String, String>();String jsapi_ticket = getTicket();if (WechatPayStringUtil.isEmpty(jsapi_ticket)) {logger.info("获取jsapi_ticket异常");return "";}if (WechatPayStringUtil.isEmpty(nonce_str)) {logger.info("nonce_str参数不能为空");return "";}signParams.put("nonce_str", nonce_str);signParams.put("jsapi_ticket", jsapi_ticket);if (WechatPayStringUtil.isEmpty(timestamp)) {logger.info("timestamp参数不能为空");return "";}signParams.put("timestamp", timestamp);if (WechatPayStringUtil.isEmpty(url)) {logger.info("url参数不能为空");return "";}signParams.put("url", url);String signature = "";try {signature = WechatPayUtil.getSignature(signParams);} catch (IOException e) {logger.info("wx.config签名生成异常:" + e.getMessage());e.printStackTrace();}if (signature.equals("false")) {return "";}return signature;}/** * 获取当前公众号jsapi_ticke * * @return * @throws Exception */public static String getTicket() {// Cache cache = CacheManager.getCacheInfo("WeiXinUtils.getTicket");// if ((cache == null) || (cache.isExpired())) {String ticket = "";String result = "";try {String parameter = "access_token=" + getAccessToken() + "&type=jsapi";result = WechatPayHttpUtils.HttpPosts("https://api.weixin.qq.com/cgi-bin/ticket/getticket?", parameter);logger.info("========= 获取权限getTicket" + result);ticket = JSON.parseObject(result).getString("ticket");} catch (Exception e) {logger.error("获取当前公众号jsapi_ticke产生异常:" + e.getMessage());e.printStackTrace();}/* * cache = new Cache(); * cache.setValue(JSONObject.fromObject(result).get("ticket")); * CacheManager.putCacheInfo("WeiXinUtils.getTicket", cache, 6900000L); * return cache.getValue().toString(); */return ticket;}public static String SHA1(String decript) {try {MessageDigest digest = MessageDigest.getInstance("SHA-1");digest.update(decript.getBytes());byte messageDigest[] = digest.digest();// Create Hex StringStringBuffer hexString = new StringBuffer();// 字节数组转换为 十六进制 数for (int i = 0; i < messageDigest.length; i++) {String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);if (shaHex.length() < 2) {hexString.append(0);}hexString.append(shaHex);}return hexString.toString();} catch (NoSuchAlgorithmException e) {e.printStackTrace();}return "";}/** * 获取当前公众号access_token * * @return * @throws Exception */public static String getAccessToken() {/* * String access_token = ""; Cache cache = * CacheManager.getCacheInfo("WeiXinUtils.getAccessToken"); if ((cache * == null) || (cache.isExpired())) { log.info("AccessToken没有cache"); * String result = ""; try { String parameter = * "grant_type=client_credential&appid=" + appId + "&secret=" + * appSecret; result = GongZhongUtils.sendPost( * "https://api.weixin.qq.com/cgi-bin/token?", parameter); * log.info("appid---" + appId); log.info("secret---" + appSecret); * log.info("access_token---"+ * JSONObject.fromObject(result).get("access_token")); } catch * (Exception e) { System.err.println("获取当前公众号access_token产生异常:" + * e.getMessage()); e.printStackTrace(); } cache = new Cache(); * cache.setValue(JSONObject.fromObject(result).get("access_token")); * log.info("cache中的access_token---" + cache.getValue()); * CacheManager.putCacheInfo("WeiXinUtils.getAccessToken", cache, * 6900000L); access_token = cache.getValue().toString(); * log.info("保存在缓存中的access_token---" + access_token); } access_token = * cache.getValue().toString(); log.info("保存在缓存中的access_token---" + * access_token); try { HttpServletRequest request = * ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes( * )).getRequest(); String basePath = * request.getScheme()+"://"+request.getServerName()+request. * getContextPath()+"/"; String openid =""; * if(basePath.contains("localhost") || * basePath.contains("food.java.1yg.tv") || * basePath.contains("127.0.0.1")){ * openid="oWKsFs0OooGjWws8rFKqUkkFU_rU"; }else{ * openid="oHTpCwLU8VcPKp49HBE463eZoT-Q"; } UserInfo u = new UserInfo(); * String reslut = GongZhongUtils.sendPost( * "https://api.weixin.qq.com/cgi-bin/user/info?", "access_token=" + * access_token + "&openid="+openid); System.out.println("UserInfo:" + * reslut); JSONObject obj = JSONObject.fromObject(reslut); if (obj == * null) { String parameter = "grant_type=client_credential&appid=" + * appId + "&secret=" + appSecret; String result = * GongZhongUtils.sendPost( "https://api.weixin.qq.com/cgi-bin/token?", * parameter); log.info("appid---" + appId); log.info("secret---" + * appSecret); log.info("access_token---" + * JSONObject.fromObject(result).get("access_token")); cache = new * Cache(); cache.setValue(JSONObject.fromObject(result) * .get("access_token")); log.info("cache中的access_token---" + * cache.getValue()); * CacheManager.putCacheInfo("WeiXinUtils.getAccessToken", cache, * 6900000L); access_token = cache.getValue().toString(); } else if * (Tools.isEmpty(obj.get("errcode") + "")) { return access_token; } * else if (obj.get("errcode").equals("40001")) { String parameter = * "grant_type=client_credential&appid=" + appId + "&secret=" + * appSecret; String result = GongZhongUtils.sendPost( * "https://api.weixin.qq.com/cgi-bin/token?", parameter); * log.info("appid---" + appId); log.info("secret---" + appSecret); * log.info("access_token---" + * JSONObject.fromObject(result).get("access_token")); cache = new * Cache(); cache.setValue(JSONObject.fromObject(result) * .get("access_token")); log.info("cache中的access_token---" + * cache.getValue()); * CacheManager.putCacheInfo("WeiXinUtils.getAccessToken", cache, * 6900000L); access_token = cache.getValue().toString(); } * * } catch (Exception e) { log.info("验证access_token是否过期时获取微信用户信息异常:" + * e.toString()); e.printStackTrace(); } * * return access_token; } */String access_token = "";String result = "";try {String parameter = "grant_type=client_credential&appid=" + WechatPayConfig.APP_PUBLIC_ID + "&secret="+ WechatPayConfig.API_PUBLIC_KEY;result = WechatPayHttpUtils.HttpPosts("https://api.weixin.qq.com/cgi-bin/token?", parameter);logger.info("========= 获取权限getAccessToken" + result);access_token = JSON.parseObject(result).getString("access_token");} catch (Exception e) {logger.info("获取当前公众号access_token产生异常:" + e.getMessage());e.printStackTrace();}return access_token;}/** * 获取页面授权用户openID * * @param code * @return * @throws Exception */public static String getOpenId(String code) throws Exception {String result, openid = "";String parameter = "grant_type=authorization_code&code=" + code + "&appid=" + WechatPayConfig.APP_PUBLIC_ID+ "&secret=" + WechatPayConfig.API_PUBLIC_KEY;try {result = WechatPayHttpUtils.HttpPosts("https://api.weixin.qq.com/sns/oauth2/access_token?", parameter);logger.info("========= 获取权限getOpenId" + result);openid = JSON.parseObject(result).getString("openid");} catch (Exception e) {logger.error("获取当前openId产生异常:" + e.getMessage());e.printStackTrace();}return openid;}/** * 请求code * * @return 拉取授权地址 */public static String getCode() {// 第一个参数必须为appid 否则会appid参数错误String para = "appid=" + WechatPayConfig.APP_PUBLIC_ID + "&redirect_uri=" + WechatPayConfig.REDIRECT_URL+ "&response_type=code&scope=snsapi_base&state=wx#wechat_redirect";return "https://open.weixin.qq.com/connect/oauth2/authorize?" + para;}/** * 请求code * * @return 拉取授权地址 */public static String getCode(String redirectUrl) {// 第一个参数必须为appid 否则会appid参数错误String para = "appid=" + WechatPayConfig.APP_PUBLIC_ID + "&redirect_uri=" + redirectUrl+ "&response_type=code&scope=snsapi_base&state=wx#wechat_redirect";return "https://open.weixin.qq.com/connect/oauth2/authorize?" + para;}/** * 请求code 传递自定义参数 state 参数可修改 * * @return 拉取授权地址 */public static String getCode(String redirectUrl, String str) {// 第一个参数必须为appid 否则会appid参数错误String para = "appid=" + WechatPayConfig.APP_PUBLIC_ID + "&redirect_uri=" + redirectUrl+ "&response_type=code&scope=snsapi_base&state=" + str + "#wechat_redirect";return "https://open.weixin.qq.com/connect/oauth2/authorize?" + para;}public static void main(String[] args) {System.out.println(getAccessToken() + "--" + getTicket());}}package com.common.pay.wechatpay.util;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.io.UnsupportedEncodingException;import java.net.URL;import java.net.URLConnection;import java.net.URLEncoder;import java.security.KeyStore;import java.util.ArrayList;import java.util.List;import java.util.Map;import java.util.Map.Entry;import javax.net.ssl.SSLContext;import org.apache.http.NameValuePair;import org.apache.http.client.config.RequestConfig;import org.apache.http.client.entity.UrlEncodedFormEntity;import org.apache.http.client.methods.CloseableHttpResponse;import org.apache.http.client.methods.HttpGet;import org.apache.http.client.methods.HttpPost;import org.apache.http.conn.ssl.SSLConnectionSocketFactory;import org.apache.http.entity.StringEntity;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.HttpClients;import org.apache.http.message.BasicNameValuePair;import org.apache.http.ssl.SSLContexts;import org.apache.http.util.EntityUtils;import org.springframework.core.io.ClassPathResource;import org.springframework.core.io.Resource;import com.common.pay.wechatpay.config.WechatPayConfig;/** * HTTP工具类 */public class WechatPayHttpUtils {private static final String DEFAULT_CHARSET = "UTF-8";private static final int CONNECT_TIME_OUT = 5000; // 链接超时时间5秒private static final RequestConfig REQUEST_CONFIG = RequestConfig.custom().setConnectTimeout(CONNECT_TIME_OUT).build();private static SSLContext wx_ssl_context = null; // 微信支付ssl证书static {// 微信商家证书Resource resource = new ClassPathResource("wx_apiclient_cert.p12");try {// 加载秘钥KeyStore keystore = KeyStore.getInstance("PKCS12");char[] keyPassword = WechatPayConfig.MCH_ID.toCharArray(); // 证书密码keystore.load(resource.getInputStream(), keyPassword);wx_ssl_context = SSLContexts.custom().loadKeyMaterial(keystore, keyPassword).build();} catch (Exception e) {e.printStackTrace();}}/** * @description 功能描述: get 请求 * @param url * 请求地址 * @param params * 参数 * @param headers * headers参数 * @return 请求失败返回null */public static String get(String url, Map<String, String> params, Map<String, String> headers) {CloseableHttpClient httpClient = null;if (params != null && !params.isEmpty()) {StringBuffer param = new StringBuffer();boolean flag = true; // 是否开始for (Entry<String, String> entry : params.entrySet()) {if (flag) {param.append("?");flag = false;} else {param.append("&");}param.append(entry.getKey()).append("=");try {param.append(URLEncoder.encode(entry.getValue(), DEFAULT_CHARSET));} catch (UnsupportedEncodingException e) {// 编码失败}}url += param.toString();}String body = null;CloseableHttpResponse response = null;try {httpClient = HttpClients.custom().setDefaultRequestConfig(REQUEST_CONFIG).build();HttpGet httpGet = new HttpGet(url);response = httpClient.execute(httpGet);body = EntityUtils.toString(response.getEntity(), DEFAULT_CHARSET);} catch (Exception e) {e.printStackTrace();} finally {if (response != null) {try {response.close();} catch (IOException e) {e.printStackTrace();}}if (httpClient != null) {try {httpClient.close();} catch (IOException e) {e.printStackTrace();}}}return body;}/** * @description 功能描述: get 请求 * @param url * 请求地址 * @return 请求失败返回null */public static String get(String url) {return get(url, null);}/** * @description 功能描述: get 请求 * @param url * 请求地址 * @param params * 参数 * @return 请求失败返回null */public static String get(String url, Map<String, String> params) {return get(url, params, null);}/** * @description 功能描述: post 请求 * @param url * 请求地址 * @param params * 参数 * @return 请求失败返回null */public static String post(String url, Map<String, String> params) {CloseableHttpClient httpClient = null;HttpPost httpPost = new HttpPost(url);List<NameValuePair> nameValuePairs = new ArrayList<>();if (params != null && !params.isEmpty()) {for (Entry<String, String> entry : params.entrySet()) {nameValuePairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));}}String body = null;CloseableHttpResponse response = null;try {httpClient = HttpClients.custom().setDefaultRequestConfig(REQUEST_CONFIG).build();httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, DEFAULT_CHARSET));response = httpClient.execute(httpPost);body = EntityUtils.toString(response.getEntity(), DEFAULT_CHARSET);} catch (Exception e) {e.printStackTrace();} finally {if (response != null) {try {response.close();} catch (IOException e) {e.printStackTrace();}}if (httpClient != null) {try {httpClient.close();} catch (IOException e) {e.printStackTrace();}}}return body;}/** * @description 功能描述: post 请求 * @param url * 请求地址 * @param s * 参数xml * @return 请求失败返回null */public static String post(String url, String s) {CloseableHttpClient httpClient = null;HttpPost httpPost = new HttpPost(url);String body = null;CloseableHttpResponse response = null;try {httpClient = HttpClients.custom().setDefaultRequestConfig(REQUEST_CONFIG).build();httpPost.setEntity(new StringEntity(s, DEFAULT_CHARSET));response = httpClient.execute(httpPost);body = EntityUtils.toString(response.getEntity(), DEFAULT_CHARSET);} catch (Exception e) {e.printStackTrace();} finally {if (response != null) {try {response.close();} catch (IOException e) {e.printStackTrace();}}if (httpClient != null) {try {httpClient.close();} catch (IOException e) {e.printStackTrace();}}}return body;}/** * @description 功能描述: post https请求,服务器双向证书验证 * @param url * 请求地址 * @param params * 参数 * @return 请求失败返回null */public static String posts(String url, Map<String, String> params) {CloseableHttpClient httpClient = null;HttpPost httpPost = new HttpPost(url);List<NameValuePair> nameValuePairs = new ArrayList<>();if (params != null && !params.isEmpty()) {for (Entry<String, String> entry : params.entrySet()) {nameValuePairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));}}String body = null;CloseableHttpResponse response = null;try {httpClient = HttpClients.custom().setDefaultRequestConfig(REQUEST_CONFIG).setSSLSocketFactory(getSSLConnectionSocket()).build();httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, DEFAULT_CHARSET));response = httpClient.execute(httpPost);body = EntityUtils.toString(response.getEntity(), DEFAULT_CHARSET);} catch (Exception e) {e.printStackTrace();} finally {if (response != null) {try {response.close();} catch (IOException e) {e.printStackTrace();}}if (httpClient != null) {try {httpClient.close();} catch (IOException e) {e.printStackTrace();}}}return body;}/** * @description 功能描述: post https请求,服务器双向证书验证 * @param url * 请求地址 * @param s * 参数xml * @return 请求失败返回null */public static String posts(String url, String s) {CloseableHttpClient httpClient = null;HttpPost httpPost = new HttpPost(url);String body = null;CloseableHttpResponse response = null;try {httpClient = HttpClients.custom().setDefaultRequestConfig(REQUEST_CONFIG).setSSLSocketFactory(getSSLConnectionSocket()).build();httpPost.setEntity(new StringEntity(s, DEFAULT_CHARSET));response = httpClient.execute(httpPost);body = EntityUtils.toString(response.getEntity(), DEFAULT_CHARSET);} catch (Exception e) {e.printStackTrace();} finally {if (response != null) {try {response.close();} catch (IOException e) {e.printStackTrace();}}if (httpClient != null) {try {httpClient.close();} catch (IOException e) {e.printStackTrace();}}}return body;}// 获取ssl connection链接private static SSLConnectionSocketFactory getSSLConnectionSocket() {return new SSLConnectionSocketFactory(wx_ssl_context, new String[] { "TLSv1", "TLSv1.1", "TLSv1.2" }, null,SSLConnectionSocketFactory.getDefaultHostnameVerifier());}public static String sendPost(String url, String parameter) throws Exception {String result = post(url, parameter);return result;}public static String HttpPosts(String url, String parameterList) throws Exception {OutputStreamWriter out = null;StringBuilder result = new StringBuilder();while_1_: do {while_0_: do {do {try {try {URL urlTemp = new URL(url);URLConnection connection = urlTemp.openConnection();connection.setDoOutput(true);out = (new OutputStreamWriter(connection.getOutputStream(), "UTF-8"));out.write(parameterList);out.flush();String line = "";InputStream is = connection.getInputStream();BufferedReader br = (new BufferedReader(new InputStreamReader(is, "UTF-8")));while ((line = br.readLine()) != null)result.append(line);} catch (Exception e) {e.printStackTrace();break;}break while_0_;} catch (Exception object) {if (out != null) {try {out.close();} catch (IOException e) {e.printStackTrace();}}throw object;}} while (false);if (out != null) {try {out.close();} catch (IOException e) {e.printStackTrace();}}break while_1_;} while (false);if (out != null) {try {out.close();} catch (IOException e) {e.printStackTrace();}}} while (false);return result.toString();}}package com.common.pay.wechatpay.config;/** * WechatPayConfig 微信支付配置类 * */public class WechatPayConfig {// 微信支付应用IDpublic static final String APP_ID = "asfsdfasdfasf";// 微信支付商户IDpublic static final String MCH_ID = "sadfasfwewer";// 证书秘钥public static final String API_KEY = "asfdasfasdaf";// 微信支付公众号应用IDpublic static final String APP_PUBLIC_ID = "asdfasfasfadf";// 微信支付公众号商户IDpublic static final String MCH_PUBLIC_ID = "4234234242424";// 公众号证书秘钥public static final String API_PUBLIC_KEY = "asdfasfasfadf4234234242424";// 用户令牌public static final String ACCESS_TOKEN = "ACCESS_TOKEN";// 转发地址(下单)public static final String REDIRECT_URL = "/wechatpay_qrcode/wxprepay";}
jsp页面
<%@page language="java"contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><%long t = System.currentTimeMillis();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/";%><!DOCTYPE html PUBLIC"-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type"content="text/html; charset=UTF-8"><title>微信公众号支付</title></head><body>二维码生成如下<br><div id="qrCode"></div><script type="text/javascript"src="<%=basePath %>wechatpay_qrcode/js/jquery.min.js?t=<%=t%>"></script><script type="text/javascript"src="<%=basePath %>wechatpay_qrcode/js/jquery.qrcode.min.js?t=<%=t%>"></script><script type="text/javascript">$('#qrCode').qrcode("${codeUrl}"); </script></body></html><%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><% long t = System.currentTimeMillis();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/";%><!DOCTYPE html PUBLIC"-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type"content="text/html; charset=UTF-8"><title>微信公众号支付</title></head><body>二维码生成如下<br><div id="qrCode"></div><script type="text/javascript"src="<%=basePath %>wechatpay_qrcode/js/jquery.min.js?t=<%=t%>"></script><script type="text/javascript"src="<%=basePath %>wechatpay_qrcode/js/jquery.qrcode.min.js?t=<%=t%>"></script><script type="text/javascript">$('#qrCode').qrcode("${codeUrl}"); </script></body></html><%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> <% long t = System.currentTimeMillis();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/";%><!DOCTYPE html PUBLIC"-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"><html><head><meta name="viewport"content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/><meta name = "apple-mobile-web-app-capable"content="yes"/><meta name = "apple-mobile-web-app-status-bar-style"content="black"/><meta name = "format-detection"content="telephone=no"/><link href = "<%=basePath %>wechatpay_qrcode/css/common.css?t=<%=t%>"rel="stylesheet"type="text/css"/><title></title><style type = "text/css" > body, h1, h2, h3, p, div, ol, ul, input, button, span,:before,:after{margin: 0;padding: 0}html,body{font-size:16 px;max-width:100%;font-family:Arial,Helvetica,sans-serif}html{font-size:62.5%}ul{list-style:none}.content{padding:3 rem 1 rem}.pay_li_em{width:8 rem;text-align:right;font-style:normal;display:inline-block}.pay_li_span{margin-left:5 px}.pay_li{width:90%;margin:0 auto;height:6 rem;line-height:6 rem;border:1 px solid#d9d9d9;padding:0 1 rem;border-radius:5 px;box-sizing:border-box;-webkit-box-sizing:border-box;margin-top:2 rem;margin-bottom:2 rem;color:#5 a5a5a;font-size:15 px;vertical-align:middle}#wcPay{width:90%;display:block;border-style:none;background:#108ee 9;color:#fff;margin:0 auto;height:5 rem;line-height:5 rem;vertical-align:middle;border-radius:5 px;outline:0}#wcPay:active{background:#0e77 ca} </style><script>var currClientWidth, fontValue, originWidth;// originWidth用来设置设计稿原型的屏幕宽度(这里是以 Iphone 6为原型的设计稿)originWidth=375;__resize();// 注册 resize事件window.addEventListener('resize',__resize,false);function __resize() {currClientWidth = document.documentElement.clientWidth;// 这里是设置屏幕的最大和最小值时候给一个默认值if (currClientWidth > 640)currClientWidth = 640;if (currClientWidth < 320)currClientWidth = 320;//fontValue = ((62.5 * currClientWidth) / originWidth).toFixed(2);document.documentElement.style.fontSize = fontValue + '%';}</script></head><body><div><div class="content"><ul><li class="pay_li"><em class="pay_li_em">车场:</em><span class="pay_li_span">${parking_name} </span></li><li class="pay_li"><em class="pay_li_em">车牌:</em><span class="pay_li_span">${car_num} </span></li><li class="pay_li"><em class="pay_li_em">金额:</em><span class="pay_li_span">${pay_money} </span></li><li class="pay_li"><em class="pay_li_em">停车时长:</em><span class="pay_li_span">${parking_log} </span></li><li class="pay_li"><em class="pay_li_em">进场时间:</em><span class="pay_li_span">${approach_service_time} </span></li></ul><input id = "wcPay"type="button"value="确认支付"/></div></div><script type = "text/javascript"src="<%=basePath %>wechatpay_qrcode/js/jquery.min.js?t=<%=t%>"></script><script type = "text/javascript"src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script><script type = "text/javascript"src="<%=basePath %>wechatpay_qrcode/js/common.js?t=<%=t%>"></script><script type = "text/javascript" >function weixinPrePay() {// alert("进入支付方法");$("#wcPay").attr("disabled","disabled");// 再改成disabled$("#wcPay").val('支付中...');WeixinJSBridge.invoke('getBrandWCPayRequest',{"appId":'${appId }', // 公众号名称,由商户传入"timeStamp":'${timeStamp}', // 时间戳,自1970年以来的秒数"nonceStr":'${nonceStr}', // 随机串"package":"prepay_id="+'${prepayid}',"signType":"MD5", // 微信签名方式:"paySign":'${paySign}' // 微信签名},function(res){// 支付成功后的回调函数,详细请参见:http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=7_7if(res.err_msg=="get_brand_wcpay_request:ok"){ // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回// ok,但并不保证它绝对可靠。// 此处为安全期间,应调用商户api查询订单状态。window.location.href="<%=basePath%>wechatpay_qrcode/success.jsp";// 支付成功页面}else if(res.err_msg=="get_brand_wcpay_request:cancel") // 支付过程中用户取消{}else if(res.err_msg=="get_brand_wcpay_request:fail") // 支付失败{// TODO:支付失败的商户处理逻辑。window.location.href="<%=basePath%>wechatpay_qrcode/error.jsp";// 支付失败页面}else{window.location.href="<%=basePath%>wechatpay_qrcode/error.jsp";// 支付失败页面}$("#wcPay").removeAttr("disabled");// 要变成Enable,JQuery只能这么写$("#wcPay").val('立即支付');});}$(function() {// alert("weixinJump appId:"+'${appId }'+" ,timeStamp:"+'${timeStamp}'+", nonceStr:"+'${nonceStr}'+",signature:"+'${signature}');wx.config({debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。appId: '${appId}', // 必填,公众号的唯一标识timestamp: '${timeStamp}', // 必填,生成签名的时间戳nonceStr: '${nonceStr}', // 必填,生成签名的随机串signature: '${signature}', // 必填,调用js签名,jsApiList : [ 'checkJsApi', 'onMenuShareTimeline','onMenuShareAppMessage', 'onMenuShareQQ','onMenuShareWeibo', 'hideMenuItems', 'showMenuItems','hideAllNonBaseMenuItem', 'showAllNonBaseMenuItem','translateVoice', 'startRecord', 'stopRecord','onRecordEnd', 'playVoice', 'pauseVoice', 'stopVoice','uploadVoice', 'downloadVoice', 'chooseImage','previewImage', 'uploadImage', 'downloadImage','getNetworkType', 'openLocation', 'getLocation','hideOptionMenu', 'showOptionMenu', 'closeWindow','scanQRCode', 'chooseWXPay', 'openProductSpecificView','addCard', 'chooseCard', 'openCard' ] // 必填,需要使用的JS接口列表,这里只写支付的});// alert("初始化成功");$("#wcPay").click(function(){weixinPrePay();});});</script></body></html>
阅读全文
0 0
- 微信公众号扫码支付 spring mvc
- mvc 微信公众号支付
- 微信公众号支付
- 微信公众号支付
- 微信公众号支付
- 微信公众号微信支付
- 微信公众号支付
- 微信公众号微信支付
- 微信公众号支付
- 微信公众号支付
- 微信公众号支付
- 支付--微信公众号
- 微信公众号内调起微信支付
- 微信公众平台支付
- 微信公众号支付。
- 微信公众号支付
- 微信公众号支付
- 微信公众号支付
- hdu1160 LIS
- Oracle 11.2.0.4.0 RAC下DRM导致单节点宕机
- 数论
- Android下的配置管理之道之gerrit代码服务器搭建
- Longest Ordered Subsequence(dp)
- 微信公众号扫码支付 spring mvc
- P1119 灾后重建
- opencv 学习笔记(一)
- 17、图的应用
- 笨办法学 Python · 续 练习 45:创建 ORM
- Java 8学习之Lambda表达式
- Ubuntu Server源码编译安装MariaDB
- 初学Python
- HDU 1075 Trie树 解题报告