调用vivo开放平台接口前必须确认三件事:一是获取真实app_key和app_secret,二是所有请求头带Content-Type: application/json且JSON体UTF-8编码,三是签名须按字典序拼参后计算sha256(app_secret+str+app_secret)。

PHP 调用 vivo 开放平台接口前必须确认的三件事
不能直接用 file_get_contents 或 curl_init 乱发请求——vivo 开放平台所有接口都强制要求签名(sign),且签名逻辑依赖 app_key、app_secret、时间戳、参数排序等,漏一步就返回 {"code":4001,"msg":"签名错误"}。
- 确认你已在 vivo 开发者后台 创建应用,拿到有效的
app_key和app_secret(不是测试用的 demo key) - 所有请求必须带
Content-Type: application/json,且请求体是 UTF-8 编码的 JSON 字符串,别用application/x-www-form-urlencoded - 签名计算时,参数必须按字典序升序排列(注意:是字符串 key 排序,不是值;空值也要参与排序),然后拼接成
key1=value1&key2=value2形式再做sha256(app_secret + str + app_secret)
vivo 推送服务 PHP SDK 没官方版,得自己封装 sendPush 方法
vivo 不提供 PHP 官方 SDK,常见做法是封装一个轻量类,核心是构造推送请求体并签名。别照搬 Android 或 Java 的签名逻辑——PHP 的 hash_hmac('sha256', $str, $secret) 和 vivo 要求的 sha256(secret + str + secret) 结果不同。
- 推送 endpoint 是
https://api-push.vivo.com.cn/push/v2/send,不是文档里旧的/push/v1/地址 - 必传字段包括:
app_key、timestamp(秒级时间戳)、sign、target_type(如token)、target_list(设备 token 数组)、content(消息内容对象) -
content里title和description必须存在,否则返回{"code":4002,"msg":"content 格式错误"};若要跳转,得加intent字段,格式为"intent:#Intent;action=android.intent.action.VIEW;S.browser_fallback_url=https%3A%2F%2Fexample.com;end"(注意 URL 编码)
vivo 用户授权(OAuth2)PHP 后端验签容易卡在 getAccessToken 返回 invalid_grant
前端调用 vivo SDK 拉起授权页后,会重定向回你的回调地址并带上 code。PHP 后端用这个 code 换 access_token 时,90% 的 invalid_grant 错误是因为:没用对 grant_type=authorization_code,或 code 已被用过(vivo code 一次性且 10 分钟过期),或 redirect_uri 和申请时填的不完全一致(含末尾斜杠、协议、大小写)。
- 换取 token 的 POST 请求地址是
https://api.vivo.com.cn/oauth/token,不是授权地址 - POST 参数必须是
application/x-www-form-urlencoded(和接口签名不同),包含:client_id(即app_key)、client_secret(即app_secret)、code、grant_type=authorization_code、redirect_uri(严格匹配) - 成功响应是 JSON,含
access_token、refresh_token、expires_in(单位秒)。别忽略refresh_token——vivo access_token 有效期仅 2 小时,必须用它来续期,否则用户下次登录又要授权
PHP 验证 vivo 回调通知(如推送送达、点击)必须校验 X-Vivo-Signature 头
vivo 服务端向你配置的回调地址推送事件时,会在 HTTP Header 中带 X-Vivo-Signature,值是 sha256(app_secret + raw_body + app_secret) 的十六进制小写字符串。很多人直接读 $_POST 或 $_REQUEST,但回调是纯 JSON body,PHP 默认不解析,$_POST 为空。
- 用
file_get_contents('php://input')读原始 body,确保未被修改(比如被 nginx 的client_max_body_size截断) - 签名比对前,body 必须是原始字节流(不能
json_decode后再json_encode,顺序和空格会变) - 验签失败必须返回 HTTP 200 + 空 body,否则 vivo 会反复重试(最多 3 次),可能造成重复处理
vivo 开放平台的签名规则和参数组装细节藏得深,尤其是 app_secret 在签名中出现两次、时间戳必须是秒级、redirect_uri 必须 100% 一致这些点,文档里一笔带过,但错一个就卡死。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











