微信生态应用主体
文档入口链接:https://developers.weixin.qq.com/doc/
开发配置-公众号
业务关系:微信用户 → 公众号应用 → 公众号主体 → 微信
域名设置
业务域名
JS 安全接口域名
网页授权域名
IP 白名单和服务器配置
微信开放平台管理
开发配置-企业微信
业务关系(内部开发):企业微信用户 → 企业内应用 → 企业微信
创建应用
应用配置
工作台主页
自定义菜单
聊天侧边栏配置
设置可信域名
网页授权登录-公众号
第一步:构造授权链接
(1)scope 为 snsapi_base
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx520c15f417810387&redirect_uri=https%3A%2F%2Fchong.qq.com%2Fphp%2Findex.php%3Fd%3D%26c%3DwxAdapter%26m%3DmobileDeal%26showwxpaytitle%3D1%26vb2ctag%3D4_2030_5_1194_60&response_type=code&scope=snsapi_base&state=123#wechat_redirect
(2)scope 为 snsapi_userinfo
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxf0e81c3bee622d
60&redirect_uri=http%3A%2F%2Fnba.bluewebgame.com%2Foauth_response.php
&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
第二步:服务端通过 code 换取网页授权 access_token、openId
获取 code 后,请求以下链接获取 access_token:
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&cod
e=CODE&grant_type=authorization_code
如果网页授权的作用域为 snsapi_base,则本步骤中获取到网页授权 access_token 的同时,
也获取到了 openid,snsapi_base 式的网页授权流程即到此为止。
{
\"access_token\":\"ACCESS_TOKEN\",
\"expires_in\":7200,
\"refresh_token\":\"REFRESH_TOKEN\",
\"openid\":\"OPENID\",
\"scope\":\"SCOPE\" }
第三步:刷新 access_token(如果需要)
由于 access_token 拥有较短的有效期,当 access_token 超时后,可以使用 refresh_token
进行刷新,refresh_token 有效期为 30 天,当 refresh_token 失效之后,需要用户重新授
权。
获取第二步的 refresh_token 后,请求以下链接获取 access_token:
https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refre
sh_token&refresh_token=REFRESH_TOKEN
第四步:拉取用户信息(需 scope 为 snsapi_userinfo)
如果网页授权作用域为 snsapi_userinfo,则此时开发者可以通过 access_token 和 openid
拉取用户信息了。
请求方法 http:GET(请使用 https 协议)
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
{
\"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\"}
前端授权逻辑
代码参考
准则一
不在前端暴露任何公众号信息,如 AppID,AppSecret, IP 白名单,用户的 openId 等,
以及请求的域名相关信息,需要的授权链接和参数全部从服务端获取。
准则二
需考虑多入口应用场景,如公众号菜单,消息推送链接,会话链接等。保证任何场景下,用
户每次访问都要走公众号授权登录逻辑后方可展现相关业务。
准则三
公众号应用需考虑防止用户恶意转发分享,需实现相关的逻辑判断,以避免链接域名被微信
屏蔽。
准则四
尽量部署 https 域名访问应用,防止被广告劫持及其他安全风险
网页授权登录-企业微信
第一步:获取 access_token
获取 access_token 是调用企业微信 API 接口的第一步,相当于创建了一个登录凭证,其它
的业务 API 接口,都需要依赖于 access_token 来鉴权调用者身份。
因此开发者,在使用业务接口前,要明确 access_token 的颁发来源,使用正确的
access_token。
https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ID&corpsecret=SECRET
第二步:构造授权链接
https://open.weixin.qq.com/connect/oauth2/authorize?appid=CORPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect
员工点击后,页面将跳转至 redirect_uri?code=CODE&state=STATE,企业可根据 code 参
数获得员工的 userid
第三步:获取访问用户身份
请求地址:
https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=ACCESS_TOK
EN&code=CODE
当用户为企业成员时(无论是否在应用可见范围之内)返回示例如下:
. {
. \"errcode\": 0,
. \"errmsg\": \"ok\",
. \"UserId\":\"USERID\",
. \"DeviceId\":\"DEVICEID\"
. }
JSSDK-配置
服务端签名
通过 access_token 生成 jsapi_ticket
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPI
D&secret=APPSECRET
https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&
type=jsapi
签名生成规则如下:参与签名的字段包括 noncestr(随机字符串), 有效的 jsapi_ticket,
timestamp(时间戳), url(当前网页的 URL,不包含#及其后面部分) 。对所有待签名参数按
照字段名的 ASCII 码从小到大排序(字典序)后,使用 URL 键值对的格式(即
key1=value1&key2=value2…)拼接成字符串 string1。这里需要注意的是所有参数名均为小写
字符。对 string1 作 sha1 加密,字段名和字段值都采用原始值,不进行 URL 转义。
即 signature=sha1(string1)。 示例:
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:
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW×tamp=1414587457&url=http://mp.weixin.qq.com?params=value
步骤 2. 对 string1 进行 sha1 签名,得到 signature:
0f9de62fce790f9a083d5c99e95740ceb90c27ed
前端 config 调用
使用 JS-SDK 的页面必须先注入配置信息,否则将无法调用(同一个 url 仅需调用一次。)
wx.config({
debug: true, // 开启调试模式,调用的所有 api 的返回值会在客户端 alert 出来,若要查看传入的参数,可以在 pc 端打开,参数信息会通过 log 打出,仅在 pc 端时才会打印。
appId: \'\', // 必填,公众号的唯一标识
timestamp: , // 必填,生成签名的时间戳
nonceStr: \'\', // 必填,生成签名的随机串
signature: \'\',// 必填,签名
jsApiList: [] // 必填,需要使用的 JS 接口列表});
wx.ready(function(){
// config 信息验证后会执行 ready 方法,所有接口调用都必须在 config 接口获得结果之后,config 是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在 ready 函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在 ready 函数中。});
wx.error(function(res){
// config 信息验证失败会执行 error 函数,如签名过期导致验证失败,具体错误信息可以打开 config 的 debug 模式查看,也可以在返回的 res 参数中查看,对于 SPA 可以在这里更新签名。});
微信支付
商户模式和支付场景
设置支付目录
商户实际的支付目录必须和在微信支付商户平台设置的一致,否则会报错\"当前页面的 URL 未注册:\"
业务流程
商户系统和微信支付系统主要交互:
1、商户 server 调用统一下单接口请求订单,api 参见公共 api【统一下单 API】
2、商户 server 可通过【JSAPI 调起支付 API】调起微信支付,发起支付请求。
3、商户 server 接收支付通知,api 参见公共 api【支付结果通知 API】
4、商户 server 查询支付结果,api 参见公共 api【查询订单 API】
服务端统一下单
URL 地址:https://api.mch.weixin.qq.com/pay/unifiedorder
请求参数
wx2421b1c4370ec43b
支付测试
JSAPI 支付测试
10000100
<![CDATA[{ \"goods_detail\":[ { \"goods_id\":\"iphone6s_16G\", \"wxpay_go
ods_id\":\"1001\", \"goods_name\":\"iPhone6s 16G\", \"quantity\":1, \"price\":528800, \"go
ods_category\":\"123456\", \"body\":\"苹果手机\" }, { \"goods_id\":\"iphone6s_32G\", \"wxp
ay_goods_id\":\"1002\", \"goods_name\":\"iPhone6s 32G\", \"quantity\":1, \"price\":60880
0, \"goods_category\":\"123789\", \"body\":\"苹果手机\" } ] }]]>
1add1a30ac87aa2db72f57a2375d8fec
http://wxpay.wxutil.com/pub_v2/pay/notify.v2.php</notify_url>
oUpF8uMuAJO_M2pxb1Q9zNjWeS6o
1415659990
14.23.150.211
1
JSAPI
0CB01533B8C1EF103065174F50BCA001
服务端生成签名
签名的参数如下:
appid: wxd930ea5d5a258f4f
mch_id: 10000100
device_info: 1000
body: test
nonce_str: ibuaiVcKdpRxkhJA
第一步:对参数按照 key=value 的格式,并按照参数名 ASCII 字典序排序如下:
stringA=\"appid=wxd930ea5d5a258f4f&body=test&device_info=1000&mch_id=10000100&no
nce_str=ibuaiVcKdpRxkhJA\";
第二步:拼接 API 密钥:
stringSignTemp=stringA+\"&key=192006250b4c09247ec02edce69f6a2d\" //注:key 为商户
平台设置的密钥 key
sign=MD5(stringSignTemp).toUpperCase()=\"9A0A8659F005D6984697E2CA0A9CF3B7\" //
注:MD5 签名方式
sign=hash_hmac(\"sha256\",stringSignTemp,key).toUpperCase()=\"6A9AE1657590FD6257D6
93A078E1C3E4BB6BA4DC30B23E0EE2496E54170DACD6\" //注:HMAC-SHA256 签名方式,部分
语言的 hmac 方法生成结果二进制结果,需要调对应函数转化为十六进制字符串。
得到签名
9A0A8659F005D6984697E2CA0A9CF3B7
前端 JSAPI 调起支付
方式一:WeixinJSBridge
function onBridgeReady(){
WeixinJSBridge.invoke(
\'getBrandWCPayRequest\', {
\"appId\":\"wx2421b1c4370ec43b\", //公众号名称,由商户传入
\"timeStamp\":\"1395712654\", //时间戳,自 1970 年以来的秒数
\"nonceStr\":\"e61463f8efa94090b1f366cccfbbb444\", //随机串
\"package\":\"prepay_id=u802345jgfjsdfgsdg888\", \"signType\":\"MD5\", //
微信签名方
式: \"paySign\":\"70EA570631E4BB79628FBCA90534C63FF7FADD89\" //微信签
名 },
function(res){
if(res.err_msg == \"get_brand_wcpay_request:ok\" ){
// 使用以上方式判断前端返回,微信团队郑重提示://res.err_msg 将在用
户支付成功后返回 ok,但并不保证它绝对可靠。 } });
方式二:jssdk
wx.chooseWXPay({
timestamp: 0, // 支付签名时间戳,注意微信 jssdk 中的所有使用 timestamp 字段均为小写。但最新版的支付后台生成签名使用的 timeStamp 字段名需大写其中的 S 字符
nonceStr: \'\', // 支付签名随机串,不长于 32 位
package: \'\', // 统一支付接口返回的 prepay_id 参数值,提交格式如:prepay_id=\\*\\*\\*)
signType: \'\', // 签名方式,默认为\'SHA1\',使用新版支付需传入\'MD5\'
paySign: \'\', // 支付签名
success: function (res) {
// 支付成功后的回调函数
}});