10分钟完成微信JSAPI支付对接过程-JAVA后端接口

  1. 引入架包
		<dependency>
			<groupId>com.github.javen205</groupId>
			<artifactId>IJPay-WxPay</artifactId>
			<version>${ijapy.version}</version>
		</dependency>

在这里插入图片描述

在这里插入图片描述

配置类


package com.joolun.web.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

/**
 * <p>微信配置 Bean</p>
 *
 * @author yuhaiguang
 */
@Component
@PropertySource("classpath:/wxpay.properties")
@ConfigurationProperties(prefix = "wxpay")
public class WxPayBean {
	private String appId;
	private String appSecret;
	private String mchId;
	private String partnerKey;
	private String certPath;
	private String domain;

	public String getAppId() {
		return appId;
	}

	public void setAppId(String appId) {
		this.appId = appId;
	}

	public String getAppSecret() {
		return appSecret;
	}

	public void setAppSecret(String appSecret) {
		this.appSecret = appSecret;
	}

	public String getMchId() {
		return mchId;
	}

	public void setMchId(String mchId) {
		this.mchId = mchId;
	}

	public String getPartnerKey() {
		return partnerKey;
	}

	public void setPartnerKey(String partnerKey) {
		this.partnerKey = partnerKey;
	}

	public String getCertPath() {
		return certPath;
	}

	public void setCertPath(String certPath) {
		this.certPath = certPath;
	}

	public String getDomain() {
		return domain;
	}

	public void setDomain(String domain) {
		this.domain = domain;
	}

	@Override
	public String toString() {
		return "WxPayBean [appId=" + appId + ", appSecret=" + appSecret + ", mchId=" + mchId + ", partnerKey="
			+ partnerKey + ", certPath=" + certPath + ", domain=" + domain + "]";
	}
}


controller

AbstractWxPayApiController

package com.joolun.web.controller.weixin;

import com.ijpay.wxpay.WxPayApiConfig;

public abstract class AbstractWxPayApiController {

    public abstract WxPayApiConfig getApiConfig();
}

接口:

package com.joolun.web.controller.weixin;


import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.api.R;
import com.ijpay.core.enums.SignType;
import com.ijpay.core.enums.TradeType;
import com.ijpay.core.kit.IpKit;
import com.ijpay.core.kit.WxPayKit;
import com.ijpay.wxpay.WxPayApi;
import com.ijpay.wxpay.WxPayApiConfig;
import com.ijpay.wxpay.WxPayApiConfigKit;
import com.ijpay.wxpay.model.UnifiedOrderModel;
import com.joolun.common.core.domain.AjaxResult;
import com.joolun.web.config.WxPayBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

@RestController
@RequestMapping("/wxPay")
public class WxPayController extends AbstractWxPayApiController{
    private final Logger log = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private WxPayBean wxPayBean;

    private String notifyUrl;
    private String refundNotifyUrl;
    @Override
    public WxPayApiConfig getApiConfig() {
        WxPayApiConfig apiConfig;

        try {
            apiConfig = WxPayApiConfigKit.getApiConfig(wxPayBean.getAppId());
        } catch (Exception e) {
            apiConfig = WxPayApiConfig.builder()
                    .appId(wxPayBean.getAppId())
                    .mchId(wxPayBean.getMchId())
                    .partnerKey(wxPayBean.getPartnerKey())
                    .certPath(wxPayBean.getCertPath())
                    .domain(wxPayBean.getDomain())
                    .build();
        }
        notifyUrl = apiConfig.getDomain().concat("/wxPay/payNotify");
        refundNotifyUrl = apiConfig.getDomain().concat("/wxPay/refundNotify");
        return apiConfig;
    }


    @RequestMapping(value = "/webPay", method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    public R webPay(HttpServletRequest request) {
        // openId,采用 网页授权获取 access_token API:SnsAccessTokenApi获取
        String openId = (String) request.getSession().getAttribute("openId");
        if (openId == null) {
            openId = "oQe4A6_acTpnPFTuAaxKq0Ss-yMo";
        }

        if (StrUtil.isEmpty(openId)) {
            return R.failed("openId is null");
        }

        String ip = IpKit.getRealIp(request);
        if (StrUtil.isEmpty(ip)) {
            ip = "127.0.0.1";
        }

        WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig();

        Map<String, String> params = UnifiedOrderModel
                .builder()
                .appid(wxPayApiConfig.getAppId())
                .mch_id(wxPayApiConfig.getMchId())
                .nonce_str(WxPayKit.generateStr())
                .body("微信网页内测试")
                .attach("产品说名")
                .out_trade_no(WxPayKit.generateStr())
                .total_fee("1")
                .spbill_create_ip(ip)
                .notify_url(notifyUrl)
                .trade_type(TradeType.JSAPI.getTradeType())
                .openid(openId)
                .build()
                .createSign(wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);

        String xmlResult = WxPayApi.pushOrder(false, params);
        log.info(xmlResult);

        Map<String, String> resultMap = WxPayKit.xmlToMap(xmlResult);
        String returnCode = resultMap.get("return_code");
        String returnMsg = resultMap.get("return_msg");
        if (!WxPayKit.codeIsOk(returnCode)) {
            return R.failed(returnMsg);
        }
        String resultCode = resultMap.get("result_code");
        if (!WxPayKit.codeIsOk(resultCode)) {
            return R.failed(returnMsg);
        }

        // 以下字段在 return_code 和 result_code 都为 SUCCESS 的时候有返回

        String prepayId = resultMap.get("prepay_id");

        Map<String, String> packageParams = WxPayKit.prepayIdCreateSign(prepayId, wxPayApiConfig.getAppId(),
                wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);

        String jsonStr = JSON.toJSONString(packageParams);
        return R.failed(jsonStr);
    }


}

配置初始化拦截器

package com.joolun.web.config;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;

import com.joolun.web.interceptor.WxPayInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

@Configuration
public class IJPayConfigurer extends WebMvcConfigurationSupport {
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		//registry.addInterceptor(new AliPayInterceptor()).addPathPatterns("/aliPay/**");
		registry.addInterceptor(new WxPayInterceptor()).addPathPatterns("/wxPay/**");
		super.addInterceptors(registry);
	}

	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		// 将所有/static/** 访问都映射到classpath:/static/ 目录下
		registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
	}

	@Override
	public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
		super.configureMessageConverters(converters);

		FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
		FastJsonConfig config = new FastJsonConfig();
		config.setSerializerFeatures(

			SerializerFeature.WriteMapNullValue, // 保留map空的字段

			SerializerFeature.WriteNullStringAsEmpty, // 将String类型的null转成""

			SerializerFeature.WriteNullNumberAsZero, // 将Number类型的null转成0

			SerializerFeature.WriteNullListAsEmpty, // 将List类型的null转成[]

			SerializerFeature.WriteNullBooleanAsFalse, // 将Boolean类型的null转成false

			SerializerFeature.DisableCircularReferenceDetect);// 避免循环引用

		converter.setFastJsonConfig(config);
		converter.setDefaultCharset(Charset.forName("UTF-8"));
		List<MediaType> mediaTypeList = new ArrayList<>();
		// 解决中文乱码问题,相当于在Controller上的@RequestMapping中加了个属性produces = "application/json"
		mediaTypeList.add(MediaType.APPLICATION_JSON);
		converter.setSupportedMediaTypes(mediaTypeList);
		converters.add(converter);

		converters.add(responseBodyConverter());
	}

	@Bean
	public HttpMessageConverter<String> responseBodyConverter() {
		return new StringHttpMessageConverter(Charset.forName("UTF-8"));
	}
}

package com.joolun.web.interceptor;


import com.ijpay.wxpay.WxPayApiConfigKit;
import com.joolun.web.controller.weixin.AbstractWxPayApiController;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * <p>微信支付拦截器</p>
 *
 * @author yuhaiguang
 */
public class WxPayInterceptor implements HandlerInterceptor {

	@Override
	public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler) {
		if (HandlerMethod.class.equals(handler.getClass())) {
			HandlerMethod method = (HandlerMethod) handler;
			Object controller = method.getBean();
			if (!(controller instanceof AbstractWxPayApiController)) {
				throw new RuntimeException("控制器需要继承 AbstractWxPayApiController");
			}
			WxPayApiConfigKit.setThreadLocalWxPayApiConfig(((AbstractWxPayApiController) controller).getApiConfig());
			return true;
		}
		return false;
	}
}

在这里插入图片描述

源码:

https://gitee.com/champion-myth/wx-shop/tree/dev-wx-pay/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/755632.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

DC-DC原理,升降压原理,BUCK,BOOST

DC-DC简述 开关电源包括电源模块&#xff0c;可以直接使用&#xff0c;不需要外部电路&#xff0c;提供的功率比较小。还有电源稳压器&#xff0c;这种功率MOS一般集成在芯片内部&#xff0c;但是需要选择外部电感。另外还有PWM控制器&#xff0c;需要选择功率MOS&#xff0c;二…

centos上部署Ollama平台,实现语言大模型本地部署

网上有很多大模型&#xff0c;很多都是远程在线调用ChatGPT的api来实现的&#xff0c;自己本地是没有大模型的&#xff0c;这里和大家分享一个大模型平台&#xff0c;可以实现本地快速部署大模型。 Ollama是一个开源项目&#xff0c;它提供了一个平台和工具集&#xff0c;用于部…

【Python】已解决:ModuleNotFoundError: No module named ‘LAC‘

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决&#xff1a;ModuleNotFoundError: No module named ‘LAC‘ 一、分析问题背景 在开发或运行Python程序时&#xff0c;可能会遇到各种各样的报错&#xff0c;其中“ModuleNo…

stm32-hal库(5)--usart串口通信三种模式(主从通信)(关于通信失败和串口不断发送数据问题的解决)

问题&#xff1a; 最近发现&#xff0c;stm32cubemx最新版本f1系列的hal库&#xff08;1.85版本&#xff09;生成的hal库&#xff0c;其中stm32f1xx_hal_uart.c的库文件中&#xff0c;其串口发送接收存在一些问题&#xff1a; 1.没有使用 __HAL_LOCK 和 __HAL_UNLOCK 宏&…

多元时间序列分析——VAR(向量自回归模型)

VAR模型主要是考察多个变量之间的动态互动关系&#xff0c;从而解释各种经济冲击对经济变量形成的动态影响。这种动态关系可通过格兰杰因果关系、脉冲响应以及方差分解来进一步明确和可视化。VAR模型主要研究内生变量之间的关系&#xff0c;内生变量就是参与模型并由模型体系内…

【数据结构】(C语言):链表

链表&#xff1a; 基本单位是节点。节点至少两部分&#xff1a;数据&#xff0c;下一个数据的地址。头指针head&#xff0c;始终指向链表的第一个节点。若没有节点&#xff0c;则headNULL。链表在内存中是非连续的。不能使用索引&#xff08;下标&#xff09;查找元素。只能从…

【Vue】Vue3基础

VUE3基础 1、简介2、创建工程2.1 基于vue-cli创建&#xff08;脚手架webpack&#xff09;2.2 基于vite创建&#xff08;推荐&#xff09;2.3 目录结构2.4 vscode插件推荐 3、核心语法3.1 选项式&#xff08;options API&#xff09;和组合式&#xff08;composition API&#x…

of_match_device是怎么匹配的

这里以spi-gpio.c为例 先判断有没有匹配表和dev中有没设备树节点 struct device中有个保存设备树节点的结构体 可通过三种方式匹配&#xff1a;名字、类型、compatible 匹配成功&#xff0c;则执行第一个

海外媒体发稿:媒体宣发套餐的作用分享-华媒舍

一、神奇媒体宣发套餐 神奇媒体宣发套餐是一项专业的多媒体宣传推广服务&#xff0c;旨在帮助企业、个人快速提升品牌知名度和曝光度。它通过全面覆盖主流媒体、社交网络以及各大网络平台&#xff0c;将您的宣传信息传递给广泛的受众群体&#xff0c;实现全方位、多角度的宣传…

无人机无刷电机理论教学培训课程

本文档为一份关于Brushless电机理论的详细教程&#xff0c;由TYTO Robotics编制&#xff0c;旨在帮助用户理解brushless电机的工作原理、特性以及如何通过实验测定其关键参数Kv和Kt。文档首先介绍了brushless电机的基本组成&#xff0c;包括静止的定子和旋转的转子&#xff0c;…

python循环结构

1.while 循环 语句&#xff1a; while 循环条件表达式&#xff1a; 代码块 else&#xff1a; 代码块 小练&#xff1a; 设计一百以内的偶数相加 n 0 while n < 100:n 1if n % 2 0 :print(n) 判断是不是闰年&#xff08;四年一润和百年不润&#xff0c;或者四百年一润&am…

Linux平台下RTSP|RTMP播放器如何跟python交互投递RGB数据供视觉算法分析

技术背景 我们在对接Linux平台RTSP播放模块的时候&#xff0c;遇到这样的技术需求&#xff0c;开发者需要把Linux RTSP播放器拉取的数据&#xff0c;除了实时播放外&#xff0c;还要投递给python&#xff0c;用于视觉算法分析。 技术实现 Linux平台RTSP、RTMP直接播放不再赘…

GoLang语言

基础 安装Go扩展 go build 在项目目录下执行go build go run 像执行脚本文件一样执行Go代码 go install go install分为两步&#xff1a; 1、 先编译得到一个可执行文件 2、将可执行文件拷贝到GOPATH/bin Go 命令 go build :编译Go程序 go build -o "xx.exe"…

React+TS前台项目实战(二十一)-- Search业务组件封装实现全局搜索

文章目录 前言一、Search组件封装1. 效果展示2. 功能分析3. 代码详细注释4. 使用方式 二、搜索结果展示组件封装1. 功能分析2. 代码详细注释 三、引用到文件&#xff0c;自行取用总结 前言 今天&#xff0c;我们来封装一个业务灵巧的组件&#xff0c;它集成了全局搜索和展示搜…

基于Java的茶文化交流系统【附源码+LW】

摘 要 计算机网络发展到现在已经好几十年了&#xff0c;在理论上面已经有了很丰富的基础&#xff0c;并且在现实生活中也到处都在使用&#xff0c;可以说&#xff0c;经过几十年的发展&#xff0c;互联网技术已经把地域信息的隔阂给消除了&#xff0c;让整个世界都可以即时通话…

Meta发布LLM编译器 称将改变我们的编程方式

Meta发布了Meta 大型语言模型&#xff08;LLM&#xff09;编译器&#xff0c;这是一套强大的开源模型&#xff0c;旨在优化代码并彻底改变编译器设计。这项创新有望改变开发人员优化代码的方式&#xff0c;使代码优化更快、更高效、更具成本效益。 在将大型语言模型应用于代码和…

基于SpringBoot+Vue的大药房管理系统(带1w+文档)

基于SpringBootVue的大药房管理系统(带1w文档) 本系统主要包括管理员和用户两个用户角色&#xff1b;主要包括&#xff1a;首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;保健品分类管理&#xff0c;药品分类管理&#xff0c;药品信息管理&#xff0c;疫情常识管理…

鸿蒙登录页面及页面跳转的设计

目录 任务目标任务分析任务实施1.新建工程项目HMLogin2.设计登录页面Index.visual3.设计第二个页面SecondPage4.修改Index.ets代码5.修改SecondPage.ets代码6.运行工程 任务目标 设计一个简单的登录页面&#xff0c;要求可以将第一页的登录信息&#xff0c;传递到第二个页面&a…

3.js - 反射率(reflectivity) 、折射率(ior)

没啥太大的感觉 反射率 reflectivity 概念 反射率&#xff1a;指的是&#xff0c;材质表面反射光线的能力反射率&#xff0c;用于控制材质对环境光&#xff0c;或光源的反射程度反射率越高&#xff0c;材质表面反射的光线越多&#xff0c;看起来就越光亮使用 适用于&#xff0…

AIGC实战:LLaMA2打造中文写作利器——数据准备与模型训练全攻略

目录 一、下载并加载中文数据集二、中文数据集处理 1、数据格式 2、数据集处理之tokenizer训练格式 1&#xff09;先将一篇篇文本拼凑到一起&#xff08;只是简单的拼凑一起&#xff0c;用于训练tokenizer&#xff09; 2&#xff09;将数据集进行合并 3、数据集处理之模型&am…