# 小游戏消息推送

# 接入小游戏消息推送

首先您得告诉我们您的服务器地址

# 第一步:确定你要接入的推送能力

小游戏目前提了两种消息推送能力,分别是页面(微信公众平台)「功能」-「虚拟支付2.0」-「基本配置」-「基础配置」下的 “事件订阅配置” 和“发货推送配置”。

# 第二步:填写服务器配置

以发货推送配置为例子,点击“配置”填写服务器地址(URL)、令牌(Token) 和 消息加密密钥(EncodingAESKey)等信息。

  • URL: 开发者用来接收道具发货消息事件的接口 URL。开发者所填写的URL 必须以 http:// 或 https:// 开头,分别支持 80 端口和 443 端口。(如果你的url请求时间超过3s,会发生超时错误

  • Token: 可由开发者可以任意填写,用作生成签名(该 Token 会和接口 URL 中包含的 Token 进行比对,从而验证安全性)。

  • EncodingAESKey: 由开发者手动填写或随机生成,将用作消息体加解密密钥。

同时,开发者可选择消息加解密方式:明文模式、和安全模式(推荐)。注意:消息数据格式仅支持JSON 格式,使用安全模式开发者需要对收到的消息进行解密,但回复微信服务器的消息不需要加密

# 第三步:验证消息来自微信服务器

点击“模拟推送”,微信服务器会发送GET请求到填写的服务器地址URL上,GET请求(例如: https://your_host?signature=6298f2b139f33959c59d69da33f5c4215d9df26a&timestamp=1700735027&nonce=50328042&echostr=Mzi3wDcVa5uI)携带参数如下表所示:

参数 描述
signature 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
timestamp 时间戳
nonce 随机数
echostr 随机字符串

开发者通过检验 signature 对请求进行校验(下面有校验方式)。若确认此次 GET 请求来自微信服务器,请原样返回 echostr 参数内容,则接入生效,页面的“测试状态”会显示“已通过”,否则接入失败。

签名校验流程如下:

  1. 将token、timestamp、nonce三个参数进行字典序排序

  2. 将三个参数字符串拼接成一个字符串进行sha1加密

  3. 开发者获得加密后的字符串可与signature对比,确认该请求来源于微信

检验signature的PHP示例代码:

private function checkSignature()
{
    $signature = $_GET["signature"];
    $timestamp = $_GET["timestamp"];
    $nonce = $_GET["nonce"];

    $token = TOKEN;
    $tmpArr = array($token, $timestamp, $nonce);
    sort($tmpArr, SORT_STRING);
    $tmpStr = implode( $tmpArr );
    $tmpStr = sha1( $tmpStr );

    if ($tmpStr == $signature ) {
        return true;
    } else {
        return false;
    }
}

PHP示例代码下载:下载链接文档

# 第四步:配置测试链接

如果开发者有测试需求,可以点击“修改”生成一个发布中的版本,发布中的版本可以添加白名单用于测试。

服务器配置完成后,有的推送业务(例如“直购道具”和“商城道具”的发货推送)还需要进行业务消息的推送测试才可以开启推送,操作流程看下文的消息推送测试。

# 消息推送协议

# 直购/商城道具发货消息

# 请求参数

参数 类型 描述
ToUserName String 小游戏原始ID
FromUserName String 该事件消息的openid,道具发货场景固定为微信官方的openid
CreateTime Number 消息发送时间
MsgType String 消息类型,道具发货场景固定为:event
Event String 事件类型
商城道具场景固定为:minigame_h5_goods_deliver_notify
道具直购(游戏内)场景固定为:minigame_game_pay_goods_deliver_notify
MiniGame Object 道具直购发货参数

MiniGame

字段 类型 说明
Payload String 携带的具体内容,格式为json,具体内容如下表格Payload(因为这里需要对消息内容统一签名,所以统一把消息内容设计成json格式)
PayEventSig String 支付请求签名算法说明 (PayEventSig)
IsMock Bool True: 模拟测试推送 False:真实推送

Payload(JSON)

字段 类型 说明
OpenId String 接收道具的玩家openid
Env Number 环境配置
0:现网环境(也叫正式环境)
1:沙箱环境
OutTradeNo String 订单号
GoodsInfo Object 发货道具

GoodsInfo

字段 类型 说明
ProductId String 游戏道具id标识
Quantity Number 购买道具数量
ZoneId String 分区
OrigPrice Number 物品原始价格 (单位:分)
ActualPrice Number 物品实际支付价格(单位:分)
Attach String 透传数据
OrderSource Number 1 游戏内 2 商城下单 3 商城测试下单

# 返回参数

字段 类型 是否必填 说明
ErrCode Number 发送状态。0:成功,其他:失败 todo
ErrMsg String 错误原因,用于调试。在errcode非0 的情况下可以返回

# 消息推送测试

在完成相应业务的消息推送测试后,才会开启对应业务的消息推送服务,以“直购道具”的发货推送为例。用户在(微信公众平台)「功能」-「虚拟支付2.0」-「基本配置」-「直购配置」拉到页面最下面,有个开启道具发货推送的选项。

点击“开启推送”-“执行测试”后,微信服务器会发送以下消息内容到开发者在页面「功能」-「虚拟支付2.0」-「基本配置」-「基础配置」- 「发货推送配置」填写的服务器。安全模式是指开发者在 “发货推送配置”的消息加密方式中选择了“安全模式”, 明文模式是指开发者在 “发货推送配置”的消息加密方式中选择了“明文模式”

# URL参数:

微信服务器发往开发者服务器的请求会附带如下的url参数,其中signature用于验证消息来自微信服务器, msg_signature, nonce, timestamp用于安全模式下对消息内容的解密。

参数 是否必填 描述
signature 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
timestamp 时间戳
nonce 随机数
msg_signature 安全模式会有此参数, 消息体签名串,用于安全模式的加解密
encrypt_type 安全模式会有此参数,值固定为"aes"

# 消息解密

如果您选择了安全模式,公众平台推送的消息格式如下

{   "Encrypt":"$encrpy",
    "ToUserName":"$your_username"
}

"$encrypy"是加密后的密文, 这里的加密方法跟小程序消息推送的加密方法一致,开发者将其解密后即可得到原始消息。对于小游戏推送消息,不管是否加密, 开发者回复明文消息即可。(python3 解密代码下载)

# 消息协议格式:

# 直购道具发货

服务器发送:

{
    "ToUserName": "$your_username",
    "FromUserName": "oUrsf0TSXNtiZjP7JL9UUFiGJzmQ",
    "CreateTime": $current_timestamp,
	"MsgType": "event",
	"Event": "minigame_game_pay_goods_deliver_notify",
	"MiniGame": {
		"Payload": "{\"OpenId\":\"example_open_id\",\"OutTradeNo\":\"example_out_trade_no\",\"WeChatPayInfo\":{\"MchOrderNo\":\"example_mch_order_no\",\"TransactionId\":\"example_transaction_id\"},\"Env\":1,\"GoodsInfo\":{\"ProductId\":\"example_product_id\",\"Quantity\":1,\"ZoneId\":\"example_zone_id\",\"OrigPrice\":1000,\"ActualPrice\":1000,\"Attach\":\"example_attach_data\",\"OrderSource\":1}}",
		"PayEventSig": "$your_pay_event_sig",
        "IsMock":true
	}
}

需要返回

{"ErrCode":0,"ErrMsg":"Success"}

# 商城道具发货

服务器发送:

{
    "ToUserName": "$your_username",
    "FromUserName": "oUrsf0TSXNtiZjP7JL9UUFiGJzmQ",
    "CreateTime": $current_timestamp,
	"MsgType": "event",
	"Event": "minigame_deliver_h5_pay_products",
	"MiniGame": {
		"Payload": "{\"OpenId\":\"example_open_id\",\"OutTradeNo\":\"example_out_trade_no\",\"WeChatPayInfo\":{\"MchOrderNo\":\"example_mch_order_no\",\"TransactionId\":\"example_transaction_id\"},\"Env\":1,\"GoodsInfo\":{\"ProductId\":\"example_product_id\",\"Quantity\":1,\"ZoneId\":\"example_zone_id\",\"OrigPrice\":1000,\"ActualPrice\":1000,\"Attach\":\"example_attach_data\",\"OrderSource\":2}}",
		"PayEventSig": "$your_pay_event_sig",
        "IsMock":true
	}
}

需要返回

{"ErrCode":0,"ErrMsg":"Success"}

点击咨询小助手