失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 微信H5支付和支付宝手机支付 前台+后台

微信H5支付和支付宝手机支付 前台+后台

时间:2020-09-06 00:50:50

相关推荐

微信H5支付和支付宝手机支付 前台+后台

前台JS:

if ("wx" == zf_vallue) {var url = host + "/server/weixin/wxPayH5";url =url+'room_order_id='+order_info.order_id+'&trade_type=NATIVE&zf_vallue=wx'window.location.href=url;//判断是微信还是支付宝--->是支付宝}else if("zfb"==zf_vallue){var url = host + "/server/zfb/goAlipay";url = url+'?room_order_id='+order_info.order_id + '&hotel_id=' + hotel.hotelgroup_id + '&hotel_name=' + hotel.hotelgroup_namewindow.location.href=url;} else {$(location).attr('href', 'index.html');}

1 微信H5支付后台:

/*** 微信H5支付** @param request* @param response* @param model* @throws Exception*/@RequestMapping("/server/weixin/wxPayH5")public void wxPayH5(HttpServletRequest request, HttpServletResponse response, ModelMap model) throws Exception {Map<String, Object> result = new HashMap<String, Object>();result.put("success", false);try {// 订单号String room_order_id = request.getParameter("room_order_id");// 付款金额,必填// double total = Constant.map_order.get(room_order_id);// total=total*100;// int total_fee = new Double(total).intValue();int total_fee = 1;logger.error("==========/server/weixin/wxPayH5:" + total_fee + "========");String zf_vallue = request.getParameter("zf_vallue");// ip地址获取String basePath = request.getServerName() + ":" + request.getServerPort();// 账号信息String appid = PayConfig.APP_ID; // appidString mch_id = PayConfig.MCH_ID; // 商业号String key = PayConfig.API_KEY; // keyString currTime = PayCommonUtil.getCurrTime();String strTime = currTime.substring(8, currTime.length());String strRandom = PayCommonUtil.buildRandom(4) + "";String nonce_str = strTime + strRandom;// 价格 注意:价格的单位是分String order_price = String.valueOf(total_fee);// 获取发起电脑 ipString spbill_create_ip = HttpUtil.getRealIp(request);// 回调接口String notify_url = PayConfig.NOTIFY_URL_H5.replaceAll("localhostUrl", basePath);// String notify_url = PayConfig.NOTIFY_URL_H5.replaceAll("localhostUrl",// basePath) + getCurrentUser().getId();// 页面跳转同步通知页面路径String trade_type = "MWEB";// 设置package订单参数SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();packageParams.put("appid", appid);packageParams.put("mch_id", mch_id);// 生成签名的时候需要你自己设置随机字符串packageParams.put("nonce_str", nonce_str);packageParams.put("out_trade_no", room_order_id);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("body", PayConfig.BODY);packageParams.put("scene_info","{\"h5_info\": {\"type\":\"Wap\",\"wap_url\": \"\",\"wap_name\": \"产品名称***\"}}");String sign = PayCommonUtil.createSign("UTF-8", packageParams, key);packageParams.put("sign", sign);String requestXML = PayCommonUtil.getRequestXml(packageParams);String resXml = HttpUtil.postData(PayConfig.UFDODER_URL, requestXML);Map map = XMLUtil.doXMLParse(resXml);String urlCode = (String) map.get("code_url");// 确认支付过后跳的地址,需要经过urlencode处理String url = "/index2.html";String urlString = URLEncoder.encode(url, "UTF-8");String mweb_url = map.get("mweb_url") + "&redirect_url=" + urlString;response.sendRedirect(mweb_url);logger.info("==========/server/weixin/wxPayH5======== " + "verify_result = " + zf_vallue);result.put("sHtmlText", urlCode);result.put("success", true);} catch (Exception e) {logger.error("==========/server/weixin/wxPayH5:" + e.getMessage() + "========");result.put("errormsg", e.getMessage());}}/*** 执行回调 确认支付后处理事件 例如添加金额到数据库等操作* * @param request* @param response* @throws Exception*/@RequestMapping("/server/weixin/WxQuery")public void weixin_notify(HttpServletRequest request, HttpServletResponse response, ModelMap model)throws Exception {System.out.println("进入支付h5回调=====================");String xmlMsg = readData(request);System.out.println("pay notice---------" + xmlMsg);Map params = XMLUtil.doXMLParse(xmlMsg);// String appid = params.get("appid");// //商户号// String mch_id = params.get("mch_id");String result_code = params.get("result_code") + "";// String openId = params.get("openid");// //交易类型// String trade_type = params.get("trade_type");// //付款银行// String bank_type = params.get("bank_type");// // 总金额// String total_fee = params.get("total_fee");// //现金支付金额// String cash_fee = params.get("cash_fee");// // 微信支付订单号// String transaction_id = params.get("transaction_id");// 商户订单号String out_trade_no = params.get("out_trade_no") + "";// // 支付完成时间,格式为yyyyMMddHHmmss// String time_end = params.get("time_end");/ 以下是附加参数///String attach = params.get("attach") + "";// String fee_type = params.get("fee_type");// String is_subscribe = params.get("is_subscribe");// String err_code = params.get("err_code");// String err_code_des = params.get("err_code_des");HealthUserOrder order = hotelMapper.selOrderInfo(out_trade_no);String hotel_id = order.getHotel_id();String userid = null;try {// 过滤空 设置 TreeMapSortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();Iterator it = params.keySet().iterator();while (it.hasNext()) {String parameter = (String) it.next();String parameterValue = params.get(parameter) + "";String v = "";if (null != parameterValue) {v = parameterValue.trim();}System.out.println("key==========" + parameter + "value========" + v);packageParams.put(parameter, v);}// 查看回调参数// LogUtil.writeMsgToFile(packageParams.toString());double total_fee = Double.parseDouble(new BigDecimal((String) packageParams.get("total_fee")).divide(new BigDecimal(100)).toString());userid = (String) packageParams.get("userid");// 账号信息String resXml = "";// ------------------------------// 处理业务开始// ------------------------------if ("SUCCESS".equals((String) packageParams.get("result_code"))) {// 这里是支付成功try {depositOrder(out_trade_no, total_fee, hotel_id);} catch (Exception e) {logger.error("=======WeiXinController/server/weixin/WxQuery:" + "========" + e.getMessage());}// 执行自己的业务逻辑// 通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"+ "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";} else {model.put("sHtmlText", "付款失败");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();} catch (Exception e) {e.printStackTrace();logger.error("=======WeiXinController/server/weixin/WxQuery:" + "========" + e.getMessage());}}public static String readData(HttpServletRequest request) {BufferedReader br = null;try {StringBuilder result = new StringBuilder();br = request.getReader();for (String line; (line = br.readLine()) != null;) {if (result.length() > 0) {result.append("\n");}result.append(line);}return result.toString();} catch (IOException e) {throw new RuntimeException(e);} finally {if (br != null)try {br.close();} catch (IOException e) {e.printStackTrace();}}}

PayConfig

public class PayConfig {// 微信号public static String APP_ID = "XXXX";// 应用对应的凭证//public static String APP_SECRET = "XXXX";// 商户密钥public static String API_KEY = "XXXX";// 商业号public static String MCH_ID = "XXXXX";// 回调地址public static String NOTIFY_URL = "http://localhostUrl/resourceManager/xxxxxx?userid=";// 微信支付h5 回调地址public static String NOTIFY_URL_H5 = "/server/weixin/WxQuery";// 商品名称public static String BODY = "产品名称";// 请求地址public static String UFDODER_URL = "https://api.mch./pay/unifiedorder";// 微信支付V2账单查询接口public static String ORDERQUERY = "https://api.mch./pay/orderquery";}

HttpUtil工具类:

package com.cloud.server.utils.weixin;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import .URL;import .URLConnection;import javax.servlet.http.HttpServletRequest;import mons.logging.Log;/*** Http客户端工具类<br/>* 这是内部调用类,请不要在外部调用。* * @author miklchen**/public class HttpUtil {private final static int CONNECT_TIMEOUT = 5000; // in millisecondsprivate final static String DEFAULT_ENCODING = "UTF-8";public static String postData(String urlStr, String data) {return postData(urlStr, data, null);}public static String postData(String urlStr, String data, String contentType) {BufferedReader reader = null;try {URL url = new URL(urlStr);URLConnection conn = url.openConnection();conn.setDoOutput(true);conn.setConnectTimeout(CONNECT_TIMEOUT);conn.setReadTimeout(CONNECT_TIMEOUT);if (contentType != null)conn.setRequestProperty("content-type", contentType);OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream(), DEFAULT_ENCODING);if (data == null)data = "";writer.write(data);writer.flush();writer.close();reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), DEFAULT_ENCODING));StringBuilder sb = new StringBuilder();String line = null;while ((line = reader.readLine()) != null) {sb.append(line);sb.append("\r\n");}return sb.toString();} catch (IOException e) {} finally {try {if (reader != null)reader.close();} catch (IOException e) {}}return null;}/*** 获取真实ip地址 通过阿帕奇代理的也能获取到真实ip* @param request* @return*/public static String getRealIp(HttpServletRequest request) {String ip = request.getHeader("x-forwarded-for");if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("Proxy-Client-IP");}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("WL-Proxy-Client-IP");}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getRemoteAddr();}return ip;}}

PayCommonUtil工具类

package com.cloud.server.utils.weixin;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Iterator;import java.util.Map;import java.util.Set;import java.util.SortedMap;public class PayCommonUtil {/*** 是否签名正确,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。* * @return boolean*/public static boolean isTenpaySign(String characterEncoding, SortedMap<Object, Object> packageParams, String API_KEY) {StringBuffer sb = new StringBuffer();Set es = packageParams.entrySet();Iterator it = es.iterator();while (it.hasNext()) {Map.Entry entry = (Map.Entry) it.next();String k = (String) entry.getKey();String v = (String) entry.getValue();if (!"sign".equals(k) && null != v && !"".equals(v)) {sb.append(k + "=" + v + "&");}}sb.append("key=" + API_KEY);// 算出摘要String mysign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toLowerCase();String tenpaySign = ((String) packageParams.get("sign")).toLowerCase();// System.out.println(tenpaySign + " " + mysign);return tenpaySign.equals(mysign);}/*** @author* @date -4-22* @Description:sign签名* @param characterEncoding* 编码格式* @param parameters* 请求参数* @return*/public static String createSign(String characterEncoding, SortedMap<Object, Object> packageParams, String API_KEY) {StringBuffer sb = new StringBuffer();Set es = packageParams.entrySet();Iterator it = es.iterator();while (it.hasNext()) {Map.Entry entry = (Map.Entry) it.next();String k = (String) entry.getKey();String v = (String) entry.getValue();if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {sb.append(k + "=" + v + "&");}}sb.append("key=" + API_KEY);String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();return sign;}/*** @author* @date -4-22* @Description:将请求参数转换为xml格式的string* @param parameters* 请求参数* @return*/public static String getRequestXml(SortedMap<Object, Object> parameters) {StringBuffer sb = new StringBuffer();sb.append("<xml>");Set es = parameters.entrySet();Iterator it = es.iterator();while (it.hasNext()) {Map.Entry entry = (Map.Entry) it.next();String k = (String) entry.getKey();String v = (String) entry.getValue();if ("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k) || "sign".equalsIgnoreCase(k)) {sb.append("<" + k + ">" + "<![CDATA[" + v + "]]></" + k + ">");} else {sb.append("<" + k + ">" + v + "</" + k + ">");}}sb.append("</xml>");return sb.toString();}/*** 取出一个指定长度大小的随机正整数.* * @param length* int 设定所取出随机数的长度。length小于11* @return int 返回生成的随机数。*/public static int buildRandom(int length) {int num = 1;double random = Math.random();if (random < 0.1) {random = random + 0.1;}for (int i = 0; i < length; i++) {num = num * 10;}return (int) ((random * num));}/*** 获取当前时间 yyyyMMddHHmmss* * @return String*/public static String getCurrTime() {Date now = new Date();SimpleDateFormat outFormat = new SimpleDateFormat("yyyyMMddHHmmss");String s = outFormat.format(now);return s;}}

XMLUtil工具类

package com.cloud.server.utils.weixin;import java.io.ByteArrayInputStream;import java.io.IOException;import java.io.InputStream;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import org.jdom2.Document;import org.jdom2.Element;import org.jdom2.JDOMException;import org.jdom2.input.SAXBuilder;/*** xml工具类* * @author miklchen**/public class XMLUtil {/*** 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。* * @param strxml* @return* @throws JDOMException* @throws IOException*/public static Map doXMLParse(String strxml) throws JDOMException, IOException {strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");if (null == strxml || "".equals(strxml)) {return null;}Map m = new HashMap();InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));SAXBuilder builder = new SAXBuilder();Document doc = builder.build(in);Element root = doc.getRootElement();List list = root.getChildren();Iterator it = list.iterator();while (it.hasNext()) {Element e = (Element) it.next();String k = e.getName();String v = "";List children = e.getChildren();if (children.isEmpty()) {v = e.getTextNormalize();} else {v = XMLUtil.getChildrenText(children);}m.put(k, v);}// 关闭流in.close();return m;}/*** 获取子结点的xml* * @param children* @return String*/public static String getChildrenText(List children) {StringBuffer sb = new StringBuffer();if (!children.isEmpty()) {Iterator it = children.iterator();while (it.hasNext()) {Element e = (Element) it.next();String name = e.getName();String value = e.getTextNormalize();List list = e.getChildren();sb.append("<" + name + ">");if (!list.isEmpty()) {sb.append(XMLUtil.getChildrenText(list));}sb.append(value);sb.append("</" + name + ">");}}return sb.toString();}}

MD5Util工具类

package com.cloud.server.utils.weixin;import java.security.MessageDigest;/** * @author create by yaoyuan * @date 6月5日 下午8:13:09 */public class MD5Util {private static String byteArrayToHexString(byte b[]) {StringBuffer resultSb = new StringBuffer();for (int i = 0; i < b.length; i++)resultSb.append(byteToHexString(b[i]));return resultSb.toString();}private static String byteToHexString(byte b) {int n = b;if (n < 0)n += 256;int d1 = n / 16;int d2 = n % 16;return hexDigits[d1] + hexDigits[d2];}public static String MD5Encode(String origin, String charsetname) {String resultString = null;try {resultString = new String(origin);MessageDigest md = MessageDigest.getInstance("MD5");if (charsetname == null || "".equals(charsetname))resultString = byteArrayToHexString(md.digest(resultString.getBytes()));elseresultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));} catch (Exception exception) {}return resultString;}private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5","6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };}

2 支付宝支付后台:

/**** @Title: AlipayController.java* @Package com.sihai.controller* @Description: 前往支付宝第三方网关进行支付 Copyright: Copyright (c) *Company:FURUIBOKE.SCIENCE.AND.TECHNOLOGY** @author sihai* @date 8月23日 下午8:50:43* @version V1.0*/@RequestMapping(value = "/server/zfb/goAlipay")public void goAlipay(Order order, HttpServletRequest httpRequest, HttpServletResponse httpResponse)throws Exception {// 获得初始化的AlipayClientAlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.APPID,AlipayConfig.RSA_PRIVATE_KEY, "json", AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY,AlipayConfig.SIGNTYPE);// 设置请求参数AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();// 创建API对应的requestalipayRequest.setReturnUrl(AlipayConfig.return_url);alipayRequest.setNotifyUrl(AlipayConfig.notify_url);// 商户订单号,商户网站订单系统中唯一订单号,必填String out_trade_no = order.getRoom_order_id();// 付款金额,必填double total_amount = Constant.map_order.get(out_trade_no);total_amount=0.01;// 订单名称,必填String subject = order.getHotel_name();// 该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:1m~15d。m-分钟,h-小时,d-天,1c-当天(1c-当天的情况下,无论交易何时创建,都在0点关闭)。// 该参数数值不接受小数点, 如 1.5h,可转换为 90m。String timeout_express = "1c";alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\"," + "\"total_amount\":\"" + total_amount+ "\"," + "\"subject\":\"" + subject + "\"," + "\"timeout_express\":\"" + timeout_express + "\","+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");String form = "";try {form = alipayClient.pageExecute(alipayRequest).getBody(); // 调用SDK生成表单} catch (AlipayApiException e) {e.printStackTrace();}httpResponse.setContentType("text/html;charset=" + AlipayConfig.CHARSET);httpResponse.getWriter().write(form);// 直接将完整的表单html输出到页面httpResponse.getWriter().flush();httpResponse.getWriter().close();}//支付宝异步请求,返回参数@RequestMapping("/server/zfb/alipayQuery")@ResponseBodypublic String paynotify(HttpServletRequest request,HttpServletResponse response) throws Exception {Map<String,String> params = new HashMap<String,String>();Map requestParams = request.getParameterMap();for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {String name = (String) iter.next();String[] values = (String[]) requestParams.get(name);String valueStr = "";for (int i = 0; i < values.length; i++) {valueStr = (i == values.length - 1) ? valueStr + values[i]: valueStr + values[i] + ",";}//乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化params.put(name, valueStr);//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "UTF-8");logger.info("==========/server/zfb/alipayQuery======== "+"Key = " + name + ", Value = " + valueStr);}//商户订单号String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");//String out_trade_no="O181102112027243644";logger.info("==========/server/zfb/alipayQuery======== "+"out_trade_no = " + out_trade_no);//支付宝实际付款金额//String total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"),"UTF-8");String total_amount = "0.01";double total_order_money=Double.parseDouble(total_amount);logger.info("==========/server/zfb/alipayQuery======== "+"total_order_money = " + total_order_money);HealthUserOrder order = hotelMapper.selOrderInfo(out_trade_no);String hotel_id=order.getHotel_id();logger.info("==========/server/zfb/alipayQuery======== "+"hotel_id = " + hotel_id );//计算得出通知验证结果//boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)boolean verify_result = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, "RSA2");logger.info("==========/server/zfb/alipayQuery======== "+"verify_result = " + verify_result);String ret="";if(verify_result){//验证成功depositOrder(out_trade_no,total_order_money,hotel_id);//out.clear();//out.println("success");//请不要修改或删除System.out.println("success");ret="success";}else{//验证失败System.out.println("fail");ret="fail";}return ret;}

AlipayConfig配置:

public class AlipayConfig {// 商户appidpublic static String APPID = "02280XXXXXXX";// 私钥 pkcs8格式的public static String RSA_PRIVATE_KEY = "XXXXXX;// 服务器异步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问public static String notify_url = "/server/zfb/alipayQuery";// 页面跳转同步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问// 商户可以自定义同步跳转地址public static String return_url = "/index2.html";// 请求网关地址public static String URL = "/gateway.do";// 沙箱地址// public static String URL = "/gateway.do";// 编码public static String CHARSET = "UTF-8";// 返回格式public static String FORMAT = "json";// 支付宝公钥public static String ALIPAY_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0yr87C6BYyHzAmvHZR4d5XCs0AluXhFm7xb4Z9fEMJM1dPxu82KlBcJGy26wnhbprWbex0xzy+vy8YdRF8CLbqFWZC9CpSnNLgBBcIVpsGC5WxAJmZXeYeq6fWq8ycbV72DP07PSLW8TLV6OT8FBBFGWFBfzZUK6Ou37iAlKb+mboODWg9tIt7rps+xsm5kxnH4sJAzbeV0nkh+kk+cLJauqOkrLJnm/bFe2eArJJ9ZOWY9m35wQwOVsBd89MD4Lx7MwVVyyKn3EdjvXU4xAOgrcCPKr7f5NGk+TnjJt+RLH5ziwCSZXeI9yU4XI3zl28yz13toVMigahdRRTQIDAQAB";// 日志记录目录public static String log_path = "/log";// RSA2public static String SIGNTYPE = "RSA2";}

支付宝回调通知频率:25小时以内完成8次通知(通知的间隔频率一般是:4m,10m,10m,1h,2h,6h,15h)

如果觉得《微信H5支付和支付宝手机支付 前台+后台》对你有帮助,请点赞、收藏,并留下你的观点哦!

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