微信支付第三方sdk使用

1、引入依赖:(对于依赖冲突自行解决)

<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-pay</artifactId>
<!--<version>3.4.9.B</version>-->
<version>3.5.0</version>
<exclusions>
<exclusion>
<artifactId>httpclient</artifactId>
<groupId>org.apache.httpcomponents</groupId>
</exclusion>
<exclusion>
<artifactId>commons-lang3</artifactId>
<groupId>org.apache.commons</groupId>
</exclusion>
<exclusion>
<artifactId>commons-beanutils</artifactId>
<groupId>commons-beanutils</groupId>
</exclusion>
<exclusion>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
</exclusion>
</exclusions>
</dependency>

2、

package com.dhht.wechat.controller;

import com.dhht.wechat.VO.PayVO;import com.dhht.wechat.service.PayService;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;import javax.servlet.http.HttpServletRequest;

/* * @Author: sh * @Description: WxPayController * @Date: 11:06 2019/7/17 */

@RestController@RequestMapping("wechat/")public class WxPayController {

    @Resource    private PayService payService;

    /**     * 微信支付统一下单接口(H5)     * @param payVO     * @param request     * @return     */    @PostMapping(value = "pay",produces = "application/json;charset=UTF-8")    public String unifiedOrder(@RequestBody PayVO payVO, HttpServletRequest request){        return payService.unifiedOrder(payVO,request);    }

    /**     * 微信支付接收通知接口(供微信服务调用)     * @param xmlData     * @return     */    @PostMapping(value = "pay/notify",produces = "application/json;charset=UTF-8")    public synchronized String payNotify(@RequestBody String xmlData){

        return payService.payNotifyCallBack(xmlData);    }

    /**     * 退款结果通知接口     * @param xmlData     * @return     */    @PostMapping("/notify/refund")    public synchronized String parseRefundNotifyResult(@RequestBody String xmlData) {        return payService.parseRefundNotifyResult(xmlData);    }

}
package com.dhht.wechat.service;

import com.alibaba.fastjson.JSON;import com.dhht.wechat.VO.PayVO;import com.dhht.wechat.service.impservice.OrderRefundResultImplService;import com.dhht.wechat.service.impservice.SealOrderImplService;import com.dhht.wechat.service.impservice.SealOrderSealImplService;import com.dhht.wechat.util.ConstantUtil;import com.dhht.wechat.util.DateUtil;import com.dhht.wechat.wxpay.MyX509TrustManager;import com.dhht.wechat.wxpay.PayRespCodeMsg;import com.dhht.wechat.wxpay.PayResultVO;import com.dhht.wechat.wxpay.WechatPayConfigBean;import com.dhht.wechat.wxpay.config.WxPayProperties;import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;import com.github.binarywang.wxpay.bean.request.*;import com.github.binarywang.wxpay.bean.result.WxPayOrderCloseResult;import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult;import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;import com.github.binarywang.wxpay.service.WxPayService;import net.sf.json.JSONObject;import org.apache.commons.lang3.StringUtils;import org.jdom.Document;import org.jdom.Element;import org.jdom.input.SAXBuilder;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Service;

import javax.annotation.Resource;import javax.net.ssl.HttpsURLConnection;import javax.net.ssl.SSLContext;import javax.net.ssl.SSLSocketFactory;import javax.net.ssl.TrustManager;import javax.servlet.http.HttpServletRequest;import java.io.*;import java.math.BigDecimal;import java.net.ConnectException;import java.net.URL;import java.security.MessageDigest;import java.text.MessageFormat;import java.util.*;

/** * WxPayService */@Servicepublic class PayService {

    @Resource    private WechatPayConfigBean wechatPayConfigBean;

    @Resource    private WxPayProperties wxPayProperties;// 第三方

    @Resource    private SealOrderImplService sealOrderImplService;

    @Resource    private WxPayService wxService;// 第三方sdk

//    @Resource//    private OrderPayResultImplService orderPayResultImplService;

    @Resource    private OrderRefundResultImplService orderRefundResultImplService;

    @Value("${spbill_create_ip}")    private String SPBILL_CREATE_IP;

    @Value("${appSecret}")    private String appSecret;

    @Resource    WeiXinService weiXinService;

    @Resource    SealOrderSealImplService sealOrderSealImplService;

    /**     * 微信支付统一下单接口(H5)     *     * @param payVO     * @param request     * @return     */    public String unifiedOrder(PayVO payVO, HttpServletRequest request) {        try {

            String orderId = payVO.getOrderId();            String code = payVO.getCode();            if (StringUtils.isEmpty(orderId) || StringUtils.isEmpty(code)) {                PayResultVO payResultVO = new PayResultVO(-1, "NO", null);                return JSON.toJSONString(payResultVO);            }

            WxPayOrderQueryResult payOrderQueryResult = wechatOrderQuery(orderId);// wxService.queryOrder(null, orderId);// 查询订单状态            String payOrderQuery_return_code = payOrderQueryResult.getReturnCode();// SUCCESS/FAIL            if (ConstantUtil.PAY_RETURN_CODE_NO.equals(payOrderQuery_return_code)) {// 通信失败:FAIL                PayResultVO queryPayResultVO = new PayResultVO(-1, payOrderQueryResult.getReturnMsg(), null);                return JSON.toJSONString(queryPayResultVO);// 订单查询接口通信失败,直接返回            }

            // 订单查询通信成功:SUCCESS

            // 若业务成功

            /**             * trade_state状态如下:             * SUCCESS—支付成功             * REFUND—转入退款             * NOTPAY—未支付             * CLOSED—已关闭             * REVOKED—已撤销(刷卡支付)             * USERPAYING--用户支付中             * PAYERROR--支付失败(其他原因,如银行返回失败)商户订单支付失败需要生成新单号重新发起支付,要对原订单号调用关单,避免重复支付             */            String trade_state = payOrderQueryResult.getTradeState();            if (!ConstantUtil.PAY_TRADE_STATE_NOTPAY.equals(trade_state) && null != trade_state) {// 非未支付状态下(可以为null-代表还未生成订单,故需过滤掉)                PayResultVO tradePayResultVO = new PayResultVO(-1, ConstantUtil.PAY_STATUS_MAP.get(trade_state), null);                return JSON.toJSONString(tradePayResultVO);            }            // 以下转入订单未支付处理或还没有生成订单(trade_state==null)的处理逻辑

            //String openUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="+wxPayProperties.getAppId()+"&secret="+appSecret+"&code="+code+"&grant_type=authorization_code";            String openId = weiXinService.getOpenId(code);//SendMsgUtil.httpRequest(openUrl,"GET","{}").getString("openid");// 获取openid            // 更新订单openId--2019-09-17            Map<String, Object> paMap = new HashMap<>();            paMap.put("orderId", orderId);            paMap.put("userOpenId", openId);            sealOrderImplService.updateOrderInfo(paMap);            // 获取本系统印章订单信息            Map<String, Object> orderDetails = sealOrderImplService.getOrderMapById(orderId);            String SUB_MCH_ID = (String) orderDetails.get("SUB_MCH_ID");// 营业网点扩展信息表中的子商户号-20190910            if (StringUtils.isEmpty(SUB_MCH_ID)) {// 若无配置子商户号退出                PayResultVO payResultVO = new PayResultVO(-1, "NO-SUB_MCH_ID", null);                return JSON.toJSONString(payResultVO);            }            String siteName = (String) orderDetails.get("siteName");// 营业网点名称(刻章店名称)            float orderPrice = ((BigDecimal) orderDetails.get("ORDER_AMOUNT")).floatValue();// 订单总金额            String bodyName = siteName + "-" + ConstantUtil.ADVANCE_PAY_GOODS_NAME;// 商品名称严格按照规范-公众号支付-例如(商家名称-销售商品类目)            // 设置统一下单请求参数            // 请求对象,注意一些参数如appid、mchid等不用设置,方法内会自动从配置对象中获取到(前提是对应配置中已经设置)            WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();            orderRequest.setAppid(wxPayProperties.getAppId());// 服务商appid            orderRequest.setMchId(wxPayProperties.getMchId());// 商户号            orderRequest.setSubMchId(SUB_MCH_ID);// 子商户号            String nonceStr = DateUtil.get32UUIDMilli();            orderRequest.setNonceStr(nonceStr);// 随机串,32位以内!            orderRequest.setSignType(wxPayProperties.getSignType());// 签名类型            orderRequest.setBody(bodyName);            orderRequest.setOutTradeNo(orderId);            orderRequest.setTotalFee(BaseWxPayRequest.yuanToFen(orderPrice + ""/*order.getTotalFee()*/));//元转成分            orderRequest.setSpbillCreateIp(SPBILL_CREATE_IP);// 终端IP            orderRequest.setNotifyUrl(wxPayProperties.getNotifyUrl());// 支付结果异步回调地址            orderRequest.setTradeType(wxPayProperties.getTradeType());// 交易类型            orderRequest.setOpenid(openId);// 设置openid            WxPayMpOrderResult wxPayUnifiedOrderResult = wxService.createOrder(orderRequest);// 统一下单接口调用结果

            String appId = wxPayUnifiedOrderResult.getAppId();            String timeStamp = create_timestamp();            String package_ = wxPayUnifiedOrderResult.getPackageValue();// ConstantUtil.PACKAGE_SUFFIX + wxPayUnifiedOrderResult.getPackageValue();            String paySign = wxPayUnifiedOrderResult.getPaySign();            Map<String, Object> resultMapData = new HashMap<>();            resultMapData.put("appId", appId);            resultMapData.put("timeStamp", timeStamp);            resultMapData.put("package", package_);            resultMapData.put("paySign", paySign);            resultMapData.put("nonceStr", wxPayUnifiedOrderResult.getNonceStr());            resultMapData.put("signType", wxPayProperties.getSignType());            PayResultVO paySucessResultVO = new PayResultVO(0, "OK", resultMapData);            return JSON.toJSONString(paySucessResultVO);        } catch (Exception e) {            Map map = new HashMap();            map.put("data", e.getMessage());            PayResultVO payResultVO = new PayResultVO(-1, "NO", map);            return JSON.toJSONString(payResultVO);        }    }

    /**     * 支付回调     *     * @param xmlData     * @return     */    public synchronized String payNotifyCallBack(String xmlData) {        try {

            WxPayOrderNotifyResult wxPayOrderNotifyResult = wxService.parseOrderNotifyResult(xmlData);// 解析xml字符串            String return_code = wxPayOrderNotifyResult.getReturnCode();// SUCCESS/FAIL

            if (ConstantUtil.PAY_RETURN_CODE_NO.equals(return_code)) {// 支付通信失败                return WxPayNotifyResponse.fail("FAIL");            }            // 以下通信成功操作            String out_trade_no = wxPayOrderNotifyResult.getOutTradeNo();// 商户系统内部订单号(即本系统印章订单号)            // 内部订单支付情况            Map<String, Object> orderDetails = sealOrderImplService.getOrderMapById(out_trade_no);            if (null != orderDetails) {                String paySta = (Integer) orderDetails.get("PAY_STATUS") + "";                if ((ConstantUtil.ORDER_PAYSTATUS_1_ + "").equals(paySta)) {// 已支付直接返回                    return WxPayNotifyResponse.success("OK");                }            }

            if (ConstantUtil.PAY_RETURN_CODE_OK.equals(return_code)) {// 支付接口通信成功                String result_code = wxPayOrderNotifyResult.getResultCode();// SUCCESS/FAIL 是否真实支付成功

                if (ConstantUtil.PAY_RETURN_CODE_OK.equals(result_code)) {// 支付成功                    // 检查本库是否已经插入支付成功记录                    // orderPayResultImplService.deleteByOrderId(out_trade_no);                    //orderPayResultImplService.add(wxPayOrderNotifyResult);                    //orderPayResultImplService.insertSelective(wxPayOrderNotifyResult);                    sealOrderImplService.updateOrderPaySta(out_trade_no, ConstantUtil.ORDER_PAYSTATUS_1_);// 更新支付状态                    // 推送微信内容-2019-09-18                    sealOrderSealImplService.sendWXMsgToSite(out_trade_no);

                }                if (ConstantUtil.PAY_RETURN_CODE_NO.equals(result_code)) {// 支付失败                    closePayOrder(out_trade_no);// 支付失败的话,需要关闭订单,才能重新支付                    sealOrderImplService.upOrderRelation(out_trade_no);// 更新该订单的id,主要用于重新支付                    sealOrderImplService.updateOrderPaySta(out_trade_no, ConstantUtil.ORDER_PAYSTATUS_2_);// 更新支付状态                }                return WxPayNotifyResponse.success("OK");            } else {// 支付结果通信失败                return WxPayNotifyResponse.fail("FAIL");            }

        } catch (Exception e) {            return WxPayNotifyResponse.fail("FAIL");        }    }

    /**     * 查询订单状态     *     * @param orderId     * @return     */    public WxPayOrderQueryResult wechatOrderQuery(String orderId) {        try {            if (StringUtils.isEmpty(orderId)) {                return null;            }            Map<String, Object> orderDetails = sealOrderImplService.getOrderMapById(orderId);// 获取本系统订单的相关信息            String SUB_MCH_ID = (String) orderDetails.get("SUB_MCH_ID");// 营业网点扩展信息表中的子商户号-20190910            WxPayOrderQueryRequest wxPayOrderQueryRequest = new WxPayOrderQueryRequest();            wxPayOrderQueryRequest.setAppid(wxPayProperties.getAppId());            wxPayOrderQueryRequest.setMchId(wxPayProperties.getMchId());            wxPayOrderQueryRequest.setSubMchId(SUB_MCH_ID);// 子商户好最终通过orderId从本系统获取            wxPayOrderQueryRequest.setOutTradeNo(orderId);// 微信内部订单号与本系统订单号二选一            wxPayOrderQueryRequest.setNonceStr(DateUtil.get32UUIDMilli());            wxPayOrderQueryRequest.setSignType(wxPayProperties.getSignType());            WxPayOrderQueryResult wxPayOrderQueryResult = wxService.queryOrder(wxPayOrderQueryRequest);            return wxPayOrderQueryResult;        } catch (Exception e) {            WxPayOrderQueryResult wxPayOrderQueryResult = new WxPayOrderQueryResult();            wxPayOrderQueryResult.setReturnCode(ConstantUtil.PAY_RETURN_CODE_OK);            wxPayOrderQueryResult.setResultCode(ConstantUtil.PAY_RETURN_CODE_OK);            wxPayOrderQueryResult.setTradeState(null);            return wxPayOrderQueryResult;        }    }

    /**     * 关闭订单(关闭订单之后,重新提交支付需要更新订单号!)     *     * @param orderId     * @return     */    public WxPayOrderCloseResult closePayOrder(String orderId) {        if (StringUtils.isEmpty(orderId)) {            return null;        }        try {            Map<String, Object> orderDetails = sealOrderImplService.getOrderMapById(orderId);// 获取本系统订单的相关信息            String SUB_MCH_ID = (String) orderDetails.get("SUB_MCH_ID");// 营业网点扩展信息表中的子商户号-20190910            WxPayOrderCloseRequest wxPayOrderCloseRequest = new WxPayOrderCloseRequest();            wxPayOrderCloseRequest.setAppid(wxPayProperties.getAppId());            wxPayOrderCloseRequest.setMchId(wxPayProperties.getMchId());            wxPayOrderCloseRequest.setSubMchId(SUB_MCH_ID);// 从本系统获取通过orderDetails            wxPayOrderCloseRequest.setOutTradeNo(orderId);            wxPayOrderCloseRequest.setNonceStr(DateUtil.get32UUIDMilli());            wxPayOrderCloseRequest.setSignType(wxPayProperties.getSignType());            WxPayOrderCloseResult wxPayOrderCloseResult = wxService.closeOrder(wxPayOrderCloseRequest);            return wxPayOrderCloseResult;        } catch (Exception e) {            return null;        }    }

    /**     * 订单退款(接口请求并非退款结果)     *     * @param orderId     * @return     */    public PayResultVO refundPayOrder(String orderId) {        try {            if (StringUtils.isEmpty(orderId)) {                return null;            }            Map<String, Object> orderDetails = sealOrderImplService.getOrderMapById(orderId);// 获取本系统订单的相关信息

            // 查询微信支付订单信息            WxPayOrderQueryResult wxPayOrderQueryResult = wechatOrderQuery(orderId);            String order_return_code = wxPayOrderQueryResult.getReturnCode();// 订单查询网络状态            if (ConstantUtil.PREPAYID_RETURN_CODE_NO.equals(order_return_code)) {                PayResultVO returnPayResultVO = new PayResultVO(-1, ConstantUtil.PAY_NETWORK_EXCEP, null);                return returnPayResultVO;            }            String order_result_code = wxPayOrderQueryResult.getResultCode();// 订单查询业务状态            if (ConstantUtil.PREPAYID_RETURN_CODE_NO.equals(order_result_code)) {                PayResultVO resultPayResultVO = new PayResultVO(-1, ConstantUtil.REFUND_FAIL_MSG, null);                return resultPayResultVO;            }            String order_trade_state = wxPayOrderQueryResult.getTradeState();// 订单状态(已支付、未支付等等)            if (!ConstantUtil.PAY_TRADE_STATE_SUCCESS.equals(order_trade_state)) {// 未支付成功,直接返回                PayResultVO tradePayResultVO = new PayResultVO(-1, ConstantUtil.REFUND_FAIL_MSG, null);            }            // 以下为订单已支付后续操作(只有order_trade_state为SUCCESS可获取如下参数)            String transaction_id = wxPayOrderQueryResult.getTransactionId();// 微信内部支付订单号            int total_fee = wxPayOrderQueryResult.getTotalFee();// 订单总金额            String sub_mch_id = wxPayOrderQueryResult.getSubMchId();// 订单子商户号            String out_trade_no = wxPayOrderQueryResult.getOutTradeNo();

            WxPayRefundRequest wxPayRefundRequest = new WxPayRefundRequest();            wxPayRefundRequest.setAppid(wxPayProperties.getAppId());            wxPayRefundRequest.setMchId(wxPayProperties.getMchId());            wxPayRefundRequest.setSubMchId(sub_mch_id);// 从本系统通过orderId获取            wxPayRefundRequest.setNonceStr(DateUtil.get32UUIDMilli());            wxPayRefundRequest.setSignType(wxPayProperties.getSignType());            wxPayRefundRequest.setTransactionId(transaction_id);            wxPayRefundRequest.setOutTradeNo(out_trade_no);// 商户内部订单号            String refundNo = DateUtil.get32UUIDMilli();// 生成商户内部退款单号            wxPayRefundRequest.setOutRefundNo(refundNo);// 商户内部退款单号!!!            wxPayRefundRequest.setTotalFee(total_fee);            wxPayRefundRequest.setRefundFee(total_fee);// !!!申请退款金额????            wxPayRefundRequest.setNotifyUrl(wxPayProperties.getRefundNotifyUrl());// 退款结果通知url            WxPayRefundResult wxPayRefundResult = wxService.refund(wxPayRefundRequest);// 订单退款接口            String refund_return_code = wxPayRefundResult.getReturnCode();// 退款接口网络状态            if (ConstantUtil.PREPAYID_RETURN_CODE_NO.equals(refund_return_code)) {                PayResultVO refundExPayVO = new PayResultVO(-1, ConstantUtil.REFUND_FAIL_MSG, null);                return refundExPayVO;            }            String refund_result_code = wxPayRefundResult.getResultCode();// 退款接口结果状态            if (ConstantUtil.PREPAYID_RETURN_CODE_NO.equals(refund_result_code)) {                PayResultVO refundFailPayVO = new PayResultVO(-1, ConstantUtil.REFUND_FAIL_MSG, null);                return refundFailPayVO;            }

            // 以下为退款成功操作            PayResultVO refundSuceesResultVO = new PayResultVO(0, "OK", wxPayRefundResult);            Map<String, Object> paramMap = new HashMap<>();            paramMap.put("refundNo", refundNo);// 内部退款单号            sealOrderImplService.updateOrderInfo(paramMap);            return refundSuceesResultVO;        } catch (Exception e) {            return null;        }    }

    /**     * 退款回调通知地址     *     * @param xmlData     * @return     */    public synchronized String parseRefundNotifyResult(String xmlData) {        try {            WxPayRefundNotifyResult result = wxService.parseRefundNotifyResult(xmlData);            String return_code = result.getReturnCode();            if (ConstantUtil.PREPAYID_RETURN_CODE_NO.equals(return_code)) {// 通信失败                return WxPayNotifyResponse.fail("FAIL");            }            // 以下为通信成功返回的字段信息            WxPayRefundNotifyResult.ReqInfo reqInfo = result.getReqInfo();// 获取结果中的加密信息

            /**             * SUCCESS-退款成功             * CHANGE-退款异常             * REFUNDCLOSE—退款关闭             */            String refund_status = reqInfo.getRefundStatus();// 退款状态

            if (ConstantUtil.REFUND_STATUS_0.equals(refund_status)) {// 成功                refund_status = ConstantUtil.ORDER_PAYSTATUS_3_ + "";            }            if (ConstantUtil.REFUND_STATUS_1.equals(refund_status)) {// 异常                refund_status = ConstantUtil.ORDER_PAYSTATUS_4_ + "";            }            if (ConstantUtil.REFUND_STATUS_2.equals(refund_status)) {// 关闭                refund_status = ConstantUtil.ORDER_PAYSTATUS_4_ + "";            }            String out_trade_no = reqInfo.getOutTradeNo();// 内部订单号            Map<String, Object> paramMap = new HashMap<>();            paramMap.put("refundNo", out_trade_no);// 内部退款单号            paramMap.put("payStatus", refund_status);// 更新支付状态            sealOrderImplService.updateOrderInfo(paramMap);            orderRefundResultImplService.deleteByOrderdId(out_trade_no);// 删除订单            orderRefundResultImplService.addRefundInfo(result);// 添加退款 记录            return WxPayNotifyResponse.success("OK");        } catch (Exception e) {            return WxPayNotifyResponse.fail("FAIL");        }    }

    //******************************************************************************************************************

    /**     * 获取微信签名信息(预支付订单信息)     *     * @param payVO     * @param request     * @return     */    public synchronized String getWxPaySign(PayVO payVO, HttpServletRequest request) {        try {            if (null == payVO) {                return null;            }            String orderId = payVO.getOrderId();            String wxCode = payVO.getCode();            if (StringUtils.isEmpty(orderId) || StringUtils.isEmpty(wxCode)) {                return null;            }            // 获取openId            JSONObject openIdJson = getAccess_tokenByCode(wxCode);            int errcode_openId = openIdJson.getInt("errcode");            if (errcode_openId != 0) {// 调用获取openId接口不成功                PayRespCodeMsg payRespCodeMsg = new PayRespCodeMsg(errcode_openId, openIdJson.getString("errmsg"));                PayResultVO payResultVO = new PayResultVO(payRespCodeMsg, null);                return JSON.toJSONString(payResultVO);            }            String openid = openIdJson.getString("openid");// 用户唯一标识            String session_key = openIdJson.getString("session_key");// 会话秘钥

            // 获取本地订单相关信息            Map<String, Object> orderDetails = sealOrderImplService.getOrderMapById(orderId);            String siteName = (String) orderDetails.get("siteName");// 营业网点名称(刻章店名称)            int orderPrice = ((BigDecimal) orderDetails.get("ORDER_AMOUNT")).intValue() * 100;            String bodyName = siteName + "-" + ConstantUtil.ADVANCE_PAY_GOODS_NAME;// 商品名称严格按照规范-公众号支付-例如(商家名称-销售商品类目)            String orderno = orderId;// "1234567890";            Integer total_fee = orderPrice;// "8.88";// 订单总费用,不能有小数点,以分为单位            String nonce_str = create_nonce_str();            String timestamp = create_timestamp();

            // 获取预支付订单prepayId            SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();            String prepayIdResult = getPrepayId(request, bodyName, orderno, total_fee, openid);// 获取预支付订单id方法,返回的xml字符串结果            Map<String, String> prepayIdResultMap = doXMLParse(prepayIdResult);// xml字符串转map            String prepayId_return_code = prepayIdResultMap.get("return_code");// SUCCESS/FAIL,此字段是通信标识,非交易标识,交易是否成功需要查看result_code来判断            if (ConstantUtil.PREPAYID_RETURN_CODE_NO.equals(prepayId_return_code)) {// 获取prepayId接口通信异常                PayRespCodeMsg preRespCodeMsg = new PayRespCodeMsg(-1, ConstantUtil.WECHAT_INTERFACE_EX_MSG);//                PayResultVO preResultVO = new PayResultVO(preRespCodeMsg, null);                return JSON.toJSONString(preResultVO);            }            // 获取prepayId的接口调用通信成功后            String prepayId_result_code = prepayIdResultMap.get("result_code");// SUCCESS/FAIL,业务结果            if (ConstantUtil.PAY_RETURN_CODE_NO.equals(prepayId_result_code)) {// 获取prepayId失败                PayRespCodeMsg preNo = new PayRespCodeMsg(-1, "NO");                PayResultVO preNoVO = new PayResultVO(preNo, null);                return JSON.toJSONString(preNoVO);            }

            // 微信预支付接口通信成功且业务结果成功            // 重新生成签名            parameters.put("appId", wechatPayConfigBean.getAppId());            parameters.put("timeStamp", timestamp);            parameters.put("nonceStr", nonce_str);            parameters.put("package", "prepay_id=" + prepayIdResultMap.get("prepay_id"));            parameters.put("signType", "MD5");            String sign = createSign("UTF-8", parameters);            parameters.put("prepay_id", "prepay_id=" + prepayIdResultMap.get("prepay_id"));            parameters.put("paySign", sign);

            PayResultVO okResult = new PayResultVO(0, "OK", parameters);            return JSON.toJSONString(okResult);

        } catch (Exception e) {            PayResultVO resultVO = new PayResultVO(-1, "FALSE", null);            return JSON.toJSONString(resultVO);        }    }

    public SortedMap<Object, Object> WapSignSignatureAction (HttpServletRequest request)throws Exception {        SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();        String code = request.getParameter("code");        System.out.println("code-------------" + code);        // code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。        // 通过code换取网页授权access_token        Map<String, String> data = getAccess_tokenByCode(code);        String openid = data.get("openid");        String tName = "名称";        String orderno = "1234567890";        String total_fee = "8.88";        String nonce_str = create_nonce_str();        String timestamp = create_timestamp();        // 获取prepayId        try {            String result = getPrepayId(request, tName, orderno, Integer.parseInt(total_fee), openid);            Map<String, String> map = doXMLParse(result);            // 重新生成签名            parameters.put("appId", wechatPayConfigBean.getAppId()            );            parameters.put("timeStamp", timestamp);            parameters.put("nonceStr", nonce_str);            parameters.put("package", "prepay_id=" + map.get("prepay_id"));            parameters.put("signType", "MD5");            String sign = createSign("UTF-8", parameters);            parameters.put("prepay_id", "prepay_id=" + map.get("prepay_id"));            parameters.put("paySign", sign);        } catch (Exception e) {            e.printStackTrace();        }        return parameters;    }

    /**     * 根据用户授权code获取access_token     */    private JSONObject getAccess_tokenByCode(String code) {        Map<String, String> data = new HashMap<String, String>();        //String requestUrlMessageFormat = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code";        String requestUrlMessageFormat = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code";        String requestUrl = MessageFormat.format(requestUrlMessageFormat, wxPayProperties.getAppId()

                , appSecret

                , code);        String requestMethod = "GET";        String outputStr = "";        JSONObject json = httpRequest(requestUrl, requestMethod, outputStr);        //String access_token = (String) json.get("access_token");// 此参数最新接口文档没发现的        String openid = (String) json.get("openid");// 用户唯一标识        String session_key = json.getString("session_key");// 会话秘钥        String unionid = json.getString("unionid");// 用户在开放平台的唯一标识符,在满足 UnionID 下发条件的情况下会返回        int errcode = json.getInt("errcode");// 错误码        String errmsg = json.getString("errmsg");// 错误信息        //data.put("access_token", access_token);        data.put("openid", openid);        data.put("session_key", session_key);        data.put("unionid", unionid);        data.put("errcode", errcode + "");        data.put("errmsg", errmsg);        return json;    }

    /**     * 发起https请求并获取结果     *     * @param requestUrl    请求地址     * @param requestMethod 请求方式(GET、POST)     * @param outputStr     提交的数据     * @return JSONObject(通过JSONObject.get ( key)的方式获取json对象的属性值)     */    public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {        JSONObject jsonObject = null;        StringBuffer buffer = new StringBuffer();        try {            // 创建SSLContext对象,并使用我们指定的信任管理器初始化            TrustManager[] tm = {new MyX509TrustManager()};            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");            sslContext.init(null, tm, new java.security.SecureRandom());            // 从上述SSLContext对象中得到SSLSocketFactory对象            SSLSocketFactory ssf = sslContext.getSocketFactory();

            URL url = new URL(requestUrl);            HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();            httpUrlConn.setSSLSocketFactory(ssf);

            httpUrlConn.setDoOutput(true);            httpUrlConn.setDoInput(true);            httpUrlConn.setUseCaches(false);            // 设置请求方式(GET/POST)            httpUrlConn.setRequestMethod(requestMethod);

            if ("GET".equalsIgnoreCase(requestMethod))                httpUrlConn.connect();

            // 当有数据需要提交时            if (null != outputStr) {                OutputStream outputStream = httpUrlConn.getOutputStream();                // 注意编码格式,防止中文乱码                outputStream.write(outputStr.getBytes("UTF-8"));                outputStream.close();            }

            // 将返回的输入流转换成字符串            InputStream inputStream = httpUrlConn.getInputStream();            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

            String str = null;            while ((str = bufferedReader.readLine()) != null) {                buffer.append(str);            }            bufferedReader.close();            inputStreamReader.close();            // 释放资源            inputStream.close();            inputStream = null;            httpUrlConn.disconnect();            jsonObject = JSONObject.fromObject(buffer.toString());        } catch (ConnectException ce) {            System.err.println("Weixin server connection timed out.");        } catch (Exception e) {            System.err.println("https request error");        }        return jsonObject;    }

    /**     * 获取预支付订单id     *     * @param request     * @param name     * @param orderno     * @param total_fee     * @param openid     * @return     * @throws Exception     */    public String getPrepayId(HttpServletRequest request, String name, String orderno, Integer total_fee,                              String openid) throws Exception {        SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();        parameters.put("appid", wechatPayConfigBean.getAppId()

        );// 服务商id        parameters.put("mch_id", wechatPayConfigBean.getMchId()

        );// 商户号        parameters.put("nonce_str", CreateNoncestr());// 随机字符串        parameters.put("body", name);// 商品描述        parameters.put("out_trade_no", orderno);// 商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|*且在同一个商户号下唯一        parameters.put("total_fee", total_fee);// 支付金额单位:分        parameters.put("spbill_create_ip", getIp2(request));// 支持IPV4和IPV6两种格式的IP地址。调用微信支付API的机器IP        parameters.put("notify_url", wechatPayConfigBean.getPayResultNotifyUrl());// 接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数        parameters.put("trade_type", "JSAPI");// 交易类型,小程序取值如下:JSAPI,详细说明见        parameters.put("openid", openid);// 商户标识        parameters.put("time_expire", DateUtil.getTimeStamp());// (非必填)交易结束时间,需要动态传入,格式为yyyyMMddHHmmss-20190719114936        String sign = createSign("UTF-8", parameters);        parameters.put("sign", sign);        String requestXML = getRequestXml(parameters);        // 调用统一下单接口        String result = httpsRequest("https://api.mch.weixin.qq.com/pay/unifiedorder", "POST", requestXML);        System.out.println(result);        return result;    }

    public static String CreateNoncestr() {        String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";        String res = "";        for (int i = 0; i < 16; i++) {            Random rd = new Random();            res += chars.charAt(rd.nextInt(chars.length() - 1));        }        return res;    }

    public static String getIp2(HttpServletRequest request) {        String ip = request.getHeader("X-Forwarded-For");        if (!org.apache.commons.lang3.StringUtils.isEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {            // 多次反向代理后会有多个ip值,第一个ip才是真实ip            int index = ip.indexOf(",");            if (index != -1) {                return ip.substring(0, index);            } else {                return ip;            }        }        ip = request.getHeader("X-Real-IP");        if (!org.apache.commons.lang3.StringUtils.isEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {            return ip;        }        return request.getRemoteAddr();    }

    @SuppressWarnings("rawtypes")    public String createSign(String characterEncoding, SortedMap<Object, Object> parameters) {        StringBuffer sb = new StringBuffer();        Set es = parameters.entrySet();        Iterator it = es.iterator();        while (it.hasNext()) {            Map.Entry entry = (Map.Entry) it.next();            String k = (String) entry.getKey();            Object v = entry.getValue();            if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {                sb.append(k + "=" + v + "&");            }        }        sb.append("key=" + wechatPayConfigBean.getApiKey()        );        String sign = MD5Encode(sb.toString(), characterEncoding).toUpperCase();        return sign;    }

    public static String MD5Encode(String origin, String charsetname) {        String resultString = null;        try {            resultString = new String(origin);            MessageDigest md = MessageDigest.getInstance("MD5");            if (charsetname == null || "".equals(charsetname))                resultString = byteArrayToHexString(md.digest(resultString.getBytes()));            else                resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));        } catch (Exception exception) {        }        return resultString;    }

    private static String byteArrayToHexString(byte b[]) {        StringBuffer resultSb = new StringBuffer();        for (int i = 0; i < b.length; i++)            resultSb.append(byteToHexString(b[i]));        return resultSb.toString();    }

    private static String byteToHexString(byte b) {        int n = b;        if (n < 0)            n += 256;        int d1 = n / 16;        int d2 = n % 16;        return hexDigits[d1] + hexDigits[d2];    }

    private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d",            "e", "f"};

    @SuppressWarnings("rawtypes")    public static String getRequestXml(SortedMap<Object, Object> parameters) {        StringBuffer sb = new StringBuffer();        sb.append("<xml>");        Set es = parameters.entrySet();        Iterator it = es.iterator();        while (it.hasNext()) {            Map.Entry entry = (Map.Entry) it.next();            String k = (String) entry.getKey();            String v = (String) entry.getValue();            if ("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k) || "sign".equalsIgnoreCase(k)) {                sb.append("<" + k + ">" + "<![CDATA[" + v + "]]></" + k + ">");            } else {                sb.append("<" + k + ">" + v + "</" + k + ">");            }        }        sb.append("</xml>");        return sb.toString();    }

    /**     * * 发送https请求     *     * @param requestUrl    请求地址     * @param requestMethod 请求方式(GET、POST)     * @param outputStr     提交的数据     * @return 返回微信服务器响应的信息     */    public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {        try {            // 创建SSLContext对象,并使用我们指定的信任管理器初始化            TrustManager[] tm = {new MyX509TrustManager()};            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");            sslContext.init(null, tm, new java.security.SecureRandom());            // 从上述SSLContext对象中得到SSLSocketFactory对象            SSLSocketFactory ssf = sslContext.getSocketFactory();            URL url = new URL(requestUrl);            HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();            conn.setSSLSocketFactory(ssf);            conn.setDoOutput(true);            conn.setDoInput(true);            conn.setUseCaches(false);            // 设置请求方式(GET/POST)            conn.setRequestMethod(requestMethod);            conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");            // 当outputStr不为null时向输出流写数据            if (null != outputStr) {                OutputStream outputStream = conn.getOutputStream();                // 注意编码格式                outputStream.write(outputStr.getBytes("UTF-8"));                outputStream.close();            }            // 从输入流读取返回内容            InputStream inputStream = conn.getInputStream();            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);            String str = null;            StringBuffer buffer = new StringBuffer();            while ((str = bufferedReader.readLine()) != null) {                buffer.append(str);            }            // 释放资源            bufferedReader.close();            inputStreamReader.close();            inputStream.close();            inputStream = null;            conn.disconnect();            return buffer.toString();        } catch (ConnectException ce) {            System.out.println("连接超时");        } catch (Exception e) {            System.out.println("请求异常");        }        return null;    }

    public static String create_nonce_str() {        return UUID.randomUUID().toString().replace("-", "");    }

    public static String create_timestamp() {        return Long.toString(System.currentTimeMillis() / 1000);    }

    /**     * 解析xml     *     * @param strxml     * @return     * @throws Exception     */    @SuppressWarnings({"rawtypes", "unchecked"})    public static Map doXMLParse(String strxml) throws Exception {        strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");

        if (null == strxml || "".equals(strxml)) {            return null;        }

        Map m = new HashMap();

        InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));        SAXBuilder builder = new SAXBuilder();        Document doc = builder.build(in);        Element root = doc.getRootElement();        List list = root.getChildren();        Iterator it = list.iterator();        while (it.hasNext()) {            Element e = (Element) it.next();            String k = e.getName();            String v = "";            List children = e.getChildren();            if (children.isEmpty()) {                v = e.getTextNormalize();            } else {                v = getChildrenText(children);            }

            m.put(k, v);        }        // 关闭流        in.close();        return m;    }

    /**     * 获取子结点的xml     *     * @param children     * @return     */    @SuppressWarnings("rawtypes")    public static String getChildrenText(List children) {        StringBuffer sb = new StringBuffer();        if (!children.isEmpty()) {            Iterator it = children.iterator();            while (it.hasNext()) {                Element e = (Element) it.next();                String name = e.getName();                String value = e.getTextNormalize();                List list = e.getChildren();                sb.append("<" + name + ">");                if (!list.isEmpty()) {                    sb.append(getChildrenText(list));                }                sb.append(value);                sb.append("</" + name + ">");            }        }        return sb.toString();    }

}

原文地址:https://www.cnblogs.com/sung1024/p/11700735.html

时间: 2024-07-31 11:08:49

微信支付第三方sdk使用的相关文章

微信支付PHP SDK —— 公众号支付代码详解

在微信支付 开发者文档页面 下载最新的 php SDK http://mch.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1 这里假设你已经申请完微信支付 1. 微信后台配置  如图 我们先进行测试,所以先把测试授权目录和 测试白名单添加上.测试授权目录是你要发起微信请求的哪个文件所在的目录. 例如jsapi 发起请求一般是jsapi.php所在目录 为测试目录,测试白名单即开发人员的微信号. 正式的支付授权目录不能和测试的一样否则会报错.不填

微信支付官方SDK V3 .NET版的坑

我觉得玩微信支付最大的难点和瓶颈并不是微信支付本身,而是能够拿到微信支付的权限.首先微信支付所面向的开发对象不是个人,所以个人开发者不会有这样的权限,另外一方面公司的微信号又不会随便给个人进行开发,这样就陷入了一个比较尴尬的循环! 在好不容易搞到权限后,发现官方的sdk里面竟然有.NET版本,这让小猪欣喜如狂,赶紧下下来研究一番.这也就有了本文. 在设置好开发环境,测试白名单,,回调…确定微信后台设置已经没有问题之后. 接下来看.NET版本中的坑 默认Default.aspx中的链接竟然都是链接

PHP 微信支付-借助SDK

记一次自己亲自走通微信支付流程的过程: 首先拿到需要的公众号Appid.AppSecret.商户id.支付秘钥然后到微信支付的开发文档中下载 需要的SDK版本,第一次是全部使用SDK只是放到服务器上走了一遍.然后自己动手写了一遍 前端页面: <?php header("Content-type:text/html;charset=utf-8"); include './lib/WxPay.Api.php'; include './wxConfig.php'; include '.

Android应用之——微信微博第三方sdk登录分享使用过程中的一些常见问题

前言 近期在使用第三方登录和分享的过程中遇到了非常多问题,一方面能够归结为自己经验的不足,还有一方面事实上也说明了官方文档的含糊不清.这篇博文不会写关于怎样使用第三方登录分享,由于官方文档已经写明了步骤,这里要写的东西是官方文档里面没用说明的一些问题,也是我自己在摸索的过程中发现和解决的问题. 一.微博登录和分享 微博sdk的集成过程官方下载的sdk文档中已经基本说明清楚了.这里不提了,说两个常常遇到过问题. 1.登录后停留在授权页,也就是登录后没有返回我们的应用.排除代码方面的原因后.还有几个

第三方支付之微信支付(扫码支付)

第一步:注册微信支付账户,开通扫码支付 具体流程请参照官方说明 第二步:创建Maven项目 1. 添加微信支付SDK依赖.二维码工具依赖(微信支付需要自己通过二维码工具生成支付二维码) <!-- 微信支付 --> <dependency> <groupId>com.github.wxpay</groupId> <artifactId>wxpay-sdk</artifactId> <version>0.0.3</ver

IOS更换64位支付宝 微信支付 SDK

14年的时候苹果就下发通知:新的上线项目必须适配64-bit,更新的项目在2015年的六月一号以后也必须适配64-bit刚开始的时候没注意到这个问题,当打包完自己项目的时候,居然在适配64-bit的时候出现了一个警告, 看了一下,大概的意思也就是说,我的项目没有适配64-bit,我勒个去,上个版本还没有提示这个,这个版本居然冒出这个警告了.眼看着六月一号也即将到来,十天时间,以苹果的审核进度不一定过的了,万一中间再出个小插曲,估计上线得一个月了,加速审核苹果不一定买帐.迟早要做64bit的适配的

iOS SDK微信支付填坑!(跳转微信支付,只有确定按钮)

这两天接微信支付的SDK,遇到了一个天坑,微信文档里面不写清楚,demo里面也没有,参数少了一个无法支付啊有没有!有没有!有没有! 最后调试成功,得知真相的我眼泪掉下来... 先让我们看看是什么情况: --------------------------------------------------------我是分割线-------------------------------------------------------- 预支付订单那块就不说了,基本上都没问题,服务器会返回一个pre

微信支付四大支付模式分别有哪些区别?

微信支付是集成在微信客户端的支付功能,用户可以通过手机完成快速的支付流程.微信支付已为百货.餐厅.便利店.酒店.快递.景区.医院.售货机等提供了支付与营销的全方位支持. 目前微信支付已实现刷卡支付.扫码支付.公众号支付.APP支付,并提供企业红包.代金券.立减优惠等营销新工具,满足用户及商户的不同支付场景. 那么这四大支付模式分别有哪些区别呢? 1.刷卡支付 刷卡支付是用户展示微信钱包内的"刷卡条码/二维码"给商户系统扫描后直接完成支付的模式. 主要应用线下面对面收银的场景. 2.扫码

iOS-关于微信支付

突然发现的一篇文章,这位博主介绍的还是挺详细的,给大家分享一下 不懂的也可以咨询我qq:564702640 1.申请接入 详见 微信支付申请接入 . 创建应用+审核通过,你将得到:APP_ID.APP_SECRET.APP_KEY.PARTNER_ID .那就可以开始实现支付功能的接入. 2.业务流程 不管是客户端还是后台开发者,微信支付开发者文档里面这张交互时序图,都有必要看看.其实很多开发者,当然也包括我,在接入第三方sdk时,一般都是从其官方demo入手,快速了解其api.结果在这里就掉坑