java微信退款(支持部分退款)

什么是价值呢,就是有用的意思吧,还有,是无价

这里介绍两种退款方式:已封装和未封装两种形式

 

一、未封装

退款需要准备证书,apiclient_cert.p12这个证书,证书下载地址看这里     http://kf.qq.com/faq/161222NneAJf161222U7fARv.html    

放到resource中即可,在编译的时候保证能将它编译到class中,下面会说到

使用Spring的证书还有一点要注意,如果你放到resource中了但是不好使,具体报什么错忘了,需要加上支持:

           <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <configuration>
                    <encoding>UTF-8</encoding>
                    <!-- 过滤后缀为pem、pfx的证书文件 -->
                    <nonFilteredFileExtensions>
                        <nonFilteredFileExtension>pem</nonFilteredFileExtension>
                        <nonFilteredFileExtension>pfx</nonFilteredFileExtension>
                        <nonFilteredFileExtension>p12</nonFilteredFileExtension>
                    </nonFilteredFileExtensions>
                </configuration>
            </plugin>

工具类都是全的,只需要小改一下自己的东西就可以实现了,目录如下:

 

 

 

里面有详细的说明,需要改动的是RefundUtil和ClientCustomSSL,其他不用动

RefundUtil

做过支付才做退款对吧, 所以我不多说了,上面的内容都改成自己平台的appid和密钥,具体在哪找自己百度

ClientCustomSSL

这个类需要指定证书,上面说过了,而

String path=this.getClass().getClassLoader().getResource("/").getPath();

就是获取证书的路径,自己可以编译一下看是不是在那个文件夹下,如果在就对了,如果不在,那肯定不行(这里我们采用的相对路径,这样放到哪里都不会错也不用改)

ok了,没什么了,默认读取证书密码退款就可以了

这是调用的代码:

        RefundUtil refundUtil = new RefundUtil();
        Map<String, String> map = refundUtil.wechatRefund(transaction_id, total_fee, refund_fee, request);
        log.info("返回map集合:" + map);
        String result_code = map.get("result_code");
        log.info("result_code退款状态:" + result_code);
        if (result_code.equals("SUCCESS")) {

成功后处理自己业务逻辑

 

退款成功返回map形式:以上面的形式取出要用的就可以

{
    refund_id=50000105282018010,
    refund_fee=9900,
    coupon_refund_fee=0,
    refund_channel=,
    return_msg=OK,
    appid=wxdlsfjldk,
    nonce_str=FCAvhi2VeL0kYYn2,
    out_trade_no=20183242336,
    out_refund_no=3133e760-ccb9-4345-9466-ab2b68be,
    transaction_id=42002343452454243231346161,
    coupon_refund_count=0,
    sign=BE4CCE8009E6A5CC32342342391B,
    result_code=SUCCESS,
    mch_id=134234234,
    total_fee=9900,
    return_code=SUCCESS,
    cash_refund_fee=9900,
    cash_fee=9900
}

 

 

二、已封装(ijpay的封装方式)

引入IJPay包

public Map<String, String> wxRefund(PayCoreDTO payCoreDTO) {
        try {
            if (StrUtil.isEmpty(payCoreDTO.getRefundNo())) {
                payCoreDTO.setRefundNo(RandomUtil.randomNumbers(11));
            }
            WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig();
            Map<String, String> params = RefundModel.builder()
                    .appid(wxPayApiConfig.getAppId())
                    .mch_id(wxPayApiConfig.getMchId())
                    .nonce_str(WxPayKit.generateStr())
                    .out_trade_no(payCoreDTO.getOutTradeNo())
                    .out_refund_no(payCoreDTO.getRefundNo())
                    .total_fee(payCoreDTO.getTotalAmount().toString())
                    .refund_fee(payCoreDTO.getRefundAmount().toString())
                    .notify_url(wxPayApiConfig.getDomain())
                    .build()
                    .createSign(wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);
//            String path = AreaCode.class.getClassLoader().getResource("apiclient_cert.p12").getPath();
            log.info("微信退款入参:{}", params);
            String refundStr = WxPayApi.orderRefund(false, params, getCertStream(), wxPayApiConfig.getMchId());
            Map<String, String> xmlToMap = WxPayKit.xmlToMap(refundStr);
            String resultCode = xmlToMap.get("result_code");
            if (resultCode != null && StrUtil.equalsIgnoreCase(resultCode, "SUCCESS")) {
                return xmlToMap;
            }
            log.info("微信退款返回:{}", refundStr);
            return null;
        } catch (Exception e) {
            log.error("微信退款异常:{}", e);
        }
        return null;
    }
    public InputStream getCertStream() {
        try {
            InputStream certStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("/data/apiclient_cert.p12");
            this.certData = IoUtil.readBytes(certStream);
            certStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        ByteArrayInputStream certBis = new ByteArrayInputStream(this.certData);
        return certBis;
    }

大家可以参考官方文档,可以看到必须有out_refund_no才能实现部分退款,并且微信每次退款返回的字段都多了一个级别,稍后我贴出来参考一下

还有读取证书这里,注意读取方式,否则会报找不到的错误,这里我找到了这种方式读取成流来处理

微信多次退款返回示例

{
    "nonce_str":"vw7gh4Tw84yo5y",
    "refund_status_0":"SUCCESS",
    "refund_status_1":"SUCCESS",
    "refund_fee_1":"1",
    "sign":"09AAFA33B180D07221248855DD14",
    "refund_fee_0":"1",
    "refund_id_1":"5030110695201505562822951",
    "return_msg":"OK",
    "mch_id":"1605163579",
    "cash_fee":"2",
    "refund_id_0":"5030110691011505552066628",
    "refund_account_1":"REFUND_SOURCE_RECHARGE_FUNDS",
    "total_fee":"2",
    "refund_account_0":"REFUND_SOURCE_RECHARGE_FUNDS",
    "refund_count":"2",
    "transaction_id":"420000091101154551734639",
    "out_refund_no_0":"085635aee721ae267786b784a4cf",
    "out_refund_no_1":"0f38bd0cb305b430ab1015561cec",
    "refund_recv_accout_0":"支付用户的零钱",
    "refund_recv_accout_1":"支付用户的零钱",
    "refund_success_time_0":"2021-01-15 17:39:34",
    "refund_success_time_1":"2021-01-15 17:41:16",
    "out_trade_no":"2021011517000000000000000001",
    "appid":"wx10305aea4709787c",
    "refund_fee":"2",
    "result_code":"SUCCESS",
    "refund_channel_1":"ORIGINAL",
    "return_code":"SUCCESS",
    "refund_channel_0":"ORIGINAL"
}

未封装工具类下载地址看这里看这里:   http://download.csdn.net/download/goligory/10243034

 

有需要源码的私我(包括设计)

 

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是小酒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值