微信付出java版本之Native付款。本站提示廣大學習愛好者:(微信付出java版本之Native付款)文章只能為提供參考,不一定能成為您想要的結果。以下是微信付出java版本之Native付款正文
比來任務中接觸到一些關於微信付出方面的器械,看到給的DEMO都是PHP版本的,再加上微信付出文檔寫切實其實實不敢奉承,趟過很多坑以後閒上去做個總結。
1、後期預備
做微信開辟起首要請求一個公共賬號,請求勝利後會以郵件情勢發給你一些需要信息,公共賬號中有開辟文檔和開辟中需要信息,和測試的數據查詢。
2、對象類
1.MD5加密對象類
package com.pay.utils.weixin; import java.security.MessageDigest; public class MD5Util { public final static String MD5(String s) { char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; try { byte[] btInput = s.getBytes(); // 取得MD5摘要算法的 MessageDigest 對象 MessageDigest mdInst = MessageDigest.getInstance("MD5"); // 應用指定的字節更新摘要 mdInst.update(btInput); // 取得密文 byte[] md = mdInst.digest(); // 把密文轉換成十六進制的字符串情勢 int j = md.length; char str[] = new char[j * 2]; int k = 0; for (int i = 0; i < j; i++) { byte byte0 = md[i]; str[k++] = hexDigits[byte0 >>> 4 & 0xf]; str[k++] = hexDigits[byte0 & 0xf]; } return new String(str); } catch (Exception e) { e.printStackTrace(); return null; } } }
2.CommonUtil對象類,用於裝換成微信所需XML。以下return new String(xml.toString().getBytes(),"ISO8859-1");將對象類中的utf-8改成iso8859-1,不然微信定單中的中文會湧現亂碼,改後可以准確顯示。
package com.pay.utils.weixin; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.*; import java.util.Map.Entry; public class CommonUtil { public static String CreateNoncestr(int length) { String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; String res = ""; for (int i = 0; i < length; i++) { Random rd = new Random(); res += chars.indexOf(rd.nextInt(chars.length() - 1)); } return res; } public static String CreateNoncestr() { String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; String res = ""; for (int i = 0; i < 16; i++) { Random rd = new Random(); res += chars.charAt(rd.nextInt(chars.length() - 1)); } return res; } public static String FormatQueryParaMap(HashMap<String, String> parameters) throws SDKRuntimeException { String buff = ""; try { List<Map.Entry<String, String>> infoIds = new ArrayList<Map.Entry<String, String>>( parameters.entrySet()); Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>() { public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) { return (o1.getKey()).toString().compareTo( o2.getKey()); } }); for (int i = 0; i < infoIds.size(); i++) { Map.Entry<String, String> item = infoIds.get(i); if (item.getKey() != "") { buff += item.getKey() + "=" + URLEncoder.encode(item.getValue(), "utf-8") + "&"; } } if (buff.isEmpty() == false) { buff = buff.substring(0, buff.length() - 1); } } catch (Exception e) { throw new SDKRuntimeException(e.getMessage()); } return buff; } public static String FormatBizQueryParaMap(HashMap<String, String> paraMap, boolean urlencode) throws SDKRuntimeException { String buff = ""; try { List<Map.Entry<String, String>> infoIds = new ArrayList<Map.Entry<String, String>>( paraMap.entrySet()); Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>() { public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) { return (o1.getKey()).toString().compareTo( o2.getKey()); } }); for (int i = 0; i < infoIds.size(); i++) { Map.Entry<String, String> item = infoIds.get(i); //System.out.println(item.getKey()); if (item.getKey() != "") { String key = item.getKey(); String val = item.getValue(); if (urlencode) { val = URLEncoder.encode(val, "utf-8"); } buff += key.toLowerCase() + "=" + val + "&"; } } if (buff.isEmpty() == false) { buff = buff.substring(0, buff.length() - 1); } } catch (Exception e) { throw new SDKRuntimeException(e.getMessage()); } return buff; } public static boolean IsNumeric(String str) { if (str.matches("\\d *")) { return true; } else { return false; } } public static String ArrayToXml(HashMap<String, String> arr) { String xml = "<xml>"; Iterator<Entry<String, String>> iter = arr.entrySet().iterator(); while (iter.hasNext()) { Entry<String, String> entry = iter.next(); String key = entry.getKey(); String val = entry.getValue(); if (IsNumeric(val)) { xml += "<" + key + ">" + val + "</" + key + ">"; } else xml += "<" + key + "><![CDATA[" + val + "]]></" + key + ">"; } xml += "</xml>"; try { return new String(xml.toString().getBytes(),"ISO8859-1"); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return ""; } }
3.ClientCustomSSL對象類,用於生成sign和創立微信定單package com.pay.utils.weixin;
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import org.springframework.util.StringUtils; /** * This example demonstrates how to create secure connections with a custom SSL * context. */ public class ClientCustomSSL { public static String GetBizSign(HashMap<String, String> bizObj) throws SDKRuntimeException { HashMap<String, String> bizParameters = new HashMap<String, String>(); List<Map.Entry<String, String>> infoIds = new ArrayList<Map.Entry<String, String>>( bizObj.entrySet()); System.out.println(infoIds); Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>() { public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) { return (o1.getKey()).toString().compareTo(o2.getKey()); } }); System.out.println("--------------------"); System.out.println(infoIds); for (int i = 0; i < infoIds.size(); i++) { Map.Entry<String, String> item = infoIds.get(i); if (item.getKey() != "") { bizParameters.put(item.getKey().toLowerCase(), item.getValue()); } } //bizParameters.put("key", "12345678123456781234567812345671"); String bizString = CommonUtil.FormatBizQueryParaMap(bizParameters, false); bizString += "&key=12345678123456781234567812345671"; System.out.println("***************"); System.out.println(bizString); // return SHA1Util.Sha1(bizString); return MD5Util.MD5(bizString); } /** * 微信創立定單 * @param nonceStr * @param orderDescribe * @param orderNo * @param price * @param timeStart * @param timeExpire * @return * @throws SDKRuntimeException */ public static String CreateNativePackage(String nonceStr,String orderDescribe,String orderNo,String price,String timeStart,String timeExpire) throws SDKRuntimeException { HashMap<String, String> nativeObj = new HashMap<String, String>(); nativeObj.put("appid", "見"賬號"); //"賬號Id nativeObj.put("mch_id", "見郵件"); //商戶號 nativeObj.put("nonce_str", nonceStr); //隨機字符串 nativeObj.put("body", orderDescribe); //商品描寫 nativeObj.put("attach", "tradeno"); //附加數據 nativeObj.put("out_trade_no", orderNo); //商戶定單號(全局獨一) nativeObj.put("total_fee", price); //總金額(單元為分,不克不及帶小數點) nativeObj.put("spbill_create_ip","192.168.0.144"); //終端Ip nativeObj.put("time_start", timeStart); //生意業務肇端時光 nativeObj.put("time_expire", timeExpire); //生意業務停止時光 nativeObj.put("notify_url", CustomizedPropertyPlaceholderConfigurer.getContextProperty("wxurl")+"/weixin_callback/weixinCallback/init.action"); //回調告訴地址 nativeObj.put("trade_type", "NATIVE"); //生意業務類型 String sign = GetBizSign(nativeObj); nativeObj.put("sign", sign.toUpperCase()); return CommonUtil.ArrayToXml(nativeObj); } /** * 微信定單付出查詢 * @param nonceStr * @param orderDescribe * @param orderNo * @param price * @param timeStart * @param timeExpire * @return * @throws SDKRuntimeException */ public static String SearchNativePackage(String transactionId,String outTradeNo,String nonceStr) throws SDKRuntimeException { HashMap<String, String> nativeObj = new HashMap<String, String>(); nativeObj.put("appid", "見"共賬號"); //"賬號Id nativeObj.put("mch_id", "見郵件");//商戶號 nativeObj.put("nonce_str", nonceStr);//隨機字符串 if(!StringUtils.isEmpty(transactionId)){ nativeObj.put("transaction_id", transactionId); } if(!StringUtils.isEmpty(outTradeNo)){ nativeObj.put("out_trade_no", outTradeNo);//隨機字符串 } String sign = GetBizSign(nativeObj); nativeObj.put("sign", sign.toUpperCase()); return CommonUtil.ArrayToXml(nativeObj); /** * 微信退款 * @param outTradeNo * @param outRefundNo * @param totalFee * @param refundFee * @return * @throws SDKRuntimeException */ public static String RefundNativePackage(String outTradeNo,String outRefundNo,String totalFee,String refundFee,String nonceStr) throws SDKRuntimeException { HashMap<String, String> nativeObj = new HashMap<String, String>(); nativeObj.put("appid", "見"賬號");//"賬號Id nativeObj.put("mch_id", "見郵件");//商戶號 nativeObj.put("nonce_str", nonceStr);//隨機字符串 nativeObj.put("out_trade_no", outTradeNo);//商戶定單號(全局獨一) nativeObj.put("out_refund_no", outRefundNo);//商戶退款單號(全局獨一) nativeObj.put("total_fee", totalFee);//總金額(單元為分,不克不及帶小數點) nativeObj.put("refund_fee", refundFee);//退款金額(單元為分,不克不及帶小數點) nativeObj.put("op_user_id", "郵件"); String sign = GetBizSign(nativeObj); nativeObj.put("sign", sign.toUpperCase()); return CommonUtil.ArrayToXml(nativeObj); } /** * 微信待付出 * @param nonceStr * @param orderDescribe * @param orderNo * @param price * @param timeStart * @param timeExpire * @return * @throws SDKRuntimeException */ public static String CreateJsApiPackage(String nonceStr,String orderDescribe,String orderNo,String price,String timeStart,String timeExpire,String openId) throws SDKRuntimeException { HashMap<String, String> nativeObj = new HashMap<String, String>(); nativeObj.put("appid", "見"賬號");//"賬號Id nativeObj.put("openid", openId);//"賬號Id nativeObj.put("mch_id", "見郵件")//商戶號 nativeObj.put("nonce_str", nonceStr);//隨機字符串 nativeObj.put("body", orderDescribe);//商品描寫 nativeObj.put("attach", "tradeno");//附加數據 nativeObj.put("out_trade_no", orderNo);//商戶定單號(全局獨一) nativeObj.put("total_fee", price);//總金額(單元為分,不克不及帶小數點) nativeObj.put("spbill_create_ip","192.168.0.144");//終端Ip nativeObj.put("time_start", timeStart);//生意業務肇端時光 nativeObj.put("time_expire", timeExpire)//生意業務停止時光 nativeObj.put("notify_url",CustomizedPropertyPlaceholderConfigurer.getContextProperty("wxurl")+"/weixin_callback/weixinCallback/init.action");//告訴地址 nativeObj.put("trade_type", "JSAPI");//生意業務類型 String sign = GetBizSign(nativeObj); nativeObj.put("sign", sign.toUpperCase()); return CommonUtil.ArrayToXml(nativeObj); } /** * 微信封閉定單 * @param nonceStr * @param orderDescribe * @param orderNo * @param price * @param timeStart * @param timeExpire * @param openId * @return * @throws SDKRuntimeException */ public static String CreateCloseOrder(String outTradeNo,String nonceStr) throws SDKRuntimeException { HashMap<String, String> nativeObj = new HashMap<String, String>(); nativeObj.put("appid", "見"賬號");//"賬號Id nativeObj.put("mch_id", "見郵件");//商戶號 nativeObj.put("out_trade_no", outTradeNo);//商戶定單號(全局獨一) nativeObj.put("nonce_str", nonceStr);//隨機字符串 String sign = GetBizSign(nativeObj); nativeObj.put("sign", sign.toUpperCase()); return CommonUtil.ArrayToXml(nativeObj); } }
4.挪用微信付出接口
package com.pay.controller.weixin; import java.io.File; import java.io.FileInputStream; import java.security.KeyStore; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import javax.net.ssl.SSLContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import net.sf.json.JSONArray; import net.sf.json.JSONObject; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.SSLContexts; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.io.SAXReader; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; import com.pay.bo.PayHist; import com.pay.constants.PayHistoryPayStatus; import com.pay.constants.PayHistoryPayType; import com.pay.service.WeiXinPayService; import com.pay.utils.weixin.ClientCustomSSL; import com.pay.utils.weixin.CloseWeiXinOrderUtils; import com.pay.utils.weixin.CustomizedPropertyPlaceholderConfigurer; @RestController @RequestMapping("/Pay") public class WeiXinPayController { @Autowired WeiXinPayService weiXinPayService; private static long standardTime = 1662652800000L; /** * 前往生成二維碼的url * @param request * @param response * @return */ @RequestMapping(value="/getUrl",method=RequestMethod.POST) @ResponseStatus(HttpStatus.OK) public Object getUrl(HttpServletResponse response,@RequestBody String body){ try{ JSONObject jsonO = JSONObject.fromObject(body); PayHist ph = null; // List<Map<String,Object>> td = weiXinPayService.getTrade(orderNo); Date dt = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); String nonceStr = sdf.format(dt).toString(); Date now = new Date(); String tradePayNo = jsonO.get("orderNo").toString()+String.format("%10d",standardTime - now.getTime()).substring(0, 10); System.out.println("定單標號orderNo======="+jsonO.get("orderNo").toString()); System.out.println("10位隨機數======="+String.format("%10d",standardTime - now.getTime()).substring(0, 10)); String price = Math.round(Float.valueOf(jsonO.get("price").toString())*100)+""; Long timeExpireStrOld = dt.getTime(); Long timeNew = Long.parseLong(CustomizedPropertyPlaceholderConfigurer.getContextProperty("weixin.send2finish.overtime").toString()); Long timeExpireNew = timeExpireStrOld+timeNew; Date dtTimeExpire = new Date(timeExpireNew); SimpleDateFormat dtSdf = new SimpleDateFormat("yyyyMMddHHmmss"); String timeExpire = dtSdf.format(dtTimeExpire).toString(); System.out.println("nonceStr=="+nonceStr); System.out.println("orderNo=="+jsonO.get("orderNo").toString()); System.out.println("price=="+price); System.out.println("timeStart=="+nonceStr); System.out.println("timeExpire=="+timeExpire); JSONObject result = (JSONObject) setUrl(nonceStr,"定單",tradePayNo,price,nonceStr,timeExpire); if(result.get("status").toString().equals("success")){ ph = new PayHist(); ph.setTradePayUrl(result.getString("weixinPayUrl"));//此字段為付出鏈接,可以此鏈接生成二維碼掃碼付出 ph.setPayTradeNo(jsonO.get("orderNo").toString()); ph.setTradePayNo(tradePayNo); ph.setPayStatus(PayHistoryPayStatus.WECHAT_PAY_STATUS_WAIT); ph.setPayType(PayHistoryPayType.WECHAT); ph.setAppKey(jsonO.getString("appKey").toString()); ph.setPayAmount(price); result.put("payTradeNo", ph.getPayTradeNo()); result.put("tradePayNo", ph.getTradePayNo()); result.put("payStatus", ph.getPayStatus()); result.put("payType", ph.getPayType()); } return result; }catch(Exception e){ e.printStackTrace(); JSONObject result = new JSONObject(); result.put("status","error"); result.put("msg",e.getMessage()); // return result.toString(); } return null; } public Object setUrl(String nonceStr,String orderDescribe,String orderNo,String price,String timeStart,String timeExpire) { try{ KeyStore keyStore = KeyStore.getInstance("PKCS12"); FileInputStream instream = new FileInputStream(new File(微信證書相對途徑)); try { keyStore.load(instream, "商戶ID".toCharArray()); }finally { instream.close(); } // Trust own CA and all self-signed certs SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore,<span >商戶ID</span>.toCharArray()).build(); // Allow TLSv1 protocol only SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( sslcontext, new String[] { "TLSv1" }, null, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); CloseableHttpClient httpclient = HttpClients.custom() .setSSLSocketFactory(sslsf).build(); // HttpGet httpget = new // HttpGet("https://api.mch.weixin.qq.com/secapi/pay/refund"); HttpPost httppost = new HttpPost( "https://api.mch.weixin.qq.com/pay/unifiedorder"); String xml = ClientCustomSSL.CreateNativePackage(nonceStr,orderDescribe,orderNo,price,timeStart,timeExpire); try { StringEntity se = new StringEntity(xml); httppost.setEntity(se); System.out.println("executing request" + httppost.getRequestLine()); CloseableHttpResponse responseEntry = httpclient.execute(httppost); try { HttpEntity entity = responseEntry.getEntity(); System.out.println("----------------------------------------"); System.out.println(responseEntry.getStatusLine()); if (entity != null) { System.out.println("Response content length: " + entity.getContentLength()); /* BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(entity.getContent())); String text; while ((text = bufferedReader.readLine()) != null) { System.out.println("======="+text); }*/ SAXReader saxReader = new SAXReader(); Document document = saxReader.read(entity.getContent()); Element rootElt = document.getRootElement(); System.out.println("根節點:" + rootElt.getName()); System.out.println("==="+rootElt.elementText("result_code")); System.out.println("==="+rootElt.elementText("return_msg")); String resultCode = rootElt.elementText("result_code"); JSONObject result = new JSONObject(); Document documentXml =DocumentHelper.parseText(xml); Element rootEltXml = documentXml.getRootElement(); if(resultCode.equals("SUCCESS")){ System.out.println("=================prepay_id===================="+ rootElt.elementText("prepay_id")); System.out.println("=================sign===================="+ rootEltXml.elementText("sign")); result.put("weixinPayUrl", rootElt.elementText("code_url")); result.put("prepayId", rootElt.elementText("prepay_id")); result.put("status","success"); result.put("msg","success"); }else{ result.put("status","false"); result.put("msg",rootElt.elementText("err_code_des")); } return result; } EntityUtils.consume(entity); } finally { responseEntry.close(); } } finally { httpclient.close(); } return null; }catch(Exception e){ e.printStackTrace(); JSONObject result = new JSONObject(); result.put("status","error"); result.put("msg",e.getMessage()); return result; } } }
httpclient jar包和json jar包:下載地址。
以上就是本文的全體內容,願望對年夜家的進修有所贊助,也願望年夜家多多支撐。