Java源码示例:com.github.wxpay.sdk.WXPayUtil

示例1
/**
     * 退款结果通知
     *
     * 特别说明:退款结果对重要的数据进行了加密,商户需要用商户秘钥进行解密后才能获得结果通知的内容
     * @param request
     * @throws Exception
     */
    @RequestMapping("/refund/notify")
    public String refundNotify(HttpServletRequest request) throws Exception {

//        Map<String, String> notifyMap = new HashMap<>();
//        notifyMap.put("nonce_str", "9b4e428ae262d5dca96178027e849fa9");
//        notifyMap.put("req_info", "VKGj8c81RwQ45LcyWEVBE9/HsNfADGbgmbIAQZ2ydcbIFhIIcJFKFQwGfcSGgFGtQlWvg6KDNsRjmCjN+PvipJ3roynJ7cME0LOFG50VGtk4EYHqdjFzUVANI7GpT+i6Ok+ZWivH0MwoGK2fsz3WG+bYs2XJBwav/K89tKjFhZGitCKKBeGqcP99fa/gAL0swNXXNQHmL806Zi+QcACzL3E89BtP9FlXM2Gi+wPQafvPr+/iE+LrPdMlNUa5LiZnenZXUF24kMdhaTafczcKL4sZjRXQHEfEyc/pIZPbIjcNIETvHsskyzKuHVr/SAFkxaM6RR1Kl9pyWZGUjkH5SOeqsT8uL7YQmTlDXrnXmno3AvZdnepTGL5w69yIOmQNPeMqsd01ES9WX36GZYOigfi2+BJ9RRXjIffmpB/MFF+zryyvLTaJE2obCwFSHrmOD8YbaJqrZXOUvWZQrn7wIQgaCypo8V57cD3w5d2RSgIHNrdnEDYlbRcLNYgKuL+T9+1HPhU/frowZgwPN9IB53OahZV3p1Yvos23kvhqPCLn3BYgUihRbey6QhEtL2QyifiQ9e8WVLzWpRZ+DOa8VrhYvSuTfjRdjoNanqHFvXGP6uEsEa+DETqnexpB7xOS9m/CdmlNCwbdUplPEVzNQQdzYT4kybi00Y8A+EdairxfVyK9A7MAYAMtAO9yxV2ht0bn3SofFyZe/YSzdJgxdtcxBf1CVYN6x+yHcSueCSgq4cM/2VCwh4J1+pUVmNpEm0OVcdKbV5USkaxJR0h7Yd+n5FTz5Q2S/qvyDo202cUzLFPI5UqQm5X+FOrWDAkmmr5yVcDQIm3dAdb31jkz0X2TPYt5g7ciQ1h9heyVxJ67FexKvEM4pKCCubtWx6nyxcOUghHMrh8DSoBtewtNjbnwGVIbLsSb6X9MIYAkWIDbqNVP1f63GiZU+cJlhBmvcb8aeQUdTTj7EX5pOTIVSVv5D6SkKmpGU4FGvV+WjufuGX4ZRZo+01p6xl0sfZVmucG1UtxhX6bMCJb06yDwxpv7tGwkwS4TCK4SQp40Xe0=");
//        notifyMap.put("appid", "xxx");
//        notifyMap.put("mch_id", "xxx");
//        notifyMap.put("return_code", "SUCCESS");

        // 注意:同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。
        // 推荐的做法是,当收到通知进行处理时,首先检查对应业务数据的状态,判断该通知是否已经处理过,如果没有处理过再进行处理,如果处理过直接返回结果成功。
        // 在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重入造成的数据混乱。
        // TODO 处理业务
        Map<String, String> requstInfoMap = wxPayClient.decodeRefundNotify(request);

        // 商户处理退款通知参数后同步返回给微信参数
        Map<String, String> responseMap = new HashMap<>();
        responseMap.put("return_code", "SUCCESS");
        responseMap.put("return_msg", "OK");
        String responseXml = WXPayUtil.mapToXml(responseMap);
        return responseXml;
    }
 
示例2
/**
 * 注意:如果是沙箱环境,一提交订单就会立即异步通知,而无需拉起微信支付收银台的中间页面
 * @param request
 * @throws Exception
 */
@RequestMapping("/notify")
public void payNotify(HttpServletRequest request, HttpServletResponse response) throws Exception{
    Map<String, String> reqData = wxPayClient.getNotifyParameter(request);
    log.info(reqData.toString());


    String returnCode = reqData.get("return_code");
    String resultCode = reqData.get("result_code");
    if (WXPayConstants.SUCCESS.equals(returnCode) && WXPayConstants.SUCCESS.equals(resultCode)) {
        boolean signatureValid = wxPay.isPayResultNotifySignatureValid(reqData);

        if (signatureValid) {
            // TODO 业务处理

            Map<String, String> responseMap = new HashMap<>(2);
            responseMap.put("return_code", "SUCCESS");
            responseMap.put("return_msg", "OK");
            String responseXml = WXPayUtil.mapToXml(responseMap);

            response.setContentType("text/xml");
            response.getWriter().write(responseXml);
            response.flushBuffer();
        }
    }
}
 
示例3
/**
 * 从request的inputStream中获取参数
 * @param request
 * @return
 * @throws Exception
 */
public Map<String, String> getNotifyParameter(HttpServletRequest request) throws Exception {
    InputStream inputStream = request.getInputStream();
    ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int length = 0;
    while ((length = inputStream.read(buffer)) != -1) {
        outSteam.write(buffer, 0, length);
    }
    outSteam.close();
    inputStream.close();

    // 获取微信调用我们notify_url的返回信息
    String resultXml = new String(outSteam.toByteArray(), "utf-8");
    Map<String, String> notifyMap = WXPayUtil.xmlToMap(resultXml);

    return notifyMap;
}
 
示例4
/**
 * 解密退款通知
 *
 * <a href="https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_16&index=11>退款结果通知文档</a>
 * @return
 * @throws Exception
 */
public Map<String, String> decodeRefundNotify(HttpServletRequest request) throws Exception {
    // 从request的流中获取参数
    Map<String, String> notifyMap = this.getNotifyParameter(request);
    log.info(notifyMap.toString());

    String reqInfo = notifyMap.get("req_info");
    //(1)对加密串A做base64解码,得到加密串B
    byte[] bytes = new BASE64Decoder().decodeBuffer(reqInfo);

    //(2)对商户key做md5,得到32位小写key* ( key设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置 )
    Cipher cipher = Cipher.getInstance(ALGORITHM_MODE_PADDING);
    SecretKeySpec key = new SecretKeySpec(WXPayUtil.MD5(config.getKey()).toLowerCase().getBytes(), ALGORITHM);
    cipher.init(Cipher.DECRYPT_MODE, key);

    //(3)用key*对加密串B做AES-256-ECB解密(PKCS7Padding)
    // java.security.InvalidKeyException: Illegal key size or default parameters
    // https://www.cnblogs.com/yaks/p/5608358.html
    String responseXml = new String(cipher.doFinal(bytes),"UTF-8");
    Map<String, String> responseMap = WXPayUtil.xmlToMap(responseXml);
    return responseMap;
}
 
示例5
/**
 * 从request的inputStream中获取参数
 * code come from https://github.com/mengday/springboot-pay-example/blob/master/src/main/java/com/example/pay/configuration/WXPayClient.java
 * @param request
 * @return
 * @throws Exception
 */
public static Map<String, String> getNotifyParameter(HttpServletRequest request) throws Exception {
    InputStream inputStream = request.getInputStream();
    ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int length = 0;
    while ((length = inputStream.read(buffer)) != -1) {
        outSteam.write(buffer, 0, length);
    }
    outSteam.close();
    inputStream.close();

    // 获取微信调用我们notify_url的返回信息
    String resultXml = new String(outSteam.toByteArray(), "utf-8");
    Map<String, String> notifyMap = WXPayUtil.xmlToMap(resultXml);

    return notifyMap;
}
 
示例6
public static void main(String[] args) throws Exception {
     //解密
     String req_info="Ih5osM/5IbPfHouVrUmwebd1yAW2Gys91jv006W1237sSi3z022KxHafLIDMrQLYiBttTadgvy2cbx6DnmwDIQ52lPWfo6pAAHt7Q9DjBIpDRQ7JsbEBlomoQP2ZkdNHnWscVYuFEVlItaSlkSlcKLdB4UwMduqDYseFsUUthz6htPeBu987zXS6dKrgIbRwOxt5RfPmk1sf0oVB2yU3UH0Ly8SzBjmN1jrh4qAaUkfH6VkeMJcsZSGchQn2VresxJTbGH++JE1UsXUF3gyYpweyxBPtHoKdaggsIONR20UKNxJYPJLnEOnfQF/Ipmk8/QmTVRK7iqfVLC9EA1Auma0AlKBjZlYqynUlF3y+E2ZzgWMUlvDHZVWDbzp/TcE0q+Ukc7yQ3HBsibDR474SPlLTkCWz1iydXzkVcLqJKamsh76Liv1a0hzu0sI3qasMAfmwU6/q7/N6quq031toO1GxqkVaxBRK7e64gSOx9ArxxVFgZ7WN+JPq2OH/pTKH8ToxHA0rtxN5+aAgZGkXiIOUiHtp4mjpRxqe34WK7C7Nr0DQyOVwsXT2TTegSgWGm34aa//ZYxHedubv2iX+E7K222lptg9IqHlMXBbwKFtKtIcal61+8ciz+sB1FBpqHchC+3whTqWv5ZANiHBzaOhbIbA/mKX2XZ6Cy0iYh+bL/8Y/Hvz/UnMGzor+2anIUeBAGRQmseL4jY+Qic46WLuEhDcarCaO4JgJSAOC+VmsdrER9TRum26PFwTQwtNpxkrKCiO9Gv36Ood5D8hXnLHUH+4nbsek8ouxkCcFXq4Us0mipB3i5ksQpt23LiJm9Ahxyvptp9Q41SytS48NXiz3IxTOqDdknowedZwAtJ/fhBlwiOHD9N+pECXuNBKLaCZcatGycr0/DPELiCF+MIRQ6V60wzaZD74TKRFULd1ljNsoQIAbuGaT40WMDY6a28jBHQ/IXnD4gvSvfeumwQzp3Q9PiPyFtF6JxH7RBRj9/lmQuQozJIPZCaCNVTBfWQOdcFaBnPLN0ZNvzjA93g6jcIxHzkXHmiGfh98vq2E=";
 //    String req_info = "m4NnwrtY0jhpDgNp65H1V/0OWMtSoTYhhY89MHbflhmnaHq9ZKjx9ABq6Jpg4SccA876HVy7J9P85NpdvCMNGInZ4fANDRE+YfZe4HeF+bbFj6JETcEFPpE9YW+bTbC0D+gl/otScJfvB2QUK7+EeBGPHN1EWX9zbr2Gw6AUaORdFk3mGxV5dtjuwWQrv5juzkXDs33Z2dUMslO+i3j0cTDHqwS4hptx2j6h2HvzgzltFbjo7nysU+4rArqJvrGW/9r18e1St9XgG21NALqixfaSmqetOR4zLVL4/+z3CEz8cg5r+/4GUOTf3XFmLCZ/wEkRQhKRNVibG0NFfiG3KnqArMJ/dheQHCd7qL+XX/ZV6tj8RLMgL7R6hOiR03Ljyikdxq9M3K9CTYgf03pHJd3geXX1LgXrLxc1flL6NW+zD3ZayGYpr1WpLsSMG7z8W5j1pme6cRj3n2+CwSFnOnOkxaFuLKoJAJIqM3gbC0eN++vY73RKphlI4zZqg6o5s3MXI6ju1yoi/ZQ+XbTg2JttsdbU0aySernKwkt0rYMf0j/Mcvo2axgHbI3w/iTm141WxHUjkQ+ga2X1pOWdGifGhSmMP8oGaA/WD5MAsK1qXX0eFvUWS/PTauCSTWq5Cmr8loA/KL3jgvB0nyR4mfccB+tPy4Ny7kzOlr/VNeb0ULf96R0AWFWCtdt8AmujAP0DYiM5FSmYLI0XRhpSDjnEbBM8+isNE1GlAVR3NzzemwQORihScovpAktbRSN/d3N+NgTjSoVDiJvCOxCs3thX9qt9iwYbA+/X/gv8lza2FZyIzwkQxGRcYl8JWKpXzNW8EWUNVnSLdHvQttDeV3CvgP/x579RGd6whyFYS6AaI0qw7oTjCFh2EHS/VzGvFuv166ZlVIJ4MNvg79O9h63ZOSE1LzVqEsVh8fDCfM2GgJ9aUdl95Djgunit4yIZOdoigR3f/BEHKrYCEham11rYohaAXs4XAXWihsV3WD5j4G/P+txvjAwujvf4HDwzHgFsmSml013U2mUiy+v4zw==";

     //String req_info = "T87GAHG17TGAHG1TGHAHAHA1Y1CIOA9UGJH1GAHV871HAGAGQYQQPOOJMXNBCXBVNMNMAJAA";
     String B = AESUtil.decryptData(req_info,"2IBtBXdrqC3kCBs4gaceL7nl2nnFadQv");
//     System.out.println(B);
     Map<String,String> map = WXPayUtil.xmlToMap(B);

     System.out.println(map.get("refund_status"));


     //加密
     String str = "<root>"+
             "<out_refund_no><![CDATA[2531340110812300]]></out_refund_no>"+
             "<out_trade_no><![CDATA[2531340110812100]]></out_trade_no>"+
             "<refund_account><![CDATA[REFUND_SOURCE_RECHARGE_FUNDS]]></refund_account>"+
             "<refund_fee><![CDATA[1]]></refund_fee>"+
             "<refund_id><![CDATA[50000505542018011003064518841]]></refund_id>"+
             "<refund_recv_accout><![CDATA[支付用户零钱]]></refund_recv_accout>"+
             "<refund_request_source><![CDATA[API]]></refund_request_source>"+
             "<refund_status><![CDATA[SUCCESS]]></refund_status>"+
             "<settlement_refund_fee><![CDATA[1]]></settlement_refund_fee>"+
             "<settlement_total_fee><![CDATA[1]]></settlement_total_fee>"+
             "<success_time><![CDATA[2018-01-10 10:31:24]]></success_time>"+
             "<total_fee><![CDATA[1]]></total_fee>"+
             "<transaction_id><![CDATA[4200000052201801101409025381]]></transaction_id>"+
             "</root>";
  //   System.out.println(encryptData(str,"2IBtBXdrqC3kCBs4gaceL7nl2nnFadQv"));
 }
 
示例7
@Override
public AbstractResponse completePayment(PaymentNotifyRequest request) throws BizException {
	request.requestCheck();
	PaymentNotifyResponse response = new PaymentNotifyResponse();
	Map xmlMap = new HashMap();
	String xml = request.getXml();
	try {
		xmlMap = WXPayUtil.xmlToMap(xml);
	} catch (Exception e) {
		e.printStackTrace();
	}
	SortedMap<Object, Object> paraMap = new TreeMap<>();
	xmlMap.forEach(paraMap::put);
	//组装返回的结果的签名字符串
	String rsSign = paraMap.remove("sign").toString();
	String sign = WeChatBuildRequest.createSign(paraMap, wechatPaymentConfig.getWechatMchsecret());
	//验证签名
	if (rsSign.equals(sign)) {
		//SUCCESS、FAIL
		String resultCode = paraMap.get("return_code").toString();
		if ("SUCCESS".equals(resultCode)) {
			if ("SUCCESS".equals(paraMap.get("result_code"))) {
				//更新支付表
				Payment payment = new Payment();
				payment.setStatus(PayResultEnum.TRADE_SUCCESS.getCode());
				payment.setPaySuccessTime((UtilDate.parseStrToDate(UtilDate.simple,paraMap.get("time_end").toString(),new Date())));
				Example example = new Example(Payment.class);
				example.createCriteria().andEqualTo("orderId", paraMap.get("out_trade_no"));
				paymentMapper.updateByExampleSelective(payment, example);
				//更新订单表状态
				orderCoreService.updateOrder(1, paraMap.get("out_trade_no").toString());
				response.setResult(WeChatBuildRequest.setXML("SUCCESS", "OK"));
			}
		}
	} else {
		throw new BizException("微信返回结果签名验证失败");
	}
	return response;
}
 
示例8
/**
 * 获取沙箱环境验签秘钥API
 * <a href="https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=23_1">获取验签秘钥API文档</a>
 * @return
 * @throws Exception
 */
public Map<String, String> getSignKey() throws Exception {
    Map<String, String> reqData = new HashMap<>();
    reqData.put("appid", config.getAppID());
    reqData.put("mch_id", config.getMchID());
    reqData.put("nonce_str", WXPayUtil.generateNonceStr());
    String sign = WXPayUtil.generateSignature(reqData, config.getKey(), WXPayConstants.SignType.MD5);
    reqData.put("sign", sign);
    String responseXml = this.requestWithoutCert("https://api.mch.weixin.qq.com/sandboxnew/pay/getsignkey", reqData,
            config.getHttpConnectTimeoutMs(), config.getHttpReadTimeoutMs());

    Map<String, String> responseMap = WXPayUtil.xmlToMap(responseXml);

    return responseMap;
}
 
示例9
/**
 *
 * @param request
 * @return
 * @throws Exception
 */
@RequestMapping("/notify")
public void precreateNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
    Map<String, String> reqData = wxPayClient.getNotifyParameter(request);

    /**
     * {
     * transaction_id=4200000138201806180751222945,
     * nonce_str=aaaf3fe4d3aa44d8b245bc6c97bda7a8,
     * bank_type=CFT,
     * openid=xxx,
     * sign=821A5F42F5E180ED9EF3743499FBCF13,
     * fee_type=CNY,
     * mch_id=xxx,
     * cash_fee=1,
     * out_trade_no=186873223426017,
     * appid=xxx,
     * total_fee=1,
     * trade_type=NATIVE,
     * result_code=SUCCESS,
     * time_end=20180618131247,
     * is_subscribe=N,
     * return_code=SUCCESS
     * }
     */
    log.info(reqData.toString());

    // 特别提醒:商户系统对于支付结果通知的内容一定要做签名验证,并校验返回的订单金额是否与商户侧的订单金额一致,防止数据泄漏导致出现“假通知”,造成资金损失。
    boolean signatureValid = wxPay.isPayResultNotifySignatureValid(reqData);
    if (signatureValid) {
        /**
         * 注意:同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。
         * 推荐的做法是,当收到通知进行处理时,首先检查对应业务数据的状态,
         * 判断该通知是否已经处理过,如果没有处理过再进行处理,如果处理过直接返回结果成功。
         * 在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重入造成的数据混乱。
         */

        Map<String, String> responseMap = new HashMap<>(2);
        responseMap.put("return_code", "SUCCESS");
        responseMap.put("return_msg", "OK");
        String responseXml = WXPayUtil.mapToXml(responseMap);

        response.setContentType("text/xml");
        response.getWriter().write(responseXml);
        response.flushBuffer();
    }
}