微信支付-JSAPI

必要条件

  • 一台可通过公网地址访问的服务器

    服务器可在阿里云或腾讯云购买。

  • 一个具有支付接口权限的公众号

    公众号自然是在 ‘微信公众平台’ 申请。具有支付权限的公众号得注册为企业级公众号(或称为服务号),并且通过了企业认证。企业认证需要机关单位或企业门店的 ‘营业执照’ 。在公司的话可使用公司营业执照。如果是个人,除了借别人的就只能自己去办一个了。(我就是自己去申请办理了 “个体工商户营业执照”。办理这个营业执照需要房屋或经营场所的产权使用证明和身份证。房屋使用证明可以是购房合同,和租赁合同,或产权证和产权所有方手写的一张授权使用证明。办理地点就在经营场所所在当地的市场监督管理局,一般一周就能办理下来。办理下来后根据规定得去当地的税务局办理税务登记手续,然后就可以去正规的刻章店刻章了,这时候你这个个体户也就是小企业可以开张了。公众号有了营业执照和公章就足以办理企业认证了。当然如果你办公场地装修好了也有人上岗办公了那么这个时候可以去银行开通一个对公账户。微信支付可用的上,没有的话也没关系微信支付也可以填写私人银行账户。另外:办理税务登记后记得每个季度去办理税务申报,可在网上办理也可直接去税务局办理。逾期没办的税务局会打电话给你,有可能会影响企业信誉)

    听说前段时间微信给个人公众号也开放的支付功能,我还没去看相关文档。

  • 一个已经通过了备案的域名

    域名和服务器一样可在阿里或腾讯购买。(不过我忘了域名备案需要些什么东西了)

  • 具有一定的前后端开发能力以及服务器搭建能力

实现步骤

首要目标

在微信的小程序或公众号内的支付场景中,除了业务上的一些交互外往往最终付款的时候我们就是通过一个按钮 “结算” 或 “付款” 来唤起支付页面。然后输入密码,成功后就跳转到支付成功的页面。事实上也是如此。通过微信开放文档得知唤起支付页面就是下面这段 js 代码

1
2
3
4
5
6
7
8
9
10
11
//文档地址:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#58
wx.chooseWXPay({
timestamp: 0, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
nonceStr: '', // 支付签名随机串,不长于 32 位
package: '', // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
signType: '', // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
paySign: '', // 支付签名
success: function (res) {
// 支付成功后的回调函数(跳转到支付成功页面等操作)
}
});

我们的目标就是要这段代码能够完美的得到执行。

通过阅读文档发现这段 js 需要的参数package prepay_id 得通过统一下单接口才能拿到。而调用统一下单接口又有一个关键参数 openId 而这个 openId 得通过网页授权才能拿到。

网页授权的前提又必须开启公众号的开发者模式。开启开发者模式可参看本博客文章 微信公众号配置服务器

第一步:网页授权

网页授权又分为如下四步

文档地址:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html

引导用户进入授权页面同意授权,获取code

​ 执行窗口跳转 js 弹出授权页面

1
2
let url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxf0e81c3bee622d60&redirect_uri=http%3A%2F%2Fnba.bluewebgame.com%2Foauth_response.php&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect"
window.location.href = wxUrl;

参数 是否必须 说明
appid 公众号的唯一标识
redirect_uri 授权后重定向的回调链接地址, 请使用 urlEncode 对链接进行处理
response_type 返回类型,请填写code
scope 应用授权作用域,snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且, 即使在未关注的情况下,只要用户授权,也能获取其信息 )
state 重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节
#wechat_redirect 无论直接打开还是做页面302重定向时候,必须带此参数

appid:公众号 -> 基本配置 -> 公众号开发信息 开发者ID(AppID)

redirect_uri:为前端一个页面的地址。用户同意授权后会重定向到这个地址并会在地址后面跟上 code 值。在这个地址页面中我们通过解析到地址的 code 值向后端发起请求获取 access_token 从而获取到 openid

1
2
3
// vue 可通过 route 组件快速获取到 code 值
let code = this.$route.query.code;
alert(code);
通过code换取网页授权access_token

​ 获取code后,请求以下链接获取access_token: https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

1
2
3
4
5
6
// java 使用 fegin 请求 http 接口    
@RequestLine("GET /sns/oauth2/access_token?appid={appId}&secret={secret}&code={code}&grant_type=authorization_code")
public String getWebPageAccessToken(@Param("appId") String appId,
@Param("secret") String secret,
@Param("code") String code
);
参数 是否必须 说明
appid 公众号的唯一标识
secret 公众号的appsecret
code 填写第一步获取的code参数
grant_type 填写为authorization_code

secret:公众号 -> 基本配置 -> 公众号开发信息 开发者密码(AppSecret) ps: 没有的话根据提示设定下就可以了

接口成功返回如下:

1
2
3
4
5
6
7
{
"access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE"
}
参数 描述
access_token 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
expires_in access_token接口调用凭证超时时间,单位(秒)
refresh_token 用户刷新access_token
openid 用户唯一标识,请注意,在未关注公众号时,用户访问公众号的网页,也会产生一个用户和公众号唯一的OpenID
scope 用户授权的作用域,使用逗号(,)分隔

如果需要,开发者可以刷新网页授权access_token,避免过期

由于access_token拥有较短的有效期,当access_token超时后,可以使用refresh_token进行刷新,refresh_token有效期为30天,当refresh_token失效之后,需要用户重新授权。(这里建议 access_token 存放在 redis 中,利用 redis 过期回调机制来反复更新 token)

获取第二步的refresh_token后,请求以下链接获取access_token: https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN

参数 是否必须 说明
appid 公众号的唯一标识
grant_type 填写为refresh_token
refresh_token 填写通过access_token获取到的refresh_token参数

正确时返回的JSON数据包如下:

1
2
3
4
5
6
7
{ 
"access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE"
}

通过网页授权access_token和openid获取用户基本信息(支持UnionID机制)

如果网页授权作用域为snsapi_userinfo,则此时开发者可以通过access_token和openid拉取用户信息了。

请求方法

http:GET(请使用https协议) https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

参数说明

参数 描述
access_token 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
openid 用户的唯一标识
lang 返回国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语

返回说明

正确时返回的JSON数据包如下:

1
2
3
4
5
6
7
8
9
10
11
{   
"openid": "OPENID",
"nickname": NICKNAME,
"sex": 1,
"province":"PROVINCE",
"city":"CITY",
"country":"COUNTRY",
"headimgurl":"https://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
"privilege":[ "PRIVILEGE1" "PRIVILEGE2" ],
"unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}
参数 描述
openid 用户的唯一标识
nickname 用户昵称
sex 用户的性别,值为1时是男性,值为2时是女性,值为0时是未知
province 用户个人资料填写的省份
city 普通用户个人资料填写的城市
country 国家,如中国为CN
headimgurl 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。
privilege 用户特权信息,json 数组,如微信沃卡用户为(chinaunicom)
unionid 只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。

第二步: 微信 js-sdk 初始化配置

通过网页授权我们已经可以拿到 openid 了。这时我们是否可以执行 wx.chooseWXPay 这个 js 了呢?还不行!这里有三个步骤还要做

文档地址:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#4

步骤一:绑定域名

先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。

image-20210304235456875

这里根据提示操作下载证书配置即可。(这里的域名简单理解就是前端服务的域名)

备注:登录后可在“开发者中心”查看对应的接口权限。

步骤二:引入JS文件

在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.6.0.js

如需进一步提升服务稳定性,当上述资源不可访问时,可改访问:http://res2.wx.qq.com/open/js/jweixin-1.6.0.js (支持https)。

步骤三:通过config接口注入权限验证配置

所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复)。

1
2
3
4
5
6
7
8
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,公众号的唯一标识
timestamp: , // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '',// 必填,签名
jsApiList: [] // 必填,需要使用的JS接口列表 如只想调用支付js例:jsApiList: ['chooseWXPay']
});

wx.config 所需的参数需调后端接口返回。

(部分前端代码)

1
2
3
4
5
6
7
let url = process.env.API_PROXY_ROOT+"/weixin/wx-config-signature";
let param_url = window.location.href.split("#")[0];
api.get(url,{params:{
openid:"openid",
url:param_url
}}).then(res => {
}

(部分后端代码如下)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@Override
public ApiResult getWXConfigSignature(HttpServletRequest request, String openid, String url) {
long timeStampSec = System.currentTimeMillis() / 1000;
String timestamp = String.format("%010d", timeStampSec);
String nonceStr = RandomString.make(8);
String ticket = this.getTicket(openid);
if (ticket==null){
return ApiResult.fail(ResultCodeEnum.ERROR_WX_TOKEN_EXPIRED);
}
log.info("随机串:"+nonceStr+", 获取签名URL: " + url);
JSONObject respJson = new JSONObject();
String[] signArr = new String[]{"url=" + url, "jsapi_ticket=" + ticket, "noncestr=" + nonceStr, "timestamp=" + timestamp};
Arrays.sort(signArr);
String signStr = StringUtils.join(signArr, "&");
System.out.println("签名string!=:"+signStr);
String resSign = DigestUtils.sha1Hex(signStr);

log.info("返回的签名:" + resSign);
respJson.put("appId", appId);
respJson.put("timestamp", timestamp);
respJson.put("nonceStr", nonceStr);
respJson.put("signature", resSign);
log.info(respJson.toString());
return ApiResult.ok(respJson);
}

签名算法

签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。

即signature=sha1(string1)。 示例:

1
2
3
4
noncestr=Wm3WZYTPz0wzccnW
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg
timestamp=1414587457
url=http://mp.weixin.qq.com?params=value

步骤1. 对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1:

1
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW&timestamp=1414587457&url=http://mp.weixin.qq.com?params=value

步骤2. 对string1进行sha1签名,得到signature:

1
0f9de62fce790f9a083d5c99e95740ceb90c27ed

jsapi_ticket

jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取(注意这里的 token 不是前面网页授权的 token 详情参看文档)。由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket 。

  1. 参考以下文档获取access_token(有效期7200秒,开发者必须在自己的服务全局缓存access_token):https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html
  2. 用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket):https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi

成功返回如下JSON:

1
2
3
4
5
6
{
"errcode":0,
"errmsg":"ok",
"ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",
"expires_in":7200
}

获得jsapi_ticket之后,就可以生成JS-SDK权限验证的签名了。

第三步:唤起支付

终于到了 wx.chooseWXPay 的部分了。不过别高兴的太早,前面也说了调用这段 js 代码需要的 prepay_id 等参数我们需要提前准备好来,自然也是请求后端接口获取到喽。获取 prepay_id 的过程称之为 统一下单

文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1

统一下单

在官方文档中统一下单的参数还是不少的。有了参数后还需要生成签名。生成完签名后参数 map 还得转成 xml 格式。这里微信提供了 java 版 demo 可以帮我们省去不少麻烦。

demo下载 文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1

java版下载解压后如下:

image-20210305104608204

根据个人喜好可以将 src 代码和 pom 依赖复制到项目使用。也可以用 maven 打个包后引入项目中使用。打包时可能会遇到一个错误,这是由于构建该项目的 maven 版本比较老导致的。百度下解决方法就是在 pom 的 build 标签里的内容用 pluginManagement 包裹下就好。另外注意打包前 需将源码 WXPayConfig 类中的 抽象方法都加上 public 修饰(不要问我为啥,你试过就知道)

在项目中使用的时候可参照 README.md 文件进行使用。算了还是贴下我的代码吧。他文件中说的不对 不是用 implements 而是用 extends 一些方法的实现也不全。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
public class MyConfig extends WXPayConfig {

private byte[] certData;

public MyConfig() throws Exception {
String certPath = "";
// String certPath = path_linux;
System.out.println("path:=="+certPath);
if (IpAddressUtil.isWindowsOS()){
// 证书文件登录商户平台申请和安装:https://pay.weixin.qq.com/index.php/core/cert/api_cert
certPath = "F:\\\\个人开发\\\\证书\\\\weixin\\\\WXCertUtil\\\\cert\\\\apiclient_cert.p12";
}
File file = new File(certPath);
InputStream certStream = new FileInputStream(file);
this.certData = new byte[(int) file.length()];
certStream.read(this.certData);
certStream.close();
}
@Override
public String getAppID() {
//公众号 appid
return "appId";
}

@Override
public String getMchID() {
//登录商户平台获取:https://pay.weixin.qq.com/index.php/extend/employee
return "商户id";
}

@Override
public String getKey() {
//登录商户平台设置:https://pay.weixin.qq.com/index.php/core/cert/api_cert
return "商户api密钥";
}

@Override
public InputStream getCertStream() {
ByteArrayInputStream certBis = new ByteArrayInputStream(this.certData);
return certBis;
}

@Override
public int getHttpConnectTimeoutMs() {
return 8000;
}

@Override
public int getHttpReadTimeoutMs() {
return 10000;
}

@Override
public IWXPayDomain getWXPayDomain() {
IWXPayDomain iwxPayDomain = new IWXPayDomain() {
@Override
public void report(String domain, long elapsedTimeMillis, Exception ex) {
}
@Override
public DomainInfo getDomain(WXPayConfig config) {
return new IWXPayDomain.DomainInfo(WXPayConstants.DOMAIN_API, true);
}
};
return iwxPayDomain;
}
}

除去上边配置的参数和非必填项,统一下单的参数大概有这些(不包括签名)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Map<String, String> data = new HashMap<String, String>();
//商品描述 自定义
data.put("body", "青云软件工作室会员充值");
//商户订单号(这里的订单号长度不能太短,不然会提示该参数无效。传 1 和 100 就能见效哦)
data.put("out_trade_no", "生成的订单号");
//设备号 自定义参数,可以为终端设备号(门店号或收银设备ID),PC网页或公众号内支付可以传"WEB"
data.put("device_info", "");
//标价币种
data.put("fee_type", "CNY");
//标价金额 支付金额 单位为 分
data.put("total_fee", "total_fee");
//终端IP java后台从请求头中解析得到的微信端页面请求来的IP
data.put("spbill_create_ip", "ip");
//通知地址
data.put("notify_url", "微信支付处理成功后回调地址");
//交易类型
data.put("trade_type", "JSAPI");
//JSAPI 方式 支付时 必须传openid
data.put("openid","openid");
//商品ID trade_type=NATIVE时,此参数必传。此参数为二维码中包含的商品ID,商户自行定义。
//data.put("product_id", "12");

调用统一下单:

1
2
3
4
5
MyConfig config = new MyConfig();
WXPay wxpay = new WXPay(config);
//统一下单。参数 data 就是上面的 map.
//wxpay.unifiedOrder 方法内部会自动为我们生成签名 并将参数转换成 xml 。然后 调用微信接口将结果返回。
Map<String, String> resp = wxpay.unifiedOrder(data);

成功后我们就能拿到 prepay_id 了

1
2
3
4
5
6
7
if ("SUCCESS".equals(resp.get("return_code"))){
//业务 ok
if ("SUCCESS".equals(resp.get("result_code"))){
//预支付会话标识
String prepay_id = resp.get("prepay_id");
}
}
组织参数并返回给前端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Map map = new HashMap<String,String>();
map.put("appId",appId);
map.put("timeStamp",String.valueOf(System.currentTimeMillis() / 1000));
map.put("nonceStr",RandomString.make(16));
//prepay_id 就是一字符串。但这里需拼接 prepay_id=
map.put("package","prepay_id="+prepay_id);
//签名类型 得与统一下单 wxpay.unifiedOrder 中的保持一致。
//看到 微信文档中有的地方会说 签名方式默认 MD5。但我这边 wxpay.unifiedOrder 里就是 HMAC-SHA256。哈哈 坑死人不偿命的那种
//不知道官方 demo wxpay.unifiedOrder 的签名以后会不会改。这里最好要自己 debug 看下
map.put("signType","HMAC-SHA256");
// 签名 说明:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#58
//WXPayUtil.generateSignature 为官方 demo 里的方法 拿过来用就是了
String sign = WXPayUtil.generateSignature(map,mchkey, WXPayConstants.SignType.HMACSHA256);
map.put("paySign",sign);
return ApiResult.ok(map);
唤起支付

唤起支付所在的的页面是需要在配置的

相关文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_3

一切就绪 前端 js 可通过按钮来触发这段代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
wxpay:function () {
//后台预支付(统一下单) 接口地址
let url = process.env.API_PROXY_ROOT+"/weixin/prepay-order";
let params = {
//根据业务接口的设定 来传
};
api.post(url,{params:params}).then(res => {
let con = res.data;
console.log(con);
if (con.success==true){
//唤起支付 这里的 con.data 就是上面组织的 参数 map 哦
wx.chooseWXPay({
timestamp: con.data.timeStamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
nonceStr: con.data.nonceStr, // 支付签名随机串,不长于 32 位
package: con.data.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
signType: con.data.signType, // 签名方式
paySign: con.data.paySign, // 支付签名
success: function (res) {
// 支付成功后的回调函数
//如果清空购物车 调用 api 清空购物车
debugger
console.log(res);
}
});
}
})
},

如果一次性成功!那么恭喜你太幸运了。

关于调试

  • 在整个开发配置中微信让我们配置了一些个域名或目录(如支付目录,js 安全域名等),这些其实都限制了我们在调试的时候必须使用域名。我的做法是把域名解析到自己宽带的IP(前提是网络拨号得到的IP,如果不是的话可打供应商电话让其配置),然后在路由器配置虚拟服务器和端口转发,转到自己电脑的ip和端口上。这样通过域名访问的公众号页面经过路由器由转到我们本地来了。
  • 此外唤起支付的 js 在开发者工具上执行是没有效果的。会提示:chooseWXPay:没有此SDK或暂不支持此SDK模拟。是因为这个 js 只有在手机微信的浏览器执行才能被识别。微信开发者工具有个预览功能,点击会有二维码。在手机与电脑在同一网络环境下手机微信扫码该页面就能在微信里打开了。自此就能正常唤起支付了。

关于工具

关于公众号的一些配置

  • 公众号 -> 基本配置

    image-20210305162815211

    1. 开发者密码:一些配置项要用到
    2. ip 白名单:白名单中的 IP 才能调微信的接口
    3. 服务器配置:配置成功才能成为开发者。然后才可以在公众平台网站中申请微信认证,认证成功后,将获得更多接口权限
  • 公众号-> 开发者工具 -> web 开发者工具

    image-20210305165240649

    绑定过的开发者账号才能登录微信开发者工具。绑定的对象必须是关注了该公众号的用户。

  • 公众号 -> 公众号设置

    image-20210305165514980

    在这些域名下的前端服务才能调用微信 js 功能。

  • 微信商户平台 -> 账户中心 -> API安全

    image-20210305165854877

    API证书与API密钥调用支付接口需用到。

    商户信息的商户 id 支付接口也会用到。

参考文档

微信开发文档:https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Overview.html

JSAPI 开发文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=1_1

博客:https://blog.csdn.net/u013391488/article/details/79314041