/** * 获取微信支付所需信息(统一下单接口调用) * @param backURL * @param mDealerOrderEntity * @param mCarInfoEntity * @return * @throws JSONException * @throws IOException * @throws JDOMException */ public Map<String, String> getWechatOrderInfo(String notifyUrl, MDealerOrderEntity mDealerOrderEntity, String body, HttpServletRequest request, HttpServletResponse response) throws Exception { Map<String, String> resultMap = new HashMap<String, String>(); //生成payPreId Map<String, String> payPreIdMap = WechatUtil.getPayPreId(mDealerOrderEntity.getGoodorderno(), body, notifyUrl, request.getRemoteAddr(), String.valueOf((int)(mDealerOrderEntity.getMoney()*100))); String prePayId = payPreIdMap.get("prepay_id"); if(StringUtils.isNotEmpty(prePayId)) { //生成调用微信APP参数 resultMap = WechatUtil.genPayReq(prePayId); } return resultMap; }
此方法返回的数据如下
{ "appid": "123132131", "noncestr": "416e5cf0acb7e553a880b7647903da6e", "packageValue ": "Sign=WXPay", "partnerid ": "1276000000", "prepayid ": "wx2015101611341514a3cbbbf90572184370", "timestamp ": "1444966497", "sign": "1DD72B07607B0B41D2827954150D89E9" }
/** * 处理微信支付通知 * @param request * @return * @throws Exception */ public String saveWechatNotify(HttpServletRequest request, HttpServletResponse response) throws Exception { Map<String, String> noticeMap = XMLUtil.parseXml(request); String transactionId = noticeMap.get("transaction_id"); MWechatInfoEntity wechatInfoEntity = this.findEntityByProperty(MWechatInfoEntity.class, "transactionId", transactionId); //如果wechatInfoEntity存在,说明请求已经处理过,直接返回 if(wechatInfoEntity != null) { return "SUCCESS"; } String sign = noticeMap.get("sign"); noticeMap.remove("sign"); // 验签通过 if (WechatUtil.getSignVeryfy(noticeMap, sign)) { // 通信成功此字段是通信标识,非交易标识,交易是否成功需要查看result_code来判断 if ("SUCCESS".equals(noticeMap.get("return_code"))) { // 交易成功 if ("SUCCESS".equals(noticeMap.get("result_code"))) { // 商户订单号 String goodorderno = noticeMap.get("out_trade_no"); MDealerOrderEntity mDealerOrderEntity = this.findEntityByProperty(MDealerOrderEntity.class, "goodorderno", goodorderno); MCarInfoEntity mCarInfoEntity = this.get(MCarInfoEntity.class, mDealerOrderEntity.getCarid()); // 订单更新时间 mDealerOrderEntity.setUpdatetime(new Date()); // ------------------------------ // 处理业务开始 // ------------------------------ // 这里写自己业务相关 // ------------------------------ // 处理业务完毕 // ------------------------------ noticeMap.put("sign", sign); this.common99Service.saveWechatInfo(noticeMap, mDealerOrderEntity.getId()); } else { // 错误时,返回结果未签名,记录retcode、retmsg看失败详情。 System.out.println("查询验证签名失败或业务错误"); System.out.println("retcode:" + noticeMap.get("retcode") + " retmsg:" + noticeMap.get("retmsg")); } return "SUCCESS"; } else { System.out.println("后台调用通信失败"); } return "SUCCESS"; } else { System.out.println("通知签名验证失败"); } return null; }
package com.jim.iweb.haocheok.tenpay.util; import java.io.IOException; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Random; import org.apache.commons.httpclient.HttpStatus; import org.apache.http.NameValuePair; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.utils.URIBuilder; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import org.jdom2.JDOMException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class WechatUtil { private static Logger logger = LoggerFactory.getLogger(WechatUtil.class); public static final String TAG = "Wechat.Util"; private static final int timeout = 5000; public static byte[] httpPost(String url, String entity) throws URISyntaxException, IOException { if (url == null || url.length() == 0) { logger.info(TAG, "httpPost, url is null"); return null; } CloseableHttpClient httpClient = HttpClients.createDefault(); URIBuilder uriBuilder = new URIBuilder(url); HttpPost httpPost = new HttpPost(uriBuilder.build()); RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(timeout).setConnectionRequestTimeout(timeout).setConnectTimeout(timeout).build(); httpPost.setConfig(requestConfig); // 避免汉字乱码导致请求失败, httpPost.setEntity(new StringEntity(entity, "UTF-8")); CloseableHttpResponse resp = null; try { resp = httpClient.execute(httpPost); if (resp.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { logger.info(TAG, "httpGet fail, status code = " + resp.getStatusLine().getStatusCode()); return null; } return EntityUtils.toByteArray(resp.getEntity()); } catch (Exception e) { logger.info(TAG, "httpPost exception, e = " + e.getMessage()); e.printStackTrace(); return null; } finally { if (httpClient != null) { httpClient.close(); } if (resp != null) { resp.close(); } } } /** * 把数组所有元素排序,并按照“参数=参数值”的模式用“&”字符拼接成字符串 * * @param params * 需要排序并参与字符拼接的参数组 * @return 拼接后字符串 */ public static String createLinkString(Map<String, String> params) { List<String> keys = new ArrayList<String>(params.keySet()); Collections.sort(keys); String prestr = ""; for (int i = 0; i < keys.size(); i++) { String key = keys.get(i); String value = params.get(key); if (i == keys.size() - 1) {// 拼接时,不包括最后一个&字符 prestr = prestr + key + "=" + value; } else { prestr = prestr + key + "=" + value + "&"; } } return prestr; } /** * 根据反馈回来的信息,生成签名结果 * * @param Params * 通知返回来的参数数组 * @param sign * 比对的签名结果 * @return 生成的签名结果 */ public static boolean getSignVeryfy(Map<String, String> Params, String sign) { // 过滤空值、sign与sign_type参数 // Map<String, String> sParaNew = AlipayCore.paraFilter(Params); // 获取待签名字符串 String preSignStr = createLinkString(Params); preSignStr += "&key=" + ConstantUtil.API_KEY; // 获得签名验证结果 String resultSign = MD5.getMessageDigest(preSignStr.getBytes()).toUpperCase(); // String resultSign = MD5Util.MD5Encode(preSignStr.toString(), "UTF-8").toLowerCase(); if (sign.equals(resultSign)) { return true; } else { return false; } } /** * 装配xml,生成请求prePayId所需参数 * * @param params * @return */ public static String toXml(List<NameValuePair> params) { StringBuilder sb = new StringBuilder(); sb.append("<xml>"); for (int i = 0; i < params.size(); i++) { sb.append("<" + params.get(i).getName() + ">"); sb.append(params.get(i).getValue()); sb.append("</" + params.get(i).getName() + ">"); } sb.append("</xml>"); return sb.toString(); } /** * 生成签名 */ public static String genPackageSign(List<NameValuePair> params) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < params.size(); i++) { sb.append(params.get(i).getName()); sb.append('='); sb.append(params.get(i).getValue()); sb.append('&'); } sb.append("key="); sb.append(ConstantUtil.API_KEY); String packageSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase(); return packageSign; } /** * * @param goodOrderNo * @param body * @param noticeUrl * @param ip * @param totalFee * @return */ public static String genProductArgs(String goodOrderNo, String body, String noticeUrl, String ip, String totalFee) { StringBuffer xml = new StringBuffer(); try { String nonceStr = getNonceStr(); xml.append("</xml>"); List<NameValuePair> packageParams = new LinkedList<NameValuePair>(); packageParams.add(new BasicNameValuePair("appid", ConstantUtil.APP_ID)); packageParams.add(new BasicNameValuePair("body", body)); packageParams.add(new BasicNameValuePair("mch_id", ConstantUtil.MCH_ID)); packageParams.add(new BasicNameValuePair("nonce_str", nonceStr)); packageParams.add(new BasicNameValuePair("notify_url", noticeUrl)); packageParams.add(new BasicNameValuePair("out_trade_no", goodOrderNo)); packageParams.add(new BasicNameValuePair("spbill_create_ip", ip)); packageParams.add(new BasicNameValuePair("total_fee", totalFee)); packageParams.add(new BasicNameValuePair("trade_type", "APP")); String sign = genPackageSign(packageParams); packageParams.add(new BasicNameValuePair("sign", sign)); String xmlstring = toXml(packageParams); return xmlstring; } catch (Exception e) { logger.info("genProductArgs fail, ex = " + e.getMessage()); return null; } } /** * 生成app支付签名 * * @param params * @return */ public static String genAppSign(List<NameValuePair> params) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < params.size(); i++) { sb.append(params.get(i).getName()); sb.append('='); sb.append(params.get(i).getValue()); sb.append('&'); } sb.append("key="); sb.append(ConstantUtil.API_KEY); String appSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase(); logger.info("orion", appSign); return appSign; } /** * 生成调用微信app支付所需参数 * * @param prepayId * @return */ public static Map<String, String> genPayReq(String prepayId) { Map<String, String> resultMap = new HashMap<String, String>(); String timeStamp = getTimeStamp(); String nonceStr = getNonceStr(); List<NameValuePair> signParams = new LinkedList<NameValuePair>(); signParams.add(new BasicNameValuePair("appid", ConstantUtil.APP_ID)); signParams.add(new BasicNameValuePair("noncestr", nonceStr)); signParams.add(new BasicNameValuePair("package", "Sign=WXPay")); signParams.add(new BasicNameValuePair("partnerid", ConstantUtil.MCH_ID)); signParams.add(new BasicNameValuePair("prepayid", prepayId)); signParams.add(new BasicNameValuePair("timestamp", timeStamp)); String sign = genAppSign(signParams); resultMap.put("appid", ConstantUtil.APP_ID); resultMap.put("noncestr", nonceStr); resultMap.put("packageValue", "Sign=WXPay"); resultMap.put("partnerid", ConstantUtil.MCH_ID); resultMap.put("prepayid", prepayId); resultMap.put("timestamp", timeStamp); resultMap.put("sign", sign); return resultMap; } /** * 微信支付生成预支付订单 * * @throws IOException * @throws JDOMException */ public static Map<String, String> getPayPreId(String goodOrderNo, String body, String noticeUrl, String ip, String totalFee) throws Exception { String paramsXml = genProductArgs(goodOrderNo, body, noticeUrl, ip, totalFee); logger.info("orion", paramsXml); byte[] buf = WechatUtil.httpPost(ConstantUtil.URL, paramsXml); String contentXml = new String(buf); Map<String, String> resultMap = XMLUtil.doXMLParse(contentXml); return resultMap; } public static String getNonceStr() { Random random = new Random(); return MD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes()); } public static String getTimeStamp() { return String.valueOf(System.currentTimeMillis() / 1000); } }
package com.jim.iweb.haocheok.tenpay.util; public class ConstantUtil { /** * 商家可以考虑读取配置文件 */ //初始化 public static String APP_ID = "wxsdfsdfsf5fdbc";//微信开发平台应用id public static String APP_SECRET = "aab95csdfsdfsffdcsdfsfs0df34";//应用对应的凭证 //商户号 public static String MCH_ID = "1233312201"; public static String PARTNER = "1233312201";//财付通商户号 public static String API_KEY = "KgjyjirmjajdfjsdjfsjffVpT6RMbrB"; public static String PARTNER_KEY = "KgjyjirmjajdfjsdjfsjffVpT6RMbrB";//商户号对应的密钥 public static String URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";//获取预支付id的接口url }