springboot整合微信支付

springboot整合微信支付


提示:springboot整合微信支付,简单明了,兄弟们我们直接开始。

1.maven引入微信库

            <!-- 微信支付 -->
            <dependency>
                <groupId>com.github.binarywang</groupId>
                <artifactId>weixin-java-pay</artifactId>
                <version>${wx-java.version}</version>
            </dependency>

            <!-- 微信公共 -->
            <dependency>
                <groupId>com.github.binarywang</groupId>
                <artifactId>weixin-java-common</artifactId>
                <version>${wx-java.version}</version>
            </dependency>

2.封写公共微信支付service

代码如下(示例):


/**
 * 微信Service接口
 *
 * @author 张亚楠
 * @date 2022-11-18
 */
@Service
@Slf4j
public class WeixinPayService {

    @Autowired
    private RedisCache redisUtils;
    
    // 业务层service注入 根据自己的业务需求来

    /**
     * 首先定义公共支付入口
     *
     * @param orderNo 订单号
     * @param from    应用来源 比如说 APP 小程序 H5等等
     * @param attach  备注  业务场景 比如:积分订单、普通订单、拼团订单 
     * @param body    订单内容
     * @return Object
     */
    @Transactional
    public Object unifyPay(String orderNo, String from, String attach, String body) {
        // 用于用户校验
        long uid = 0;
        // 支付金额计算
        int payPrice = 0;
        BigDecimal bigDecimal = new BigDecimal(100);
		
		// 获取当前登录人信息 该方法已封装好获取当前登录人信息
        LoginUser loginUser = SecurityUtils.getLoginUser();
            //门诊订单校验
            if ("积分订单还是普通订单的区分".equals(attach)) {
                // 根据订单号查询该条订单是否已经被创建 以下方法为已经封装好的。
                Order orderInfo = orderService.getOrderInfo(orderNo, null);
                // 订单校验为空则返回提示
                if (ObjectUtil.isNull(orderInfo)) {
                    throw new BaseException("订单不存在");
                }
                // 如果订单不为空的话 根据订单状态判断是否可以支付该订单
                if (orderInfo.getState().equals("已支付")) {
                    throw new BaseException("该订单已支付");
                }
                 // 如果订单支付金额小于0 则无需支付
                if (orderInfo.getPayPrice().compareTo(BigDecimal.ZERO) <= 0) {
                    throw new BaseException("该订单无需支付");
                }
                // 用户信息
                uid = orderInfo.getMemberUserId().intValue();

                // 总金额计算
                payPrice = bigDecimal.multiply(orderInfo.getPayPrice()).intValue();
            }
           

            // 用户校验
            User user= userService.selectById(uid);
            if (user==null){
                throw new BaseException("用户错误");
            }
            // 获取WxPayService 下方代码会展示这里的方法 主要是为了判断订单来源
            WxPayService wxPayService = getWxPayService(from);
            // 微信支付(创建订单、成功回调配置) 
            WxPayUnifiedOrderRequest orderRequest = getWxPayUnifiedOrderRequest(orderNo, from, attach, body, payPrice);
            try {
                return wxPayService.createOrder(orderRequest);
            }catch (WxPayException e) {
                log.info("支付错误信息:{}",e.getMessage());
                throw new BaseException(e.getMessage());
            }
        }
        return null;
    }

    /**
     * 获取微信getWxPayService  注意该方法里封装好的 getPayService   重中之重!!! 这个方法会在下方的另一个代码块进行展示
     * @param from
     * @return
     */
    private WxPayService getWxPayService(String from) {
        WxPayService wxPayService = null;
        // 判断渠道来源 是app 还是小程序 还是h5 支付
        if("app支付".equals(from)){
        // 注意该方法里封装好的 getPayService   重中之重!!!
            wxPayService = WxPayConfiguration.getPayService(PayMethodEnum.WXAPP);
        }else if("小程序支付".equals(from) ){
        // 注意该方法里封装好的 getPayService   重中之重!!!
            wxPayService = WxPayConfiguration.getPayService(PayMethodEnum.APP);
        }else{
           
        }
        return wxPayService;
    }
    

    /**
     * 微信支付(创建订单、成功回调配置)
     * @param orderNo 订单号
     * @param from 来源
     * @param attach 订单类型
     * @param body 请求体
     * @param payPrice 价格
     * @return
     */
    private WxPayUnifiedOrderRequest getWxPayUnifiedOrderRequest(String orderNo, String from, String attach, String body, int payPrice) {
    	// 将信息传入 并且设置支付成功回调地址 
        WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
        orderRequest.setOutTradeNo(orderNo);
        orderRequest.setTotalFee(payPrice);
        orderRequest.setSpbillCreateIp(IpUtil.getLocalIP());
        // 配置成功回调地址   this.getApiUrl() 服务器地址
        orderRequest.setNotifyUrl(this.getApiUrl() + "/api/member/order/notify");
        orderRequest.setBody(body);
        orderRequest.setAttach(attach);
        // 支付判断
        if(AppFromEnum.APP.getValue().equals(from)){
            orderRequest.setTradeType("APP");
        }else {
            throw new BaseException("非App端,无法进行支付!");
        }
        return orderRequest;
    }

    /**
     * 获取移动端Api地址
     * @return url 移动端Api地址
     */
    private String getApiUrl(){
        //String apiUrl = redisUtils.getCacheObject(SystemKeyConstants.API_URL);
        String apiUrl = "https://icloudinfo.cn";
        if(StrUtil.isBlank(apiUrl)){
            throw new BaseException("请配置移动端Api地址");
        }
        return apiUrl;
    }

    /**
     * 企业打款
     * @param openid 微信openid
     * @param no 单号
     * @param userName 用户姓名
     * @param amount 金额
     * @param appUserType 用户类型
     * @throws WxPayException
     */
    @Transactional
    public void entPay(String openid,String no,String userName,Integer amount, String appUserType) throws WxPayException {
        no = UUID.randomUUID().toString().replace("-", "");
        WxPayService wxPayService = WxPayConfiguration.getPayService(PayMethodEnum.APP);
        EntPayRequest entPayRequest = new EntPayRequest();
        entPayRequest.setOpenid(openid);
        entPayRequest.setPartnerTradeNo(no);
        entPayRequest.setCheckName("NO_CHECK");
        entPayRequest.setReUserName(userName);
        entPayRequest.setAmount(amount);
        entPayRequest.setDescription("提现");
        entPayRequest.setSpbillCreateIp(IpUtil.getLocalIP());
        wxPayService.getEntPayService().entPay(entPayRequest);
    }

    /**
     * 退款 传入订单号即可
     */
    public void refundOrder(String orderNo) {
		// 拿到订单号先对该订单查询 抛出异常
        Order order = OrderService.lambdaQuery().eq(order::getOrderNo,orderNo).one();
        if(order == null) {
            throw  new BaseException("问诊订单异常!");
        }
        
        WxPayService wxPayService = WxPayConfiguration.getPayService(PayMethodEnum.APP);
        WxPayRefundRequest wxPayRefundRequest = new WxPayRefundRequest();
        BigDecimal bigDecimal = new BigDecimal("100");
        int totalFee = bigDecimal.multiply(order.getPayPrice()).intValue();
        //订单总金额
        wxPayRefundRequest.setTotalFee(totalFee);
        wxPayRefundRequest.setOutTradeNo(order.getOpOrderNo());
        //生成退款单号
        String orderSn = IdUtil.getSnowflake(0,0).nextIdStr();
        wxPayRefundRequest.setOutRefundNo(orderSn);
        //退款金额
        wxPayRefundRequest.setRefundFee(totalFee);
        // 退款成功回调
        wxPayRefundRequest.setNotifyUrl(this.getApiUrl() + "/api/member/order/notify/refund");
        try {
            wxPayService.refundV2(wxPayRefundRequest);
        } catch (WxPayException e) {
            log.info("退款错误信息:{}",e.getMessage());
            throw new BaseException(e.getMessage());
        }
    }

3.第三部分封装WxPayConfiguration

package com.freorange.wx.config;

import com.freorange.common.constant.CacheConstants;
import com.freorange.common.core.redis.RedisCache;
import com.freorange.common.enums.PayMethodEnum;
import com.freorange.common.utils.spring.SpringUtils;
import com.freorange.wx.constants.YbfConstants;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;

import java.util.Map;

/**
 * 支付配置
 * @author 张亚楠
 * @date 2022/11/18
 */
@Slf4j
@Configuration(proxyBeanMethods = false)
public class WxPayConfiguration {

	private static Map<String, WxPayService> payServices = Maps.newHashMap();
	// redis缓存
	private static final RedisCache redisUtils = SpringUtils.getBean(RedisCache.class);

	/**
	 *  获取WxPayService
	 * @return
	 */
	public static WxPayService getPayService(PayMethodEnum payMethodEnum) {
		// 定义key
		WxPayService wxPayService = payServices.get("XXXXXXXXX");
		if(wxPayService == null) {
			WxPayConfig payConfig = new WxPayConfig();
			switch (payMethodEnum){
				case APP:
					// 配置商户信息 这些就是微信商户开放平台需要注册拿到的一些信息 可以存到redis里然后set
					payConfig.setAppId();
					payConfig.setMchId();
					payConfig.setMchKey();
					payConfig.setKeyPath();
					break;
				default:
			}
			// 可以指定是否使用沙箱环境
			payConfig.setUseSandboxEnv(false);
			wxPayService = new WxPayServiceImpl();
			wxPayService.setConfig(payConfig);
			// 最终把keyput
			payServices.put(YbfConstants.YSHOP_WEIXIN_APP_PAY_SERVICE+payMethodEnum.getValue(), wxPayService);
		}
		return wxPayService;
    }

	/**
	 * 移除WxPayService
	 */
	public static void removeWxPayService(){
		redisUtils.deleteObject("1");
		payServices.remove("1");
	}

}


4.第四部分封装成功回调

	/**
     * 订单支付成功回调  
     *
     * @param xmlData
     * @return
     */
    @Transactional
    @Anonymous 开放接口
    @PostMapping("/notify")
    @ApiOperation(value = "支付成功回调订单")
    public String renotify(@RequestBody String xmlData) {
        try {
            WxPayService wxPayService = null;
            wxPayService = WxPayConfiguration.getPayService(PayMethodEnum.APP);
            if (wxPayService == null) {
                throw new BaseException("支付成功回调错误!");
            }
            // 解析回调成功的xmlData
            WxPayOrderNotifyResult notifyResult = wxPayService.parseOrderNotifyResult(xmlData);
            // 拿到订单号 和 支付来源 微信支付还是app支付
            String orderId = notifyResult.getOutTradeNo();
            String attach = notifyResult.getAttach();
            // 门诊单回调
            if ("普通订单还是积分订单等等".equals(attach)){
                Order order = orderSerive.lambdaQuery().eq(Order::getOpOrderNo, orderId).or()
                        .eq(Order ::getOrderNo, orderId).one();
                if (ybfOutpatientOrder == null) {
                    throw new BaseException("订单单异常!");
                }
                // 判断无任何异常则更新订单状态
                order.setState(OrderStatusEnum.WAIT_SAY.getValue());
                order.setPayTime(new Date());
                orderService.update(Order);
				// 下方可以写自己的业务 发短信等
            }
            return WxPayNotifyResponse.success("处理成功!");
        } catch (WxPayException e) {
            return WxPayNotifyResponse.fail(e.getMessage());
        }
    }



总结

提示:希望这篇文章对大家有用,一起学习一起进步!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值