微信支付

微信官方文档,地址如下: https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=1_1

导入微信官方的三个工具类WXPayUtil, WxPayContants,WxPayXmlUtil

//统一下单
public AppWxPay wxPay(AppWxPayInfo info) {
    String APPID = ""; //填写自己的
    String MCHID = ""; //填写自己的
    String APISECRET = ""; //填写自己的
    Map<String, String> map = new HashMap<>();
    String nonceStr = WXPayUtil.generateNonceStr();

    //小程序ID
    map.put("appid", APPID);
    //商户ID
    map.put("mch_id", MCHID);
    //随机字符串
    map.put("nonce_str", nonceStr);
    //商品描述
    map.put("body", info.getBody());
    //商户订单号
    map.put("out_trade_no", info.getOutTradeNo());
    //标价金额(单位为分)
    map.put("total_fee", "1");
    //终端IP
    map.put("spbill_create_ip", info.getSpbillCreateIp());
    //通知地址
    map.put("notify_url", "http://**/noticeUrl");//回调地址自己项目的接口
    //交易类型
    map.put("trade_type", "JSAPI");
    //用户标识
    map.put("openid", info.getOpenId());
    //交易起始时间
    Date startDate = new Date();
    map.put("time_start", DateUtils.dateFormat(startDate, "yyyyMMddHHmmss"));
    //交易结束时间
    Date endDate = DateUtils.dateAddMinutes(startDate, 5);
    map.put("time_expire", DateUtils.dateFormat(endDate, "yyyyMMddHHmmss"));
    //获取签名并生成xml字符串
    String formData = WXPayUtil.generateSignedXml(map, APISECRET);
    //这里调用下单的接口
    map = this.doPost("https://" + WXPayConstants.DOMAIN_API +         WXPayConstants.UNIFIEDORDER_URL_SUFFIX, formData);

    //app调用支付的参数
    AppWxPay wxPay = new AppWxPay();
    wxPay.setNonceStr(nonceStr);
    wxPay.setPrepayId(map.get("prepay_id"));
    wxPay.setTimeStamp(WXPayUtil.getCurrentTimestamp() + "");
    //生成二次签名
    String sign = this.getWxPaySign(wxPay);
    wxPay.setPaySign(sign);
    wxPay.setOutTradeNo(info.getOutTradeNo());
    return wxPay;
}


public String getWxPaySign(AppWxPay wxPay){
    Map<String, String> map = new HashMap<>();
    String APISECRET = "";//填写自己的
    String APPID = "";//填写自己的
    map.put("appId", APPID);
    map.put("nonceStr", wxPay.getNonceStr());
    map.put("package", "prepay_id=" + wxPay.getPrepayId());
    map.put("signType", "MD5");
    map.put("timeStamp", wxPay.getTimeStamp());
    String sign = WXPayUtil.generateSignature(map, APISECRET);    
    return sign;
}

public class AppWxPay {
    private String nonceStr;
    private String prepayId;
    private String timeStamp;
    private String paySign;
    private String outTradeNo;
    private String ip;
    //get set
}
    /**
     * 返回成功xml
     */
    private String resSuccessXml = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";

    /**
     * 返回失败xml
     */
    private String resFailXml = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文为空]]></return_msg></xml>";

    @ApiOperation( value = "支付回调" )
    @RequestMapping( value = "/noticeUrl", method = RequestMethod.POST )
    public void noticeUrl(HttpServletRequest request, HttpServletResponse response) {
        System.out.println("------------------进入微信通知地址-----------------");
        SysConfig config = configService.findSysConfig();
        DataInputStream in;
        String wxNotifyXml;
        //通知微信回调成功 否则微信将请求八次
        String resXml = resFailXml;
        try {
            in = new DataInputStream(request.getInputStream());
            byte[] dataOrigin = new byte[request.getContentLength()];
            in.readFully(dataOrigin); // 根据长度,将消息实体的内容读入字节数组dataOrigin中

            in.close(); // 关闭数据流
            wxNotifyXml = new String(dataOrigin); // 从字节数组中得到表示实体的字符串
            Map<String, String> map = WXPayUtil.xmlToMap(wxNotifyXml);
            System.out.println(map);

            //判断支付是否成功
            if (WXPayConstants.SUCCESS.equalsIgnoreCase(map.get("result_code"))) {
                //判断签名是否正确
                if (WXPayUtil.isSignatureValid(map, config.getWxApiSecret())) {
                    resXml = resSuccessXml;
                    //更改订单状态
                    String orderNum = map.get("out_trade_no");
                   
                } else {
                    WXPayUtil.getLogger().info("微信支付:判断签名错误");
                }
            } else {
                WXPayUtil.getLogger().info("微信支付:支付失败");
            }
        } catch (Exception e) {
            WXPayUtil.getLogger().error("微信支付:支付回调发布异常:", e);
        } finally {
            try {
                BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
                out.write(resXml.getBytes());
                out.flush();
                out.close();
            } catch (IOException e) {
                WXPayUtil.getLogger().error("微信支付:支付回调发布异常:out", e);
            }
        }
    }

 

以下是微信退款https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_4

 

// 退款 需要证书
public void refund(AppWxRefund refund) {
        Map<String, String> map = new HashMap<>();
        String APPID = "";//填写自己的
        String MCHID = "";//填写自己的
        String APISECRET = "";//填写自己的
        String nonceStr = WXPayUtil.generateNonceStr();
        Random rand = new Random();
        //退款单号
        int randNum = rand.nextInt(9999);
        String refundNo = "rf-" + System.currentTimeMillis() + randNum;
        map.put("appid", APPID);
        map.put("mch_id", MCHID);
        map.put("nonce_str", nonceStr);
        map.put("out_trade_no", refund.getOutTradeNo());
        map.put("out_refund_no", refundNo);
        //金额 自己设置 分为单位
        map.put("total_fee", "1");
        map.put("refund_fee", "1");
        map.put("notify_url", "http://wx.buluofangzhou.com/app/pay/refund");
        //获取签名并生成xml字符串
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        InputStream inputStream; // 这是自己的证书 商户名台配置得到一个证书文件
        keyStore.load(inputStream, password.toCharArray());
        SSLContext sslcontext = SSLContexts.custom()
                .loadKeyMaterial(keyStore, password.toCharArray())//这里也是写密码的
                .build();
        // Allow TLSv1 protocol only
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                sslcontext,
                new String[]{"TLSv1"},
                null,
                SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
        CloseableHttpClient httpclient = HttpClients.custom()
                .setSSLSocketFactory(sslsf)
                .build();
        String data = WXPayUtil.generateSignedXml(map, APISECRET);

        try {
            HttpPost httpost = new HttpPost("https://" + WXPayConstants.DOMAIN_API + WXPayConstants.REFUND_URL_SUFFIX); // 设置响应头信息
            httpost.addHeader("Connection", "keep-alive");
            httpost.addHeader("Accept", "*/*");
            httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
            httpost.addHeader("Host", "api.mch.weixin.qq.com");
            httpost.addHeader("X-Requested-With", "XMLHttpRequest");
            httpost.addHeader("Cache-Control", "max-age=0");
            httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
            httpost.setEntity(new StringEntity(data, "UTF-8"));
            CloseableHttpResponse response = httpclient.execute(httpost);
            try {
                HttpEntity entity = response.getEntity();
                String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
                EntityUtils.consume(entity);
            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }
    }




    微信退款需要AES 解密
    java中的AES 256算法遇到 Illegal key size or default parameters错的解决办法
    需要更换jre lib security 下的包local_policy.jar,US_export_policy.jar
    官网下载https://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html java8


    @ApiOperation( value = "微信退款回调接口" )
    @RequestMapping( value = "/refund", method = RequestMethod.POST )
    public void refund(HttpServletRequest request, HttpServletResponse response) {
        String resXml = "";
        InputStream inStream;
        try {
            inStream = request.getInputStream();
            ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inStream.read(buffer)) != -1) {
                outSteam.write(buffer, 0, len);
            }
            WXPayUtil.getLogger().info("refund:微信退款----start----");
            // 获取微信调用我们notify_url的返回信息
            String result = new String(outSteam.toByteArray(), "utf-8");
            WXPayUtil.getLogger().info("refund:微信退款----result----=" + result);
            // 关闭流
            outSteam.close();
            inStream.close();
            // xml转换为map
            Map<String, String> map = WXPayUtil.xmlToMap(result);
            if (WXPayConstants.SUCCESS.equalsIgnoreCase(map.get("return_code"))) {
                WXPayUtil.getLogger().info("refund:微信退款----返回成功");
                String req_info = map.get("req_info");
                String resultStr = AESUtil.decryptData(req_info);
                Map<String, String> aesMap = WXPayUtil.xmlToMap(resultStr);
                String refund_status = aesMap.get("refund_status");
                String orderNum = aesMap.get("out_trade_no");
                if (!WXPayConstants.SUCCESS.equals(refund_status)) {
                    resXml = resFailXml;
                } else {
                    resXml = resSuccessXml;
                    //do something
                }
            } else {
                WXPayUtil.getLogger().error("refund:支付失败,错误信息:" + map.get("return_msg"));
                resXml = resFailXml;
            }
        } catch (Exception e) {
            WXPayUtil.getLogger().error("refund:微信退款回调发布异常:", e);
        } finally {
            try {
                BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
                out.write(resXml.getBytes());
                out.flush();
                out.close();
            } catch (IOException e) {
                WXPayUtil.getLogger().error("refund:微信退款回调发布异常:out:", e);
            }
        }
    }

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值