All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hn.pay.wxpay.WxPayUtils Maven / Gradle / Ivy

There is a newer version: 1.0.18
Show newest version
package com.hn.pay.wxpay;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.hn.config.HnConfigUtils;
import com.hn.pay.exception.PayException;
import com.hn.pay.wxpay.domain.WxPayParam;
import com.hn.pay.wxpay.enums.TradeType;
import com.hn.pay.wxpay.utils.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 描述:
 * 微信支付工具类
 *
 * @author fei
 *  2019-08-21 11:29
 */
public class WxPayUtils {
    private static final Log log = LogFactory.get();

    /**
     * 配置前缀名
     */
    private static final String CONFIG_KEY = "pay.wx";
    /**
     * 应用id
     */
    private static String APPID = HnConfigUtils.getConfig(CONFIG_KEY + ".appid");
    /**
     * 商户号
     */
    private static String MCH_ID = HnConfigUtils.getConfig(CONFIG_KEY + ".mchId");
    /**
     * 商户密钥
     */
    private static String PARTNER_KEY = HnConfigUtils.getConfig(CONFIG_KEY + ".partnerKey");
    /**
     * 异步通知地址
     */
    private static String NOTIFY_URL = HnConfigUtils.getConfig(CONFIG_KEY + ".notifyUrl");

    static {
        WxPayApiConfig wxPayApiConfig = WxPayApiConfig.New()
                .setAppId(APPID)
                .setMchId(MCH_ID)
                .setPaternerKey(PARTNER_KEY)
                .setPayModel(WxPayApiConfig.PayModel.BUSINESSMODEL);
        WxPayApiConfigKit.setThreadLocalWxPayApiConfig(wxPayApiConfig);
    }

    /**
     * 微信H5 支付
     * 注意:必须再web页面中发起支付且域名已添加到开发配置中
     * @param request {@link HttpServletRequest}
     * @param response {@link HttpServletResponse}
     * @param wxPayParam {@link WxPayParam}
     */
    public static void wapPay(HttpServletRequest request, HttpServletResponse response,WxPayParam wxPayParam) {
        String notifyUrl = wxPayParam.getNotifyUrl();
        if(StrUtil.isBlank(notifyUrl)){
            notifyUrl = NOTIFY_URL;
        }

        Map params = WxPayApiConfigKit.getWxPayApiConfig()
                .setAttach(wxPayParam.getAttach())
                .setBody(wxPayParam.getBody())
                .setSpbillCreateIp(IpKit.getRealIp(request))
                .setTotalFee(wxPayParam.getTotalFee())
                .setTradeType(TradeType.MWEB)
                .setNotifyUrl(notifyUrl)
                .setOutTradeNo(wxPayParam.getOutTradeNo())
                .setSceneInfo(wxPayParam.getH5Info().toJson())
                .build();

        String xmlResult = WxPayApi.pushOrder(false, params);
        log.info(xmlResult);
        Map result = WxPayKit.xmlToMap(xmlResult);

        String return_code = result.get("return_code");
        String return_msg = result.get("return_msg");
        if (!WxPayKit.codeIsOk(return_code)) {
            log.error("return_code>" + return_code + " return_msg>" + return_msg);
            throw new PayException(return_msg);
        }
        String result_code = result.get("result_code");
        if (!WxPayKit.codeIsOk(result_code)) {
            log.error("result_code>" + result_code + " return_msg>" + return_msg);
            throw new PayException(return_msg);
        }
        // 以下字段在return_code 和result_code都为SUCCESS的时候有返回
        String prepay_id = result.get("prepay_id");
        String mweb_url = result.get("mweb_url");

        log.info("prepay_id:" + prepay_id + " mweb_url:" + mweb_url);
        try {
            response.sendRedirect(mweb_url);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * app支付
     * @param request {@link HttpServletRequest}
     * @param wxPayParam {@link WxPayParam}
     * @return app支付参数
     */
    public static String appPay(HttpServletRequest request,WxPayParam wxPayParam) {
        //不用设置授权目录域名
        //统一下单地址 https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1#

        String notifyUrl = wxPayParam.getNotifyUrl();
        if(StrUtil.isBlank(notifyUrl)){
            notifyUrl = NOTIFY_URL;
        }

        Map params = WxPayApiConfigKit.getWxPayApiConfig()
                .setAttach(wxPayParam.getAttach())
                .setBody(wxPayParam.getBody())
                .setSpbillCreateIp(IpKit.getRealIp(request))
                .setTotalFee(wxPayParam.getTotalFee())
                .setTradeType(TradeType.APP)
                .setNotifyUrl(notifyUrl)
                .setOutTradeNo(wxPayParam.getOutTradeNo())
                .build();

        String xmlResult = WxPayApi.pushOrder(false, params);
        log.info(xmlResult);
        Map resultMap = PaymentKit.xmlToMap(xmlResult);

        String returnCode = resultMap.get("return_code");
        String returnMsg = resultMap.get("return_msg");
        if (!PaymentKit.codeIsOK(returnCode)) {
            log.error("微信app支付失败return_code:{},return_msg:{}",returnCode,returnMsg);
            throw new PayException("微信app支付失败:"+returnMsg);
        }
        // 以下字段在return_code 和result_code都为SUCCESS的时候有返回

        String prepay_id = resultMap.get("prepay_id");
        //封装调起微信支付的参数 https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_12

        Map packageParams = new HashMap();
        packageParams.put("appid", WxPayApiConfigKit.getWxPayApiConfig().getAppId());
        packageParams.put("partnerid", WxPayApiConfigKit.getWxPayApiConfig().getMchId());
        packageParams.put("prepayid", prepay_id);
        packageParams.put("package", "Sign=WXPay");
        packageParams.put("noncestr", System.currentTimeMillis() + "");
        packageParams.put("timestamp", System.currentTimeMillis() / 1000 + "");
        String packageSign = PaymentKit.createSign(packageParams, WxPayApiConfigKit.getWxPayApiConfig().getPaternerKey());
        packageParams.put("sign", packageSign);

        String jsonStr = JSONUtil.toJsonStr(packageParams);
        log.info("微信app支付最新返回apk的参数:" + jsonStr);
        return jsonStr;
    }

    /**
     * 微信公众号支付
     * JSAPI支付
     *
     * @param request {@link HttpServletRequest}
     * @param wxPayParam {@link WxPayParam}
     * @param openId openId
     * @return 接口返回参数
     */
    public static String webPay(HttpServletRequest request,WxPayParam wxPayParam, String openId) {
        // openId,采用 网页授权获取 access_token API:SnsAccessTokenApi获取
//		String openId = (String) request.getSession().getAttribute("openId");

        String notifyUrl = wxPayParam.getNotifyUrl();
        if(StrUtil.isBlank(notifyUrl)){
            notifyUrl = NOTIFY_URL;
        }

        Map params = WxPayApiConfigKit.getWxPayApiConfig()
                .setAttach(wxPayParam.getAttach())
                .setBody(wxPayParam.getBody())
                .setOpenId(openId)
                .setSpbillCreateIp(IpKit.getRealIp(request))
                .setTotalFee(wxPayParam.getTotalFee())
                .setTradeType(TradeType.JSAPI)
                .setNotifyUrl(notifyUrl)
                .setOutTradeNo(wxPayParam.getOutTradeNo())
                .build();

        String xmlResult = WxPayApi.pushOrder(false, params);
        log.info(xmlResult);
        Map resultMap = PaymentKit.xmlToMap(xmlResult);

        String returnCode = resultMap.get("return_code");
        String returnMsg = resultMap.get("return_msg");
        if (!PaymentKit.codeIsOK(returnCode)) {
            log.error("微信公众号支付失败return_code:{},return_msg:{}",returnCode,returnMsg);
            throw new PayException("微信公众号支付失败:"+returnMsg);
        }
        // 以下字段在return_code 和result_code都为SUCCESS的时候有返回
        String prepay_id = resultMap.get("prepay_id");
        Map packageParams = PaymentKit.prepayIdCreateSign(prepay_id);
        return JSONUtil.toJsonStr(packageParams);
    }

    /**
     * 小程序支付
     * @param request {@link HttpServletRequest}
     * @param wxPayParam {@link WxPayParam}
     * @param openId openId
     * @return 小程序支付返回参数
     */
    public static String miniAppPay(HttpServletRequest request,WxPayParam wxPayParam,String openId) {
        String notifyUrl = wxPayParam.getNotifyUrl();
        if(StrUtil.isBlank(notifyUrl)){
            notifyUrl = NOTIFY_URL;
        }

        Map params = WxPayApiConfigKit.getWxPayApiConfig()
                .setAttach(wxPayParam.getAttach())
                .setBody(wxPayParam.getBody())
                .setOpenId(openId)
                .setSpbillCreateIp(IpKit.getRealIp(request))
                .setTotalFee(wxPayParam.getTotalFee())
                .setTradeType(TradeType.JSAPI)
                .setNotifyUrl(notifyUrl)
                .setOutTradeNo(wxPayParam.getOutTradeNo())
                .build();

        String xmlResult = WxPayApi.pushOrder(false, params);
        log.info(xmlResult);
        Map resultMap = PaymentKit.xmlToMap(xmlResult);

        String returnCode = resultMap.get("return_code");
        String returnMsg = resultMap.get("return_msg");
        if (!PaymentKit.codeIsOK(returnCode)) {
            log.error("微信小程序支付失败return_code:{},return_msg:{}",returnCode,returnMsg);
            throw new PayException("微信小程序支付失败:"+returnMsg);
        }
        String prepay_id = resultMap.get("prepay_id");
        Map packageParams = new HashMap();
        packageParams.put("appId", WxPayApiConfigKit.getWxPayApiConfig().getAppId());
        packageParams.put("timeStamp", System.currentTimeMillis() / 1000 + "");
        packageParams.put("nonceStr", System.currentTimeMillis() + "");
        packageParams.put("package", "prepay_id=" + prepay_id);
        packageParams.put("signType", "MD5");

        String packageSign = PaymentKit.createSign(packageParams, WxPayApiConfigKit.getWxPayApiConfig().getPaternerKey());
        packageParams.put("paySign", packageSign);

        String jsonStr = JSONUtil.toJsonStr(packageParams);
        log.info("小程序支付最新返回小程序支付的参数:" + jsonStr);
        return jsonStr;
    }

    /**
     * 回调通知
     * @param request {@link HttpServletRequest}
     * @return  success xml
     */
    public static String payNotify(HttpServletRequest request) {
        String xmlMsg = HttpKit.readData(request);
        System.out.println("支付通知=" + xmlMsg);
        Map params = PaymentKit.xmlToMap(xmlMsg);
//		String appid  = params.get("appid");
//		//商户号
//		String mch_id  = params.get("mch_id");
        String result_code = params.get("result_code");
//		String openId      = params.get("openid");
//		//交易类型
//		String trade_type      = params.get("trade_type");
//		//付款银行
//		String bank_type      = params.get("bank_type");
//		// 总金额
//		String total_fee     = params.get("total_fee");
//		//现金支付金额
//		String cash_fee     = params.get("cash_fee");
//		// 微信支付订单号
//		String transaction_id      = params.get("transaction_id");
//		// 商户订单号
//		String out_trade_no      = params.get("out_trade_no");
//		// 支付完成时间,格式为yyyyMMddHHmmss
//		String time_end      = params.get("time_end");

        /////////////////////////////以下是附加参数///////////////////////////////////

        String attach = params.get("attach");
//		String fee_type      = params.get("fee_type");
//		String is_subscribe      = params.get("is_subscribe");
//		String err_code      = params.get("err_code");
//		String err_code_des      = params.get("err_code_des");
        // 注意重复通知的情况,同一订单号可能收到多次通知,请注意一定先判断订单状态
        if (PaymentKit.verifyNotify(params, WxPayApiConfigKit.getWxPayApiConfig().getPaternerKey())) {
            if (("SUCCESS").equals(result_code)) {
                //更新订单信息
                log.warn("更新订单信息:" + attach);
                //发送通知等
                Map xml = new HashMap();
                xml.put("return_code", "SUCCESS");
                xml.put("return_msg", "OK");
                return PaymentKit.toXml(xml);
            }
        }

        return null;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy