Skip to content

LCM服务端(V2版本) 接入指南



1、游戏服务端与LCM服务端交互(GS vs LS)

简体域名
- Production: https://lcm-api.mobage.cn
- Sandbox : https://lcm-api-sand.mobage.cn
繁体域名
- Production: https://lcm-api.mobage.tw
- Sandbox : https://lcm-api-sand.mobage.tw
接口签名验证:
- Game Server和LCM Server之间使用MD5延签。
- LCM系统事先线下发行consumer keyconsumer secret给Game Server方,每一次Game Server通过Web API调用LCM Server的时候,都需要在Http的header里面加入 signature 头 - 以下为 signature 头部的生成方法:

1. 以method=post,接受参数为json为例;原始body参数          
    {
    "key": "10000000", // key -> LCM 下发的consumer key
    "b":"b",
    "d":["a","b","c"],
    "a":"a",
    "c":"c",
    "g":{"g":"g","f":"f"}
    }

 2. 将secret添加到参数中原始body参数          
    {
    "key": "10000000",
    "b":"b",
    "d":["a","b","c"],
    "a":"a",
    "c":"c",
    "secret":"dena-dev", // secret -> LCM 下发的consumer secret
    "g":{"g":"g","f":"f"}
    }

 3. 将参数按照key升序排序,依次将key value合并; 如果value是list或者object,则递归   
    sign_string = aabbccdabcgffggkey10000000secretdena-dev

 4. 将得到的字符串md5      
    md5(sign_string) = 9d1a8070bb9735c203f5e348e4c27abf

 5. 将md5串作为signature字段添加到header中

1-1 登陆:AccessToken校验接口

  • /game/token/validate : 指定一个accessToken,检查该accessToken是否合法
  • Method: POST

  • Request:

    type value
    signature xxxxxxxxxxxxxx
    Accept application/json
    Content-Type application/json
    Request body {"key":"10000000", "accessToken": "xxx.xxx.xxx"}
  • Response:

    type value
    Content-Type application/json
    Response body
  • Response body:

    key type description
    key string consumer key
    lid long
    storeType string
    storeAccount string
    rnInfo int 0:未录入, 1:未成年人, 2:成年人

    example:

    无 realNameExceptionInfo 字段:
    {
        "key": "10000000",
        "lid": 810801,
        "storeType": "LCM_A_CN",
        "storeAccount": "109900",
        "rncStatus": 0,
        "rnInfo": 1  
    }
    有 realNameExceptionInfo 字段:
    {
        "key": "10000000",
        "lid": 810801,
        "storeType": "LCM_A_CN",
        "storeAccount": "109900",
        "rnInfo": 1,
        "rncStatus": 0,
        "realNameExceptionInfo": {
            "code": "9992000",
            "message": "not available for minor",
            "trace": "192899.60.16065656803670299"
        }
    }

    rncStatus -> 认证状态:0: 认证成功 1: 认证中。2: 认证失败 3:待认证
  • 防沉迷相关异常码【 realNameExceptionInfo

    code message desc
    9991900 NEED_RECORD_REAL_NAME_INFO_CAN_SKIP 需要实名且可跳过 (实名制)
    9991901 NEED_RECORD_REAL_NAME_INFO_CANNOT_SKIP 需要实名且不可跳过(实名制)
    9992000 not available for minor 未成年游玩时间段限制生效(防沉迷)
    9992001 reached play time limit 未成年游玩总时长限制生效(防沉迷)
  • 状态码

    status description
    200 OK
    400 request body is wrong
    401 wrong sign
    429 too many request
    500 Internal Server Error

1-2 支付:消费L币接口

  • bank/spend/{lid} : 消费用户的L币(lid 用户标识)
  • Method: POST
  • Request:

    type value
    signature xxxxxxxxxxxxxx
    Accept application/json
    Content-Type application/json
    Request body { "key":"10000000", "items":[ ],"memo":"","billingId":"abc123"}
  • Response:

    type value
    Content-Type application/json
    Response body {"transactionId": "hSkwNL-wQQN-qF-P-oOXhvphg", "paidAmount": 7, "freeAmount": 2,"paidBalance": 1030,"freeBalance": 10 }
  • 状态码

    status description
    200 OK
    400 bad request
    401 wrong sign
    402 invalid parameter
    402 指定的用户不存在指定的storeType的Bank信息
    409 余额不足
    429 too many request
    500 Internal Server Error
  • Example for Request body:

        简洁模式(推荐):
        {
          "items": [{
            "id": "gacha1",
            "totalValue": 300,
            "quantity": "1"
          }, {
            "id": "gacha2",
            "totalValue": 200,
            "quantity": "3"
          }],
          "memo": "可选,供游戏记录更多信息",
          "billingId": "abc123:可选(最长128个字符)"
        }
        旧模式(继续兼容):
        {
          "items": [{
            "id": "gacha1",
            "paidValue": 100,
            "freeValue": 200,
            "totalValue": 300,
            "quantity": "1"
          }, {
            "id": "gacha2",
            "paidValue": 200,
            "freeValue": 0,
            "totalValue": 200,
            "quantity": "3"
          }],
          "memo": "可选,供游戏记录更多信息",
          "billingId": "abc123//可选(最长128个字符)"
        }
  • 注意:

  • 1.物品价格:

    • totalValue是物品的单价(对应商品配置中L币的数量),如果未传入totalValue或该值为0,则看paidValue和freeValue,如果有值,则不关心paidValue和freeValue的值;
    • paidValue和freeValue加起来是物品的單價。quantity是物品的數量。
    • L服務器端會計算總共這條request應該扣除多少Paid L幣和Free L幣;
    • paidTotal = sum(paidValue*quantity) 例子中 paidTotal = 100*1 + 200*3 即 item gacha1 和 gacha2 总的paidValue之和 freeTotal = sum(freeValue*quantity) 例子中 freeTotal = 200*1 + 0*3 即item gacha1 和gacha2 总的freeValue之和
  • 2.余额判断:

    • 有totalValue时,totalValue>paidBalance+freeBalance则余额不足;
    • 没有totalValue时,paidBalance和freeBalance分别判断 paidTotal>paidBalance 或者 freeTotal>freeBalance都会是余额不足
  • 3.支付:

    • 有totalValue时,先消费freeBalance, 后消费paidBalance
  • 4.billing id:

    • 该字段请务必传入LCM订单号(<福利L币及>余额消费是可能获取不到LCM订单号,请游戏自行创建一个唯一id或者传空),主要用于超时重试,如果不传会直接扣款,如果传了,第一次会扣款,重复传多次不扣款,第三方可用该字段重试一些失败的消费,不同消费操作传入全局唯一的值,同一笔消费重试时每次传入相同的值。

1-3 支付:消费L币查询接口(可选)

  • bank/queryConsume/{billingId} : 消费记录查询(billingId 消费订单标识)
  • Method: POST
  • Request:

    type value
    signature xxxxxxxxxxxxxx
    Accept application/json
    Content-Type application/json
    Request body { "key": "10000000" }
  • Response:

    type value
    Content-Type application/json
    Response body {"code":"204", "message": "the consume record already exist"}

    code : 204表示已经存在消费记录,205表示不存在消费记录

  • 状态码

    status description
    200 OK
    400 bad request
    401 wrong sign
    402 invalid parameter
    403 指定的用户不存在指定的storeType的Bank信息
    409 余额不足
    429 too many request
    500 Internal Server Error
    ### 1-4 支付:LCM服务端异步回调接口(可选)
    - LCM建议游戏服务器可以向LCM提供异步回调接口,用于接收异步到账通知,在收到异步回调时考虑给用户补发道具或者物品,并做好去重操作,避免向LCM重复消费
    - URL(需要游戏服务器提供)配置在LCM后台(目前只支持配置一个地址, 如需配置多地址请咨询平台同事);如下图红色框位置
    mkdocs
    - Method: POST
    - Request:
    • 1、headers:

      User-Agent = MobageUA/2.0 Content-Type = application/json

    • 2、Request body:

      { "lid": 406, "transaction_id": "ul8IEN-S2QP-megc-AGrNgI7g", "store_type": "APPLE", "paid_lnum": 6, "free_lnum": 0, "sku": "lcm.denachina.pickle.tire01", "status": 2, "memo": "", "sign": "65ff4b5cd481a955cf12447cbed264ac" }

    • 3、签名生成方式

      MD5_32(lid + transaction_id + store_type + paid_lnum + free_lnum + sku + status + consumer_secret) 以上面的请求体为例:sign = MD5_32(406ul8IEN-S2QP-megc-AGrNgI7gAPPLE60lcm.denachina.pickle.tire012999) 结果为 65ff4b5cd481a955cf12447cbed264ac

    • 4、body体参数定义

      name description 是否参与md5签名
      lid 用户标识
      transaction_id LCM订单号
      store_type 渠道名称
      paid_lnum 付费L币数量
      free_lnum 免费L币数量
      sku 商品编号
      status 0:尚未回调,1:回调失败,2:回调成功
      memo 订单详情
      expires_date 订阅过期时间戳(apple订阅订单会传入该字段)
      sign MD5签名
  • Response:

    请求结果返回 httpcode = 200 时,表示请求游戏服务器成功;httpcode != 200 时,LCM会在12小时内重试5次

    1-5 支付:苹果订阅异步回调接口(可选)

    • LCM建议游戏服务器在启用APPLE订阅功能是可以向LCM提供异步回调接口,用于接收异步订阅取消通知,在收到异步回调时终止和用户的订阅关系
    • URL(需要游戏服务器提供)给到平台同事配置(目前只支持配置一个地址, 如需配置多地址请咨询平台同事);或者自行配置在OPE工具的lcmadmin的app配置的模块中; mkdocs mkdocs
  • Method: POST

  • Request:

    • 1、headers:

      Content-Type = application/x-www-form-urlencoded

    • 2、Request body

      name description 是否参与md5签名
      lid 用户标识
      memo 用户开启订阅创建订单时游戏透传的memo字段
      store_type 渠道名称
      notification_type 订阅通知类型 -> 'CANCEL'
      cancellation_date 订阅取消的Unix时间戳(单位: s)
      sign MD5签名
    • 3、签名生成方式

      sign = MD5_32(cancellation_date + lid + memo + notification_type + store_type + secret)

  • Response:

    请求结果返回 httpcode = 200 时,表示请求游戏服务器成功;httpcode != 200 时,LCM会重试

    1-6 支付:苹果谷歌退款订单查询接口(可选)

  • LCM服务提供接口,用于返回对应游戏谷歌、苹果支付的退单用户信息(lid、store、lnum、order_id、sku、memo等)

  • /order/refund/query

  • Method: GET

  • Request:

  • 1、headers

    signature = MD5加密字符串

  • 2、Request body

    name description 是否参与md5签名 类型
    queryType 查询类型,1:返回最近15分钟内的恶意退单信息,2:返回指定时间范围内的恶意退单信息,3:根据lid进行查询,不传时间范围则默认查询指定lid的最近15分钟内的恶意退单信息 Integer
    startTime 起始时间,不得超过当前时间1个月,当查询类型为2时为必传参数 Long
    endTime 截止时间,当查询类型为2时为必传参数 Long
    key LCM系统对应游戏的consumer_key String
    lid 用户的lid,想根据用户的lid进行查询时传入 Long
  • 3、签名生成方式

    步骤:
    1. 将lcm下发的游戏的consumer_secret作为"secret"加入到参数中,并将所有的参数按照key升序排序,依次将key value合并
    2. 将得到的字符串md5      
    3. 将md5串作为signature字段添加到header中

    例子:以pickle为例,consumer_key为abc,consumer_secret为999
    查询类型为1时:
    https://lcm-api.mobage.tw/order/refund/query?queryType=1&key=abc
    则:
    拼接后的字符串为:
    sign_string="keyabcqueryType1secret999"
    md5后的字符串为:
    md5(sign_string) = aa3f8bb1aff327508ccb34220f6db7ea

    查询类型为2时:
    https://lcm-api.mobage.tw/order/refund/query?queryType=2&startTime=1586763068&endTime=1586939994&key=abc
    则:
    拼接后的字符串为:
    sign_string="endTime1586939994keyabcqueryType2secret999startTime1586763068"
    md5后的字符串为:
    md5(sign_string) = e9e9b8bc71371dd0a83a6508d0746cf3
  • Response:

  • 1、Response body

    name description
    returnCode 返回状态码,100表示返回异常,200表示返回成功
    returnMsg 返回结果msg
    returnData 返回结果集,为json格式
    totalCount 返回结果总数,为returnData内的值
    data 退单信息集合,为returnData内的值
  • 2、examples

    正常返回时:
    {
        "returnCode": 200,
        "returnMsg": "successed",
        "returnData": {
            "data": [
                {
                    "orderId": "HeDX88-lmTd-WBq--48ZTrS0g",
                    "storeType": "GOOGLE",
                    "lid": 1000000000058786,
                    "lnum": 1,
                    "sku": "lcm.dena_zhifu.alipay.tire01",
                    "memo": "from api test"
                },
                {
                    "orderId": "LdWD9O-g2TH-myar-aULkjqhw",
                    "storeType": "GOOGLE",
                    "lid": 1000000000058787,
                    "lnum": 1,
                    "sku": "lcm.dena_zhifu.alipay.tire01",
                    "memo": "from api test"
                }
            ],
            "totalCount": 2
        }
    }


    异常返回时:
    {
        "returnCode": 100,
        "returnMsg": "startTime can't beyond lately one month",
        "returnData": null
    }   

1-7 支付:苹果谷歌促销码异步回调接口(可选)

  • LCM建议游戏服务器在启用苹果谷歌促销码功能时向LCM提供异步回调接口,用于接收兑换成功的异步通知,在收到异步回调时向用户发放对应道具
  • URL(需要游戏服务器提供)给到平台同事配置(目前只支持配置一个地址);或者自行配置在OPE工具的 lcmadminapp配置额外app信息1 模块中;

  • Method: POST

  • Request:

    • 1、headers:

      Content-Type = application/application.json

    • 2、Request body

      name description 是否参与md5签名
      order_id 兑换后生成的LCM唯一标示
      lid_list 可领取的用户标识列表【分隔符 , 】
      uuid 用户设备标示
      sku 商品编号(苹果: type=3 苹果兑换商品; 谷歌: type=0 普通商品)
      store_type 渠道名称
      redemption_time 兑换码兑换的时间戳
      sign MD5签名
    • 3、签名生成方式

      sign = MD5_32(lid_list + order_id +redemption_time + sku + store_type + uuid + secret)

    • 4、苹果和谷歌的区别

      • 苹果 : type = 3 为特殊商品,需要在苹果后台新生成并配置于LCM后台
      • 谷歌 : type = 0 为普通商品,复用应用内商品;只会推送用户在谷歌商店兑换成功的通知 (应用内兑换会按照普通商品的购买流程正常到账)
  • Response:

    请求结果返回 httpcode = 200 时,表示请求游戏服务器成功;httpcode != 200 时,LCM会重试

1-8 注销:游戏端唤起注销功能,AccessToken校验

  • auth/logOff : 注销接口,指定一个accessToken,检查该accessToken是否合法,检验合法后可唤起注销
  • Method: POST
  • Request:

    type value
    signature xxxxxxxxxxxxxx
    Accept application/json
    Content-Type application/json
    Request body {"key":"10000000", "accessToken": "xxx.xxx.xxx"}
  • Response:

    type value
    Content-Type application/json
    Response body {"redirectURL":"https://tickets-prod-cn-stage.mobage.cn/1?type=0&content=mbyYRznNR8u0Z5PhKBMx8rKcEBCNQ1DPM8FRMrsl3aLm3reGlp7h5A2GgQq4F7DGg8Yk6b4KrMwEnKx5Q/U%2BPmD4qA/BHSGk2DUGlsUF1yPNFaA6UGJuxc3C%2BekOZCDaWHIml2%2BR1pJMc04IEdChZc/woJ7yHMG4Qa9k/75k9JQRWfTt%2BaIbIYR%2BSn5LY1fb6KwjVMqxTOWPy6f4IiU5irYa0wGE58N/M41I/OZXI2A%3D&logOff=1"}
    备注 :
     1.Response body 返回结果中redirectURL为重定向URL,只需游戏方将redirectURL对应的网页展示出来(游戏内部通过webview打开),具体注销功能由lcm实现
     2.可参考 服务器2.0接入文档中 1-1 登陆:AccessToken校验接口中的参数值 
  • 状态码

    status description
    200 OK
    400 request body is wrong
    401 wrong sign
    429 too many request
    500 Internal Server Error

2、联系方式

  • LCM-SERVER 邮箱: mobageplatformdev_cn@dena.jp

Back to top