Sdk-h5-server

来自陌陌游戏WIKI
Chao.yu讨论 | 贡献2020年2月6日 (四) 10:15的版本

跳转至: 导航搜索

登录检验接口

1). 接口功能

验证用户是否登录。

2). 接口名

https://game.immomo.com/v2/srv/login/check

3). 调用时机

客户端调用SDK登录后,服务器确认此次是否是真实登录

4). 提交参数

参数名 类型 必填 说明
appid string Y 应用ID
sign string Y 参数签名
vtoken string Y 由客户端提交的验证参数
userid string Y 用户ID

注:vtoken对应MMSDK.getUserInfo的vtoken字段,24小时失效,不是token(永久有效)

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"
   }

}


6). 错误列表

错误码 错误描述
30016 vtoken不合法
30009 App secret 错误
30001 用户未授权
30500 服务器未知错误
30101 参数错误


支付通知

1).(仔细看这里 ):

   支付成功时陌陌向游戏服务器发起http请求。
   游戏方务必进行RSA签名校验,防止通知内容伪造;   
   建议 接入下面的支付反查接口,以确认是来自陌陌的通知;
   建议对通知数据中的app_trade_no , total_fee,    product_id,  appid 进行验证, 如果任意一个验证不通过,则表明是异常通知,务必忽略;
   过滤重复的通知
   校验通过之后务必返回给陌陌  success 字符串,否则陌陌认为游戏方没有成功接受支付通知,会重试15次,时间分别是0s,  10s, 25s, 40s ..... 2h17m15s;
   

2). 参数列表

参数名 类型 必选 说明
appid string Y 应用id
momoid string Y 和sdk返回userid一致,即加密后的momoid
trade_no string Y Momo返回的订单号
app_trade_no string Y 游戏商的订单号,(长度不超过64字节
sign string Y 签名
product_id string Y 商品id
currency_type int Y 货币类型 0-现金 1-陌陌币
total_fee double Y 价格(当 currency_type=0单位:元当currency_type=1 单位:陌陌币,1元=10陌陌币)
trade_time string Y 交易时间戳
is_test_order string Y 是否是测试订单 1-测试订单 0-普通订单
channel_type int Y 支付渠道 0-苹果 1-支付宝 2-短信 3-陌陌币 4-网页版 5-银联 6-中国移动短信快捷支付 7-微信 8-陌陌钱包 14-网页支付商城 200-其他
encrypted string Y 加密结果[具体加密算法如下]
encrypt_type string Y RSA

以上参数设置以Form格式提交(POST方式给CP通知,需要对参数进行URLDecode处理) 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/


下发消息

接口地址: https://game.immomo.com/v2/srv/message/box

参数:

  1. appid 应用id
  2. userid 用户id, 加密后的momoid
  3. content 发送内容
  4. sign 签名
   返回内容
   {
   "ec": 0,
   "em": "success",
   "timesec": 1578132537,
   "data": {
       "result" => true;
   }

}


数据打点(游戏室)

接口地址: https://game-api.immomo.com/3/server/prop/sync-game-data

参数:

  1. appid 应用id
  2. userid 用户id, 加密后的momoid
  3. type start 游戏开始,score 上报游戏总的分, outcome 游戏胜负结果
  4. time 秒级时间戳
  5. sign 签名
  6. score (int) type = score 时传递
  7. outcome type = outcome 时传递 1.胜利 0.失败
   返回内容
    {
       "ec": 0,
       "em": "success",
       "result": {
           "ec": 200,
           "em": "success",
           "data": [],
       }
   }


签名算法

签名算法为:

 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 = $_REQUEST;  //接收陌陌传递过来的数据详情
   $app_secret = '280ffa37af884aa3abbacb7c01ad16e4’;  //陌陌提供的 app_secret
   //陌陌传递数据通过RSA签名方式
   
       //根据签名算法拼凑 待签名字符串
       ksort($cp_data_arr);
       $res = ;
       foreach($cp_data_arr as $key=>$value) {
           if($key == 'sign') {
               continue;
           }
           $res .= $key .'='. $value.'&';
       }
       $sign = md5($res.$app_secret);  //待验签字符串