首页 / JAVA / JAVA微信支付代码
JAVA微信支付代码
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了JAVA微信支付代码,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含14064字,纯文字阅读大概需要21分钟。
内容图文
![JAVA微信支付代码](/upload/InfoBanner/zyjiaocheng/837/87492d0b8b9b4a90b5685b817889aa6d.jpg)
微信官方文档:https://pay.weixin.qq.com/wiki/doc/api/index.html
MD5Util.java
package weixin; import java.security.MessageDigest; 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())); else resultString = 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" }; }
RandomUtil.java
package weixin; import java.util.Random; public class RandomUtil { private static char ch[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1' };//最后又重复两个0和1,因为需要凑足数组长度为64 private static Random random = new Random(); //生成指定长度的随机字符串 public static synchronized String createRandomString(int length) { if (length > 0) { int index = 0; char[] temp = new char[length]; int num = random.nextInt(); for (int i = 0; i < length % 5; i++) { temp[index++] = ch[num & 63];//取后面六位,记得对应的二进制是以补码形式存在的。 num >>= 6;//63的二进制为:111111 // 为什么要右移6位?因为数组里面一共有64个有效字符。为什么要除5取余?因为一个int型要用4个字节表示,也就是32位。 } for (int i = 0; i < length / 5; i++) { num = random.nextInt(); for (int j = 0; j < 5; j++) { temp[index++] = ch[num & 63]; num >>= 6; } } return new String(temp, 0, length); } else if (length == 0) { return ""; } else { throw new IllegalArgumentException(); } } }
SignUtil.java
package weixin; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.*; public class SignUtil { /** * 微信支付签名算法sign * @param parameters * @return */ @SuppressWarnings("unchecked") public static String createSign(SortedMap<Object,Object> parameters,String key){ 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=" + key); String sign = MD5Util.MD5Encode(sb.toString(), "UTF-8").toUpperCase(); return sign; } /** * 与接口配置信息中的 token 要一致,这里赋予什么值,在接口配置信息中的Token就要填写什么值, * 两边保持一致即可,建议用项目名称、公司名称缩写等,我在这里用的是项目名称weixinface */ private static String token = "HR9QhjKMCoUQlwd"; /** * 验证签名 * @param signature * @param timestamp * @param nonce * @return */ public static boolean checkSignature(String signature, String timestamp, String nonce){ String[] arr = new String[]{token, timestamp, nonce}; // 将 token, timestamp, nonce 三个参数进行字典排序 Arrays.sort(arr); StringBuilder content = new StringBuilder(); for(int i = 0; i < arr.length; i++){ content.append(arr[i]); } MessageDigest md = null; String tmpStr = null; try { md = MessageDigest.getInstance("SHA-1"); // 将三个参数字符串拼接成一个字符串进行 shal 加密 byte[] digest = md.digest(content.toString().getBytes()); tmpStr = byteToStr(digest); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } content = null; // 将sha1加密后的字符串可与signature对比,标识该请求来源于微信 return tmpStr != null ? tmpStr.equals(signature.toUpperCase()): false; } /** * 将字节数组转换为十六进制字符串 * @param digest * @return */ private static String byteToStr(byte[] digest) { // TODO Auto-generated method stub String strDigest = ""; for(int i = 0; i < digest.length; i++){ strDigest += byteToHexStr(digest[i]); } return strDigest; } /** * 将字节转换为十六进制字符串 * @param b * @return */ private static String byteToHexStr(byte b) { // TODO Auto-generated method stub char[] Digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; char[] tempArr = new char[2]; tempArr[0] = Digit[(b >>> 4) & 0X0F]; tempArr[1] = Digit[b & 0X0F]; String s = new String(tempArr); return s; } }
XmlPostUtil.java
package weixin; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; public class XmlPostUtil { public static byte[] sendXmlRequest(String path, String params) throws Exception { URL url = new URL(path); System.out.println("发送xml:" + params); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST");// 提交模式 conn.setDoOutput(true);// 是否输入参数 conn.setRequestProperty("Pragma:", "no-cache"); conn.setRequestProperty("Cache-Control", "no-cache"); conn.setRequestProperty("Content-Type", "text/xml"); byte[] bypes = params.toString().getBytes("UTF-8"); conn.getOutputStream().write(bypes);// 输入参数 InputStream inStream = conn.getInputStream(); return readInputStream(inStream); } public static byte[] readInputStream(InputStream inStream) throws Exception { ByteArrayOutputStream outStream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = 0; while ((len = inStream.read(buffer)) != -1) { outStream.write(buffer, 0, len); } byte[] data = outStream.toByteArray();//网页的二进制数据 outStream.close(); inStream.close(); System.out.println(new String(data, "utf-8")); return data; } }
XMLUtil.java
package weixin; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.util.*; /** *xml工具类 * */ public class XMLUtil { /** * 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。 * @param strxml * @return * @throws JDOMException * @throws IOException */ public static Map doXMLParse(String strxml) throws JDOMException, IOException { if(null == strxml || "".equals(strxml)) { return null; } Map m = new HashMap(); InputStream in = String2Inputstream(strxml); SAXBuilder builder = new SAXBuilder(); /**********************修复部分内容*********************/ String FEATURE = "http://apache.org/xml/features/disallow-doctype-decl"; builder.setFeature(FEATURE, true); FEATURE = "http://xml.org/sax/features/external-general-entities"; builder.setFeature(FEATURE, false); FEATURE = "http://xml.org/sax/features/external-parameter-entities"; builder.setFeature(FEATURE, false); FEATURE = "http://apache.org/xml/features/nonvalidating/load-external-dtd"; builder.setFeature(FEATURE, false); 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(); } public static InputStream String2Inputstream(String str) { return new ByteArrayInputStream(str.getBytes()); } public static String mapToXml(SortedMap<Object, Object> sortedMap){ StringBuffer sb = new StringBuffer("<xml>"); Iterator iterator = sortedMap.keySet().iterator(); while (iterator.hasNext()) { Object key = (String) iterator.next(); Object value = sortedMap.get(key); sb.append("<"+key+">"); sb.append("<![CDATA["+value+"]]>"); sb.append("</"+key+">"); } sb.append("</xml>"); return sb.toString(); } }
PaymentConfig.java
package weixin; public class PaymentConfig { /*******微信支付参数*********/ //公众账号ID public static final String appid="wx7805396575372a58"; //密钥 public static final String appKey="b48e1a77ff733225e2308b6b69whcmxy"; //商户号 public static final String mch_id="1522400871"; //接口地址 public static final String pay_url="https://api.mch.weixin.qq.com/pay/unifiedorder"; //支付返回地址 public static final String wxRetrun="http://szsh.jetsum.cn/cmxy/wechart_notice.jspx"; //交易场景信息 public static final String scene_info = "{\"h5_info\": {\"type\":\"Wap\",\"wap_url\": \"https://pay.qq.com\",\"wap_name\": \"传媒学院在线报名\"}} "; public static final int ENROLL_PRICE = 200; }
WeChatPay.java
package weixin; import org.jdom.JDOMException; import java.io.IOException; import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; public class WeChatPay { /** * h5支付 * @param orderNo 订单号 * @param money 金额(分) * @param body 描述 * @param ip 请求ip * @return */ public String getPaymentUrl(String orderNo,int money,String body,String ip){ SortedMap<Object, Object> paramMap = new TreeMap<Object, Object>(); paramMap.put("appid", PaymentConfig.appid); paramMap.put("mch_id", PaymentConfig.mch_id); paramMap.put("nonce_str", RandomUtil.createRandomString(32)); paramMap.put("body", body); paramMap.put("out_trade_no", orderNo); paramMap.put("total_fee", money*100); //paramMap.put("total_fee", 1); paramMap.put("spbill_create_ip", ip); paramMap.put("notify_url", PaymentConfig.wxRetrun); paramMap.put("trade_type", "MWEB"); paramMap.put("scene_info", PaymentConfig.scene_info); paramMap.put("sign", SignUtil.createSign(paramMap, PaymentConfig.appKey)); String rXml = ""; String paymentUrl = ""; try { rXml = new String(XmlPostUtil.sendXmlRequest(PaymentConfig.pay_url, XMLUtil.mapToXml(paramMap))); String code = (String)XMLUtil.doXMLParse(rXml).get("return_code"); if(code.equals("SUCCESS")){ paymentUrl = (String)XMLUtil.doXMLParse(rXml).get("mweb_url"); } } catch (Exception e) { // TODO: handle exception } return paymentUrl; } /** * 公众号内支付 * @param orderNo 订单号 * @param money 金额(分) * @param body 描述 * @param ip 请求ip * @param openid 公众号openid * @return */ public Map getPaymentMap(String orderNo,int money,String body,String ip,String openid){ //一次签名 SortedMap<Object, Object> paramMap = new TreeMap<Object, Object>(); paramMap.put("appid",PaymentConfig.appid);//公众号ID paramMap.put("mch_id",PaymentConfig.mch_id);//商户号 paramMap.put("nonce_str",RandomUtil.createRandomString(32));//32位随机字符串 paramMap.put("body",body);//商品描述 paramMap.put("out_trade_no",orderNo);//商户订单号 paramMap.put("total_fee",String.valueOf(money*100));//设置交易金额 金额为分 //paramMap.put("total_fee",1);//设置交易金额 金额为分 paramMap.put("spbill_create_ip",ip);//客户机IP paramMap.put("notify_url",PaymentConfig.wxRetrun);//通知地址 paramMap.put("trade_type","JSAPI");//支付方式 原生扫码 paramMap.put("openid", openid);//添加openid paramMap.put("sign",SignUtil.createSign(paramMap, PaymentConfig.appKey)); String rXml = ""; String prepayid=""; try { rXml = new String(XmlPostUtil.sendXmlRequest(PaymentConfig.pay_url, XMLUtil.mapToXml(paramMap))); prepayid = (String) XMLUtil.doXMLParse(rXml).get("prepay_id");//得到预支付id } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } //二次签名 SortedMap<Object, Object> paramMap1 = new TreeMap<Object, Object>(); paramMap1.put("appId", PaymentConfig.appid); paramMap1.put("timeStamp", System.currentTimeMillis()); paramMap1.put("package", "prepay_id="+prepayid); paramMap1.put("signType", "MD5"); paramMap1.put("nonceStr", RandomUtil.createRandomString(32)); paramMap1.put("paySign", SignUtil.createSign(paramMap1, PaymentConfig.appKey)); return paramMap1; } /** * 二维码支付 * @param orderNo * @param money * @param body * @param ip * @return */ public Map getPaymentMapCode(String orderNo,int money,String body,String ip){ //一次签名 SortedMap<Object, Object> paramMap = new TreeMap<Object, Object>(); paramMap.put("appid",PaymentConfig.appid);//公众号ID paramMap.put("mch_id",PaymentConfig.mch_id);//商户号 paramMap.put("nonce_str",RandomUtil.createRandomString(32));//32位随机字符串 paramMap.put("body",body);//商品描述 paramMap.put("out_trade_no",orderNo);//商户订单号 paramMap.put("total_fee",String.valueOf(money));//设置交易金额 金额为分 //paramMap.put("total_fee",1);//设置交易金额 金额为分 paramMap.put("spbill_create_ip",ip);//客户机IP paramMap.put("notify_url",PaymentConfig.wxRetrun);//通知地址 paramMap.put("trade_type","NATIVE");//支付方式 原生扫码 paramMap.put("product_id", "shangpingid"); //自行定义 paramMap.put("sign",SignUtil.createSign(paramMap, PaymentConfig.appKey)); String rXml = ""; String prepayid=""; try { rXml = new String(XmlPostUtil.sendXmlRequest(PaymentConfig.pay_url, XMLUtil.mapToXml(paramMap))); prepayid = (String) XMLUtil.doXMLParse(rXml).get("prepay_id");//得到预支付id } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } //二次签名 SortedMap<Object, Object> paramMap1 = new TreeMap<Object, Object>(); paramMap1.put("appId", PaymentConfig.appid); paramMap1.put("timeStamp", System.currentTimeMillis()); paramMap1.put("package", "prepay_id="+prepayid); paramMap1.put("signType", "MD5"); paramMap1.put("nonceStr", RandomUtil.createRandomString(32)); paramMap1.put("paySign", SignUtil.createSign(paramMap1, PaymentConfig.appKey)); try { Map map = XMLUtil.doXMLParse(rXml); System.out.println("return_code:"+map.get("return_code")); System.out.println("code_url:"+map.get("code_url")); return map; } catch (JDOMException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return paramMap1; } }
内容总结
以上是互联网集市为您收集整理的JAVA微信支付代码全部内容,希望文章能够帮你解决JAVA微信支付代码所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。