厂商实名上报API接入文档
介绍

响应国家关于开展网络游戏防沉迷实名验证系统接入工作,配合游戏厂商进行实名游玩数据的上报。

接口规范和说明

游戏用户行为数据上报,面向已经接入网络游戏防沉迷实名认证系统的游戏运营单位提供服务,游戏运营单位调用以供上报游戏用户上下线行为数据。 游戏厂商提供数据接收地址,小7提供数据上报。

本文档根据网络游戏防沉迷实名认证系统接口对接技术规范简化而来,厂商接收到小7上报数据之后进行解密即可使用。此方式小7平台会将用户上下线数据 以国家认证系统的要求拼接好上报给厂商,厂商的工作只需要解密数据,根据【appkey】匹配游戏并且使用此游戏 识别码上报小7平台返回的【data】数据即可。

请求方式

POST

请求格式

application/json; charset=utf-8

响应格式

JSON

上报频率

用户存在游戏上下线行为即触发数据上报,数据量以及频率受厂商开服等因素影响。

请求报文体明文数据

字段 类型 必填 名称 字段说明
timestamps String Y 调用时间 格式为时间戳,单位毫秒
appkey String Y 游戏方在小7平台的唯一标识 游戏方在小7平台的唯一标识,在开放平台可查询。注:H5游戏以game_key取值为准
data String Y 请求报文体加密数据 请求报文体加密数据,由本文档规定方式进行解密
osType String 系统类型(网游) iosandroid,游戏双端使用相同appkey对接时,此参数必传

请求报文体加密数据

字段 类型 长度 必填 名称 字段说明
collections List Y 上报对象 游戏用户上下线行为数据上报对象
collections[n].no Int 3 Y 条目编码 在批量模式中标识一条行为数据,取值范围1-128
collections[n].si String 32 Y 游戏内部会话标识 一个会话标识只能对应唯一的实名用户,一个实名用户可以拥有多个会话标识;同一用户单次游戏会话中,上下线动作必须使用同一会话标识上报备注:会话标识仅标识一次用户会话,生命周期仅为一次上线和与之匹配的一次下线,不会对生命周期之外的任何业务有任何影响
collections[n].bt Int 1 Y 用户行为类型 游戏用户行为类型【0:下线;1:上线】
collections[n].ot Long 10 Y 行为发生时间 行为发生时间戳,单位秒
collections[n].ct Int 1 Y 上报类型 用户行为数据上报类型【0:已认证通过用户;2:游客用户】
collections[n].di String 32 设备标识 游客模式设备标识,由游戏运营单位生成,游客用户下必填
collections[n].pi String 38 用户唯一标识 已通过实名认证用户的唯一标识,已认证通过用户必填

响应参数

字段 类型 名称 说明
errcode Int 状态码 状态码【0:成功】
errmsg String 状态描述 状态描述
数据加密说明

1.RSA秘钥

接收小7请求时,使用当前游戏在小7开放平台所生成的公钥进行解密。私钥加密,公钥解密,超出解析长度,分段解析。

2. 数据签名加密

将请求报文体加密数据和RSA私钥使用openssl算法进行加密,并将加密结果进行base64编码,最终得到data的值

3. 签名验签

验签为签名的逆运算,首先将接收到的data数据进行base64解码,再使用RSA公钥进行openssl签名解析

4. PHP代码参考

<?php/** * 数据加解密PHP代码参考 */class Signature{    /**     * 数据加密     * @param $payload     * @param $rsaPrivateKey     * @return string     */    public static function encrypt($payload, $rsaPrivateKey)    {        $encrypted = '';        $rsaPrivateKey = self::formatRsaPrivateKey($rsaPrivateKey);        $priId = openssl_get_privatekey($rsaPrivateKey);        $keyLen = openssl_pkey_get_details($priId)['bits'];        $partLen = $keyLen / 8 - 11;        $parts = str_split($payload, $partLen);        foreach ($parts as $part) {            $encryptedTemp = '';            openssl_private_encrypt($part, $encryptedTemp, $rsaPrivateKey);            $encrypted .= $encryptedTemp;        }        return base64_encode($encrypted);    }    /**     * 数据解密     * @param $encrypt     * @param $rsaPublicKey     * @return string     */    public static function decrypt($encrypt, $rsaPublicKey)    {        $str = str_replace(' ', '+', $encrypt);        $decrypted = "";        $rsaPublicKey = self::formatRsaPublicKey($rsaPublicKey);        $priId = openssl_get_publickey($rsaPublicKey);        $keyLen = openssl_pkey_get_details($priId)['bits'];        $partLen = $keyLen / 8;        $base64Decoded = base64_decode($str);        $parts = str_split($base64Decoded, $partLen);        foreach ($parts as $part) {            $decryptedTemp = '';            openssl_public_decrypt($part, $decryptedTemp, $rsaPublicKey);            $decrypted .= $decryptedTemp;        }        return $decrypted;    }    /**     * 格式化公钥     * @param string $publicKey     * @return string     */    public static function formatRsaPublicKey($publicKey)    {        return "-----BEGIN PUBLIC KEY-----\r\n" . wordwrap($publicKey, 64, "\r\n", TRUE) . "\r\n-----END PUBLIC KEY-----";    }    /**     * 格式化私钥     * @param string $privateKey     * @return string     */    public static function formatRsaPrivateKey($privateKey)    {        return "-----BEGIN RSA PRIVATE KEY-----\r\n" . wordwrap($privateKey, 64, "\r\n", TRUE) . "\r\n-----END RSA PRIVATE KEY-----";    }}//私钥(测试密钥)$privateKey = 'MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDDxRpuKIdYQ3lRHlIHJLbwJUKJVSVORZEISw/flJmz1rXATtuiKuPSGmDvDK7qF7J0imX3gF7DPAzckd7jlL9Ri95hCj/Ovclvjq+mgkxA+KQ3JlI5HGaM+WjMi4CVhbnpfcB6t75iQfW4IV556pbQFxPg2+WOfe/IkZiXM7eRYK6KdkfTCGvFK2LJvlImmOWDHP4xVS4EAkINgBGjpYK4IBNO537/3vCykEJ5yz+W29RA9oal6EKFsLbhTdUGYuxIKbGMA8tAki6QfqzLq1WgrmOaM2cWwKtZuR3rwfq2yb10Y9xQyA1bF5qFT/y1I61f3gBpN9Thynzjpift0fglAgMBAAECggEAIVoJ96xl6m6MU3qD5P2nQOBIJpdf5KbLX4tSJ/fr+4xfqGSG3GjMKTYfP3p8rhrdZydQ2cp/2mj3k/gx7bmgombeus+BMVp538yCNi7KiOMTLuYTafFhszCmXvqBLHf8xT+MNBvrjlfIYdclfkWt7cOQumUcBZuE5zmOsmu4IUb4ArjKsEmGDqdsp3fCESzbMWqBinvOmdUy+3VbBTpSjU/PDWCd/OgnTHpwPY7O9T7zSo8grkkWyq79W5kz7PLXdtqt1DNChUjHHv+ANM3T5L127BlHDskyG24AGrDzLmCmNQab4qFtOjPtHdsXsQm8cllgzD4lvP6ThuAG8DK4IQKBgQDnoCY8CLc2kUNyibdaA5N7y4xaY9vm1t6jKf37fOS069GkUNfOb8r+Pxp70UAKzMBWZ4iVlDbEh3FU0jveYutsUUbjEB4qI19/jvUHahKzaE9DCK3HkGvjT3NkQmZ+LslS/CxJtyZl+mN8/Ur6OA7p/l8BuJMVMXY+G7mQRZVtzQKBgQDYXwZX712DP5DTLcoUwOM9mIa8UFIFoZN+lwKLq8c0wbpZ3uicU90YwCPVvuATp/fwjOgOEId8HkLeBXkbqkJRimI0y4bTPzHNk0JDlTso79ERcglA9wU4j3C6OArB0Id/u2cVSex/JW3arQt2jRk5JCSDtWn7k1cB9qPvckUbuQKBgA3nYSQtacIOyjuv5J+0oz/FIjGy2Npsf4TP2n0kLB5oIXd5mtq7fzXv18ki8HM1gz4sjNhdw0Pc1YK/8/QPgA5KerTanNTutqbTkAXX6jN2yXs+pB/cnX1RoZ2dFsXwTQl8NbRfGCD6/Mnd8og+oTaOnGlgCQQ2qeBkjakJZETpAoGBAIu/FAHHf8Y9T/SVJmexDRPDZ4JI/jDU4sZoEiTTlZ3lYc6ZwfL1118c+ggbd+46FlEvMNGkq1zmzplHP6k2lg7EKhmfOj1GG4yDB9FOmR8fhRCXbpKe+KhHPK+JcqkrXdiJ2VJOpIiaTBFoona3OwtE5LCMgx8RUqjZ+5ezXh9BAoGBAIz5//GXs1kJoGQatr0rvE4CvVLVbKHaVaXy7MAcp4uya3g1cZh3Swje8e4RD6UfiKmx+aPETfw9IkXbrPTYmXCNDx5bSbbPL+WMY8c7F7K0krOfl8Vtzg5cCfo45+IsLCM16sDT0MhLCPUMWj0kcd4bKcAc3CENaL3U03oLE58r';//公钥(测试密钥)$publicKey = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw8UabiiHWEN5UR5SByS28CVCiVUlTkWRCEsP35SZs9a1wE7boirj0hpg7wyu6heydIpl94BewzwM3JHe45S/UYveYQo/zr3Jb46vpoJMQPikNyZSORxmjPlozIuAlYW56X3Aere+YkH1uCFeeeqW0BcT4Nvljn3vyJGYlzO3kWCuinZH0whrxStiyb5SJpjlgxz+MVUuBAJCDYARo6WCuCATTud+/97wspBCecs/ltvUQPaGpehChbC24U3VBmLsSCmxjAPLQJIukH6sy6tVoK5jmjNnFsCrWbkd68H6tsm9dGPcUMgNWxeahU/8tSOtX94AaTfU4cp846Yn7dH4JQIDAQAB';//小7发送给厂商的数据(测试数据)$testData = array(    "collections" =>        array(            array(                "no" => 1,                "si" => "2387337ba1e0b0249ba90f55b2ba2521",                "bt" => 0,                "ot" => 1617079205,                "ct" => 0,                "di" => "cf79ae6addba60ad018347359bd144d2",//此数据在ct为0时为非必填                "pi" => "1fffbjzos82bs9cnyj1dna7d6d29zg4esnh99u"            ),            array(                "no" => 2,                "si" => "2387337ba1e0b0249ba90f55b2ba2521",                "bt" => 1,                "ot" => 1617080905,                "ct" => 0,                "di" => "cf79ae6addba60ad018347359bd144d2",//此数据在ct为0时为非必填                "pi" => "1fffbjzos82bs9cnyj1dna7d6d29zg4esnh99u"            ),        ));//将发送数据转化成json格式$testData = json_encode($testData, 1);//小7进行数据加密(私钥加密)$encrypted = Signature::encrypt($testData, $privateKey);//厂商进行数据解密(公钥解密)$decrypted = Signature::decrypt($encrypted, $publicKey);echo "--------------------------------------------------------------", PHP_EOL;echo "原始数据:" . $testData, PHP_EOL;echo "--------------------------------------------------------------", PHP_EOL;echo "加密后的数据:" . $encrypted, PHP_EOL;echo "--------------------------------------------------------------", PHP_EOL;echo "解密后的数据:" . $decrypted, PHP_EOL;
接口规范和说明

游戏用户行为数据上报,面向已经接入网络游戏防沉迷实名认证系统的游戏运营单位提供服务,游戏运营单位调用以供上报游戏用户上下线行为数据。

小7平台在厂商检查用户登录的接口中返回国家实名认证系统上报所需要的必要参数,由厂商完成数据上报。厂商根据实际使用的检查登录接口获取相关数据。

响应格式

JSON

接口示例

https://api.x7sy.com/user/check_v4_login?tokenkey=de28191a4c808d36787d97f1a3825be1&sign=e7f1d806155b64483611042a23167448

参数说明

字段 类型 必填 字段说明
tokenkey String Y 由【小7SDK】传递给【游戏客户端】
sign String Y 是appkey与tokenkey的md5值,appkey在前,tokenkey在后,整个字符串是小写

响应参数

字段 类型 名称 说明
guid String 小号ID 标识用户在小7平台中的唯一标识
username String 用户名称 用户名称,(对于这个用户名称,游戏方接入的时候【不应该】使用它作为游戏的唯一标识,应该仅仅使用guid作为唯一标识)
is_real_user String 实名状态 是否已经实名,1表示已经实名,-1表示还没有实名
is_eighteen String 未成年状态 是否满足18岁,1表示已经满18岁,-1表示还没有满18岁
si String 游戏内部会话标识 一个会话标识只能对应唯一的实名用户,一个实名用户可以拥有多个会话标识;同一用户单次游戏会话中,上下线动作必须使用同一会话标识上报备注:会话标识仅标识一次用户会话,生命周期仅为一次上线和与之匹配的一次下线,不会对生命周期之外的任何业务有任何影响
pi String 用户唯一标识 已通过实名认证用户的唯一标识,已认证通过用户必填
di String 设备标识 游客模式设备标识,由游戏运营单位生成,游客用户下必填
特别说明

1. 当前接口游戏方正在使用,参考服务端接入文档

2. 部分情况下可能出现用户为已实名状态却没有返回【pi】,厂商无需上报该用户数据。

模拟数据
调试说明

1. 签名助手使用测试RSA密钥对,私钥下载公钥下载,此密钥对仅供此页面测试使用,勿做其他用途

2. 加密标准数据已明文展示,厂商可根据需求自由调整字段类型。

3. 提交表单之后会发起对实名上报地址的请求,厂商可进行相关测试。

4. 以上模拟测试仅针对接入方式1。

结果