springboot使用com.github.binarywang包实现微信网页上的支付和退款

 更新时间:2024年05月27日 11:27:14   作者:layman0528  
最近做项目需要实现在pc端需要实现微信的支付,本文主要介绍了springboot使用com.github.binarywang包实现微信网页上的支付和退款,具有一定的参考价值,感兴趣的可以了解一下

前提

微信小程序中实现微信支付是从小程序中调去微信支付的界面直接进行支付,那么在pc端需要实现微信的支付呢,是需要出现一个二维码让用户使用扫码支付的。

注意:

需要实现pc端的微信支付,需要在微信商户平台开通native支付,并且下载并配置商户证书

在这里插入图片描述

在这里插入图片描述

设置好这些之后,直接看看在springboot 或者springclound 中如何实现。

maven依赖

 		<dependency>
            <groupId>com.github.binarywang</groupId>
            <artifactId>weixin-java-pay</artifactId>
            <version>4.1.0</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
       </dependency>

步骤

在yml中定义微信的商户号,密码等等

wxpay:
  appId: appId
  mchId: mchId
  mchKey: mchKey
  keyPath: /home/wxpay_cert/apiclient_cert.p12
  privateKeyPath: /home/wxpay_cert/apiclient_key.pem
  privateCertPath: /home/wxpay_cert/apiclient_cert.pem

  notifyUrl: notifyUrl
  refundNotifyUrl: refundNotifyUrl
  serialNo: serialNo

notifuyUrl 是 支付回调地址
refundNotifyUrl是 退款回调地址
这两个地址都必须是外网可访问的地址

新建WechatPayConfig类来读取yml文件的中信息

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "wxpay")
public class WechatPayConfig {
    private String appId;
    private String mchId;
    private String mchKey;
    private String keyPath;
    private String privateKeyPath;
    private String privateCertPath;
    private String notifyUrl;

    private String redUrl;
    private String refundNotifyUrl;

    private String serialNo;
}

获取ip地址帮助类

IpUtils

public class IpUtils
{
       public static String getIpAddr()
    {
        return getIpAddr(ServletUtils.getRequest());
    }
    }

ServletUtils (客户端工具类)

   public static HttpServletRequest getRequest()
    {
        try
        {
            return getRequestAttributes().getRequest();
        }
        catch (Exception e)
        {
            return null;
        }
    }
    
       public static ServletRequestAttributes getRequestAttributes()
    {
        try
        {
            RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
            return (ServletRequestAttributes) attributes;
        }
        catch (Exception e)
        {
            return null;
        }
    }

微信支付Service类

@Service
@ConditionalOnClass(WxPayService.class)
@EnableConfigurationProperties(WechatPayConfig.class)
@AllArgsConstructor
public class WechatPayService {
	 static Logger logger = LoggerFactory.getLogger(WechatPayService.class);
	 private WechatPayConfig wechatPayConfig;
	     public WxPayService wxPayService() {
        WxPayConfig payConfig = new WxPayConfig();
        payConfig.setAppId(wechatPayConfig.getAppId());
        payConfig.setMchId(wechatPayConfig.getMchId());
        payConfig.setMchKey(wechatPayConfig.getMchKey());
        payConfig.setApiV3Key(wechatPayConfig.getMchKey());
        payConfig.setKeyPath(wechatPayConfig.getKeyPath());
        payConfig.setUseSandboxEnv(false);

        logger.info("wechatPayConfig.getPrivateKeyPath():{}",wechatPayConfig.getPrivateKeyPath());
        WxPayService wxPayService = new WxPayServiceImpl();
        wxPayService.setConfig(payConfig); //微信配置信息
        return wxPayService;
    }
	
	//生成支付二维码
	//BookingInfo 是你订单表
	 public String generatePayQrCode(BookingInfo booking, String ip) {
        try {

       
            WxPayService wxPayService = wxPayService();
            WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
            orderRequest.setOutTradeNo(booking.getDisplayNo()); //订单号
            orderRequest.setTotalFee(BigDecimal.valueOf(booking.getDisplayPrice()).multiply(new BigDecimal(100)).intValue()); //金额,转换成分 ,至少支付1分钱
            orderRequest.setSpbillCreateIp(ip);
            orderRequest.setNotifyUrl(wechatPayConfig.getRedUrl());
            orderRequest.setBody("");
            orderRequest.setAttach("");
            orderRequest.setTradeType("NATIVE");//交易类型
            orderRequest.setProductId(booking.getId().toString());

            WxPayNativeOrderResult wxPayNativeOrderResult = (WxPayNativeOrderResult) wxPayService.createOrder(orderRequest);
            return wxPayNativeOrderResult.getCodeUrl();
        } catch (Exception e) {
            // 处理异常
            e.printStackTrace();
            return e.getMessage();
        }
    }
	
	//支付回调函数
	 public String payNotify(String xmlData) {
        try {
            WxPayService wxPayService = wxPayService();
            WxPayOrderNotifyResult notifyResult = wxPayService.parseOrderNotifyResult(xmlData);
            String orderId = notifyResult.getOutTradeNo();//拿到订单号获取订单
            logger.info("wechatPayConfig.rePayNotify():{}", xmlData);
          	
          	//处理的业务
          	//因为会重复调用,如果你这里是钱包这种,那么一定要判断是否支付过了


            return WxPayNotifyResponse.success("成功_" + orderInfo.getId());
        } catch (WxPayException e) {
            e.printStackTrace();
            return WxPayNotifyResponse.fail(e.getMessage());
        }
    }

	//退款订单请求
	//RefundInfo 退款的订单,这里单笔订单,如果是多笔,你可以构建list 要循环执行
	//RefundInfo 中需要包括 支付订单的订单号、支付金额、退款的订单号、退款金额
	  public String redRefundPay(RefundInfo refund){
        try {
            if (refund == null) {
                return "订单获取失败";
            }
            WxPayService wxPayService = wxPayService();
            WxPayRefundRequest orderRequest = new WxPayRefundRequest();
            orderRequest.setOutTradeNo(refund.getDisplayNo());
            orderRequest.setNotifyUrl(wechatPayConfig.getRefundNotifyUrl());
            orderRequest.setTotalFee(BigDecimal.valueOf(refund.getDisplaySum()).multiply(new BigDecimal(100)).intValue());
            orderRequest.setRefundFee(BigDecimal.valueOf(refund.getDisplayPrice()).multiply(new BigDecimal(100)).intValue());
            orderRequest.setOutRefundNo(memberRedRefund.getDisplayNo());

            WxPayRefundResult wxPayRefundResult = wxPayService.refund(orderRequest);

            if ("SUCCESS".equals(wxPayRefundResult.getReturnCode())
                    && "SUCCESS".equals(wxPayRefundResult.getResultCode())) {
                /**
                 * 系统内部业务逻辑
                 */
               
                logger.info("wechatPayConfig.redRefundNotify():{}", refund.toString());
                
                return "退款中";
            }
            return "退款失败";


        } catch (Exception e) {
            // 处理异常
            e.printStackTrace();
            return e.getMessage();
        }
    }

	//退款回调函数
	 public String redRefundNotify(String xmlData) {
        try {
            WxPayService wxPayService = wxPayService();
            WxPayRefundNotifyResult notifyResult = wxPayService.parseRefundNotifyResult(xmlData);
            String orderId = notifyResult.getReqInfo().getOutRefundNo();//拿到订单号获取订单

            logger.info("wechatPayConfig.redRefundNotify():{}", xmlData);
            //编写自己的业务处理逻辑


            return WxPayNotifyResponse.success("成功_" + orderInfo.getId());
        } catch (WxPayException e) {
            e.printStackTrace();
            return WxPayNotifyResponse.fail(e.getMessage());
        }
    }
}

到此这篇关于springboot使用com.github.binarywang包实现微信网页上的支付和退款的文章就介绍到这了,更多相关springboot微信支付和退款内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

相关文章

  • SpringEvents与异步事件驱动案例详解

    SpringEvents与异步事件驱动案例详解

    本文深入探讨了SpringBoot中的事件驱动架构,特别是通过Spring事件机制实现组件解耦和系统扩展性增强,介绍了事件的发布者、事件本身、事件监听器和事件处理器的概念,感兴趣的朋友跟随小编一起看看吧
    2024-09-09
  • 如何在springboot中配置和使用mybatis-plus

    如何在springboot中配置和使用mybatis-plus

    这篇文章主要给大家介绍了关于如何在springboot中配置和使用mybatis-plus的相关资料,MyBatis Plus是MyBatis的增强版,旨在提供更多便捷的特性,减少开发工作,同时保留了MyBatis的灵活性和强大性能,需要的朋友可以参考下
    2023-11-11
  • Java程序包装成桌面应用程序方式

    Java程序包装成桌面应用程序方式

    这篇文章主要介绍了Java程序包装成桌面应用程序方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-01-01
  • Java多线程基础——Lock类

    Java多线程基础——Lock类

    Lock类是Java类来提供的功能,丰富的api使得Lock类的同步功能比synchronized的同步更强大。本文对此进行详细介绍,下面跟着小编一起来看下吧
    2017-02-02
  • java实现图片裁切的工具类实例

    java实现图片裁切的工具类实例

    这篇文章主要介绍了java实现图片裁切的工具类实例,涉及Java针对图片的读取、修改等相关操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-11-11
  • Java非静态成员变量之死循环(详解)

    Java非静态成员变量之死循环(详解)

    下面小编就为大家带来一篇Java非静态成员变量之死循环(详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • 为什么mybatis中的SqlSession一定要关闭

    为什么mybatis中的SqlSession一定要关闭

    这篇文章主要介绍了为什么mybatis中的SqlSession一定要关闭,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • Java中什么是类加载及类加载的过程

    Java中什么是类加载及类加载的过程

    Java类加载是JVM将类文件加载至内存,分加载、连接(验证/准备/解析)和初始化三阶段,本文给大家介绍Java中什么是类加载及类加载的过程,感兴趣的朋友一起看看吧
    2025-06-06
  • 浅谈一下Java中的堆和栈

    浅谈一下Java中的堆和栈

    这篇文章主要介绍了一下Java中的堆和栈,Java数据类型在执行过程中存储在两种不同形式的内存中:栈和堆,它们通常由运行Java虚拟机(JVM)的底层平台维护,需要的朋友可以参考下
    2023-04-04
  • java中利用List的subList方法实现对List分页(简单易学)

    java中利用List的subList方法实现对List分页(简单易学)

    本篇文章主要介绍了java中list数据拆分为sublist实现页面分页的简单代码,具有一定的参考价值,有需要的可以了解一下。
    2016-11-11

最新评论