微信退款

海豚精灵https://www.whhtjl.com优课GOhttps://mgo.whhtjl.com

相信大家已在网上找了各种资料,也看过了各种文档,对于整个流程我就不再重复啦,有疑惑的小伙伴可以移步微信开放平台查看详情,网页地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4

我大概的说下我们项目中的业务逻辑:若当前用户是VIP用户,当前用户再次成功购买VIP卡后,将原有的且未用完的VIP卡费原路退还给用户;效果图如下所示:

重点代码如下所示:

我这里后端使用的SpringBoot,Maven项目,代码如下:

<!--公众号(包括订阅号和服务号) -->
<dependency>
	<groupId>com.github.binarywang</groupId>
	<artifactId>weixin-java-mp</artifactId>
	<version>2.7.0</version>
</dependency>
<!--微信支付 -->
<dependency>
	<groupId>com.github.binarywang</groupId>
	<artifactId>weixin-java-pay</artifactId>
	<version>3.0.0</version>
</dependency>

在application.properties中配置相关信息

微信APP支付这块是需要证书,大家自行去微信开放平台配置下载后放入resources目录下,可直接用classpath:xxxxxx.p12引入

#微信支付
wx.pay.appId=XXXXXXXXXXXXXXXXXXXXX
wx.pay.appSecret=XXXXXXXXXXXXXXXXXXXXX
wx.pay.mchId=XXXXXXXXXXXXXXXXXXXXX
wx.pay.mchKey=XXXXXXXXXXXXXXXXXXXXX
wx.pay.keyPath=classpath:apiclient_cert.p12
wx.pay.tradeType=APP

创建实体类

package com.ltf.config;
 
import lombok.Data;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
 
/**
 * 微信支付商户基本信息
 * @author xhz
 *
 */
@Data
@Component
@ConfigurationProperties(prefix = "wx.pay")
public class WeChatPayProperties {
 
	/**
	 * appId
	 */
	private String appId;
	/**
	 * 公众平台密钥
	 */
	private String appSecret;
	/**
	 * 商户号
	 */
	private String mchId;
	/**
	 * 商户密钥
	 */
	private String mchKey;
	/**
	 * 证书
	 */
	private String keyPath;
	/**
	 * 交易类型
	 * <pre>
	 * JSAPI--公众号支付
	 * NATIVE--原生扫码支付
	 * APP--app支付
	 * </pre>
	 */
	private String tradeType;
 
	@Override
	public String toString() {
		return ToStringBuilder.reflectionToString(this,
				ToStringStyle.MULTI_LINE_STYLE);
	}
 
}

创建控制层

package com.ltf.controller;

import com.alibaba.fastjson.JSONObject;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.ltf.cache.CacheUtil;
import com.ltf.entity.User;
import com.ltf.utils.SingletonLoginUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import javax.servlet.http.HttpServletRequest;

/**
 * 微信退款
 * @author xhz
 *
 */
@RestController
@RequestMapping(value = "/api/client/refund/")
@Slf4j
public class WeChatRefundController extends BaseController{

	private static final String REFUND_SUCCESS = "SUCCESS";

	@Autowired
	private WxPayService wxPayService;

	/**
	 * 微信退款
	 * @return
	 */
	@SuppressWarnings("static-access")
	@PostMapping(value = "weChatRefund")
	public JSONObject refund(@RequestParam("mobileCode") String mobileCode,@RequestParam("withdrawalAmount") String withdrawalAmount,HttpServletRequest request) {
		try {
			User user=SingletonLoginUtils.getLoginUser(request);
			if(user!=null){
				if(user.getIsAvailable()==2){
					return this.formatJSON(500, "抱歉,冻结状态下无法提现!", null);
				}else{
					if(user.getMobile()!=null&&!"".equals(user.getMobile().trim())){
						// 从缓存提取手机验证码
						String mobileCodeNum = (String) CacheUtil.get(user.getMobile()+ "_mobileCodeNum_withdrawMoney");
						if (!mobileCode.equals(mobileCodeNum) || mobileCodeNum == null) {
							return this.formatJSON(500, "请输入正确的手机验证码!",null);
						}else{
							if(withdrawalAmount!=null&&!"".equals(withdrawalAmount.trim())){
								//申请退款
								WxPayRefundRequest refundInfo = WxPayRefundRequest.newBuilder()
										//订单号
										.outTradeNo("202006291442477005999225798514")
										//退款订单号
										.outRefundNo("202006291442477005999225798514")
										//金额
										.totalFee(yuanToFee(new BigDecimal(withdrawalAmount)))
										//退款金额
										.refundFee(yuanToFee(new BigDecimal(withdrawalAmount)))
										//todo 回调地址
										.notifyUrl("https://你的域名/api/client/refund/refundNotify")
										.build();
								WxPayRefundResult wxPayRefundResult;
								wxPayRefundResult = wxPayService.refund(refundInfo);
								//判断退款信息是否正确
								if (REFUND_SUCCESS.equals(wxPayRefundResult.getReturnCode())
										&& REFUND_SUCCESS.equals(wxPayRefundResult.getResultCode())) {
									/**
									 * 系统内部业务逻辑
									 */
									//减掉可提现金额
									return this.formatJSON(200, "OK", null);
								}else{
									return this.formatJSON(500, "提现失败!", null);
								}
							}else{
								return this.formatJSON(500, "请填写提现金额!", null);
							}
						}
					}else{
						return this.formatJSON(500, "请先绑定手机号!", null);
					}
				}
			}else{
				return this.formatJSON(500, "登录状态已失效,请重新登录!", null);
			}
		} catch (WxPayException e) {
			log.error("微信退款接口错误信息= {}", e);
			return this.formatJSON(500, "微信退款接口出现异常!", null);
		}
	}


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

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

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值