微信 支付(H5) (七) --基于Spring
发布日期:2022-01-11 03:09:52 浏览次数:3 分类:技术文章

本文共 17754 字,大约阅读时间需要 59 分钟。

Controller:

    /**     * 获取支付     */    @RequestMapping(params={"getPayInfo"})    @ResponseBody    public Map  getPayInfo(HttpServletRequest request) {        Map
result = new HashMap();        int i=1;        try {                Map dataMap=new HashMap();                String weiXinId=request.getParameter("weiXinId");                String amount=request.getParameter("amount");                String ordersid=request.getParameter("ordersid");                 String ip= request.getRemoteAddr();                 dataMap.put("ordersid", ordersid);                 dataMap.put("ip", ip);                 dataMap.put("opendid", weiXinId);                 dataMap.put("amount", amount);                  JSONObject jsonObject= rewardService.payReward(dataMap);                if(null==jsonObject){                    result.put("responsecode", "0");                    result.put("responsemsg",  "获取支付信息失败");                }                else{                // 新增支付数据                result.put("payinfo", jsonObject);                result.put("responsecode", "1");                result.put("responsemsg",  "获取支付信息成功");                }                            } catch (Exception e) {            result.put("responsecode", "0");            result.put("responsemsg",  "获取支付信息失败");            e.printStackTrace();        }        return result;            }

service:

private static String NOTIFY_URL="http://"+Constants.url+"/DDKX/WXRewardController/payNotify.do"; //回调地址		/**	 * 支付 打赏	 */	@Override	public JSONObject payReward(Map
map) { //要获取 订单号 , 用户id ,金额 ,spbill_create_ip String ordersid=map.get("ordersid"); String amount=map.get("amount"); String ip=map.get("ip"); String opendid=map.get("opendid"); String notify_url=NOTIFY_URL; //-----------------------------------回调地址 String nonce_str=Sign.create_nonce_str().toUpperCase(); SortedMap
parameters = new TreeMap
(); parameters.put("appid", Constants.appid); parameters.put("mch_id", Constants.mch_id); parameters.put("device_info", "WEB"); parameters.put("nonce_str", nonce_str); parameters.put("body", "打赏"); parameters.put("out_trade_no", ordersid); parameters.put("total_fee", amount); parameters.put("spbill_create_ip", ip); parameters.put("notify_url", notify_url); parameters.put("trade_type", "JSAPI"); parameters.put("openid", opendid); PayUtil payUtil=PayUtil.getInstance(); String prepay_id=payUtil.getPrepay_id(parameters); System.out.println(">>>>>>>>>>prepay_id:"+prepay_id); if(prepay_id==null) return null; return payUtil.getPayInfo4JSON(prepay_id,nonce_str); }

(帮助类)PayUtil:

import java.io.BufferedReader;import java.io.FileInputStream;import java.io.InputStreamReader;import java.util.Map;import java.util.Set;import java.util.SortedMap;import java.util.TreeMap;import net.sf.json.JSONObject;public class PayUtil {	private static final String  goUrl="https://api.mch.weixin.qq.com/pay/unifiedorder";	//private static Map
payModel=new HashMap
(); private static String payplate1=null; private PayUtil (){}; private static volatile PayUtil instance=null; public static PayUtil getInstance(){ if(instance==null){ synchronized(PayUtil.class){ if(instance==null){ instance=new PayUtil(); //payModel.put("payplate1", loadxml("/payplate/payplate1.xml")); payplate1=loadxml("/payplate/payplate1.xml"); } } } return instance; } /** * 加载模版 * @param xmlurl * @return */ private static String loadxml(String xmlurl){ String path=PayUtil.class.getResource("/").getPath()+xmlurl; String xmlString=""; try { FileInputStream fileInputStream=new FileInputStream(path); InputStreamReader inputStreamReader=new InputStreamReader(fileInputStream,"UTF-8"); BufferedReader reader=new BufferedReader(inputStreamReader); String tempString=null; while((tempString=reader.readLine())!=null) xmlurl+=tempString; reader.close(); } catch (Exception e) { e.printStackTrace(); } return xmlurl; } /** * 获取Prepay_id 顺带附加 SIGN 字段 * @param parameters * @return */ public String getPrepay_id(SortedMap
parameters){ String mysign1=Sign.createSign("UTF-8", parameters); String xmlparam=payplate1; parameters.put("SIGN", mysign1); xmlparam=strReplaceXML(xmlparam, parameters); String data= HttpClientUtil.httpRequestComm(goUrl, EnumMethod.POST.name(),xmlparam); if(null==data) return null; JSONObject jsonObject= Xml2JsonUtil.xml2JSON(data).getJSONObject("xml"); System.out.println(">>>>>>>>>>服务器回复:"+jsonObject.toString()); return jsonObject.containsKey("prepay_id")?jsonObject.getJSONArray("prepay_id").getString(0):null; } /** * 替换 模版里的xml 大写标识内容 * @param xml * @param parameters * @return */ public String strReplaceXML(String xml,SortedMap
parameters){ Set
es = parameters.keySet(); for(String ss:es){ xml=xml.replace(ss.toUpperCase(), parameters.get(ss)); } return xml; } /** * 生成 网页支付所需 参数包 * @param prepay_id * @return */ public JSONObject getPayInfo4JSON(String prepay_id,String nonce_str){ SortedMap
dataMap = new TreeMap
(); dataMap.put("appId", Constants.appid); dataMap.put("timeStamp", System.currentTimeMillis() / 1000+""); dataMap.put("nonceStr",nonce_str); dataMap.put("package", "prepay_id="+prepay_id); dataMap.put("signType", "MD5"); String mysign2=Sign.createSign("UTF-8", dataMap); dataMap.put("paySign", mysign2); JSONObject jsonObject=JSONObject.fromObject(dataMap); return jsonObject; } }

(帮助模板)payplate1.xml:

APPID
MCH_ID
DEVICE_INFO
NONCE_STR
BODY
OUT_TRADE_NO
TOTAL_FEE
SPBILL_CREATE_IP
NOTIFY_URL
TRADE_TYPE
OPENID
SIGN
(帮助类)Xml2JsonUtil:

package com.gzkit.ddkx.util;import java.io.ByteArrayInputStream;import java.io.InputStream;import java.io.StringReader;import java.util.HashMap;import java.util.Iterator;import java.util.LinkedList;import java.util.List;import java.util.Map;import org.dom4j.Document;import org.dom4j.Element;import org.dom4j.io.SAXReader;import net.sf.json.JSONArray;import net.sf.json.JSONObject;public class Xml2JsonUtil {    /**     * 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。     */        public static Map
XMLParse2Map(String strxml){       Map
m = new HashMap
();    try {            if(null == strxml || "".equals(strxml)) {            return null;            }            SAXReader sb = new SAXReader();              Document doc = sb.read(new StringReader(strxml));            Element root = doc.getRootElement();             List list =root.elements();            Iterator it = list.iterator();            while(it.hasNext()) {            Element e = (Element) it.next();            String k = e.getName();            String v = "";            List children = e.elements();            if(children.isEmpty()) {                    v = e.getTextTrim();            } else {                    v = getChildrenText(children);            }            m.put(k, v);            }                } catch (Exception e) {                    // TODO: handle exception                }            return m;    }         /**     * 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。     */        public  static JSONObject XMLParse2JSON(String strxml){            return JSONObject.fromObject(XMLParse2Map(strxml));    }        /**      * 获取子结点的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.getTextTrim();            List list = e.elements();            sb.append("<" + name + ">");            if(!list.isEmpty()) {            sb.append(getChildrenText(list));            }            sb.append(value);            sb.append("
");            }            }            return sb.toString();    }            /**      * 转换一个xml格式的字符串到json格式     获取的值都是 jsonarray 要解多层         */          @SuppressWarnings("unchecked")          public static  JSONObject xml2JSON(InputStream is) {              JSONObject obj = new JSONObject();              try {                  SAXReader sb = new SAXReader();                  Document doc = sb.read(is);                Element root = doc.getRootElement();                  obj.put(root.getName(), iterateElement(root));                  return obj;              } catch (Exception e) {                  return null;              }          }                  /**      * 转换一个xml格式的字符串到json格式          */          @SuppressWarnings("unchecked")          public static  JSONObject xml2JSON(String is) {              JSONObject obj = new JSONObject();              try {                  SAXReader sb = new SAXReader();                  Document doc = sb.read(new StringReader(is));                Element root = doc.getRootElement();                  obj.put(root.getName(), iterateElement(root));                  return obj;              } catch (Exception e) {                  return null;              }          }              /**      * 一个迭代方法          *           * @param element          * : org.jdom.Element          * @return java.util.Map 实例          */          @SuppressWarnings("unchecked")          private static Map  iterateElement(Element element) {              List jiedian = element.elements() ;            Element et = null;              Map obj = new HashMap();              List list = null;              for (int i = 0; i < jiedian.size(); i++) {                  list = new LinkedList();                  et = (Element) jiedian.get(i);                  if (et.getTextTrim().equals("")) {                      if (et.elements().size() == 0)                          continue;                      if (obj.containsKey(et.getName())) {                          list = (List) obj.get(et.getName());                      }                      list.add(iterateElement(et));                      obj.put(et.getName(), list);                  } else {                      if (obj.containsKey(et.getName())) {                          list = (List) obj.get(et.getName());                      }                      list.add(et.getTextTrim());                      obj.put(et.getName(), list);                            }              }              return obj;          }                            public static void main(String[] args) {        String str1="
";              JSONObject array=Xml2JsonUtil.xml2JSON(str1).getJSONObject("xml");            System.out.println(array.getJSONArray("prepay_id").get(0));       }}

(帮助类)Sign:

/*** *  * @author yuki_ho * */public class Sign {	 public static Map        sign(String url) {	        Map          ret = new HashMap           ();	        String nonce_str = create_nonce_str();	        String timestamp = create_timestamp();	        String signature = null;	        	        if(null==Constants.jsapi_ticket)	        {	        	WXListener.getJsapi_ticket(WXListener.accessToken.getAccessToken());	        }	        	        //注意这里参数名必须全部小写,且必须有序	        String[] paramArr = new String[] { "jsapi_ticket=" + Constants.jsapi_ticket,					"timestamp=" + timestamp, "noncestr=" + nonce_str, "url=" + url };			Arrays.sort(paramArr);			String content = paramArr[0].concat("&"+paramArr[1]).concat("&"+paramArr[2])					.concat("&"+paramArr[3]);				        System.out.println(content);	        try	        {	        	MessageDigest md = MessageDigest.getInstance("SHA-1");				// 对拼接后的字符串进行 sha1 加密				byte[] digest = md.digest(content.toString().getBytes());				signature = MD5Util.byteArrayToHexString(digest);		        }	        catch (NoSuchAlgorithmException e)	        {	            e.printStackTrace();	        }	     	        ret.put("url", url);	        ret.put("jsapi_ticket", Constants.jsapi_ticket);	        ret.put("nonceStr", nonce_str);	        ret.put("timestamp", timestamp);	        ret.put("signature", signature);	        System.out.println(url);			ret.put("appId", Constants.appid);	        return ret;	    }	 /** 	     * 微信支付签名算法sign 	     * @param characterEncoding 	     * @param parameters 	     * @return 	     */  	    @SuppressWarnings("unchecked")  	    public static String createSign(String characterEncoding,SortedMap              parameters){  	        StringBuffer sb = new StringBuffer();  	        Set es = parameters.entrySet();//所有参与传参的参数按照accsii排序(升序)  	        Iterator it = es.iterator();  	        while(it.hasNext()) {  	            Map.Entry entry = (Map.Entry)it.next();  	            String k = (String)entry.getKey();  	            Object v = entry.getValue();  	            if(null != v && !"".equals(v)   	                    && !"sign".equals(k) && !"key".equals(k)) {  	                sb.append(k + "=" + v + "&");  	            }  	        }  	        sb.append("key=" +Constants.key);  	        String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();  	        return sign;  	    }  	 	    private static String create_nonce_str() {	      return RandomStringGenerator.getRandomStringByLength(32);	    }	    private static String create_timestamp() {	        return String.valueOf(System.currentTimeMillis()).substring(0, 10);	    }	    }
 
前端页面:
wx.config({        debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。        appId: '${appid}', // 必填,公众号的唯一标识        timestamp: '${timestamp}', // 必填,生成签名的时间戳        nonceStr: '${nonceStr}', // 必填,生成签名的随机串        signature: '${signature}',// 必填,签名,见附录1        jsApiList: [            'chooseWXPay'        ] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2    });
function pay(){        wx.chooseWXPay({            timestamp: ${paytimestamp}, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符            nonceStr: '${paynonceStr}', // 支付签名随机串,不长于 32 位            package: '${paypackage}', // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***)            signType: '${paysignType}', // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'            paySign: '${paySign}', // 支付签名            success: function (res) {            if(res.errMsg == "chooseWXPay:ok") {        
                       // 支付成功后的回调函数
             }else if(res.errMsg == "chooseWXPay:fail"){
                $.toast("支付失败请刷新重试!","cancel");
             }
             // 支付成功后的回调函数
                                                   
} }); }
 
微信回调后台:
//  -----报文-----//	               {is_subscribe=Y, //			appid=xxxxxxxxxxxx, //			fee_type=CNY, //			nonce_str=5FMGNBEUY0W1RFNBMHGINYUN8MF6W6CE, //			out_trade_no=xxxxxxxxxxxxxxxxx, //			device_info=WEB, //			transaction_id=xxxxxxxxxxxxxxx, //			trade_type=JSAPI, //			sign=0C869ED5882C641960798CD2DDDC0F7C, //			result_code=SUCCESS,//			mch_id=xxxxxxxxxxx, //			total_fee=1, //			time_end=20160908143148, //			openid=xxxxxxxxxxxxxxxxxxxx, //			bank_type=CMB_CREDIT, //			return_code=SUCCESS, //			cash_fee=1}	/**	 * 获取支付	 * 	 */	@RequestMapping(value={"payNotify"})	@ResponseBody    public void  payNotify(HttpServletRequest request,HttpServletResponse response) {   		String resultStr=null;		try {	    	InputStream inStream = request.getInputStream();	    	ByteArrayOutputStream outSteam = new ByteArrayOutputStream();	    	byte[] buffer = new byte[1024];	    	int len = 0;	    	while ((len = inStream.read(buffer)) != -1) {	    	    outSteam.write(buffer, 0, len);	    	}	    	outSteam.close();	    	inStream.close();	    	resultStr  = new String(outSteam.toByteArray(),"utf-8");	    	Map
resultMap = Xml2JsonUtil.XMLParse2Map(resultStr); System.out.println(resultMap.toString()); //---------------获取的参数 String result_code = resultMap.get("result_code"); System.out.println("result_code:"+result_code); String out_trade_no = resultMap.get("out_trade_no"); System.out.println("out_trade_no:"+out_trade_no); String sign = resultMap.get("sign"); String time_end = resultMap.get("time_end"); String total_fee= resultMap.get("total_fee"); String transaction_id=resultMap.get("transaction_id"); String return_code = resultMap.get("return_code"); System.out.println("return_code:"+return_code); //验证签名------------------------------------------------ System.out.println("微信回传:"+sign); resultMap.remove("sign"); SortedMap
sortMap=new TreeMap
(resultMap); String mysign= Sign.createSign("UTF-8", sortMap); System.out.println("我的签名:"+mysign); //--------------------------------------------------------- if("SUCCESS".equals(return_code)){ if("SUCCESS".equals(result_code)){ //业务 } }
                  //通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.
  response.getWriter().write("<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>"); } }else { String err_code= resultMap.get("err_code"); System.out.println("打赏出错:"+err_code);} } catch (IOException e) {e.printStackTrace();}catch(Exception e){e.printStackTrace();}}
 

转载地址:https://yuki-ho.blog.csdn.net/article/details/52312502 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:JAVA 并发编程-线程池(七)
下一篇:使用SortedMap对HashMap排序

发表评论

最新留言

哈哈,博客排版真的漂亮呢~
[***.90.31.176]2024年04月10日 22时42分02秒