SpringBoot实现微信支付

这篇具有很好参考价值的文章主要介绍了SpringBoot实现微信支付。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在目前的互联网上,我们已经经常使用微信支付进行各种支付操作。微信支付作为一种移动支付的新时代产品,新颖的功能和稳定的操作流程使得它在用户中深得信任。对于一些企业或者个人,如何实现和使用微信支付成了一个不可避免的问题。为此,本文将介绍如何使用SpringBoot来快速实现微信支付的功能。

准备工作

在实现微信支付之前,需要先确保满足以下条件:

  • 使用微信公众号或者小程序账号,并开通支付功能;
  • 有自己的服务器,能够接收微信支付的通知;
  • 使用Java SpringBoot框架。

如果已经满足以上条件,则可以开始进行以下步骤。

申请微信支付

首先需要前往微信公众平台或者微信开放平台进行注册和登录。在登录之后,在菜单中找到“开发者中心”,并选择“开发设置”,然后找到“微信支付”功能,进入申请流程。

在申请过程中,需要填写一些相关的信息,并上传一些必须的文件(如商户证书等)。在完成审核之后,会获得一些必要的信息,如appidmch_idkey 等。

引入依赖

在SpringBoot项目中,使用微信支付需要引入对应的依赖。在pom.xml文件中添加以下依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>    
    <groupId>com.github.wxpay</groupId>    
    <artifactId>wxpay-sdk</artifactId>
    <version>3.0.10</version>
</dependency>

注意:以上依赖中的版本号可能跟您当前使用的版本号不一致,可以根据实际情况进行更改。

配置参数

在项目的配置文件中,需要添加以下配置信息:

#微信支付的相关配置
wxpay.appid=你的appid
wxpay.mchid=你的商户id
wxpay.key=你的商户key
wxpay.notifyurl=你的后台接收微信支付结果通知的url
wxpay.trade_type=JSAPI
# 等等

代码实现

预支付

在使用微信支付之前,需要先生成一个预支付订单,在此之后才能发起支付。以下代码实现了通过预支付生成支付订单并获取支付信息:

/**
 * 创建统一下单接口
 * @param order
 * @return
 * @throws Exception
 */
public Map<String, String> createUnifiedOrder(Order order) throws Exception {
    // 1.生成随机字符串
    String nonceStr = WXPayUtil.generateNonceStr();
    // 2.生成订单号
    String outTradeNo = order.getOutTradeNo();
    // 3.获取订单金额,单位是分
    String totalFee = order.getTotalFee().toString();
    // 4.获取用户openId(JSAPI支付必需)
    String openid = order.getOpenid();
    // 5.配置统一下单参数
    Map<String, String> data = new HashMap<>();
    data.put("appid", wxpayAppid);
    data.put("mch_id", wxpayMchid);
    data.put("nonce_str", nonceStr);
    if (order.getBody() != null) {
        data.put("body", order.getBody()); 
    }
    data.put("out_trade_no", outTradeNo);
    data.put("total_fee", totalFee);
    data.put("spbill_create_ip", order.getSpbillCreateIp()); 
    data.put("notify_url", wxpayNotifyurl); 
    data.put("trade_type", wxpayTrade_type); 
    data.put("openid", openid); 
    // 6.生成签名
    String sign = WXPayUtil.generateSignature(data, wxpayKey, WXPayConstants.SignType.MD5);
    data.put("sign", sign);
    // 7.将参数转换为XML格式,通过HTTP请求调用微信支付接口
    String requestXml = WXPayUtil.mapToXml(data);
    WXPay wxPay = new WXPay(wxpayConfig);
    Map<String, String> resultMap = wxPay.unifiedOrder(data);
    // 8.对微信支付接口返回的数据进行处理并返回,包括二次签名和返回给前端的数据格式处理。
    Map<String, String> resultMap = wxPay.unifiedOrder(data);
    String returnCode = resultMap.get("return_code");
    String resultCode = resultMap.get("result_code");
    if(WXPayConstants.SUCCESS.equals(returnCode) && WXPayConstants.SUCCESS.equals(resultCode)) {
        String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
        String prepayId = resultMap.get("prepay_id");
        // 生成响应给前端的参数列表
        Map<String, String> responseMap = new HashMap<>();
        responseMap.put("timeStamp", timeStamp);
        responseMap.put("nonceStr", nonceStr);
        responseMap.put("signType", WXPayConstants.MD5);
        responseMap.put("package", "prepay_id=" + prepayId);
        // 二次签名
        String responseSign = WXPayUtil.generateSignature(responseMap, wxpayKey, WXPayConstants.SignType.MD5);
        responseMap.put("paySign", responseSign);
        return responseMap;
    } else {
        return null;
    }
}
支付结果回调

支付结果回调通知是微信支付中非常重要的一步,因为它能够实时地将支付的结果反馈给我们的服务端。当用户支付成功后,微信会通过POST方式把相关支付通知发送到我们所设定的回调URL上,我们需要在回调URL所在的服务中对支付结果进行处理。

/**
 * 微信支付结果通知接口(POST方式)
 * @param request
 * @param response
 * @return
 */
@ResponseBody
@PostMapping(value="/wxpay/notify")
public String handleWxPayNotify(HttpServletRequest request, HttpServletResponse response) {
    try {
        ServletInputStream inputStream = request.getInputStream();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        String line;
        String result = "";
        while((line = bufferedReader.readLine()) != null){
            result += line;
        }
        // 此处 result 就是接受到的微信支付异步通知报文,直接使用WXPayUtil工具解析xml报文内容即可
        Map<String, String> resultMap = WXPayUtil.xmlToMap(result);
        // 通过微信支付通知的返回结果,校验是否支付成功
        String returnCode = resultMap.get("return_code");
        String resultCode = resultMap.get("result_code");
        if(WXPayConstants.SUCCESS.equals(returnCode) && WXPayConstants.SUCCESS.equals(resultCode)) {
            String outTradeNo = resultMap.get("out_trade_no");
            //... 业务逻辑处理
            // 返回给微信支付结果通知接收服务器的信息
            String returnMsg = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml>";
            return returnMsg;
        } else {
            String returnMsg = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[支付失败]]></return_msg>" + "</xml>";
            return returnMsg;
        }
    } catch (Exception e) {
        logger.error("微信支付结果回调出现异常:{}", e.getMessage());
        return null;
    }
}

完整的控制器代码如下:

package com.example.demo.controller;

import com.example.demo.config.WxpayConfig;
import com.example.demo.dto.Order;
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

@RestController
public class WxPayController {

    private static final Logger logger = LoggerFactory.getLogger(WxPayController.class);

    @Autowired
    private WxpayConfig wxpayConfig;

    @Value("${wxpay.appid}")
    private String wxpayAppid;

    @Value("${wxpay.mchid}")
    private String wxpayMchid;

    @Value("${wxpay.key}")
    private String wxpayKey;

    @Value("${wxpay.notifyurl}")
    private String wxpayNotifyurl;

    @Value("${wxpay.trade_type}")
    private String wxpayTrade_type;

    /**
     * 创建统一下单接口
     * @param order
     * @return
     * @throws Exception
     */
    public Map<String, String> createUnifiedOrder(Order order) throws Exception {
        // 1.生成随机字符串
        String nonceStr = WXPayUtil.generateNonceStr();
        // 2.生成订单号
        String outTradeNo = order.getOutTradeNo();
        // 3.获取订单金额,单位是分
        String totalFee = order.getTotalFee().toString();
        // 4.获取用户openId(JSAPI支付必需)
        String openid = order.getOpenid();
        // 5.配置统一下单参数
        Map<String, String> data = new HashMap<>();
        data.put("appid", wxpayAppid);
        data.put("mch_id", wxpayMchid);
        data.put("nonce_str", nonceStr);
        if (order.getBody() != null) {
            data.put("body", order.getBody()); 
        }
        data.put("out_trade_no", outTradeNo);
        data.put("total_fee", totalFee);
        data.put("spbill_create_ip", order.getSpbillCreateIp()); 
        data.put("notify_url", wxpayNotifyurl); 
        data.put("trade_type", wxpayTrade_type); 
        data.put("openid", openid); 
        // 6.生成签名
        String sign = WXPayUtil.generateSignature(data, wxpayKey, WXPayConstants.SignType.MD5);
        data.put("sign", sign);
        // 7.将参数转换为XML格式,通过HTTP请求调用微信支付接口
        String requestXml = WXPayUtil.mapToXml(data);
        WXPay wxPay = new WXPay(wxpayConfig);
        Map<String, String> resultMap = wxPay.unifiedOrder(data);
        // 8.对微信支付接口返回的数据进行处理并返回,包括二次签名和返回给前端的数据格式处理。
        Map<String, String> resultMap = wxPay.unifiedOrder(data);
        String returnCode = resultMap.get("return_code");
        String resultCode = resultMap.get("result_code");
        if(WXPayConstants.SUCCESS.equals(returnCode) && WXPayConstants.SUCCESS.equals(resultCode)) {
            String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
            String prepayId = resultMap.get("prepay_id");
            // 生成响应给前端的参数列表
            Map<String, String> responseMap = new HashMap<>();
            responseMap.put("timeStamp", timeStamp);
            responseMap.put("nonceStr", nonceStr);
            responseMap.put("signType", WXPayConstants.MD5);
            responseMap.put("package", "prepay_id=" + prepayId);
            // 二次签名
            String responseSign = WXPayUtil.generateSignature(responseMap, wxpayKey, WXPayConstants.SignType.MD5);
            responseMap.put("paySign", responseSign);
            return responseMap;
        } else {
            return null;
        }
    }

    /**
     * 微信支付结果通知接口(POST方式)
     * @param request
     * @param response
     * @return
     */
    @ResponseBody
    @PostMapping(value="/wxpay/notify")
    public String handleWxPayNotify(HttpServletRequest request, HttpServletResponse response) {
        try {
            ServletInputStream inputStream = request.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            String line;
            String result = "";
            while((line = bufferedReader.readLine()) != null){
                result += line;
            }
            // 此处 result 就是接受到的微信支付异步通知报文,直接使用WXPayUtil工具解析xml报文内容即可
            Map<String, String> resultMap = WXPayUtil.xmlToMap(result);
            // 通过微信支付通知的返回结果,校验是否支付成功
            String returnCode = resultMap.get("return_code");
            String resultCode = resultMap.get("result_code");
            if(WXPayConstants.SUCCESS.equals(returnCode) && WXPayConstants.SUCCESS.equals(resultCode)) {
                String outTradeNo = resultMap.get("out_trade_no");
                //... 业务逻辑处理
                // 返回给微信支付结果通知接收服务器的信息
                String returnMsg = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml>";
                return returnMsg;
            } else {
                String returnMsg = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[支付失败]]></return_msg>" + "</xml>";
                return returnMsg;
            }
        } catch (Exception e) {
            logger.error("微信支付结果回调出现异常:{}", e.getMessage());
            return null;
        }
    }

    /**
     * 发起微信支付
     * @param order
     * @return
     * @throws Exception
     */
    @PostMapping("/wxpay")
    public Map<String, String> wxPay(@RequestBody Order order) throws Exception {
        // 生成微信支付订单并获取支付信息
        Map<String, String> result = createUnifiedOrder(order);
        if(result != null) {
            return result;
        } else {
            return null;
        }
    }
}

总结

通过以上步骤,我们已经成功地实现了SpringBoot实现微信支付的功能。在实际使用中,您可以根据具体需求对代码进行调整,增强支付的可用性。同时我们也需要注意,支付过程中需要注意数据安全性和消息传递的可靠性。

希望本文对您有所帮助,谢谢阅读。文章来源地址https://www.toymoban.com/news/detail-647525.html

到了这里,关于SpringBoot实现微信支付的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 微信小程序完整实现微信支付功能(SpringBoot和小程序)

    1.前言 不久前给公司实现支付功能,折腾了一阵子,终于实现了,微信支付对于小白来说真的很困难,特别是没有接触过企业级别开发的大学生更不用说,因此尝试写一篇我如何从小白实现微信小程序支付功能的吧,使用的后端是 SpringBoot 。 2.准备工作 首先,要实现支付功能

    2024年02月04日
    浏览(51)
  • springboot整合IJPay实现微信支付-V3---微信小程序

    微信支付适用于许多场合,如小程序、网页支付、但微信支付相对于其他支付方式略显麻烦,我们使用IJpay框架进行整合 JPay 让支付触手可及, 封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。不依赖任何第三方 mvc 框架,仅仅作为工具使用简单

    2024年02月02日
    浏览(55)
  • 免签支付●微信支付宝个人收款方案●免签约,免营业执照,稳定安全,私有化部署,0手续,微信支付,支付宝支付,vmq二开,springboot,java,躺平在线要饭...

    预览:在线预览 ,视频演示,截图一览 教程:视频教程 加V获取源码 :微信号:ainowv (微信名:ainow) keywords(全): 免签约,免营业执照,稳定安全,私有化部署,0手续,微信支付,支付宝支付,vmqbeggar二开,springboot,java,躺平在线要饭... 免签支付实现个人微信支付宝二维

    2024年02月03日
    浏览(28)
  • 【SpringBoot】SpringBoot2.x知识点杂记

    本文仅供学习交流使用 为什么要使用 Spring Boot 因为Spring, SpringMVC 需要使用的大量的配置文件 (xml文件) 还需要配置各种对象,把使用的对象放入到spring容器中才能使用对象 需要了解其他框架配置规则。 SpringBoot 就相当于 不需要配置文件的Spring+SpringMVC。 常用的框架和第三

    2024年02月03日
    浏览(35)
  • SpringBoot知识点复习

    约定优于配置:Spring Boot鼓励开发人员遵循一组默认约定,减少配置的复杂性。 自动配置:Spring Boot可以自动配置应用程序,根据项目的依赖和需要自动配置Spring特性。 嵌入式Web服务器:Spring Boot提供了内嵌的Web服务器,如Tomcat、Jetty和Undertow,使Web应用程序的部署变得简单。

    2024年02月05日
    浏览(34)
  • 知识点19--springboot多模块开发

    本篇向大家介绍本系列demo教程中最后一个知识点就是多模块开发,多模块听着高大上,其实就是依靠maven相互之间的依赖,把多个模块融合进一个项目中而已,说的再直白一些就是像日常开发那样把其他模块导入一个模块,这个模块用来启动并调用所有模块而已。下面通过一

    2024年02月06日
    浏览(34)
  • SpringBoot + Vue基本知识点荟萃

    Maven是一个项目管理工具,可以对Java项目进行自动化的构建和依赖管理 项目构建:提供标准的,跨平台的自动化构建项目的方式 依赖管理:方便快捷的管理项目依赖的资源(jar包),避免资源间的版本冲突等问题 统一开发结构:提供标准的,统一的项目开发结构,如下图所

    2023年04月17日
    浏览(42)
  • Springboot实体类entity相关知识点详解

    目录 entity实体类相关知识点详解:       解释1:上面代码使用的注解是 Lombok 提供的注解,用于简化实体类的开发。       解释2:属性的注释自动生成问题:                解释3:java序列化反序列化,实体类实现Serializable接口:                     java序列化和反

    2024年02月08日
    浏览(32)
  • 【SpringBoot知识点预备】| Xml 和 JavaConfig

    目录 一:Xml 和 JavaConfig 1. JavaConfig 第一种:使用传统的XML配置文件的方式管理Bean 第二种:使用JavaConfig来管理Bean对象 2. @ImportResource注解(导入其它的xml配置文件) 3. 导入外部的属性配置文件 第一种方式:@PropertySource注解+@Value注解+@Componenet注解 第二种:@ConfigurationProperti

    2024年02月06日
    浏览(25)
  • Spring、Springboot、SpringCloud--包含的知识点大全

    类型 难度 AOP spring-自定义AOP面向切面注解--统一切面处理-登陆信息采集 快速入门Springboot+AOP实现切面处理请求Demo 线程池 通俗易懂的线程池底层原理,一文知所有 数据结构 数据结构-链表篇 数据结构--数组篇 数据结构之-concurrentHashMap源码分析 JVM JVM调优及各种问题处理 事务

    2024年02月13日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包