当前位置: 首页 > news >正文

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;}@Overridepublic 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());@Autowiredprivate WxPayBean wxPayBean;private String notifyUrl;private String refundNotifyUrl;@Overridepublic 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})@ResponseBodypublic 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 {@Overridepublic void addInterceptors(InterceptorRegistry registry) {//registry.addInterceptor(new AliPayInterceptor()).addPathPatterns("/aliPay/**");registry.addInterceptor(new WxPayInterceptor()).addPathPatterns("/wxPay/**");super.addInterceptors(registry);}@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {// 将所有/static/** 访问都映射到classpath:/static/ 目录下registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");}@Overridepublic 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转成0SerializerFeature.WriteNullListAsEmpty, // 将List类型的null转成[]SerializerFeature.WriteNullBooleanAsFalse, // 将Boolean类型的null转成falseSerializerFeature.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());}@Beanpublic 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 {@Overridepublic 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/

相关文章:

  • JVM专题九:JVM分代知识点梳理
  • mysql8 锁表与解锁
  • java:aocache:基于aspectJ实现的方法缓存工具
  • 等保2.0对云计算有哪些特定的安全要求?
  • AI Agent项目实战(03)-利用TTS技术让你的AI Agent发声
  • jenkins在使用pipeline时,为何没有方块形视图
  • CSF视频文件格式转换WMV格式(2024年可用)
  • k8s架构设计思想
  • python Flask methods
  • 【linux】网络基础(2)——udp协议
  • RabbitMQ 之 延迟队列
  • 【开发环境】MacBook M2安装git并拉取gitlab项目,解决gitlab出现Access Token使用无效的方法
  • ElementUI搭建
  • 百日筑基第八天-看看mybatis
  • ARP 原理详解 二
  • 【跃迁之路】【444天】程序员高效学习方法论探索系列(实验阶段201-2018.04.25)...
  • Android开源项目规范总结
  • canvas 绘制双线技巧
  • github指令
  • iOS编译提示和导航提示
  • Java反射-动态类加载和重新加载
  • java小心机(3)| 浅析finalize()
  • k8s 面向应用开发者的基础命令
  • Solarized Scheme
  • Xmanager 远程桌面 CentOS 7
  • 阿里云应用高可用服务公测发布
  • 看完九篇字体系列的文章,你还觉得我是在说字体?
  • 马上搞懂 GeoJSON
  • 每天一个设计模式之命令模式
  • 前端攻城师
  • 前端知识点整理(待续)
  • 什么软件可以提取视频中的音频制作成手机铃声
  • 在 Chrome DevTools 中调试 JavaScript 入门
  • 【干货分享】dos命令大全
  • %3cli%3e连接html页面,html+canvas实现屏幕截取
  • (20)目标检测算法之YOLOv5计算预选框、详解anchor计算
  • (arch)linux 转换文件编码格式
  • (Java数据结构)ArrayList
  • (Redis使用系列) Springboot 在redis中使用BloomFilter布隆过滤器机制 六
  • (附源码)apringboot计算机专业大学生就业指南 毕业设计061355
  • (附源码)ssm失物招领系统 毕业设计 182317
  • (蓝桥杯每日一题)平方末尾及补充(常用的字符串函数功能)
  • (三分钟了解debug)SLAM研究方向-Debug总结
  • (实战)静默dbca安装创建数据库 --参数说明+举例
  • (一)C语言之入门:使用Visual Studio Community 2022运行hello world
  • (转)memcache、redis缓存
  • .Family_物联网
  • .form文件_SSM框架文件上传篇
  • .java 9 找不到符号_java找不到符号
  • .Net 垃圾回收机制原理(二)
  • .net 验证控件和javaScript的冲突问题
  • .NET 中使用 TaskCompletionSource 作为线程同步互斥或异步操作的事件
  • .NET 中选择合适的文件打开模式(CreateNew, Create, Open, OpenOrCreate, Truncate, Append)
  • .NET/C# 中设置当发生某个特定异常时进入断点(不借助 Visual Studio 的纯代码实现)
  • .NET:自动将请求参数绑定到ASPX、ASHX和MVC(菜鸟必看)