当前位置:   article > 正文

Spring Boot 微信小程序用户支付、退款及企业付款到用户零钱、银行卡 -- 自用_com.github.binarywang.wxpay

com.github.binarywang.wxpay

配置文件

build.gradle

// 注意 com.github.binarywang微信支付包版本应与微信其他包版本一致
compile 'com.github.binarywang:weixin-java-pay:4.1.0'
  • 1
  • 2

application.yml

wx:
  # 微信支付
  pay:
    # 小程序的appID
    appid: appid
    # 商户号
    mchId: mchId
    # 商户密钥
    mchKey: mchKey
    # 证书路径
    keyPath: apiclient_cert.p12
    # 交易类型:JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付
    tradeType: JSAPI
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

微信支付商户基本信息配置信息

WeChatPayProperties.java

/**
 * 微信支付商户基本信息
 *
 * @author developer_cw
 * @date 2021-10-26
 */
@Data
@Component
@ConfigurationProperties(prefix = "wx.pay")
public class WeChatPayProperties {

    /**
     * appId
     */
    private String appId;
    /**
     * 商户号
     */
    private String mchId;
    /**
     * 商户密钥
     */
    private String mchKey;
    /**
     * 证书
     */
    private String keyPath;
    /**
     * 交易类型
     * JSAPI--公众号支付
     * NATIVE--原生扫码支付
     * APP--app支付
     */
    private String tradeType;

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this,
                ToStringStyle.MULTI_LINE_STYLE);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

微信支付信息注入bean中

WechatPayConfig.java

/**
 * @author developer_cw
 * @date 2021-10-26
 * 微信支付信息注入bean 中
 */
@Component
public class WechatPayConfig {

    @Autowired
    private WeChatPayProperties properties;

    @Bean
    @ConditionalOnMissingBean
    public WxPayConfig payConfig() {
        WxPayConfig payConfig = new WxPayConfig();
        payConfig.setAppId(this.properties.getAppId());
        payConfig.setMchId(this.properties.getMchId());
        payConfig.setMchKey(this.properties.getMchKey());
        payConfig.setKeyPath(this.properties.getKeyPath());
        payConfig.setTradeType(this.properties.getTradeType());
        return payConfig;
    }

    @Bean
    public WxPayService wxPayService(WxPayConfig payConfig) {
        WxPayService wxPayService = new WxPayServiceImpl();
        wxPayService.setConfig(payConfig);
        return wxPayService;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

返回交给前端调起支付的信息

WxPayReturnInfoVO.java

/**
 * 返回交给前端调起支付的信息
 *
 * @author developer_cw
 * @date 2021-10-26
 */
@Data
public class WxPayReturnInfoVO {

    private String appId;
    
    private String timeStamp;
    
    private String nonceStr;
    
    private String prepayId;
    
    private String paySign;
    
    private String signType;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

控制器

WeChatPayController.java

/**
 * 微信支付相关 控制器
 *
 * @author developer_cw
 * @date 2021-10-26
 */
@Slf4j
@RestController
public class WeChatPayController {

    @Autowired
    WxPayService wxPayService;

    @Autowired
    WeChatPayProperties weChatPayProperties;

    private static final String REFUND_SUCCESS = "SUCCESS";

    /**
     * 此处处理订单信息,构建订单数据。
     * 将构建好的支付参数返回到前端,前端调起微信支付
     */
    public WxPayReturnInfoVO weChatPay() {
        /**
         * 系统内部业务逻辑
         */
		// 构建支付参数
        final WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = WxPayUnifiedOrderRequest.newBuilder()
                //调起支付的人的 openId
                .openid("")
                //用户生成的唯一订单编号
                .outTradeNo("")
                //订单金额 单位分
                .totalFee(0)
                //商品描述
                .body("")
                //获取本地IP
                .spbillCreateIp(InetAddress.getLoopbackAddress().getHostAddress())
                //回调的 URL 地址
                .notifyUrl("")
                .build();
        WxPayUnifiedOrderResult wxPayUnifiedOrderResult;
        try {
            wxPayUnifiedOrderResult = wxPayService.unifiedOrder(wxPayUnifiedOrderRequest);
        } catch (WxPayException e) {
            e.printStackTrace();
            throw new Exception("微信支付调起失败!");
        }
        //组合参数构建支付
        Map<String, String> paySignInfo = new HashMap<>(5);
        String timeStamp = createTimestamp();
        String nonceStr = String.valueOf(System.currentTimeMillis());
        paySignInfo.put("appId", weChatPayProperties.getAppId());
        paySignInfo.put("nonceStr", nonceStr);
        paySignInfo.put("timeStamp", timeStamp);
        paySignInfo.put("signType", "MD5");
        paySignInfo.put("package", "prepay_id=" + wxPayUnifiedOrderResult.getPrepayId());
        String[] signInfo = new String[0];
        String paySign = SignUtils.createSign(paySignInfo, "MD5", weChatPayProperties.getMchKey(), signInfo);

        //组合支付参数
        WxPayReturnInfoVO returnPayInfoVO = new WxPayReturnInfoVO();
        returnPayInfoVO.setAppId(weChatPayProperties.getAppId());
        returnPayInfoVO.setNonceStr(nonceStr);
        returnPayInfoVO.setPaySign(paySign);
        returnPayInfoVO.setSignType("MD5");
        returnPayInfoVO.setPrepayId(wxPayUnifiedOrderResult.getPrepayId());
        returnPayInfoVO.setTimeStamp(timeStamp);
        return returnPayInfoVO;
    }

    /**
     * 微信支付回调
     * 
     * @param xmlData 微信返回的流
     * @return String
     */
    public String parseOrderNotifyResult(@RequestBody String xmlData) {
        try {
            final WxPayOrderNotifyResult notifyResult = this.wxPayService.parseOrderNotifyResult(xmlData);
            // 自身支付订单号
            notifyResult.getOutTradeNo();
            /**
             * 系统内部业务逻辑
             */
            return WxPayNotifyResponse.success("回调成功!");
        } catch (WxPayException e) {
            e.printStackTrace();
            return WxPayNotifyResponse.fail("回调有误!");
        }
    }

    /**
     * 微信退款
     * 
     * @return String
     */
    public R refund() {
    
        /**
         * 系统内部业务逻辑
         */
         
        //申请退款
        WxPayRefundRequest refundInfo = WxPayRefundRequest.newBuilder()
                // 支付订单号
                .outTradeNo("")
                // 退款订单号
                .outRefundNo("")
                // 支付金额 单位分
                .totalFee(0)
                // 退款金额 单位分
                .refundFee(0)
                //todo 微信退款回调地址
                .notifyUrl("")
                .build();
        WxPayRefundResult wxPayRefundResult;
        try {
            wxPayRefundResult = wxPayService.refund(refundInfo);
            //判断退款信息是否正确
            if (REFUND_SUCCESS.equals(wxPayRefundResult.getReturnCode())
                    && REFUND_SUCCESS.equals(wxPayRefundResult.getResultCode())) {
                /**
                 * 系统内部业务逻辑
                 */
                return R.success("退款中");
            }
        } catch (WxPayException e) {
            log.error("微信退款接口错误信息= {}", e);
            System.out.println(e.getMessage());
        }

        return R.fail(400, "退款失败");
    }


    /**
     * 仅支持一次性退款,多次退款需要修改逻辑
     *
     * @param xmlData 微信返回的流数据
     * @return String
     */
    public String refundNotify(@RequestBody String xmlData) {
        WxPayRefundNotifyResult wxPayRefundNotifyResult;
        try {
            wxPayRefundNotifyResult = wxPayService.parseRefundNotifyResult(xmlData);
        } catch (WxPayException e) {
            log.error("退款失败,失败信息:{}", e);
            System.out.println(e.getMessage());
            return WxPayNotifyResponse.fail("退款失败");
        }
        //判断你返回状态信息是否正确
        if (REFUND_SUCCESS.equals(wxPayRefundNotifyResult.getReturnCode())) {
            WxPayRefundNotifyResult.ReqInfo reqInfo = wxPayRefundNotifyResult.getReqInfo();
            //判断退款状态
            if (REFUND_SUCCESS.equals(reqInfo.getRefundStatus())) {
                try {
                    /**
                     * 一、可能会重复回调,需要做防重判断
                     * 二、处理我们系统内部业务,做修改订单状态,释放资源等!
                     */
                    return WxPayNotifyResponse.success("退款成功!");
                } catch (Exception e) {
                    e.printStackTrace();
                    System.out.println(e.getMessage());
                }
            }
        }
        return WxPayNotifyResponse.fail("退款失败!");
    }

    /**
     * 企业付款到用户零钱
     */
    public void entPay() {
        /**
         * 系统内部业务逻辑
         */
        EntPayRequest wxEntPayRequest = new EntPayRequest();
        wxEntPayRequest.setAppid(weChatPayProperties.getAppId());
        wxEntPayRequest.setMchId(weChatPayProperties.getMchId());
        // 系统订单id
        wxEntPayRequest.setPartnerTradeNo("");
        // 付款用户的wxopenid
        wxEntPayRequest.setOpenid("");
        // 实名校验
        // NO_CHECK:不校验真实姓名
        // FORCE_CHECK:强校验真实姓名(未实名认证的用户会校验失败,无法转账)
        // OPTION_CHECK:针对已实名认证的用户才校验真实姓名(未实名认证用户不校验,可以转账成功)
        wxEntPayRequest.setCheckName("NO_CHECK");
        // 付款金额 单位分
        wxEntPayRequest.setAmount(0);
        // 描述
        wxEntPayRequest.setDescription("提现");
        // 调用接口的机器IP地址
        wxEntPayRequest.setSpbillCreateIp("");

        try {
            EntPayResult wxEntPayResult = wxPayService.getEntPayService().entPay(wxEntPayRequest);
            if (REFUND_SUCCESS.equals(wxEntPayResult.getResultCode())
                    && REFUND_SUCCESS.equals(wxEntPayResult.getReturnCode())) {
                log.info("企业对个人付款成功!\n付款信息:\n" + wxEntPayResult);
                System.out.println("企业对个人付款成功!\n付款信息:\n" + wxEntPayResult);
                /**
                 * 系统内部业务逻辑
                 */
            } else {
                log.error("err_code: " + wxEntPayResult.getErrCode()
                        + "  err_code_des: " + wxEntPayResult.getErrCodeDes());
                System.out.println("提现失败! " + "err_code: " + wxEntPayResult.getErrCode() + "  err_code_des: " + wxEntPayResult.getErrCodeDes());
                /**
                 * 系统内部业务逻辑
                 */
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("提现失败! " + e.getMessage());
        }
    }

	/**
     * 企业付款到用户银行卡
     */
    public void payBank() {
        /**
         * 系统内部业务逻辑
         */
        EntPayBankRequest wxEntPayBankRequest = new EntPayBankRequest();
        wxEntPayBankRequest.setAppid(weChatPayProperties.getAppId());
        wxEntPayBankRequest.setMchId(weChatPayProperties.getMchId());
        // 系统订单编号(唯一)
        wxEntPayBankRequest.setPartnerTradeNo("");
        // 收款方银行卡号
        wxEntPayBankRequest.setEncBankNo("");
        // 收款方银行卡所属银行
        wxEntPayBankRequest.setBankCode("");
        // 付款金额 单位分
        wxEntPayBankRequest.setAmount(0);
        // 订单备注 100字以内
        wxEntPayBankRequest.setDescription("");

        try {
            EntPayBankResult wxEntPayBankResult = wxPayService.getEntPayService().payBank(wxEntPayBankRequest);
            if (REFUND_SUCCESS.equals(wxEntPayBankResult.getResultCode())
                    && REFUND_SUCCESS.equals(wxEntPayBankResult.getReturnCode())) {
                log.info("企业对银行卡付款成功!\n付款信息:\n" + wxEntPayBankResult);
                System.out.println("企业对银行卡付款成功!\n付款信息:\n" + wxEntPayBankResult);
                /**
                 * 系统内部业务逻辑
                 */
            } else {
                log.error("err_code: " + wxEntPayBankResult.getErrCode()
                        + "  err_code_des: " + wxEntPayBankResult.getErrCodeDes());
                System.out.println("企业对银行卡付款失败! " + "err_code: " + wxEntPayBankResult.getErrCode() + "  err_code_des: " + wxEntPayBankResult.getErrCodeDes());
                /**
                 * 系统内部业务逻辑
                 */
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("企业对银行卡付款失败! " + e.getMessage());
        }
    }

    /**
     * 1 块钱转为 100 分
     * 元转分
     *
     * @param bigDecimal 钱数目
     * @return 分
     */
    private int yuanToFee(BigDecimal bigDecimal) {
        return bigDecimal.multiply(new BigDecimal(100)).intValue();
    }

    /**
     * 时间
     *
     * @return 时间戳
     */
    private String createTimestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/一键难忘520/article/detail/874138
推荐阅读
相关标签
  

闽ICP备14008679号