基于微信公众号,搭建一套简单的电商支付环境(下)-- 微信公众号的对接

news2024/11/23 22:22:23

一、接着上文

上文把部署情况介绍了,侧重于网络及代理,本文选择把微信公众号的对接实现介绍一下。

还是那句话,微信官方的文档已非常详细,这里先摘抄一些重要的概念。

其次,待对接微信公众号的接口众多,我们只为获取openId,只需要对接那么几个接口。
在这里插入图片描述

二、术语

1、用户

支付请求必须有appId和openId,所谓微信公众号的对接,对于我来说,就是为获取微信用户的openId。

为了识别用户,每个用户针对每个公众号会产生一个安全的OpenID,如果需要在多公众号、移动应用之间做用户共通,则需前往微信开放平台,将这些公众号和应用绑定到一个开放平台账号下,绑定后,一个用户虽然对多个公众号和应用有多个不同的OpenID,但他对所有这些同一开放平台账号下的公众号和应用,只有一个UnionID。

2、什么是accessToken

access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取access_token失效。

3、公众号的appId和appSecret

在所有的接口中,都必须传入这两个字段。所以你得找到它们。
在这里插入图片描述

4、安全文件

公众号设置->功能设置, 依次设置业务域名、JS接口安全域名和网页授权域名。

在这里插入图片描述

将文件MP_verify_sJ7aG7qAZXmLo2xl.txt(点击下载)上传至填写域名或路径指向的web服务器(或虚拟主机)的目录(若填写域名,将文件放置在域名根目录下,例如wx.qq.com/MP_verify_sJ7aG7qAZXmLo2xl.txt;若填写路径,将文件放置在路径目录下,例如wx.qq.com/mp/MP_verify_sJ7aG7qAZXmLo2xl.txt),并确保可以访问。

在这里插入图片描述
我这里把上面文件已保存至192.168.2.70所在的前端h5服务器。

三、对接实现

开源的微信公众号对接实现:WxJava ,及其对接示例:weixin-java-mp-demo。对接的接口比较全面,我们只选择了几个需要对接的接口。

1、对接流程

在这里插入图片描述

2、获取授权码和网页授权access_token

参考微信官方文档:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html
写得真的是太详细了,有接口有入参还有示例。(真的是有点太白看到崔颢写的登黄鹤楼有得一比)

如果你获取accessToken报错40164错误码,提示你的Ip非法,那么有两种可能:一是你没有把外网出口IP添加到白名单;二是刚添加白名单,需要等几分钟后才生效。

在这里插入图片描述

在这里插入图片描述

  • 获取授权码code:https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
  • 通过code获取网页授权access_token:https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code

返回字段说明截图,见下:
在这里插入图片描述

3、获取access_token

获取access_token的接口是:https://api.weixin.qq.com/cgi-bin/token?appid=%s&secret=%s&grant_type=client_credential

参考微信官方文档:https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html

注意:这里有两个access_token,别混淆错了。
在这里插入图片描述

至此,我们简易的对接微信公众号的接口就已满足了。(你有可能还需要定期刷新access_token、获取ticket并管理、根据openId查询用户信息等)

    /**
     * 获取微信预授权code
     */
    private String authCode = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";
    /**
     * 根据微信授权码code获取网页授权access_token和openId
     */
    private String pageAuthAccessToken = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code";
    
    /**
     * 获取access_token
     * 和下面的接口有所区别:本接口是生成access_token,而下面的接口生成的是网页授权access_token。
     */
    private String accessToken = "https://api.weixin.qq.com/cgi-bin/token?appid=%s&secret=%s&grant_type=client_credential";
    
    /**
     * 刷新access_token
     */
    private String refreshAccessToken = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=%s&grant_type=refresh_token&refresh_token=%s";
    /**
     * 获取ticket
     */
    private String jsApiTicket = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi";
    /**
     * 获取用户基本信息
     */
    private String userInfo = "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s";

4、多个公众号的配置

简单设计思路:
使用一个Map存储,key是appCode,value信息包括appId、appSecret等。

这里摘抄开源项目的代码:

  • yml配置文件
wx:
  mp:
    configs:
      - appId: wxs9a9692ecfa0kdbc # 第一个公众号的appid
        secret: 83623c6ab0f33f54266old04df7x02sa # 公众号的appsecret
        token:  # 接口配置里的Token值
        aesKey:  # 接口配置里的EncodingAESKey值
      - appId:   # 第二个公众号的appid,以下同上
        secret: 
        token: 
        aesKey: 
  • java源码
package com.github.binarywang.demo.wx.mp.config;

import com.github.binarywang.demo.wx.mp.utils.JsonUtils;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

import java.util.List;

/**
 * wechat mp properties
 *
 * @author <a href="https://github.com/binarywang">Binary Wang</a>
 */
@Data
@ConfigurationProperties(prefix = "wx.mp")
public class WxMpProperties {
    /**
     * 多个公众号配置信息
     */
    private List<MpConfig> configs;

    @Data
    public static class MpConfig {
        /**
         * 设置微信公众号的appid
         */
        private String appId;

        /**
         * 设置微信公众号的app secret
         */
        private String secret;

        /**
         * 设置微信公众号的token
         */
        private String token;

        /**
         * 设置微信公众号的EncodingAESKey
         */
        private String aesKey;
    }

    @Override
    public String toString() {
        return JsonUtils.toJson(this);
    }
}

5、权限校验

在获取微信授权码code后,调用登录接口,生成并颁发token给客户端。

后面的接口都需要校验,以保护后端的业务接口安全。

简要的校验实现:

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.http.HttpStatus;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


@Slf4j
@WebFilter(filterName = "jwtFilter", urlPatterns = {"/api/*"})
public class JwtFilter implements Filter {

    private static String PREFIX = "Bearer ";
    private static String AUTHORIZATION = "AUTHORIZATION";

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest r = (HttpServletRequest) request;
        String path = r.getRequestURI();
        # 登录接口排除在外
        if (path.contains("api/v1/login")) {
            chain.doFilter(request, response);
        } else {
            String token = r.getHeader(AUTHORIZATION);
            
            # 校验token的合法

            chain.doFilter(request, response);
        }
    }

    @Override
    public void destroy() {

    }

}

四、总结

回到我们的目标,本文非对接全部的微信公众号,只需两个接口。
正所谓“弱水三千,只取一瓢饮”,还是那句话,你如果要对接其他的更多接口,请参考上文给的开源项目。

有了用户公众号的openId,后面的支付接口测试就能进展下去了。

至于具体的支付联调,待后面有时间再补充。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

面试算法-165-随机链表的复制

题目 给你一个长度为 n 的链表&#xff0c;每个节点包含一个额外增加的随机指针 random &#xff0c;该指针可以指向链表中的任何节点或空节点。 构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成&#xff0c;其中每个新节点的值都设为其对应的原节点的值。新节…

K8s 命令行工具

文章目录 K8s 命令行工具kubectl 工具在任意节点使用kubectl方式创建对象命令显示和查找资源更新资源修补资源编辑资源Scale 资源删除资源查看pod信息节点相关操作 K8s 命令行工具 在搭建集群的时候&#xff0c;我们通过yum 下载了kubeadm kubelet kubectl 三个命令行工具&…

两步解决 Flutter Your project requires a newer version of the Kotlin Gradle plugin

在开发Flutter项目的时候,遇到这个问题Flutter Your project requires a newer version of the Kotlin Gradle plugin 解决方案分两步: 1、在android/build.gradle里配置最新版本的kotlin 根据提示的kotlin官方网站搜到了Kotlin的最新版本是1.9.23,如下图所示: 同时在Ko…

鸿蒙TypeScript学习第14天:【联合类型】

1、TypeScript 联合类型 联合类型&#xff08;Union Types&#xff09;可以通过管道(|)将变量设置多种类型&#xff0c;赋值时可以根据设置的类型来赋值。 注意&#xff1a;只能赋值指定的类型&#xff0c;如果赋值其它类型就会报错。 创建联合类型的语法格式如下&#xff1…

MATLAB 构建协方差矩阵,解算特征值和特征向量(63)

MATLAB 局部点云构建协方差矩阵,解算特征值和特征向量(63) 一、算法介绍二、算法实现1.代码2.结果一、算法介绍 对于某片有待分析的点云,我们希望构建协方差矩阵,计算特征值和特征向量,这是很多算法必要的分析方法,这里提供完整的计算代码(验证正确) !!! 特别需要注意…

10分钟带你学会配置DNS服务正反向解析

正向解析 服务端IP客户端IP网址192.168.160.134192.168.160.135www.openlab.com 一、首先做准备工作&#xff1a; 关闭安全软件&#xff0c;关闭防火墙&#xff0c;下载bind软件 [rootserver ~]# setenforce 0 [rootserver ~]# systemctl stop firewalld [rootserver ~]# y…

iOS开发之为什么需要引用计数

iOS开发之为什么需要引用计数 在iOS开发中&#xff0c;Objective-C与Swift语言都是通过引用计数进行内存管理&#xff0c;实际上Python、Ruby、C等语言也提供了基于引用计数的内存管理方式&#xff0c;它们有一个共同点&#xff0c;那就是都是面向对象的编程语言。 引用计数可…

jmeter实验 模拟:从CSV数据到加密请求到解密返回数据再到跨越线程组访问解密后的数据

注意,本实验所说的加密只是模拟加密解密,您需要届时写自己的加解密算法或者引用含有加密算法的相关jar包才行. 思路: 线程组1: 1.从CSV文件读取原始数据 2.将读取到的数据用BeanShell预习处理器进行加密 3.HTTP提取器使用加密后的数据发起请求 4.使用BeanShell后置处理器…

word从零基础到高手【办公】

第1课 - word基础操作快速入门第2课 - 让你效率10倍提升的快捷操作第3课 - word排版快速入门第4课 - 排版实战案例讲解第5课 - 搞定论文排版全过程第6课 - 让你的word更强大的神技第7课 - 提高工作效率必备的批量操作 资料截图如下: 发送: "word办公" 获取提取码

计算机视觉——图像特征提取D2D先描述后检测特征提取算法原理

概述 局部特征提取是计算机视觉中的一个重要任务&#xff0c;它旨在从图像中提取出能够代表图像局部结构和外观信息的特征。这些特征通常用于图像匹配、物体识别、三维重建、跟踪和许多其他应用。传统方法&#xff0c;如尺度不变特征变换&#xff08;SIFT&#xff09;&#xf…

6.4Python之字典的可变数据类型

字典是不可变数据类型&#xff0c;但其值都是可变数据类型。添加修改删除&#xff0c;都是通过改变寻址的方式做数据的变化。 例如&#xff1a; d1 {"a": 1, "b": 2, "c": 5} print(d1) print(id(d1)) print(d1["c"], "的ID&a…

天猫精灵要会员,不能听歌,还能用来干什么呢?榨干它的剩余价值

目录 起因&#xff1a;以听歌为主要功能的设备&#xff0c;却不能听歌了 1.蓝牙音箱 2.控制智能家电 3.万能遥控器&#xff0c;需要一个外接设备 4.倒计时/提醒&#xff0c;闹钟提醒&#xff0c;整点提醒&#xff08;这功能有人不喜欢&#xff0c;闲吵&#xff0c;还不能关…

大话设计模式——9.单例模式(Singleton Pattern)

简介 确保一个类只有一个实例&#xff0c;并提供全局访问点来获取该实例&#xff0c;是最简单的设计模式。 UML图&#xff1a; 单例模式共有两种创建方式&#xff1a; 饿汉式&#xff08;线程安全&#xff09; 提前创建实例&#xff0c;好处在于该实例全局唯一&#xff0c;不…

JVM修炼之路【11】- GC调优 、性能调优

上一篇中 我们详细讲了内存溢出 内存泄漏 还有相关的案例。 这篇博客中我们主要了解一下GC调优。 有些新手可能会有一点 疑问—— 这两者不是一回事吗&#xff1f;&#xff1f; 其实说一回事 也没错 因为GC调优本质上还是针对 堆上的内存 只不过前面我们关注的侧重点在于 不合…

Centos 7.9.2009 下 Gitlab 完全卸载

一、linux版本&#xff1a;lsb_release -a 二、GtiLab 版本 # 查看gitlab的版本号 cat /opt/gitlab/embedded/service/gitlab-rails/VERSION 三、开始卸载 3.1&#xff0c;停止Gitlab 相关服务 # 停止所有GitLab相关服务&#xff1a; sudo gitlab-ctl stop# 移除GitLab包…

Cascader 级联选择器 - 选择器最后一级数据为空

原因&#xff1a;将扁平数据转化为树形数据时&#xff0c;给每个项都添加了 children export const transList2Tree (list, rootPid) > {const result []list.forEach(item > {if (item.pid rootPid) {const children transList2Tree(list, item.id)item.children …

「51媒体-邀约媒体」活动发布会新闻通稿如何写?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 撰写活动发布会的新闻通稿需要遵循一定的结构和内容要点&#xff0c;以确保信息的准确性、完整性和吸引力。以下是撰写活动发布会新闻通稿的基本步骤和建议&#xff1a; 标题&#xff1…

【预约报名】SNP 2024转型世界大会——共创共赢

业务方式正在以惊人的速度演变&#xff0c;然而&#xff0c;您的业务数据始终是最宝贵的财富之一。在这个基础上构建人工智能和机器学习工具&#xff0c;将成为企业保持竞争力的关键。 要实现这一飞跃&#xff0c;您需要现代化的IT环境和可靠的软件解决方案&#xff0c;以确保…

力扣 |142. 环形链表 II

用快慢指针的方法 根据推出的表达式&#xff1a;slow和fast相遇的时候&#xff0c;让slow和位于头节点的p同时 向前走&#xff0c;刚好在入环的节点处相遇&#xff01;注意&#xff1a;b和c交界的点不一定是从例如-4这个节点处&#xff0c; 可能是0节点处。因为相遇的点只能是…

工厂方法模式:解锁灵活的对象创建策略

在软件设计中&#xff0c;工厂方法模式是一种非常实用的创建型设计模式&#xff0c;它不仅提升了系统的灵活性&#xff0c;还简化了对象的创建过程。本文将详细探讨工厂方法模式的核心概念、实现方式、应用场景以及与其他设计模式的对比&#xff0c;旨在提供一份全面且实用的指…