微信支付之NATIVE支付(springboot)

349 阅读2分钟
  1. 业务介绍:根据产品金额生成二维码来进行微信扫码支付
  2. html页
<script type="text/javascript" src="//static.runoob.com/assets/qrcode/qrcode.min.js"></script>
<body>
<div  id="qrcode"></div>
<script>
    var qrcode = new QRCode(document.getElementById("qrcode"));
    qrcode.makeCode(data.data.code_url);
<script>
</body>
  1. Controller
@RestController
@CrossOrigin
@RequestMapping("/pay")
public class PayController {

    
    @PostMapping("/createPay")
    public BusiResult createPayOrder(@RequestBody PayVo payvo){
        // todo 生成订单号,获取价格,获取内容。。。


        //向微信发起调用生成预付链接
        Map res = WXPayPubUtil.createNative(payvo.getOrderId(),
                payvo.getFee(),
                payvo.getExpirTime());
        System.out.println(res);
        return BusiResult.success(res);
    }


    @PostMapping("/queryPayStatus")
    public BusiResult queryPayStatus(@RequestBody OrderTable payVo){
        //向微信发起调用生成预付链接
        Map res = WXPayPubUtil.queryPayStatus(payVo.getOrderNumber());
        System.out.println(res);
        return BusiResult.success(res);
    }

@RequestMapping("/wxNotify")
    public void notify(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 拿到微信回调信息
        InputStream inputStream = request.getInputStream();
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
        StringBuffer sb = new StringBuffer();
        // 将微信回调信息转为字符串
        String line;
        while ((line = in.readLine()) != null) {
            sb.append(line);
        }
        in.close();
        inputStream.close();
        String strXml = sb.toString();
        Map<String, String> map = WXPayUtil.xmlToMap(strXml);
        System.out.println(map);
        // 获取业务信息
        String outTradeNo = map.get("out_trade_no");
        String totalFee = map.get("total_fee");
        String appId = map.get("appid");
        String mchId = map.get("mch_id");
        String transactionId = map.get("transaction_id");
        String resultCode = map.get("result_code");
        String attach = map.get("attach");
        Boolean juge = WXPayPubUtil.callbackPay(response,strXml,map);
        // todo 根据不同业务类型处理不同业务(实际开发需要校验订单号和支付款)
        if (juge) {
        
        }
        
    }
}
  1. 实体类
@Data
public class PayVo {
    private String orderId;//订单编号
    private Integer fee; //金额
    private Integer expirTime; //失效时间
}
  1. 实现类
public class WXPayPubUtil {

    private static final String APP_ID = "" ; //OPEN_ID/APP_ID

    private static final String PARTNER = "" ; //商户号;
    
    //private static final String SUB_PARTNER = ""; //特约商户(没有可取消)

    private static final String PARTNER_KEY = ""; //IVIP2秘钥

    private static final String PAY_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";

    private static final String QRY_URL = "https://api.mch.weixin.qq.com/pay/orderquery";

    /**
     *
     * @param out_trade_no 订单号
     * @param total_fee   总金额
     * @param expireTimeMin  失效时间
     * @return
     */
    public static Map createNative(String out_trade_no, Integer total_fee ,String docunt, Integer expireTimeMin) {
        Map<String, String> param = new HashMap();
        param.put("appid", APP_ID);
        param.put("mch_id", PARTNER);
        //param.put("sub_mch_id",SUB_PARTNER);
        param.put("nonce_str", WXPayUtil.generateNonceStr());
        param.put("body", ""); //定义订单内容
        param.put("out_trade_no", out_trade_no);  //商户订单编号
        param.put("total_fee", String.valueOf(total_fee));  //总金额
        param.put("spbill_create_ip", "127.0.0.1");
        param.put("notify_url", "http://www.xxx.com:xxxx/pay/wxNotify"); //微信支付成功回调
        param.put("trade_type", "NATIVE");
        Date date = new Date();
        long time = date.getTime();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        String timeStart = simpleDateFormat.format(time);
        String timeEnd = simpleDateFormat.format(time + expireTimeMin * 60000);
        param.put("time_start", timeStart); //订单创建时间
        param.put("time_expire", timeEnd); //定义失效时间
        try {

            String xmlParam = WXPayUtil.generateSignedXml(param, PARTNER_KEY); //参数转换
            HttpUtil client = new HttpUtil(PAY_URL);

            client.setHttps(true);
            client.setXmlParam(xmlParam);
            client.post();
            String result = client.getContent();
            Map<String, String> resultMap = WXPayUtil.xmlToMap(result);
            System.out.println(resultMap);

            Map<String, String> map = new HashMap<>();
            map.put("code_url", resultMap.get("code_url"));
            map.put("total_fee", String.valueOf(total_fee));
            map.put("out_trade_no", out_trade_no);

            return map;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * @param out_trade_no  订单号
     * @return
     */
    public static Map queryPayStatus(String out_trade_no) {

        Map param = new HashMap();
        param.put("appid", APP_ID);
        param.put("mch_id", PARTNER);
        param.put("sub_mch_id",SUB_PARTNER);
        param.put("out_trade_no", out_trade_no);
        param.put("nonce_str", WXPayUtil.generateNonceStr());
        try {
            String xmlParam = WXPayUtil.generateSignedXml(param, PARTNER_KEY);
            HttpUtil client = new HttpUtil(QRY_URL);
            client.setHttps(true);
            client.setXmlParam(xmlParam);
            client.post();
            String result = client.getContent();
            Map<String, String> map = WXPayUtil.xmlToMap(result);
            // todo 写业务

            return map;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    

    /**
     * @param
     * @return
     */
    @SneakyThrows
    public static Boolean callbackPay (HttpServletResponse response,String strXml,Map<String, String> map){
        boolean juge = false;
        // 验签
        boolean signatureValid = WXPayUtil.isSignatureValid(strXml, PARTNER_KEY);

        PrintWriter writer = response.getWriter();
        // 判断签名是否正确
        if (signatureValid) {
            // 判断回调信息是否成功
            if ("SUCCESS".equals(map.get("result_code"))) {
                // 通知微信订单处理成功
                String noticeStr = setXML("SUCCESS", "");
                writer.write(noticeStr);
                writer.flush();
                //返回true
                juge = true;
            }
        } else {
            // 通知微信订单处理失败
            String noticeStr = setXML("FAIL", "");
            writer.write(noticeStr);
            writer.flush();
        }
        return juge;
    }

    private static String setXML(String return_code, String return_msg) {
        return "<xml><return_code><![CDATA[" + return_code + "]]></return_code><return_msg><![CDATA[" + return_msg + "]]></return_msg></xml>";
    }
}
  1. pom配置
<!--微信支付依赖包-->
<dependency>
    <groupId>com.github.wxpay</groupId>
    <artifactId>wxpay-sdk</artifactId>
    <version>0.0.3</version>
</dependency>