需求:用户充值使用后的剩余金额,需要退回到用户原路。
参考文档:微信支付-开发者文档
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 #微信小程序appIdapp_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 {//小程序appidprivate 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")@ResponseBodypublic CommonResult<Boolean> refund(String amount,Integer userId) {return CommonResult.success(chargeOrderStatusService.refund(amount,userId));}
实现类
/*** 退款*/@Overridepublic 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*/@Overridepublic 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;}