微信公众平台开发
订阅号和服务号和企业号
订阅号每天一条,收拢至订阅号文件夹,不强制推送;服务号每月一条,消息仍展示在聊天列表,但下发消息将即时提醒用户。
1、订阅号:主要偏于为用户传达资讯(类似报纸杂志),认证前后都是每天只可以群发一条消息。
2、服务号:主要偏于服务交互(类似银行,114,提供服务查询),认证前后都是每个月可群发4条消息;
3、企业号:主要用于公司内部通讯使用,需要先验证身份才可以关注成功企业号。
验证登录和授权:AccessToken
1.查看appid及appsecret
公众号后台界面查看
2.获取accessToken
1.临时方法获取
临时通过在线测试 或者 浏览器/postman等方式发送get请求获取返回结果里的accessToken
2.接口获取
第三方需要一个access_token获取和刷新的中控服务器(这个服务器会提前进行刷新,确保无缝连接)。
并发获取access_token会导致AccessToken互相覆盖,影响具体的业务功能,所以需要加并发锁
用户标识:openid和UnionID
为了识别用户,每个用户针对每个公众号会产生一个安全的OpenID。如果需要在多公众号、移动应用之间做用户共通,则需前往微信开放平台,将这些公众号和应用绑定到一个开放平台账号下。绑定后,一个用户虽然对多个公众号和应用有多个不同的OpenID,但他对所有这些同一开放平台账号下的公众号和应用,只有一个UnionID,可以在用户管理-获取用户基本信息(UnionID机制)文档了解详情。
一个用户对于一个公众号只会存在一个openid,即使取消关注了再关注,openid也不会改变。如果一个大公司下有多个公众号,会产生不同的openid,为了实现该公司下公众号间的数据互通,会有一个唯一的UnionID作为用户的唯一标识
提供服务
公众号主要通过公众号消息会话和公众号内网页来为用户提供服务的:
1、公众号消息会话
公众号是以微信用户的一个联系人形式存在的,消息会话是公众号与用户交互的基础。
目前公众号内主要有这样几类消息服务的类型,分别用于不同的场景。
1)群发消息:公众号可以以一定频次(订阅号为每天1次,服务号为每月4次),向用户群发消息,包括文字消息、图文消息、图片、视频、语音等。
在公众号后台管理界面的创作管理可以编辑后选择群发
2)被动回复消息:在用户给公众号发消息后,微信服务器会将消息发到开发者预先在开发者中心设置的服务器地址(开发者需要进行消息真实性验证),公众号可以在5秒内做出回复,可以回复一个消息,也可以回复命令告诉微信服务器这条消息暂不回复。被动回复消息可以设置加密(在公众平台官网的开发者中心处设置,设置后,按照消息加解密文档来进行处理。其他3种消息的调用因为是API调用而不是对请求的返回,所以不需要加解密)。
3)客服消息:在用户给公众号发消息后的48小时内,公众号可以给用户发送不限数量的消息,主要用于客服场景。用户的行为会触发事件推送,某些事件推送是支持公众号据此发送客服消息的,详见微信推送消息与事件说明文档。
4)模板消息:在需要对用户发送服务通知(如刷卡提醒、服务预约成功通知等)时,公众号可以用特定内容模板,主动向用户发送消息。
2、公众号内网页
许多复杂的业务场景,需要通过网页形式来提供服务,这时需要用到:
1)网页授权获取用户基本信息:通过该接口,可以获取用户的基本信息(获取用户的OpenID是无需用户同意的,获取用户的基本信息则需用户同意)
2)微信JS-SDK:是开发者在网页上通过JavaScript代码使用微信原生功能的工具包,开发者可以使用它在网页上录制和播放微信语音、监听微信分享、上传手机本地图片、拍照等许多能力。
全局返回码
公众号每次调用接口时,可能获得正确或错误的返回码,开发者可以根据返回码信息调试接口,排查错误
-1:系统繁忙,此时请开发者稍候再试
0:请求成功
4xxxx,6xxxx,9xxxx:各种问题的返回码
开始开发
1.申请服务器
2.搭建服务
后端程序配置微信的设置
3.申请公众号
4.开发者基本配置
1.填写服务器配置
服务器地址(URL)、Token和EncodingAESKey
URL是开发者用来接收微信消息和事件的接口URL。
Token可由开发者可以任意填写,用作生成签名(该Token会和接口URL中包含的Token进行比对,从而验证安全性)。
EncodingAESKey由开发者手动填写或随机生成,将用作消息体加解密密钥
填写并提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上,GET请求:signature(微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数),timestamp(时间戳),nonce(随机数),echostr(随机字符串)
通过检验signature对请求进行校验:
1)将token、timestamp、nonce三个参数进行字典序排序
2)将三个参数字符串拼接成一个字符串进行sha1加密
3)将加密后的字符串与signature对比,true表示是微信发来的,false表示不是微信。
若确认此次GET请求来自微信服务器,原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败
2.后续可以在公众号后台的开发/基本配置里修改配置:
开发者ID(AppID):自动生成
开发者密码(AppSecret):可以重置自动生成复制
IP白名单:配置自己的白名单以便调用测试接口获得access_token
服务器地址(URL):http://外网IP/wx ,端口固定为80(http://外网IP/wx)
令牌(Token):自主设置,这个token与前面的access_token不是一回事。这个token只用于验证开发者服务器
消息加解密密钥(EncodingAESKey)
5.后端进行框架构思
主要有三个部分:负责业务逻辑部分的服务器,负责对接微信API的API-Proxy服务器,以及唯一的AccessToken中控服务器
1)AccessToken中控服务器:
负责: 提供主动刷新和被动刷新机制来刷新accessToken并存储(为了防止并发刷新,注意加并发锁),提供给业务逻辑有效的accessToken。
优点: 避免业务逻辑方并发获取access_token,避免AccessToken互相覆盖,提高业务功能的稳定性。
2)API-Proxy服务器:
负责:专一与微信API对接,不同的服务器可以负责对接不同的业务逻辑,更可进行调用频率、权限限制。
优点:某台API-proxy异常,还有其余服务器支持继续提供服务,提高稳定性,避免直接暴漏内部接口,有效防止恶意攻击,提高安全性
3)后端服务的服务器
6.码代码
7.在线测试
在线测试接口可以输入access_token,进行接口测试,返回”请求失败”,说明代码有问题,检查代码逻辑。
“请求成功”,然后根据返回结果查看是否符合预期
8.真实体验
手机端微信关注测试
自定义菜单
- 自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单。
- 一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分将会以“…”代替。
- 创建自定义菜单后,菜单的刷新策略是,在用户进入公众号会话页或公众号profile(简介)页时,如果发现上一次拉取菜单的请求在5分钟以前,就会拉取一下菜单,如果菜单有更新,就会刷新客户端的菜单。测试时可以尝试取消关注公众账号后再次关注,则可以看到创建后的效果
设置类型:
click:点击推事件。用户点击click类型按钮后,微信服务器会通过消息接口推送消息类型为event的结构给开发者(参考消息接口指南),并且带上按钮中开发者填写的key值,开发者可以通过自定义的key值与用户进行交互;
view:跳转URL。用户点击view类型按钮后,微信客户端将会打开开发者在按钮中填写的网页URL,可与网页授权获取用户基本信息接口结合,获得用户基本信息。
scancode_push:扫码推事件用户点击按钮后,微信客户端将调起扫一扫工具,完成扫码操作后显示扫描结果(如果是URL,将进入URL),且会将扫码的结果传给开发者,开发者可以下发消息。(这种是直接显示结果)
scancode_waitmsg:扫码推事件且弹出“消息接收中”提示框用户点击按钮后,微信客户端将调起扫一扫工具,完成扫码操作后,将扫码的结果传给开发者,同时收起扫一扫工具,然后弹出“消息接收中”提示框,随后可能会收到开发者下发的消息。(这种会直接返回公众号界面,并等待开发者下发消息)
pic_sysphoto:弹出系统拍照发图用户点击按钮后,微信客户端将调起系统相机,完成拍照操作后,会将拍摄的相片发送给开发者,并推送事件给开发者,同时收起系统相机,随后可能会收到开发者下发的消息。
pic_photo_or_album:弹出拍照或者相册发图用户点击按钮后,微信客户端将弹出选择器供用户选择“拍照”或者“从手机相册选择”。用户选择后即走其他两种流程。
pic_weixin:弹出微信相册发图器用户点击按钮后,微信客户端将调起微信相册,完成选择操作后,将选择的相片发送给开发者的服务器,并推送事件给开发者,同时收起相册,随后可能会收到开发者下发的消息。
location_select:弹出地理位置选择器用户点击按钮后,微信客户端将调起地理位置选择工具,完成选择操作后,将选择的地理位置发送给开发者的服务器,同时收起位置选择工具,随后可能会收到开发者下发的消息。
media_id:下发消息(除文本消息)用户点击media_id类型按钮后,微信服务器会将开发者填写的永久素材id对应的素材下发给用户,永久素材类型可以是图片、音频、视频、图文消息。请注意:永久素材id必须是在“素材管理/新增永久素材”接口上传后获得的合法id。
view_limited:跳转图文消息URL用户点击view_limited类型按钮后,微信客户端将打开开发者在按钮中填写的永久素材id对应的图文消息URL,永久素材类型只支持图文消息。请注意:永久素材id必须是在“素材管理/新增永久素材”接口上传后获得的合法id。
view类型:弹出网页(pc版本)
media_id类型:显示图文消息
click类型:发现公众号系统提示:“该公众号暂时无法提供服务“
点击click类型button,微信后台会推送一个event类型的xml 给开发者,需要开发者进一步完善后台代码逻辑,增加对自定义菜单事件推送的响应,必须设置key值
创建/修改接口:
这里的url应该是直接的url,nginx配置后需要前后端代码进行重定向
“sub_button”: [ ]里为空,代表不包含二级菜单
需要先获得access_token,然后POST(使用https协议) https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN,请求体为:
1 | { |
返回0表示设置成功。
需要修改时,直接按流程发送,只是请求体里的东西作修改即可,不需要删除已有的菜单栏
查询接口:
GET https://api.weixin.qq.com/cgi-bin/get_current_selfmenu_info?access_token=ACCESS_TOKEN,返回结果的json即为接口
删除接口:
GET https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN,返回0即为删除成功
事件推送:
用户点击自定义菜单后,微信会把事件推送给开发者,请注意,点击菜单弹出子菜单,不会产生上报
推送的事件有10种类型,对应接口的type:
1 | <xml> |
个性化菜单接口
可以通过该接口,让公众号的不同用户群体看到不一样的自定义菜单
接收消息
当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包发到开发者填写的URL上。
1.接收文本消息
1.粉丝给公众号发送的文本消息
粉丝给公众号发送文本消息:“欢迎开启公众号开发者模式”,在开发者后台,收到公众平台发送的xml 如下:(下文均隐藏了ToUserName 及 FromUserName 信息)
1 | <xml> |
解释:
createTime 是微信公众平台记录粉丝发送该消息的具体时间
text: 用于标记该xml 是文本消息,一般用于区别判断
欢迎开启公众号开发者模式: 说明该粉丝发给公众号的具体内容是欢迎开启公众号开发者模式
MsgId: 是公众平台为记录识别该消息的一个标记数值, 微信后台系统自动产生
- 被动回复文本消息
即公众号给粉丝发送的文本消息,官方wiki链接: 被动回复用户消息
特别强调:
1) 被动回复消息,即发送被动响应消息,不同于客服消息接口
2) 它其实并不是一种接口,而是对微信服务器发过来消息的一次回复
3) 收到粉丝消息后不想或者不能5秒内回复时,需回复“success”字符串
4) 客服接口在满足一定条件下随时调用
公众号想回复给粉丝一条文本消息,内容为“test”, 那么开发者发送给公众平台后台的xml 内容如下:
1 | <xml> |
特别备注:
1)ToUserName(接受者)、FromUserName(发送者) 字段请实际填写。
2)createtime 只用于标记开发者回复消息的时间,微信后台发送此消息都是不受这个字段约束。
3)text : 用于标记 此次行为是发送文本消息 (当然可以是image/voice等类型)。
4)文本换行 ‘\n’。
3.回复success问题
查询官方wiki 开头强调: 假如服务器无法保证在五秒内处理回复,则必须回复“success”或者“”(空串),否则微信后台会发起三次重试。
解释一下为何有这么奇怪的规定。发起重试是微信后台为了尽可以保证粉丝发送的内容开发者均可以收到。如果开发者不进行回复,微信后台没办法确认开发者已收到消息,只好重试。
真的是这样子吗?尝试一下收到消息后,不做任何回复。在日志中查看到微信后台发起了三次重试操作,日志截图如下:
三次重试后,依旧没有及时回复任何内容,系统自动在粉丝会话界面出现错误提示“该公众号暂时无法提供服务,请稍后再试”。
如果回复success,微信后台可以确定开发者收到了粉丝消息,没有任何异常提示。因此请大家注意回复success的问题。
- 流程图
2.接收图片消息
MediaID
目的:
1)引入素材管理
2)以文本消息,图片消息为基础,可自行理解剩余的语音消息、视频消息、地理消息等
预实现功能:
接受粉丝发送的图片消息,并立马回复相同的图片给粉丝。
1.接收图片消息
即粉丝给公众号发送的图片消息。官方wiki链接:消息管理/接收消息-接受普通消息/ 图片消息从实例讲解,粉丝给公众号发送一张图片消息,在公众号开发者后台接收到的xml如下:
1 | <xml> |
特别说明:
PicUrl: 这个参数是微信系统把“粉丝“发送的图片消息自动转化成url。 这个url可用浏览器打开查看到图片。
MediaId: 是微信系统产生的id 用于标记该图片,详情可参考wiki素材管理/获取临时素材,
2.被动回复图片消息
即公众号给粉丝发送的图片消息。官方wiki链接:消息管理/发送消息-被动回复用户消息/ 图片消息)
特别说明:
1) 被动回复消息,即发送被动响应消息,不同于客服消息接口
2) 它其实并不是一种接口,而是对微信服务器发过来消息的一次回复
3) 收到粉丝消息后不想或者不能5秒内回复时,需回复“success”字符串
4) 客服接口在满足一定条件下随时调用
开发者发送给微信后台的xml 如下:
1 | <xml> |
这里填写的MediaId的内容,其实就是粉丝的发送图片的原MediaId,所以粉丝收到了一张一模一样的原图。 如果想回复粉丝其它图片怎么呢?
1) 新增素材,请参考 新增临时素材 或者 新增永久素材
2) 获取其MediaId,请参考 获取临时素材MediaID 或者 获取永久素材MediaID
3.3 流程图
3.语音消息
4.视频消息
5.小视频消息
6.地理位置信息
7.链接消息
接收事件推送
只有点击了微信的自定义菜单,才会被认定为是一个事件,向指定的url发送事件推送的xml
1 关注/取消关注事件
用户在关注与取消关注公众号时,微信会把这个事件推送到开发者填写的URL。方便开发者给用户下发欢迎消息或者做帐号的解绑。为保护用户数据隐私,开发者收到用户取消关注事件时需要删除该用户的所有信息
2 扫描带参数二维码事件
用户扫描带场景值二维码时,可能推送以下两种事件:
- 如果用户还未关注公众号,则用户可以关注公众号,关注后微信会将带场景值关注事件推送给开发者。
- 如果用户已经关注公众号,则微信会将带场景值扫描事件推送给开发者
3 上报地理位置事件
用户同意上报地理位置后,每次进入公众号会话时,都会在进入时上报地理位置,或在进入会话后每5秒上报一次地理位置,公众号可以在公众平台网站中修改以上设置。上报地理位置时,微信会将上报地理位置事件推送到开发者填写的URL。
4 自定义菜单事件
用户点击自定义菜单后,微信会把点击事件推送给开发者,请注意,点击菜单弹出子菜单,不会产生上报
5 点击菜单拉取消息时的事件推送
6 点击菜单跳转链接时的事件推送
被动回复用户消息
当用户发送消息给公众号时(或某些特定的用户操作引发的事件推送时),会产生一个POST请求,开发者可以在响应包(Get)中返回特定XML结构,来对该消息进行响应(现支持回复文本、图片、图文、语音、视频、音乐)。
严格来说,发送被动响应消息其实并不是一种接口,而是对微信服务器发过来消息的一次回复。
1、直接回复success(推荐方式) 2、直接回复空串(指字节长度为0的空字符串,而不是XML结构体中content字段的内容为空)
1、开发者在5秒内未回复任何内容 2、开发者回复了异常数据,比如JSON数据等
就会出现“该公众号暂时无法提供服务,请稍后再试”
回复文本消息:
1 | public String toXML(String toUserName,String fromUserName,String text){ |
回复图片消息
这里的media_id需要先调用接口上传图片。图片格式为jpg才能成功。
1 | public String toImageXML(String toUserName,String fromUserName,String media_id){ |
这些回复用户消息都是一般只能回复一条,如果两条的话,还需要调用客服回复消息接口。
自动回复规则
开发者可以通过该接口,获取公众号当前使用的自动回复规则,包括关注后自动回复、消息自动回复(60分钟内触发一次)、关键词自动回复
模板消息
- 模板消息调用时主要需要模板ID和模板中各参数的赋值内容
- 模板中参数内容必须以”.DATA”结尾,否则视为保留字
- 模板保留符号””
在模版消息发送任务完成后,微信服务器会将是否送达成功作为通知,发送到开发者中心中填写的服务器配置地址中
微信网页开发
适配问题
安卓版微信直接调用系统浏览器内核,它是用chrome改造做的一套WKwebView,概念上类似是一套组件,目前的安卓微信浏览器都是使用的QQ浏览器的X5内核。
iOS则是调用safari,但微信iOS客户端于2017年3月1日前逐步升级为WKWebview内核。ios也可以自己切换为UIWebview。微信内任意入口进入任意网页,在网页加载成功后向下拉动页面(或点击网页右上角菜单按钮),使之显示出地址栏,当地址栏以 “此网页由” 开头即为当前使用WKWebview(目前基本都是这个),若以“网页由”则是使用的UIWebview
网页授权
如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑。
OAuth2.0鉴权
1、引导用户进入授权页面同意授权,获取code
在确保微信公众账号拥有授权作用域(scope参数)的权限的前提下(服务号获得高级接口后,默认拥有scope参数中的snsapi_base和snsapi_userinfo),引导关注者打开如下页面:https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect 若提示“该链接无法访问”,请检查参数是否填写错误,是否拥有scope参数对应的授权作用域权限。
尤其注意:由于授权操作安全等级较高,所以在发起授权请求时,微信会对授权链接做正则强匹配校验,如果链接的参数顺序不对,授权页面将无法正常访问。
如果用户同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE
跳转回调redirect_uri,应当使用https链接来确保授权code的安全性。
code说明 : code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期
关于网页授权回调域名的说明
1、在微信公众号请求用户网页授权之前,开发者需要先到公众平台官网中的“开发 - 接口权限 - 网页服务 - 网页帐号 - 网页授权获取用户基本信息”的配置选项中,修改授权回调域名。请注意,这里填写的是域名(是一个字符串),而不是URL,因此请勿加 http:// 等协议头;
2、授权回调域名配置规范为全域名,比如需要网页授权的域名为:www.qq.com,配置以后此域名下面的页面http://www.qq.com/music.html 、 http://www.qq.com/login.html 都可以进行OAuth2.0鉴权。但http://pay.qq.com 、 http://music.qq.com 、 http://qq.com 无法进行OAuth2.0鉴权
3、如果公众号登录授权给了第三方开发者来进行管理,则不必做任何设置,由第三方代替公众号实现网页授权即可
关于网页授权的两种scope的区别说明
1、以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面)
2、以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。
3、用户管理类接口中的“获取用户基本信息接口”,是在用户和公众号产生消息交互或关注后事件推送后,才能根据用户OpenID来获取用户基本信息。这个接口,包括其他微信接口,都是需要该用户(即openid)关注了公众号后,才能调用成功的。
2、通过code换取网页授权access_token(与基础支持中的access_token不同)
这里通过code换取的是一个特殊的网页授权access_token,与基础支持中的access_token(该access_token用于调用其他接口)不同。公众号可通过下述接口来获取网页授权access_token。如果网页授权的作用域为snsapi_base,则本步骤中获取到网页授权access_token的同时,也获取到了openid,snsapi_base式的网页授权流程即到此为止。
尤其注意:由于公众号的secret和获取到的access_token安全级别都非常高,必须只保存在服务器,不允许传给客户端。后续刷新access_token、通过access_token获取用户信息等步骤,也必须从服务器发起
获取code后,请求以下链接获取access_token: https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
关于网页授权access_token和普通access_token的区别
1、微信网页授权是通过OAuth2.0机制实现的,在用户授权给公众号后,公众号可以获取到一个网页授权特有的接口调用凭证(网页授权access_token),通过网页授权access_token可以进行授权后接口调用,如获取用户基本信息;
2、其他微信接口,需要通过基础支持中的“获取access_token”接口来获取到的普通access_token调用。
3、如果需要,开发者可以刷新网页授权access_token,避免过期
由于access_token拥有较短的有效期,当access_token超时后,可以使用refresh_token进行刷新,refresh_token有效期为30天,当refresh_token失效之后,需要用户重新授权
获取第二步的access_token后,请求以下链接获取refresh_token: https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
4、通过网页授权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
关于UnionID机制
1、请注意,网页授权获取用户基本信息也遵循UnionID机制。即如果开发者有在多个公众号,或在公众号、移动应用之间统一用户帐号的需求,需要前往微信开放平台(open.weixin.qq.com)绑定公众号后,才可利用UnionID机制来满足上述需求。
2、UnionID机制的作用说明:如果开发者拥有多个移动应用、网站应用和公众帐号,可通过获取用户基本信息中的unionid来区分用户的唯一性,因为同一用户,对同一个微信开放平台下的不同应用(移动应用、网站应用和公众帐号),unionid是相同的。
关于特殊场景下的静默授权
1、上面已经提到,对于以snsapi_base为scope的网页授权,就静默授权的,用户无感知;
2、对于已关注公众号的用户,如果用户从公众号的会话或者自定义菜单进入本公众号的网页授权页,即使是scope为snsapi_userinfo,也是静默授权,用户无感知。
检验授权凭证(access_token)是否有效
http:GET(请使用https协议) https://api.weixin.qq.com/sns/auth?access_token=ACCESS_TOKEN&openid=OPENID
返回0代表有效
网页开发样式库:WEBUI
微信JS-SDK
是微信公众平台 面向网页开发者提供的基于微信内的网页开发工具包
通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验
1.绑定域名
先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
备注:登录后可在“开发者中心”查看对应的接口权限
2.引入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)。
备注:支持使用 AMD/CMD 标准模块加载方法加载
3.通过config接口注入权限验证配置
所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复)
1 | wx.config({ |
签名算法:JS-SDK使用权限签名算法
jsapi_ticket(通过access_token获取)
生成签名之前必须先了解一下jsapi_ticket,jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket 。
- 参考以下文档获取access_token(有效期7200秒,开发者必须在自己的服务全局缓存access_token):https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html
- 用第一步拿到的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 | { |
获得jsapi_ticket之后,就可以生成JS-SDK权限验证的签名了。
签名算法(通过jsapi_ticket,noncestr,timestamp,url获取)
签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。
即signature=sha1(string1)。 示例:
1 | noncestr=Wm3WZYTPz0wzccnW |
步骤1. 对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1:
1 | jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW×tamp=1414587457&url=http://mp.weixin.qq.com?params=value |
步骤2. 对string1进行sha1签名,得到signature:
1 | 0f9de62fce790f9a083d5c99e95740ceb90c27ed |
注意事项
- 签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。
- 签名用的url必须是调用JS接口页面的完整URL。
- 出于安全考虑,开发者必须在服务器端实现签名的逻辑。
4.通过ready接口处理成功验证
1 | wx.ready(function(){ |
5.通过error接口处理失败验证
1 | wx.error(function(res){ |
接口调用说明
在4的ready接口下可以继续调用以下接口:
所有接口通过wx对象(也可使用jWeixin对象)来调用,参数是一个对象,除了每个接口本身需要传的参数之外,还有以下通用参数:
- success:接口调用成功时执行的回调函数。
- fail:接口调用失败时执行的回调函数。
- complete:接口调用完成时执行的回调函数,无论成功或失败都会执行。
- cancel:用户点击取消时的回调函数,仅部分有用户取消操作的api才会用到。
- trigger: 监听Menu中的按钮点击时触发的方法,该方法仅支持Menu中的相关接口。
备注:不要尝试在trigger中使用ajax异步请求修改本次分享的内容,因为客户端分享操作是一个同步操作,这时候使用ajax的回包会还没有返回。
以上几个函数都带有一个参数,类型为对象,其中除了每个接口本身返回的数据之外,还有一个通用属性errMsg,其值格式如下:
调用成功时:”xxx:ok” ,其中xxx为调用的接口名
用户取消时:”xxx:cancel”,其中xxx为调用的接口名
调用失败时:其值为具体错误信息
基础接口
判断当前客户端版本是否支持指定JS接口。这个接口是最基本的接口,一般都需要先拿这个接口验证一下,再在这个接口下调用你所需要使用的接口。
1 | wx.checkJsApi({ |
备注:checkJsApi接口是客户端6.0.2新引入的一个预留接口,第一期开放的接口均可不使用checkJsApi来检测
1 | 例: |
WEB开发者工具
调试工具
云开发
开发者可以使用云开发开发微信小程序、小游戏、公众号,无需搭建服务器,即可使用云端能力。
云开发为开发者提供完整的原生云端支持和微信服务支持,弱化后端和运维概念,无需搭建服务器,使用平台提供的 API 进行核心业务开发,即可实现快速上线和迭代,同时这一能力,同开发者已经使用的云服务相互兼容,并不互斥。
Cookie和LocalStorage设置相关
一:退出微信账号后,将会清空所有Cookie和LocalStorage。
二:页面功能依赖Cookie,或有涉及到Cookie的相关逻辑 WKWebview内部实现变更,会影响目前页面Cookie相关的逻辑。
变化1:跨域存取Cookie 问题说明:在访问一个页面A时,如果页面A引用了另一个页面B的资源(页面A和B为不同的域名),这时页面B就被认为是第三方页面。若在页面B中设置Cookie,就会命中WKWebview下阻止第三方跨域设置Cookie的安全策略,导致问题出现。 适配建议: 在WKWebview中是默认阻止跨域的第三方设置Cookie。所有通过Cookie传递的信息,可通过业务后台存储需要传递的信息,然后给页面一个存储信息相对应的access_token加密码,再通过Url中加入自己业务的access_token进行页面间的信息传递。
变化2:微信原生层面的网络请求读取不到WKWebview中设置的cookie,即使域名是相同的。 问题说明:如果页面的资源或图片存储的服务器依赖校验Cookie来返回数据的情况,在切换到WKWebview后,在微信内长按保存,或者点击预览大图时,原生层面发起的网络请求将不会完整地带上所设置的Cookie,会导致图片保存失败或预览失败。 适配建议: 建议静态资源cookie free。如果确实有信息需要传递,可通过业务后台存储需要传递的信息,然后给页面一个存储信息相对应的access_token加密码,再通过Url中加入自己业务的access_token进行页面间信息传递。
除上述两种情况,开发者不用担心其他情况下Cookie丢失的问题,所有请求都会带上完整的Cookie
微信公众号网页引导用户关注公众号(非官方方法)
登陆微信公众号后台(https://mp.weixin.qq.com);
按F12打开调试面板,在console栏输入:
1
wx.commonData.data.uin_base64
如图:
把显示出来的字符串替换到下面的括号里;
1
https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=(上面获取到的uin_base64)#wechat_redirect
例如:
1
https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=MzxxxxxxxxxxOQ==#wechat_redirect
根据业务需求将拼接好的链接放到程序中,例如当用户点击时,跳转至此链接,引导用户关注公众号;
此方法打开公众号页面后,关注按钮会消失,不过点击顶部公众号名称时,仍可跳转到有关注入口的页面;
客服
谨慎评估客服接待能力
自动回复
微信后台提供的关键词自动回复:用户咨询之后,系统会自动匹配关键词,匹配不上的推送给多客服
关键词自动回复设置上限200条,每条最多10个关键词。加起来也就2000个关键词,适合业务类型简单,咨询问题比较集中。或者粉丝比较少的阶段
如果后台配置麻烦,可以二次开发接口,在自己的服务器后台通过接口添加关键词回复:(缺点:可能客户咨询的问题千奇百怪无法正确匹配)
如果用户咨询未匹配到关键词,系统会给出7个大的问题分类,用户可以回复问题编号。系统自动回复二级问题分类。然后在各个问题之间,设置一些相关问题编号。
通过这种主要问题框架引导+关键词匹配的方式,自动回复匹配率提升效果非常明显。适用于用户问题比较集中
还可以找做客服机器人的供应商,通过人工智能+语言搜索引擎,自动识别用户语义。根据用户的意思,推荐相关问题。这样你只用维护自己的问题库,机器人帮你解决用户提问分析。还有一些智能机器人,对接公司本身的数据库。通过对用户标签/行为/状态的分析,及规则设定。推测用户可能要问的问题,或者动态生成定制化的客服页。
客服回复
多客服回复,即人工回复:适用于个性化问题,需要配备人工回答
实现方式:简单的自动回复过滤+1个人工+尽量引导自助服务
客服回复分类:
1.根据业务分类:1号客服负责哪个系列商品
2.根据不同状态分类:1号客服负责售前,售后
3.根据客户身份分类:普通和vip专属客服
还可以找客服端供应商,功能完善。除了微信之外,很多还支持app、pc、电话等全渠道接入。在咨询数据、工作量统计、客服监控等方面也比较完善。有的也配备了智能机器人、可视化IVR(交互式语音应答)操作面板等;或者邮件、短信等营销通道;再或者CRM(客户关系管理)后台。
开通微信后台的服务下的对话能力,原导购(推荐)
可以在微信后台配置,在微信上的小程序服务号对话助手完成对话,根据用户绑定到具体的顾问。顾问可以生成自己的二维码,当客户扫描后会自动绑定到当前顾问;也可以后台直接分配。但是顾问只能主动给用户发几次消息 (以设置好的微信身份)
后台会有数据统计信息
开通微信后台的服务下的客服
由多客服功能更新来,现在是新版的客服功能。
可以绑定微信号,在网页版接入回复消息(以设置好的客服身份)。客服功能会在云端保存30天的聊天记录
只提供网页版聊天。不支持下载聊天记录,不支持手机端使用,不支持关闭会话,不支持发送语音,目前仅支持发送图片
咨询列表是按时间倒序排列。咨询量大的情况下,每次都是接进最近提问的,前面未接入的更是一直等不到
(进行绑定的时候一直显示系统繁忙,请稍后再试)
开发接口
上面两个服务都可以在后台直接配置,是微信官方给的服务。也可以自己二次开发,设置更多的功能
如果需要更强大的功能,又没有能力开发接口,可以直接使用第三方的服务:当用户发消息后,程序将消息转发给第三方,第三方通知给个人及时回复。
自己开发:
微信公众号支付(微信)
注意:
1.分为V2和V3(目前采用v2,因为文档和示例多了点)
2014年9月10号之前申请的为v2版,之后申请的都为v3版
微信支付V2版中的参数如下:
AppID
AppSecret
支付专用签名串PaySignKey
商户号PartnerID
初始密钥PartnerKey
并且包含一个证书文件: 安全证书
微信支付V3版中的参数如下:
AppID
AppSecret
商户号PartnerID
初始密钥PartnerKey
商户号MCHID
申请编号
商户平台登录帐号
商户平台登录密码
包含5个证书文件(证书pkcs12格式、证书pem格式、证书密钥pem格式、CA证书, 安全证书)
2.分为普通商户和特约商户
微信支付服务商可以非常方便的给企业开通微信支付商户,这种微信服务商开通的微信支付商户,我们通常称为子账户,微信官方称为:特约商户。特约商户与普通商户功能基本上是一样的,唯一区别就是支付流程上有些不同。子账户需要通过服务商中转,同时需要添加Sub_APPID,才能支付成功。
1、微信普通商户,需要公众号认证才能开通。而特约商户不需要公众号即可由服务商开通,但是如果想用公众号支付,仍然需要绑定已经认证的微信公众号(服务号)。
2、虽然特约商户号,可以不认证服务号就能开通(节约300元/年),但是不绑定服务号,只能使用微信扫码支付,适合线下店铺使用。如果有线上业务建议使用普通商户。
3、大部分第三方平台或微信应用都不支持特约商户的模式(Sub_APPID),所以建议如果有网站业务需要微信收款,还是使用普通微信商户吧。
基本流程:
用户点击一个支付按钮–>{后台一大推处理}–>用户看到了一个输入密码的界面,包含金额等一些信息–>用户输入密码后出来一个支付成功的页面–>返回系统自己的页面
准备工作(进行配置)
微信公众号后台,微信支付,开发配置中有一个支付授权目录,测试授权目录,测试白名单
1)获取用户授权(之前的设置获取openid)
获得用户openid
2)调用统一下单接口获取预支付id(后端程序获取prepay_id返回给前端参数)
都在后端获取
参考https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_4
请求的url:https://api.mch.weixin.qq.com/pay/unifiedorder
请求方式:POST
请求的参数列表:
参数 | 名称 | 来源 |
---|---|---|
appid | 应用ID | 登陆微信公众号后台-开发-基本配置 |
mch_id | 微信支付商户号 | 登陆微信支付后台,即可看到 |
device_info | 设备号 | 终端设备号(门店号或收银设备ID),注意:PC网页或公众号内支付请传”WEB” |
body | 商品描述 | 商品或支付单简要描述(中文可能会存在签名错误) |
trade_type | 交易类型 | JSAPI(公众号支付),NATIVE(原生扫码支付),APP(app支付) MICROPAY–刷卡支付,刷卡支付有单独的支付接口,不调用统一下单接口 (参考https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_2) |
nonce_str | 随机字符串 | 不长于32位(参考算法https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3) |
notify_url | 通知地址 | 接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数 |
out_trade_no | 商户订单号 | 商户系统内部的订单号,32个字符内、可包含字母 (参考https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_2) |
total_fee | 总金额 | 订单总金额,单位为分 |
openid | 用户标识 | trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标识 |
sign | 签名 | 官方给的签名算法(参考https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3) |
spbill_create_ip | 终端ip | 调用微信支付API的机器ip(支持ipv4和ipv6) |
receipt | 开发票入口开放标识 | 传入Y时,支付成功和支付详情页将出现开票入口(需在后台开通电子发票功能,该字段才可用) |
key(生成key需要) | 参与签名的参数 | key设置路径:微信商户平台(pay.weixin.qq.com)–>账户设置–>API安全–>密钥设置 |
获得sign:
1.把所有要传递的参数键值对去掉值是空的,剩下的参数名ASCII码从小到大排序后,使用URL键值对格式(key1=value1&key2=value2…)拼接成StringA
2.把StringA后面多加一组键值&key=商户平台密钥获得StringB
3.把StringB按要求做”MD5”或”HMAC-SHA256”计算,并将结果字符转为大写即可得到sign
调用微信的统一下单地址:https://api.mch.weixin.qq.com/pay/unifiedorder
调用统一下单地址时 传的参数个参数名称和参数值与生成签名时相比多了一个sign的参数,其他参数名称需要全部相同,nonce_str的值可以不同
获取预支付ID时,如果返回值是【签名错误】。那真是的你的签名错了,请仔细核对生成sign的参数名称、参数值和调用统一下单接口的参数名称和参数值
最终需要得到:prepay_id
将参数返回给前端
1 | public R weiXinPay(OrderDTO orderDTO) throws Exception { |
3)H5调起微信支付的内置JS(前端通过参数回调起微信的支付工具)
后台传回前台的参数
注意:WeixinJSBridge内置对象在其他浏览器中无效。
getBrandWCPayRequest参数定义:
参数 | 名称 | 说明 |
---|---|---|
appId | 应用ID | 永远不变 |
timeStamp | 时间戳 | 工具类调用(参考https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_2) |
nonceStr | 随机字符串 | 跟上面一样 |
package | 订单详情扩展字符串 | 统一下单接口返回的prepay_id参数值,提交格式如:prepay_id=*** |
signType | 签名方式 | 签名算法,暂支持MD5 |
paySign | 签名 | 这个签名,要重新生成,在后台(上面5个参数+key生成) |
注:生成prepay_id时appid是小写的i,生成paySign时,appId是大写的I
返回结果值说明:
返回值 | 描述 |
---|---|
get_brand_wcpay_request:ok | 支付成功 |
get_brand_wcpay_request:cancel | 支付过程中用户取消 |
get_brand_wcpay_request:fail | 支付失败 |
1 | vue中使用: |
4)支付完成后,微信回调URL的处理(设定的url对结果处理)
1)解析传过来的流信息,通过重新签名的方式验证流中包含的信息的正确性。就是验证sign,判断这个信息到底是不是微信发的
2)return_code和result_code都是SUCCESS的话,处理商户自己的业务逻辑。就是订单的支付状态啊等一些信息。
3)告诉微信,我收到你的返回值了。不用在发了。
和支付宝不同,微信返回的是数据流
1、商户系统对于支付结果通知的内容一定要做签名验证,并校验返回的订单金额是否与商户侧的订单金额一致,防止数据泄露导致出现“假通知”,造成资金损失。
2、当收到通知进行处理时,首先检查对应业务数据的状态,判断该通知是否已经处理过,如果没有处理过再进行处理,如果处理过直接返回结果成功。在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重入造成的数据混乱。
3、技术人员可登进微信商户后台扫描加入接口报警群,获取接口告警信息。
接口链接
该链接是通过【统一下单API】中提交的参数notify_url设置,如果链接无法访问,商户将无法接收到微信通知。
通知url必须为直接可访问的url,不能携带参数。公网域名必须为https,如果是走专线接入,使用专线NAT IP或者私有回调域名可使用http。
● notify_url需要填写商户自己系统的真实地址,不能填写接口文档或demo上的示例地址。
● notify_url必须是以https://或http://开头的完整全路径地址,并且确保url中的域名和IP是外网可以访问的,不能填写localhost、127.0.0.1、192.168.x.x等本地或内网IP。
● notify_url不能携带参数。
示例:notify_url:“https://pay.weixin.qq.com/wxpay/pay.action”
● 返回报文必须是xml格式,字段名需与接口文档说明的一致,报文前后和各字段标签中间不能包含特殊字符。
● notify_url的代码处理逻辑不能做登录态校验。
● 商户系统收到支付结果通知,需要在5秒内返回应答报文,否则微信支付认为通知失败,后续会重复发送通知。
● 同样的通知可能会多次发送给商户系统,商户系统必须能够正确处理重复的通知。如果已处理过,直接给微信支付返回成功。
● 商户侧对微信支付回调IP有防火墙策略限制的,需要对以下IP段开通白名单:
上海电信出口网段:101.226.103.0/25
上海联通出口网段:140.207.54.0/25
上海CAP出口网段:121.51.58.128/25(新增)
深圳电信出口网段:183.3.234.0/25
深圳联通出口网段:58.251.80.0/25
深圳CAP出口网段:121.51.30.128/25(新增)
香港出口网段:203.205.219.128/25
*注意:上海CAP、深圳CAP的出口为新增,商户侧需要新开防火墙
1 | //支付完成后,微信会把相关支付和用户信息发送到商户设定的通知URL,需要在这个URL下进行代码:验证签名,并回应微信。 |
微信服务器返回给url的参数
字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述 |
---|---|---|---|---|---|
返回状态码 | return_code | 是 | String(16) | SUCCESS | SUCCESS/FAIL此字段是通信标识,非交易标识,交易是否成功需要查看result_code来判断 |
返回信息 | return_msg | 否 | String(128) | 签名失败 | 返回信息,如非空,为错误原因签名失败参数格式校验错误 |
在return_code为SUCCESS的时候有返回
字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述 |
---|---|---|---|---|---|
小程序ID | appid | 是 | String(32) | wx8888888888888888 | 微信分配的小程序ID |
商户号 | mch_id | 是 | String(32) | 1900000109 | 微信支付分配的商户号 |
设备号 | device_info | 否 | String(32) | 013467007045764 | 微信支付分配的终端设备号, |
随机字符串 | nonce_str | 是 | String(32) | 5K8264ILTKCH16CQ2502SI8ZNMTM67VS | 随机字符串,不长于32位 |
签名 | sign | 是 | String(32) | C380BEC2BFD727A4B6845133519F3AD6 | 签名,详见签名算法 |
签名类型 | sign_type | 否 | String(32) | HMAC-SHA256 | 签名类型,目前支持HMAC-SHA256和MD5,默认为MD5 |
业务结果 | result_code | 是 | String(16) | SUCCESS | SUCCESS/FAIL |
错误代码 | err_code | 否 | String(32) | SYSTEMERROR | 错误返回的信息描述 |
错误代码描述 | err_code_des | 否 | String(128) | 系统错误 | 错误返回的信息描述 |
用户标识 | openid | 是 | String(128) | wxd930ea5d5a258f4f | 用户在商户appid下的唯一标识 |
是否关注公众账号 | is_subscribe | 是 | String(1) | Y | 用户是否关注公众账号,Y-关注,N-未关注 |
交易类型 | trade_type | 是 | String(16) | JSAPI | JSAPI、NATIVE、APP |
付款银行 | bank_type | 是 | String(32) | CMC | 银行类型,采用字符串类型的银行标识,银行类型见银行列表 |
订单金额 | total_fee | 是 | int | 100 | 订单总金额,单位为分 |
应结订单金额 | settlement_total_fee | 否 | int | 100 | 应结订单金额=订单金额-非充值代金券金额,应结订单金额<=订单金额。 |
货币种类 | fee_type | 否 | String(8) | CNY | 货币类型,符合ISO4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型 |
现金支付金额 | cash_fee | 是 | int | 100 | 现金支付金额订单现金支付金额,详见支付金额 |
现金支付货币类型 | cash_fee_type | 否 | String(16) | CNY | 货币类型,符合ISO4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型 |
总代金券金额 | coupon_fee | 否 | int | 10 | 代金券金额<=订单金额,订单金额-代金券金额=现金支付金额,详见支付金额 |
代金券使用数量 | coupon_count | 否 | int | 1 | 代金券使用数量 |
代金券类型 | coupon_type_$n | 否 | String | CASH | CASH–充值代金券 NO_CASH—非充值代金券并且订单使用了免充值券后有返回(取值:CASH、NO_CASH)。$n为下标,该笔订单使用多张代金券时,从0开始编号,举例:coupon_type_0、coupon_type_1注意:只有下单时订单使用了优惠,回调通知才会返回券信息。 下列情况可能导致订单不可以享受优惠:可能情况。 |
代金券ID | coupon_id_$n | 否 | String(20) | 10000 | 代金券ID,$n为下标,该笔订单使用多张代金券时,从0开始编号,举例:coupon_id_0、coupon_id_1 注意:只有下单时订单使用了优惠,回调通知才会返回券信息。 下列情况可能导致订单不可以享受优惠:可能情况。 |
单个代金券支付金额 | coupon_fee_$n | 否 | int | 100 | 单个代金券支付金额,$n为下标,从0开始编号 |
微信支付订单号 | transaction_id | 是 | String(32) | 1217752501201407033233368018 | 微信支付订单号 |
商户订单号 | out_trade_no | 是 | String(32) | 1212321211201407033568112322 | 商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|*@ ,且在同一个商户号下唯一。 |
商家数据包 | attach | 否 | String(128) | 123456 | 商家数据包,原样返回 |
支付完成时间 | time_end | 是 | String(14) | 20141030133525 | 支付完成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则 |
1 | <xml> |
1.用微信回调函数中传的参数,进行重新签名。将获得的签名与xml中的sign对比,如果相同,证明是微信返回的通知
2.进行支付完的逻辑处理
3.返回给微信收到的消息(参考https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7)
1 | String xml = "<xml> <return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>"; |
示例:
1 | <xml> |
需要返回给微信的参数
示例:
1 | <xml> |
5)支付后的验证(前端获得支付结果后需要进行查单)
1、 前端返回“用户取消”的情况,则订单状态保持未支付状态,并提示用户支付未完成。
2、前端返回“成功”或“报错”的情况,商户需要调用商户查单接口,确认订单状态。
1)如果商户查单接口明确返回支付成功,则给用户展示支付成功页。
2)如果商户查单接口返回订单未支付,需要提醒用户“稍后进入订单管理页核实订单状态,不要重复发起支付”。商户后端需要及时获取、更新订单状态,实现逻辑参考【后端服务处理】。当用户再次进入订单管理页面,对未支付的订单再次发起支付时,商户应该使用原单号发起,不要更换支付单号,避免用户重复支付。
【定时轮询查单】
如果长时间没有收到支付结果通知,商户后台应该定时轮询调用《微信支付查单接口》去核实订单状态。
方案一
以订单下单成功时间为基准(或者以前端支付返回成功或者报错后,第一次调用商户查单接口未成功的时间为基准),每隔5秒/30秒/1分钟/3分钟/5分钟/10分钟/30分钟调用《微信支付查单接口》查询一次,最后一次查询还是未返回支付成功状态,则停止后续查询,并调用《关单接口》关闭订单。(轮询时间间隔和次数,商户可以根据自身业务场景灵活设置)
方案二
定时任务每隔30秒启动一次,找出最近10分钟内创建并且未支付的订单,调用《微信支付查单接口》核实订单状态。系统记录订单查询的次数,在10次查询之后状态还是未支付成功,则停止后续查询,并调用《关单接口》关闭订单。(轮询时间间隔和次数,商户可以根据自身业务场景灵活设置)
【T+1日对账处理】
1、商户在T+1日上午10点以后,调用《微信支付对账单下载接口》,或者登录微信商户平台手工下载T日交易账单,然后根据对账单中的订单数据,逐笔与商户系统中的订单核对。
2、核对时有如下几种情况:
1)订单匹配成功,并且状态都是支付成功:正常情况,对账成功。
2)订单匹配成功,但是商户侧状态非支付成功:商户根据自身业务情况,决定是否把订单状态更新为支付成功并给用户发货,或者是给用户发起退款。
3)订单匹配失败,对账单中的单号在商户系统未找到记录:异常情况,需要商户排查系统是否出现数据异常。
4)订单匹配失败,商户系统中成功的订单在对账单中未找到记录:异常情况,需要商户排查是否订单处理逻辑有bug。
总结
微信公众号的支付:(需严格按照微信的开发文档填写对应参数,否则接口调用失败!)
1.前端调用起微信支付的组件WeixinJSBridge
2.后端调用统一下单的接口,将返回值传入前端方法里的参数:WeixinJSBridge.invoke()
3.前端根据方法的参数向微信服务器请求。后端会向统一下单时设置的url传xml格式的结果,需要进行逻辑处理并返回信息。前端会返回res.err_msg,根据返回值get_brand_wcpay_request的结果进行后续操作:
1)ok或者fail :调用后台的查单接口,订单变为已支付提示成功,订单未变提示等待,然后调用微信的查单接口进行查单
2)cancel:提示取消订单的信息
4.进行支付时进行倒计时,倒计时结束后调用关闭订单接口
5.第二天调用对账单接口进行对账
遇到的问题:
1.支付的前端页面必须同步,不能使用异步方法。
2.支付的统一下单里的参数,商品描述和系统内的订单号必须统一,否则一样的订单号,描述不一样,微信会认为是不同的两个订单,返回201 商户订单号重复。
3.如果prepay_id为null,前端取不到package里的prepay_id,会显示缺少total_fee。
微信公众号支付(支付宝)
微信公众号里调用支付宝接口只能使用网页支付
1.配置环境
1.创建应用,签约“手机网站支付”功能。然后配置关键参数
微信公众号里接入支付宝的其它方法,由于2家的竞争对象,微信中无法打开支付宝收款是微信浏览器限制所致,可以引导用户转到系统浏览器,即可用支付宝收款
关闭微信浏览器的方法
1 | document.addEventListener('WeixinJSBridgeReady', function(){ window.WeixinJSBridge.call('closeWindow'); }, false); |
注意事项
1.每个接口都有每日接口调用频次限制,可以在公众平台官网-开发者中心处查看具体频次。
2.公众平台以access_token为接口调用凭据,来调用接口,所有接口的调用需要先获取access_token,access_token在2小时内有效,过期需要重新获取,但1天内获取次数有限,开发者需自行存储,详见获取接口调用凭据(access_token)文档
3.公众平台接口调用仅支持80端口
微信公众号接口必须以http://或https://开头,分别支持80端口和443端口
4.涉及用户数据:
- 您的服务需要收集用户任何数据的,必须事先获得用户的明确同意,且仅应当收集为运营及功能实现目的而必要的用户数据, 同时应当告知用户相关数据收集的目的、范围及使用方式等,保障用户知情权。
- 您收集用户的数据后,必须采取必要的保护措施,防止用户数据被盗、泄漏等。
- 您在特定微信公众号中收集的用户数据仅可以在该特定微信公众号中使用,不得将其使用在该特定微信公众号之外或为其他任何目的进行使用,也不得以任何方式将其提供给他人。
- 如果腾讯认为您收集、使用用户数据的方式,可能损害用户体验,腾讯有权要求您删除相关数据并不得再以该方式收集、使用用户数据。
- 一旦您停止使用本服务,或腾讯基于任何原因终止您使用本服务,您必须立即删除全部因使用本服务而获得的数据(包括各种备份), 且不得再以任何方式进行使用。
其他规范:
- 请勿为任何用户自动登录到微信公众平台提供代理身份验证凭据。
- 请勿提供跟踪功能,包括但不限于识别其他用户在个人主页上查看、点击等操作行为。
- 请勿自动将浏览器窗口定向到其他网页。
- 请勿设置或发布任何违反相关法规、公序良俗、社会公德等的玩法、内容等。
- 请勿公开表达或暗示,您与腾讯之间存在合作关系,包括但不限于相互持股、商业往来或合作关系等,或声称腾讯对您的认可。