微信App支付(一)
来源:互联网 发布:java泛型方法调用 编辑:程序博客网 时间:2024/04/30 14:00
微信app支付签名
在这里记录自己微信app支付(java后台)中,遇到的问题,方便日后查阅,也方便有需要的小伙伴。
微信app支付流程:组合业务参数签名,然后发送给微信统一下单接口,得到微信返回的预支付id:prepay_id。再二次签名后把参数给app端,调起微信支付。
parameters.put("appid", WeixinConfig.appid);//微信分配的公众账号ID(企业号corpid即为此appId),例如:wxd678efh567hg6787parameters.put("mch_id", WeixinConfig.mch_id); // 微信支付分配的商户号parameters.put("nonce_str", nonce_str);// 随机字符串:数字+大写字母的组合,32位parameters.put("body", WeixinConfig.body); // 商品或支付单简要描述,格式:需传入应用市场上的APP名字-实际商品名称,天天爱消除-游戏充值。parameters.put("out_trade_no", out_trade_no);// 商户系统内部的订单号parameters.put("total_fee", total_fee);// 总金额 单位为分,不能带小数parameters.put("notify_url", WeixinConfig.notify_url);// 接收微信支付异步通知回调地址parameters.put("trade_type", WeixinConfig.trade_type);// 交易类型:APPparameters.put("spbill_create_ip", WeixinConfig.spbill_create_ip);// APP和网页支付提交[用户端ip],Native支付填调用微信支付API的机器IP。
以上是第一次签名必须传的一些参数,如果业务有需求还可以参考微信支付文档的选填参数列表。
public class WXSignUtils { // http://mch.weixin.qq.com/wiki/doc/api/index.php?chapter=4_3 // 商户Key:改成公司申请的即可 // 32位密码设置地址:http://www.sexauth.com/ jdex1hvufnm1sdcb0e81t36k0d0f15nc /** * 微信支付签名算法sign * @param characterEncoding * @param parameters * @return */ public static String createSign(String characterEncoding, Map<String, String> parameters) { List<String> keys = new ArrayList<String>(parameters.keySet()); Collections.sort(keys); String prestr = ""; for (int i = 0; i < keys.size(); i++) { String key = keys.get(i); String value = parameters.get(key); if (i == keys.size() - 1) {// 拼接时,不包括最后一个&字符 prestr = prestr + key + "=" + value; } else { prestr = prestr + key + "=" + value + "&"; } } prestr = prestr + "&" + "key=" + WeixinConfig.private_key; System.out.println("字符串拼接后是:" + prestr.toString()); String sign = MD5Util.MD5Encode(prestr.toString(), characterEncoding).toUpperCase(); return sign; }}以上是签名方法,里面的MD5Util就是一般的MD5加密, Collections.sort(keys)这个排序一定要排序,不然签名错误。Key就是api密钥,是当时设置在微信平台里的32位密钥,这个密钥设置好以后就无法再查看,所以一定要本地保存。
/** * 构造xml参数 * @param xml * @return */ public static String xmlInfo(Unifiedorder unifiedorder){ //构造xml参数的时候,至少包含所有必传参数 /* * <xml> <appid>wx2421b1c4370ec43b</appid> <attach>支付测试</attach> <body>JSAPI支付测试</body> <mch_id>10000100</mch_id> <nonce_str>1add1a30ac87aa2db72f57a2375d8fec</nonce_str> <notify_url>http://wxpay.weixin.qq.com/pub_v2/pay/notify.v2.php</notify_url> <openid>oUpF8uMuAJO_M2pxb1Q9zNjWeS6o</openid> <out_trade_no>1415659990</out_trade_no> <spbill_create_ip>14.23.150.211</spbill_create_ip> <total_fee>1</total_fee> <trade_type>JSAPI</trade_type> <sign>0CB01533B8C1EF103065174F50BCA001</sign> </xml> */ if(unifiedorder!=null){ StringBuffer bf = new StringBuffer(); bf.append("<xml>"); bf.append("<appid><![CDATA["); bf.append(unifiedorder.getAppid()); bf.append("]]></appid>"); bf.append("<mch_id><![CDATA["); bf.append(unifiedorder.getMch_id()); bf.append("]]></mch_id>"); bf.append("<nonce_str><![CDATA["); bf.append(unifiedorder.getNonce_str()); bf.append("]]></nonce_str>"); bf.append("<sign><![CDATA["); bf.append(unifiedorder.getSign()); bf.append("]]></sign>"); bf.append("<body><![CDATA["); bf.append(unifiedorder.getBody()); bf.append("]]></body>"); /*bf.append("<detail><![CDATA["); bf.append(unifiedorder.getDetail()); bf.append("]]></detail>"); bf.append("<attach><![CDATA["); bf.append(unifiedorder.getAttach()); bf.append("]]></attach>");*/ bf.append("<out_trade_no><![CDATA["); bf.append(unifiedorder.getOut_trade_no()); bf.append("]]></out_trade_no>"); bf.append("<total_fee><![CDATA["); bf.append(unifiedorder.getTotal_fee()); bf.append("]]></total_fee>"); bf.append("<spbill_create_ip><![CDATA["); bf.append(unifiedorder.getSpbill_create_ip()); bf.append("]]></spbill_create_ip>"); /*bf.append("<time_start><![CDATA["); bf.append(unifiedorder.getTime_start()); bf.append("]]></time_start>"); bf.append("<time_expire><![CDATA["); bf.append(unifiedorder.getTime_expire()); bf.append("]]></time_expire>");*/ bf.append("<notify_url><![CDATA["); bf.append(unifiedorder.getNotify_url()); bf.append("]]></notify_url>"); bf.append("<trade_type><![CDATA["); bf.append(unifiedorder.getTrade_type()); bf.append("]]></trade_type>"); bf.append("</xml>"); return bf.toString(); } return ""; }
以上是就是微信以XML的形式发送请求的包装。
public static String httpsRequest(String requestUrl, String requestMethod, String output) { try{ URL url = new URL(requestUrl); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.setDoOutput(true); connection.setDoInput(true); connection.setUseCaches(false); connection.setRequestMethod(requestMethod); if (null != output) { OutputStream outputStream = connection.getOutputStream(); outputStream.write(output.getBytes("UTF-8")); outputStream.close(); } // 从输入流读取返回内容 InputStream inputStream = connection.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String str = null; StringBuffer buffer = new StringBuffer(); while ((str = bufferedReader.readLine()) != null) { buffer.append(str); } bufferedReader.close(); inputStreamReader.close(); inputStream.close(); inputStream = null; connection.disconnect(); return buffer.toString(); }catch(Exception ex){ ex.printStackTrace(); } return ""; }
以上就是把之前打包好的xml(output)发送到微信统一下单接口requestUrl,requestMethod为post请求。签名没问题,微信会返回预支付id:prepay_id
finalpackage.put("appid", WeixinConfig.appid); // appid finalpackage.put("timestamp", timestamp); // 时间戳 十位 finalpackage.put("noncestr", nonce_string); // 随机字符串 finalpackage.put("package", "Sign=WXPay"); // 固定值 finalpackage.put("partnerid", WeixinConfig.mch_id); // 商户id(微信商户平台获取) finalpackage.put("prepayid", prepay_id); // 第一次请求微信,成功后,返回的参数
再把这六个参数用同样的方法签名,把得到的签名和上述参与签名的参数传给app端。
然后app端就可以调起微信支付了。
1 0
- 微信App支付(一)
- Java 微信支付之APP支付服务端 (一)
- 支付--微信APP支付
- 微信支付app
- 微信支付app
- 微信APP支付
- app微信支付
- APP微信支付
- app微信支付
- 微信APP支付
- 支付--微信APP
- 微信APP支付
- 微信app支付
- 微信APP支付
- 微信APP支付
- 基于PHP的APP微信支付开发(一)
- Android App支付系列(一):微信支付接入详细指南(附官方支付demo)
- Android App支付系列(一):微信支付接入详细指南(附官方支付demo)
- mac系统sourcetree外部比对工具不能启用
- sublime text 3 介绍以及免费使用方法
- Toast的简单应用
- Yslow安装使用, 网站性能工具Yslow
- 区间覆盖问题 例题 POJ 2376
- 微信App支付(一)
- 关于线程中异常的处理
- Java强引用、软引用、弱引用、虚引用详解
- 使用API网关构建微服务
- springMVC mybatis整合dao接口(mapper接口) spring注入失败
- iOS最不卡顿的圆角图片的设置(UIImage分类)
- shadowsocks启动命令
- 设计模式--适配器模式
- 卷积和池化