查看“Sdk-h5-server”的源代码
←
Sdk-h5-server
跳转至:
导航
、
搜索
因为以下原因,你没有权限编辑本页:
您所请求的操作仅限于该用户组的用户使用:
用户
您可以查看与复制此页面的源代码。
== 前言 == * 服务端接口调用,构造请求数据并签名必须在''商户服务端完成,商户的应用密钥绝对不能保存在商户 APP 客户端中,也不能从服务端下发'' * <font color="red">请求参数必须是 表单POST提交过来 , ''Content-Type: application/x-www-form-urlencoded'' </font> === 签名算法 === 所有接口都需要做参数签名,防止伪造请求 签名算法为: 1). 参数排序:将所有参数名按字典顺序进行排序[sign字段不参与签名] 2). 参与签名的数据不要做 URL Encoding,一律以 UTF-8 编码参与签名。 3). 参数拼接:将所有参数按 k1=v1&k2=v2&k3=v3...格式进行拼接。 4). 将第3步所得得字符串 &APP_SECRET [每个游戏分配得密钥],生成待签名字符串。 5). 第4步所得的字符串md5 就是最终的sign了 参考PHP示例: <?php public function notify() { $cp_data_arr = $_POST; //接收陌陌传递过来的数据详情 $app_secret = '280ffa37af884aa3abbacb7c01ad16e4’; //陌陌提供的 app_secret //根据签名算法拼凑 待签名字符串 ksort($cp_data_arr); $res = ''; foreach($cp_data_arr as $key=>$value) { if($key == 'sign') { continue; } $res .= $key .'='. $value.'&'; } $sign = md5($res.$app_secret); //待验签字符串 === 错误码 === 接口响应ec大于0为错误 <table border="1" cellpadding="1" cellspacing="0"> <tr> <td>错误码</td> <td>错误描述</td> </tr> <tr> <td>21001</td> <td>接口不存在</td> </tr> <tr> <td>21002</td> <td>appid没有传</td> </tr> <tr> <td>21003</td> <td>userid没传或者是错误的</td> </tr> <tr> <td>21004</td> <td>缺失必传参数</td> </tr> <tr> <td>21005</td> <td>参数错误,值不合法</td> </tr> <tr> <td>21006</td> <td>签名(sign)校验失败</td> </tr> <tr> <td>21007</td> <td>vtoken已过期</td> </tr> <tr> <td>21008</td> <td>vtoken错误</td> </tr> <tr> <td>21009</td> <td>用户未授权登录</td> </tr> <tr> <td>21010</td> <td>消息盒子推送--未配置权限</td> </tr> <tr> <td>21011</td> <td>消息盒子推送失败-用户未开启</td> </tr> <tr> <td>21012</td> <td>道具消耗-道具不存在</td> </tr> <tr> <td>21015</td> <td>道具消耗-服务不可用</td> </tr> </table> == 接口 == === 登录检验 === 1). 接口功能 验证用户是否登录。 2). 接口名 https://game.immomo.com/v2/srv/login/check 3). 调用时机 客户端调用SDK登录后,服务器确认此次是否是真实登录 4). 提交参数 <table border="1" cellpadding="1" cellspacing="0"> <tr> <th>参数名</th> <th>类型</th> <th>必填</th> <th>说明</th> </tr> <tr> <td>appid</td> <td>string</td> <td>Y</td> <td>应用ID</td> </tr> <tr> <td>sign</td> <td>string</td> <td>Y</td> <td>参数签名</td> </tr> <tr> <td>vtoken</td> <td>string</td> <td>Y</td> <td>由客户端提交的验证参数</td> </tr> <tr> <td>userid</td> <td>string</td> <td>Y</td> <td>用户ID</td> </tr> </table> <font color="red" >注:vtoken对应[[Sdk-h5-client#.E8.8E.B7.E5.8F.96.E7.94.A8.E6.88.B7.E8.B5.84.E6.96.99|MMSDK.getUserInfo]]的vtoken字段,24小时失效,不是token(永久有效)</font> 5). 返回值:(JSON) { "ec": 0, "em": "success", "timesec": 1578132537, "data": { "userid": "UmFXSDh1VVRFcGFpbzNBdG1HNzU5dz09", "name": "吴道林", "sign": "一天一苹果,疾病远离我", "vip": 0, "reg_time": 1357445132, "constellation": "摩羯座", "birthday": "1987-01-15", "age": 32, "sex": "M", "avatar": "https://img.momocdn.com/album/45/AE/45AE5B32-42BB-F81A-409A-777956E45ADA20171204_S.jpg", "photo": [ "45AE5B32-42BB-F81A-409A-777956E45ADA20171204" ], "city": "隐身", "cityid": 110100, "big_r": "2" } } === 消息盒子推送 === 接口地址: https://game.immomo.com/v2/srv/message/box 参数: # appid 应用id # userid 用户id, 加密后的momoid # content 发送内容 # sign 签名 返回内容 { "ec": 0, "em": "success", "timesec": 1578132537, "data": { "result" => true; } } === 数据同步 === 接口地址: https://game-api.immomo.com/3/server/prop/sync-game-data 参数: # appid 应用id # userid 用户id, 加密后的momoid # type start 游戏开始,score 上报游戏总的分, outcome 游戏胜负结果 # time 秒级时间戳 # sign 签名 # score (int) type = score 时传递 # outcome type = outcome 时传递 1.胜利 0.失败 返回内容 { "ec": 0, "em": "success", "result": { "ec": 200, "em": "success", "data": [], } } === 游戏室-任务完成上报 === 陌陌-游戏室-任务中心,约定好的任务完成后触发通知操作 接口地址: https://game.immomo.com/v2/srv/sync/task 参数: # appid 应用id # userid 用户id, 加密后的momoid # task_id 任务id # sign 签名 返回内容 { "ec": 0, "em": "success", "result": { "ec": 200, "em": "success", "data": [], } } === 转盘抽奖创建订单 === 转盘流程时序图: [[文件:turntable.png]] 接口地址: https://game.immomo.com/v2/srv/draw/create 参数: # appid 应用id # userid 用户id, 加密后的momoid # order_id 订单ID (只能包含数字和字母 32位) # type 抽奖类型 1、单抽 10、10抽 100、百抽 # awards 抽奖获得的奖品信息 json数组 [{'prop_id' : '111',num:2, begin_consume_time(道具开始消耗时间戳毫秒): 1593500012000}] # extra 扩展参数.json格式 # create_time 毫秒时间戳 # sign 签名 返回内容 { "ec": 0, "em": "success", "timesec": 1578996514, "data": { "order_id": "202006301523423xxxxxxxxx", } } === 转盘付费道具消耗通知 === 通过转盘付费抽奖获取的道具,消耗的时候通知 接口地址: https://game.immomo.com/v2/srv/draw/usedNotify 参数: # appid 应用id # userid 用户id, 加密后的momoid # product_id 消耗道具ID # product_num 消耗道具数量 # time 毫秒时间戳 # sign 签名 返回内容 { "ec": 0, "em": "success", "timesec": 1592986638, "data": { "consumeOrderId": "20200624161718284039623000001"//陌陌道具系统订单ID } } == 支付通知 == 1).(<font color='red'>仔细看这里 </font>): 支付成功时陌陌向游戏服务器发起http请求。 游戏方务必进行RSA签名校验,防止通知内容伪造; 同时必须对通知数据中的app_trade_no , total_fee, product_id, appid 进行验证, 如果任意一个验证不通过,则表明是异常通知,务必忽略; 过滤重复的通知 校验通过之后务必返回给陌陌 success 字符串,否则陌陌认为游戏方没有成功接受支付通知,会重试15次,时间分别是0s, 10s, 25s, 40s ..... 2h17m15s; 2). 参数列表 {| class="wikitable" |- |参数名 |类型 |必选 |说明 |- |appid |string |Y |应用id |- |momoid |string |Y |和sdk返回userid一致,即加密后的momoid |- |trade_no |string |Y |Momo返回的订单号 |- |app_trade_no |string |Y |游戏商的订单号,(<font color='red'>长度不超过64字节 </font>) |- |sign |string |Y |签名 |- |product_id |string |Y |商品id |- |currency_type |int |Y |货币类型 0-人民币 |- |total_fee |double |Y |价格(单位:元) |- |trade_time |string |Y |交易时间戳 |- |is_test_order |string |Y |是否是测试订单 1-测试订单 0-普通订单 |- |channel_type |int |Y |支付渠道 3-陌陌币 8-陌陌钱包 |- |encrypted |string |Y |加密结果[具体加密算法如下] |- |encrypt_type |string |Y |RSA |} 以上参数设置以Form格式提交(<font color='red'>POST方式给CP通知,需要对参数进行URLDecode处理</font>) CP 返回示例: 成功返回success7个标准字样。 失败返回示例[JSON]: { ec: 非0错误码, em: 错误描述, //错误描述尽可能简短清晰,便于后期快速查询问题 } 签名之前,请游戏方先向陌陌索要校验RSA签名所需要的公钥。 签名算法为: 1). 参数排序:将所有参数名按字母顺序进行排序,没有值的参数不要参与签名。[sign,encrypted,encrypt_type不参与签名] 注:按照字母顺序进行排序的时候,是按照字符在ASCII码中的顺序进行的从小到大的排序。第一个字符如果一样的话, 就按照第二个字符在ASCII码中的顺序继续进行排序。如此类推。 2). 参与签名的数据不要做 URL Encoding,一律以 UTF-8 编码参与签名。 3). 参数拼接:将所有参数按 k1=v1&k2=v2&k3=v3...格式进行拼接。 4). 将第3步所得得字符串 &APP_SECRET [每个游戏分配得密钥],生成待签名字符串。 RSA签名 当获得到通知返回的待签名字符串后,把待签名字符串,陌陌提供的公钥,陌陌通知返回参数中的参数encrypted的值[base64_decode处理下] 三者一同放入RSA的签名函数中进行非对称的签名运算,来判断签名是否校验通过。 签名备注: 陌陌在对字符串进行加密的时候使用的是 SHA1withRSA (OPENSSL_ALGO_SHA1) 参考示例: 1、JAVA示例: JAVA版本[[文件:Pay-java-demo.zip]] 2、PHP示例: <?php public function notify() { $cp_data_arr = $_REQUEST; //接收陌陌传递过来的数据详情 $app_secret = '280ffa37af884aa3abbacb7c01ad16e4’; //陌陌提供的 app_secret //陌陌传递数据通过RSA签名方式 if (isset($cp_data_arr['encrypt_type']) && $cp_data_arr['encrypt_type'] === 'RSA') { $appid = $cp_data_arr['appid']; //根据签名算法拼凑 待签名字符串 ksort($cp_data_arr); $res = ''; foreach($cp_data_arr as $key=>$value) { if($value === '' || $key == 'encrypted' || $key == 'encrypt_type' || $key == 'sign') { continue; } $res .= $key .'='. $value.'&'; } $data = $res.$app_secret; //待验签字符串 $public_key = ''; //陌陌提供的 公钥 $pu_key = openssl_pkey_get_public($public_key); $unsign_msg = base64_decode($cp_data_arr['encrypted']); $res = openssl_verify($data, $unsign_msg, $pu_key); //error_log("verify result is " . $res); if ($res) { //执行 发货操作 并 返回陌陌所需要的 success 字样 echo 'success'; } else { echo 'falied'; } } } 3、Python示例: !/usr/bin/env python import base64 from Crypto.PublicKey import RSA from Crypto.Signature import PKCS1_v1_5 from Crypto.Cipher import PKCS1_OAEP from Crypto.Hash import SHA if __name__ == '__main__': # 应用密钥 app_secret = '' # 支付签名检验用的公钥 pub_key = '' # http request 参数 params = {'appid':'appid', 'momoid':'VEgwQng3emRNK2c4Wjd0cW5mcHRUZz09', 'trade_no':'20151026143931553920061', 'app_trade_no':'79396e329eaf4e8b94f27c41cfc7b944-6377453-405-14', 'product_id':'com.wemomo.game.buyu.8', 'currency_type':'0', 'total_fee':'15', 'trade_time':'1445841571', 'channel_type':'5', 'sign':'06c56a89949d617def52f371c357b6db', 'encrypted':'JYoeEzoh6ucdslnYVeqFFBi4NZZRc3vsjjIIH63THISkxGzXkdElCjum7zgWFL9IdacPoESRabG3v9QJARi7vC7byURM3hB9dVFFMFpBWym+LWyW4vgPUQTVfc06JHUAGLKxLMEgq2HKniJPp+5JYw8E+WWB\/TvxuQbOJn6L1sc=', 'encrypt_type':'RSA'} # 对http request参数按key排序(升序)并连接起来 items = params.items() items.sort() data = '' for key, value in items: if key == 'encrypted' or key == 'encrypt_type' or key == 'sign' or value == '': continue data = data + key + '=' + value + '&' data = data + app_secret print data # 校验签名,其中签名需要base64 decode rsa_key = RSA.importKey(pub_key) signature_scheme = PKCS1_v1_5.new(rsa_key) digest = SHA.new(data.encode('utf-8')) signature = base64.b64decode(params['encrypted']) result = signature_scheme.verify(digest, signature) if result: print '签名校验通过。' else: print '签名校验失败。' 4、C++示例 说明:需要依赖第三方库,地址:http://www.cryptopp.com/ == 礼包发放通知 == 1).(<font color='red'>仔细看这里 </font>): 陌陌-游戏室-礼包中心,用户点击兑换后通知。 游戏方务必进行RSA签名校验,防止通知内容伪造; 根据trade_no做幂等性校验 2). 参数列表 post提交, ''Content-Type: application/x-www-form-urlencoded'' {| class="wikitable" |- |参数名 |类型 |必选 |说明 |- |appid |string |Y |应用id |- |userid |string |Y |和sdk返回userid一致,即加密后的momoid |- |trade_no |string |Y |用户兑换礼包的订单号 |- |gift_bag_id |string |Y |游戏商的礼包ID,(<font color='red'>长度不超过64字节 </font>) |- |trade_time |string |Y |交易时间戳 |- |sign |string |Y |签名 <font color="red">等价于支付通知的 `encrypted`, 相同的加密算法</font> |} 3). 返回值 <br /> 返回json格式字符串 {"ec":200, "em":"success"}; <font color="red">ec 200表示成功,201 表示用户不存在,202:其他失败情况 </font> 4). 加密参考示例 PHP示例: <?php public function notify() { $cp_data_arr = $_POST; //接收陌陌传递过来的数据详情 $app_secret = '280ffa37af884aa3abbacb7c01ad16e4’; //陌陌提供的 app_secret $public_key = '’; //陌陌提供的 RSA 公钥 //拼凑 数据 ksort($cp_data_arr); $res = ''; foreach($cp_data_arr as $key=>$value) { if($key == 'sign') { continue; } $res .= $key .'='. $value.'&'; } $data = md5($res.$app_secret); //待验签数据 $pu_key = openssl_pkey_get_public($public_key); $unsign_msg = base64_decode($cp_data_arr['sign']); $res = openssl_verify($data, $unsign_msg, $pu_key); //error_log("verify result is " . $res); if ($res) { //执行 发货操作 并 返回陌陌所需要的 success 字样 echo json_encode(['ec' => 200, 'em' => 'success']); } else { echo json_encode(['ec' => 202, 'em' => '签名错误']);; } exit(); == 转盘抽奖扣费成功通知 == 1). 扣费成功时陌陌向游戏服务器发起http请求。 游戏方务必进行RSA签名校验,防止通知内容伪造; 过滤重复的通知。根据order_id做幂等 校验通过之后务必返回给陌陌 success 字符串,否则陌陌认为游戏方没有成功接受支付通知,会重试15次,时间分别是0s, 10s, 25s, 40s ..... 2h17m15s; 2). 参数列表 {| class="wikitable" |- |参数名 |类型 |必选 |说明 |- |appid |string |Y |应用id |- |userid |string |Y |加密后的momoid |- |order_id |string |Y |Momo返回的订单号 |- |sign |string |Y | <font color="red"> 签名 等价于支付通知的 `encrypted`, 相同的加密算法</font> |- |is_test |string |Y |是否是测试订单 1-测试订单 0-普通订单 |} 以上参数设置以Form格式提交(<font color='red'>POST方式给CP通知,需要对参数进行URLDecode处理</font>) CP 返回示例: 成功返回success7个标准字样。 失败返回示例[JSON]: { ec: 非0错误码, em: 错误描述, //错误描述尽可能简短清晰,便于后期快速查询问题 }
返回至
Sdk-h5-server
。
导航菜单
个人工具
登录
命名空间
页面
讨论
变种
视图
阅读
查看源代码
查看历史
更多
搜索
导航
首页
最近更改
陌陌游戏
H5SDK
快速接入
SDK接口
服务器接口
常见问题
运营商
功能说明文档
运营商(单机版)
运营商(网游版)
上线标准
服务器性能压测
常用工具
服务器篇
客户端篇
外挂篇
工具
链入页面
相关更改
特殊页面
页面信息