微信小程序余额退费

需求:用户充值使用后的剩余金额,需要退回到用户原路。

参考文档:微信支付-开发者文档

pom.xml配置:

<!--微信支付SDK-->
<dependency>
    <groupId>com.github.wechatpay-apiv3</groupId>
    <artifactId>wechatpay-java</artifactId>
    <version>0.2.12</version>
</dependency>

<!--微信支付SDK-->
<dependency>
    <groupId>com.github.wechatpay-apiv3</groupId>
    <artifactId>wechatpay-apache-httpclient</artifactId>
    <version>0.4.4</version>
</dependency>

配置说明:在application.yml文件中配置

wx:
  app_id: wx70f123456abc0000 #微信小程序appId
  app_secret: 012029bc88ab195f64000c0f40003ed9 #小程序秘钥
  mch_id: 1000008342 #微信支付商户号
  mch_serial_no: 47401236EAE7432BA123456E95F3EC483A000000 #商户API证书序列号
  api_key: ABCD20225806STOPCHARGE0123WXZFSH #微信支付API密钥;apiV3秘钥
  key_path: C:\apiclient_key.pem #商户API私钥路径
package com.xxxx.common.vo;

import lombok.Data;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "wx")
@Data
@ToString
public class WxPayV3Vo {
    //小程序appid
    private String appId;
    //商户号
    private String mchId;
    //证书序列号
    private String mchSerialNo;
    //小程序秘钥
    private String appSecret;
    //微信支付API密钥;apiV3秘钥
    private String apiKey;
    //证书地址
    private String keyPath;
}

不废话直接上代码

控制层:小程序传2个参数,余额和用户Id

    /**
     * 退款
     * @param amount
     * @param userId
     * @return
     */
    @ApiOperation(value = "退款", notes = "退款")
    @GetMapping(value = "/refund")
    @ResponseBody
    public CommonResult<Boolean> refund(String amount,Integer userId) {
        return CommonResult.success(chargeOrderStatusService.refund(amount,userId));
    }

实现类

    /**
     * 退款
     */
    @Override
    public boolean refund(String amount, Integer userId) {
        BigDecimal amount1 = new BigDecimal(amount);

        //查询充值订单集合
        List<UserRecharge> chargeOrderStatusList = selectChargeOrderData(userId);

        for (UserRecharge userRecharge : chargeOrderStatusList) {
            String orderId = userRecharge.getOrderId();//商户订单号
            if (amount1.compareTo(BigDecimal.ZERO) <= 0) {
                throw new CrmebException("退款金额不能为0,请修改退款金额");
            }
            //用户剩余金额
            User user = queryUserMoney(userId);
            //退款金额>用户剩余金额
            if (amount1.compareTo(user.getNowMoney()) > 0) {
                throw new CrmebException("退款金额大于剩余金额,请修改退款金额");
            }
            if (amount1.compareTo(user.getNowMoney()) <= 0) {
                try {
                    //开始退款
                    chargeOrderStatusService.refundStart(amount1, userId, orderId);
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new CrmebException("微信申请退款失败!");
                }
            }
        }
        return false;
    }
    /**
     * 查询充值订单
     *
     * @return
     */
    private List<UserRecharge> selectChargeOrderData(Integer userId) {
        LambdaQueryWrapper<UserRecharge> lqw = Wrappers.lambdaQuery();
        lqw.eq(UserRecharge::getUid, userId);
        lqw.orderByDesc(UserRecharge::getCreateTime);
        lqw.last("LIMIT 1");
        List<UserRecharge> userRechargeList = userRechargeDao.selectList(lqw);

        if (userRechargeList.size() < 0) {
            throw new CrmebException("没有找到充值订单信息");
        }
        return userRechargeList;
    }
    /**
     * 查询用户剩余金额
     *
     * @return
     */
    private User queryUserMoney(Integer userId) {
        LambdaQueryWrapper<User> lqw = Wrappers.lambdaQuery();
        lqw.eq(User::getUid, userId);
        User User = userDao.selectOne(lqw);
        if (ObjectUtil.isNull(User)) {
            throw new CrmebException("没有找到订单信息");
        }
        return User;
    }
   /**
     * 开始退款
     *
     * @param amount1 退款金额
     * @param userId
     * @param orderId
     * @return
     */
    @Override
    public CommonResult<Object> refundStart(BigDecimal amount1, Integer userId, String orderId) {
        //查询用户剩余金额
        User user = queryUserMoney(userId);

        try {
            Config config = new RSAAutoCertificateConfig.Builder()
                    .merchantId(wxPayV3Bean.getMchId())
                    .privateKeyFromPath(wxPayV3Bean.getKeyPath())
                    .merchantSerialNumber(wxPayV3Bean.getMchSerialNo())
                    .apiV3Key(wxPayV3Bean.getApiKey())
                    .build();
            //构造申请退款对象
            RefundService service = new RefundService.Builder().config(config).build();
            //请求参数
            CreateRequest requestParam = new CreateRequest();
            //设置退款金额
            AmountReq amountReq = new AmountReq();
            String amountStr = amount1.toString();//用户退款金额
            Number number = Float.parseFloat(amountStr) * 100;
            int oamount = number.intValue();
            long refundLong = Long.valueOf(oamount);
            amountReq.setRefund(refundLong);//退款金额

            String nowMoneyStr = String.valueOf(user.getNowMoney());//用户剩余金额
            Number number1 = Float.parseFloat(nowMoneyStr) * 100;
            int oamount1 = number1.intValue();
            long LongNowMoney = Long.valueOf(oamount1);

            //生成商户退款单号
            String formattedTime = formatTime(LocalDateTime.now(), "yyyyMMddHHmmss");
            String randomNum = String.valueOf(generateRandomNumber(1000, 9999));
            String StartChargeSeq = "refund_" + formattedTime + randomNum;

            amountReq.setTotal(LongNowMoney);//原订单金额
            amountReq.setCurrency("CNY");//货币类型(默认人民币)
            requestParam.setAmount(amountReq);
            requestParam.setReason("退款");
            requestParam.setOutRefundNo(StartChargeSeq);
            requestParam.setOutTradeNo(orderId);//商户订单号

            //发起请求,申请退款
            Refund refund = service.create(requestParam);
            //调用成功的响应数据
            System.out.println("退款调用成功的响应数据======" + refund);

            if (Status.SUCCESS.equals(refund.getStatus().SUCCESS)) {

                return CommonResult.success("退款成功");

            }
            if (Status.PROCESSING.equals(refund.getStatus().PROCESSING)) {
                //根据请求返回状态修改对应订单状态
                return CommonResult.success("退款中");
            }
            if (Status.ABNORMAL.equals(refund.getStatus().ABNORMAL)) {
                //根据请求返回状态修改对应订单状态
                return CommonResult.success("退款异常");
            }
            if (Status.CLOSED.equals(refund.getStatus().CLOSED)) {
                //根据请求返回状态修改对应订单状态
                return CommonResult.success("退款关闭");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值