微信开发心得

微信公众号

用户标识(openid、unionid)

openid:每个用户在每个公众号都有一个不重复的标识,即openid。
多个公众号可以绑定到一个公众平台,称为用户打通,这样这些打通的公众号下的同一个用户就有了一个共通的标识,那就是unionID。

这两个id就是微信体系中用户的唯一标识。

令牌(token)

token:令牌,是cookie和session之后的优化,微信有许多开发好的接口可以直接调用调试,那么肯定不能让你随便调用,显然需要校验,那即是access_token:访问令牌,所有接口都需要校验这个值,因此不论调用微信的什么接口,都需要先获取到access_token,这样才能继续下去,目前所有的系统都是这样做的,只是验证的东西不同,机制相同,都是token,鉴权时也是这一套。

目前微信的token有效期为2小时。且重复获取将导致上次获取的access_token失效。其实这句是废话,对同一用户,token按理说同一时刻只有一个是应该的,否则维护起来太麻烦。按理说,微信公众号的token应该有一个中控服务器定时获取,方便公用。

微信的token有时效时长为2小时,调用获取接口token接口时需要加入IP白名单。

微信通信证(access_token)

https请求接口:url拼接参数时?后面都是参数,参数之间使用&连接。

GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET;

参数含义:

  • grant_type:授予类型
  • client_credential:客户端凭据;

获取access_token时通用微信的全局返回码:

  • -1:系统繁忙,此时请开发者稍候再试
  • 0:请求成功
  • 40001:AppSecret错误或者AppSecret不属于这个公众号,请开发者确认AppSecret的正确性
  • 40002:请确保grant_type字段值为client_credential
  • 40164:调用接口的IP地址不在白名单中,请在接口IP白名单中进行设置。
  • 89503:此IP调用需要管理员确认,请联系管理员
  • 89501:此IP正在等待管理员确认,请联系管理员
  • 89506:24小时内该IP被管理员拒绝调用两次,24小时内不可再使用该IP调用
  • 89507:1小时内该IP被管理员拒绝调用一次,1小时内不可再使用该IP调用

授权(auth)

一些简单的业务需求可以直接以会话的方式通过公众号(聊天的方式去沟通)。

而其他的复杂业务,一般需要自己开发第三方的网页,那么通过微信跳转到自己开发的网页的时候,就需要携带微信的一下信息,地理位置,基本信息等,这个时候就需要微信的授权了。除了获取微信用户的opneid不需要用户授权之外,其他的所有用户信息都需用户授权。

用户授权(access_token)

  • 用户授权:用户级别。微信网页授权是通过OAuth2.0机制实现的,在用户授权给公众号后,公众号可以获取到一个网页授权特有的接口调用凭证(网页授权access_token),通过网页授权access_token可以进行授权后接口调用,如获取用户基本信息。调用次数无限制,所以无需缓存。

  • 微信授权:公众号级别,与用户无关。公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用该access_token。每天调用上限为2000次,所以需要缓存,配合校验access_token是否有效接口使用。

这两个access_token只是命名相同,意义完全不同。

接口限制

微信的接口调用除需要携带access_token外,每个接口还有调用频次和规范的限制。

微信接口权限说明

接口全局返回码说明

接口调试界面

微信公众号配置

  1. 网页授权域名:用户在网页授权页同意授权给公众号后,微信会将授权数据传给一个回调页面,回调页面需在此域名下,以确保安全可靠。

    也就说网页授权域名是用来回调的,微信需要调用这个域名找到你的回调接口,因此,这个域名要看你的服务是怎么布置的,这个回调无关前端代码还是后端代码,就是回调接口所在的服务器域名。

    比如15+2,配置jmlapp.shangjietech.cn,才可以回调https://jmlapp.shangjietech.cn/scanjml/wechatUser/getRedirectUrl

    单节点服务:配置服务的服务器的域名

    多节点服务:可以任选一台服务器配置域名,但是这样会导致回调都到该节点,多节点毫无意义了;而多节点一般都有kong或者网关,或者nginx,因此这个域名在多节点的额情况下需要配置成ngnix或者网关的域名,让nginx去负载均衡,调用nginx的域名必然能找到你的回调接口,不需要关系会到哪个服务,因为哪个服务都一样。

  2. JS接口安全域名后:公众号开发者可在该域名下调用微信开放的JS接口。配置该域名的意义是前端界面的访问域名需要和该域名一致,因此这个也是配置nginx的转发域名。

  3. 业务域名:设置业务域名后,在微信内访问该域名下页面时,不会被重新排版。用户在该域名上进行输入时,不出现下图所示的安全提示;因此这里又又是nginx的域名。

也就是说以上三个域名,都是nginx的域名,也就说前端后端服务的nginx域名。

  1. 设置与开发下的安全中心下的IP白名单:在IP白名单内的IP来源,获取access_token接口才可调用成功。,也就是说需要将获取token的服务的公网ip配置好。

  2. 内容与互动下的自动回复:设置公众号回复关键字。

  3. 广告与服务下的微信支付:设置公众号和商户号的绑定。

  4. 设置与开发下开发者工具下web开发者工具,配置微信开发者的调试者微信。

网页授权流程

获取code

第一步,获取code

请求url为:

https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxc3dea25e16088e29&redirect_uri=https%3A%2F%2F2.zoppoz.workers.dev%3A443%2Fhttp%2Ftxyscan.shangjietech.com%2Fscan%2Fcode%2Fcommon%2Fgrant.shtml&response_type=code&scope=snsapi_userinfo&state=123&connect_redirect=1#wechat_redirect

返回body为:

http://txyscan.shangjietech.com/scan/code/common/grant.shtml?code=011syNGa1wkjbC0VXqHa1FZQMI1syNGM&state=123

这个url就是拉起前端界面上的授权的,白色的“确认登录”界面!

用户确认授权之后才能拿到code,但是请注意,微信网页强制授权不规范使用时,例如在用户打开网页时立即要求用户强制授权,微信会进入快照页模式,进入快照页模式时也会返回code,但只是虚拟的无效code,并且进入快照页模式还会清除当前客户端的cookie,导致服务报错“cookies失效,请重新登录”

获取授权access_token

第二步是用code获取access_token

请求url为:

https://api.weixin.qq.com/sns/oauth2/access_token?appid=wxc3dea25e16088e29&secret=2f436d4a2351a07a0ba871128292bde9&code=011syNGa1wkjbC0VXqHa1FZQMI1syNGM&grant_type=authorization_code

返回为:

{"access_token":"51_A8UPy0BmGIsoKNA7xmqgx1m_z8MjlAmD2rbreedqhsk8ll3MOmO0uN4ZXep_u1vJY2ebmE1G-9vxPSKM5DZCPA","expires_in":7200,"refresh_token":"51_K0GlPYx0YkhbBfZdk5taf07fSpGRDVZ9Ul6Z2i5GEkUt9RxFfCoZv8cHxyY4DuLdeuCVPOk-LS-f75X8p9bRqQ","openid":"oyhOYw3Imyv1o4jWWRyd-bGvECrs","scope":"snsapi_userinfo","unionid":"ogtjJ0gEoJhP1sVbMv_eHWTKvX6s"}

但是code只能用一次,再次使用就会报错:{“errcode”:40163,“errmsg”:“code been used, rid: 61a59b6a-35e123b9-28dbbf70”}

获取用户信息

第三步使用sccess_token获取的用户的个人信息。

请求url为:

 https://api.weixin.qq.com/sns/userinfo?access_token=51_A8UPy0BmGIsoKNA7xmqgx1m_z8MjlAmD2rbreedqhsk8ll3MOmO0uN4ZXep_u1vJY2ebmE1G-9vxPSKM5DZCPA&openid=oyhOYw3Imyv1o4jWWRyd-bGvECrs&lang=zh_CN

返回为:

 {"openid":"oyhOYw3Imyv1o4jWWRyd-bGvECrs","nickname":"Lipviolet_","sex":0,"language":"","city":"","province":"","country":"","headimgurl":"https:\/\/2.zoppoz.workers.dev:443\/https\/thirdwx.qlogo.cn\/mmopen\/vi_32\/Q0j4TwGTfTJqmqAVTfZ6GFibsXGaZ3lviaOdKdlbycqYADhwG3dC00cgibnB1hRdJa0mdqQHlibFerVW9bcribTSpcg\/132","privilege":[],"unionid":"ogtjJ0gEoJhP1sVbMv_eHWTKvX6s"}

经过实践发现,该access_token可以反复使用,有效期为2小时。且请求时即使openid和access_token不匹配也能获取到个人信息。

也就是说access_token是和openid是在微信服务端绑定的,不校验请求url中的access_token和openid的对应关系。只根据access_token就可以找到对应的openid,再根据openid找到用户的userinfo。

同样还可以知道,网页授权access_token是每个用户一个;普通的token是整个公众号使用同一个;前者绑定openid,后者绑定appid。

另外,openid的计算是根据你的微信名来计算的,因此微信规定每个用户的微信号不能重复,进而一个公众号下的的每个人的openid都不同。

地理位置授权流程

微信目前无法通过微信授权之后调用个人信息获取用户的个人地理位置,(且那样获取的地理位置是微信用户自己在个人信息中填写的位置信息,错误率很高)。

因此获取用户的地理位置基本都是通过js-sdk。

配置js安全域名

第一步:

  1. 登录微信公众平台启用服务器配置
  2. 配置网页授权域名填写项目所使用的的域名并将文件下载放到项目根目录
  3. 然后在配置js安全域名同样将要下载的txt文件放到项目目录

注入配置信息

第二步:

获取注入配置信息(appId、timestamp、nonceStr、signature),所有需要使用JS-SDK的页面必须先注入配置信息。

以上参数中,appid是公众号提供的,timestamp时间戳和nonceStr随机数可以自己生成,所以因此其实就是怎么获取签名signature

获取signature

第三步:得到signature,所需参数jsapi_ticket(通过access_token获取)、noncestr、timestamp、url页面路径,

以上参数中,只有access_token需要获取。

获取通行access_token

第四步:获取access_token

https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential\&appid=wx3dd8eebbefea5de8\&secret=c9cf6381c549003f6a0f6133d679fe18

返回值:

{"access_token":"ACCESS_TOKEN","expires_in":7200}

获取jsapi_ticket

第五步:获取jsapi_ticket

jsapi_ticket的有效期为7200秒,通过access_token来获取。由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket 。

https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=52_zHPWVZdptPwTlrkzGwpUOVFfcbP6WSnkitX7cJQ_Y9TaK5Cz9TpkZQ6wAuoMFAtoLWQ5CmKMV-HlyaSpYqtZPR_RQ1ZEooFy1yiSTDg8DUeXUYIMhLtCv3nzRiDhERAJ37T8bHuifVIKwvxRBFNbADARVD\&type=jsapi

返回值:

{
  "errcode":0,
  "errmsg":"ok",
  "ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",
  "expires_in":7200
}

错误返回值:

{"errcode":40001,"errmsg":"invalid credential, access_token is invalid or not latest rid: 61e0ee12-5a441147-01376ca6"}

也就是说access_token只能是最新的才能获取ticket。并且token和ticket都是会过期,新旧兼容期有5分钟。

计算签名

第六步:

计算得出签名:

signature = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(string1, "SHA1");

微信官网计算方法

前端拉起授权页

第七步:前端调用官方微信地理位置接口,引用js

<script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
<script>
    wx.config({
        debug: false,  //调式模式,设置为ture后会直接在网页上弹出调试信息,用于排查问题
        appId: "<%=vappId%>",
        timestamp: "<%=vtimestamp%>",
        nonceStr: "<%=vnoceStr%>",
        signature: "<%=vsignature%>",
        jsApiList: [ // 所有要调用的 API 都要加到这个列表中
            'getLocation'
        ]
    });
    wx.ready(function () {
        wx.getLocation({
            success: function (res) {
                var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
                var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
                var speed = res.speed; // 速度,以米/每秒计
                var accuracy = res.accuracy; // 位置精度
            },
            cancel: function (res) {
                alert('用户拒绝授权获取地理位置');
            }
        });

    });
    wx.error(function (res) {
        alert(res.errMsg); 
    });
</script>

如上经纬度便可以从前端获取到。也就是说地理位置经纬度和微信授权,都是前端需要展示,后端配合。

授权总结

  • 首先:微信业务由前端来驱动,后端是服务于前端的,提供各种必须参数。

  • 其次,微信业务体系中只有两种授权,用户授权和公众号授权。

公众号授权

扫一扫,拍照、获取地理位置等微信功能,依赖js-sdk进行操作,分5步:

  1. 步骤一:绑定域名
  2. 步骤二:引入 JS 文件
  3. 步骤三:通过 config 接口注入权限验证配置
  4. 步骤四:通过 ready 接口处理成功验证
  5. 步骤五:通过 error 接口处理失败验证

它的核心是获取公众号授权:

@PostMapping("/getWxJsSdk")

用户授权

用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑。获取用户的基本信息。获取用户的 OpenID 是无需用户同意的,获取用户的基本信息则需用户同意。

  1. 第一步:用户同意授权,获取code

  2. 第二步:通过 code 换取网页授权access_token

  3. 第三步:刷新access_token(如果需要)

  4. 第四步:获取用户access_token(需 scope 为 snsapi_userinfo)

它的核心和目的一样,获取用户access_token(网页授权access_token):

@PostMapping(value = "/getRedirectUrl",produces = "application/json;charset=utf-8")

微信支付

微信与交易有关的场景最常用的有两种

  • 微信红包:即公众号领取形式,
  • 企业付款到零钱:即商户号转账到微信零钱。

支付文档

微信正在逐步将v2接口升级成v3,核心更新就是,将原来的同步返回发放结果改为了异步。

支付模式

  1. 付款码支付:商户扫描用户的付款码,商户定义金额。
    付款码支付是用户展示微信钱包内的“刷卡条码/二维码”给商户系统扫描后直接完成支付的模式。主要应用线下面对面收银的场景。商户使用扫码枪扫描用户微信生成的付款码

  2. Native支付:本地,即用户扫描商户的收款码,用户定义金额。
    Native支付是商户系统按微信支付协议生成支付二维码,用户再用微信“扫一扫”完成支付的模式。该模式适用于PC网站支付、实体店单品或订单支付、媒体广告支付等场景。

  3. JSAPI支付:生成付款链接,每个码只能用一次,就是相当于微信生成一个付款链接,用户扫码就是输密码界面。H5、pc、公众号、线下都可以用。
    JSAPI支付是用户在微信中打开商户的H5页面,商户在H5页面通过调用微信支付提供的JSAPI接口调起微信支付模块完成支付。应用场景有:

    • 用户在微信公众账号内进入商家公众号,打开某个主页面,完成支付
    • 用户的好友在朋友圈、聊天窗口等分享商家页面链接,用户点击链接打开商家页面,完成支付
    • 将商户页面转换成二维码,用户扫描二维码后在微信浏览器中打开页面后完成支付
  4. APP支付:手机app兼容微信支付
    APP支付又称移动端支付,是商户通过在移动端应用APP中集成开放SDK调起微信支付模块完成支付的模式。

  5. H5支付:浏览器内唤起微信支付
    H5支付主要是在手机、ipad等移动设备中通过浏览器来唤起微信支付的支付产品。

  6. 小程序支付:微信小程序唤起微信支付
    小程序支付是专门被定义使用在小程序中的支付产品。目前在小程序中能且只能使用小程序支付的方式来唤起微信支付。

现金红包

商户可以通过公众号或者服务通知向用户发放现金红包。用户领取红包后,资金到达用户微信支付零钱账户

目前只有v2,v3接口微信正在开发

官方文档

  • 调用IP地址:设置之后,仅有已设置的IP地址可以调用,其余的IP调用会报错,==========》最多支持10个
  • 单日发送金额上限:该商户一天允许发放的红包总金额上限; =========》1000000 一百万
  • 单用户单日领取上限:限制同一openid同一日领取该商户的个数上限; =========》10个
  • 单用户单日领取金额上限:限制同一openid同一日领取该商户的红包金额上限 ==========》1000元
  • 防刷等级:防刷是指微信风控针对微信小号、僵尸号、机器号等的拦截,你可以通过更改防刷等级控制防刷的强度(0级为关闭,1到3逐级递增安全等级);
  • 同时,你也可以申请更改红包额度。若超过所选使用场景的默认额度,则需要经过审核,审核通过之后才会生效;
  • 发送频率限制------默认30/秒
  • 发送个数上限------默认30/秒
  • 场景金额限制------默认红包金额为1-200元,如有需要,可前往商户平台进行设置和申请
  • 其他限制------商户单日出资金额上限–100万元;单用户单日收款金额上限–1000元;单用户单日可领取红包个数上限–10个;

其实以上问题都是常规问题,现实问题往往更加繁复,但是都有一个通用办法 —> 联系微信运营申请!!!

企业付款到零钱

v2
v3

目前企业付款到微信零钱已经从V2升级到V3版本了,最终的变更就是同步变成了异步。

  • v3下单用户1天可以付款50次是他们单独申请的,并不是所有商户都有
  • v3下单用户1天最多可以收款1000的限制是腾讯根据活动场景给设定的,他们也更改不了,目前15+2,一天是5000
  • v2目前腾讯没有明确的说结束时间,不过目前只是维护,后期肯定有政策出来,因为现在越来越不稳定
  • v3支付结果返回是异步的,给我们的对接方式是,默认为成功,失败后再回调我们的接口,支付结果他们是轮询查询的,时间节点为10s,5分钟,1小时
  • 单商户号单日付款总额度150W
  • 单笔额度 0.3—20000
  • 单人单日/单卡单日收款额度2W
  • 免密支付额度1000

如果多次提现失败因为同样的原因,微信支付的服务通知一天默认只提示一次。

总结

  • 当钱相关的 额度和频率 无法满足自己的业务需求时,自己本地使用积分进行提现存储,也是个不错的方案,即引入业务钱包系统。

  • 微信红包或者零钱都是同步接口,微信会在第一时间返回结果,成功/失败,成功就是肯定成功,但是失败中有一种特殊情况,叫做未知,未知的情况下需要轮循获取最终结果,但是未知时大概率会最终成功。因此可以将未知当做成功处理,然后轮循发现失败时再回滚。

  • 微信中重要的五个返回值

    <return_code><![CDATA[SUCCESS]]></return_code>	          ===》http请求的code
    <return_msg><![CDATA[系统繁忙,请稍后再试.]]></return_msg>     ===》http请求的msg
    <result_code><![CDATA[FAIL]]></result_code>		          ===》微信转账的code,此code为String类型,fail/success,确定红包是否成功
    <err_code><![CDATA[SYSTEMERROR]]></err_code>	          ===》转账失败的code,此code为String类型,可以根据这个code确定失败原因代号
    <err_code_des><![CDATA[系统繁忙,请稍后再试.]]></err_code_des>===》转账失败的描述。
    
  • v3是微信的发展方向,将同步改为异步,可以缓解大量的服务器压力

  • 一定要注意失败中的特殊情况:未知!!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lipviolet

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值