Lucky-Mermaid 商户 API 对接指南
本文是 Lucky-Mermaid(简称 LM)商户接入主文档,面向技术对接人员。
1. 接入整体流程
商户提供资料
-> 平台创建 Merchant / Agent
-> 平台配置 Agent 币种、游戏、钱包模式、IP 白名单
-> 平台生成并交付 Agent API 密钥
-> 商户按 LM 签名规则调用 API
-> 双方完成创建玩家、转账、进游戏、下注、查余额、查注单、报表验证
-> 生产环境切换正式域名、正式 IP 白名单和正式密钥Lucky-Mermaid 提供独立的商户 API。商户只需要按本文档的新接口路径、签名规则和
多币种规则接入。
2. 商户需要提供什么
| 项目 | 必填 | 说明 |
|---|---|---|
| 公司名称 | 是 | 用于商务和后台识别 |
| 商户名称 | 是 | 用于创建 Merchant |
| Agent 名称 | 是 | API 请求中的 agentName,由平台创建并告知商户 |
| 接入币种 | 是 | 例如 CNY、USD、THB;所有业务接口都必须传 currency |
| 游戏范围 | 是 | 需要开放的游戏 ID 列表,或全部开放 |
| 钱包模式 | 是 | transfer 转账钱包,或 single 单钱包 |
| 钱包回调地址 | 单钱包必填 | 单钱包模式下商户必须提供 HTTPS 回调地址 |
| 商户服务器出口公网 IP | 建议必填 | 用于 API 白名单;填服务器出口 IP,不是玩家 IP |
| 技术联系人 | 是 | 用于联调、签名问题、转账问题、游戏进入问题排查 |
如果商户使用多台服务器或 NAT,需要提供所有可能调用 LM API 的出口公网 IP。单个 IP
建议按 CIDR 写成 /32,例如 203.0.113.4/32。
3. 平台需要配置什么
| 配置 | 说明 |
|---|---|
| Merchant | 商户主体 |
| Agent | 商户下的接入通道;请求里的 agentName 对应这里 |
| Agent API Key | 请求头 KEY 使用的身份;允许平台分配独立 API key 字符串,不要求等于 agentName |
| Agent 币种 | 控制这个 Agent 可以使用哪些 currency |
| 游戏授权 | 控制这个 Agent 可以打开哪些游戏 |
| 钱包模式 | 控制资金模式;首版支持 transfer 和 single |
| IP 白名单 | 限制商户哪些出口 IP 可以调用 API |
| 单钱包回调配置 | 单钱包模式下配置商户 HTTPS 回调地址和回调签名密钥 |
| 币种汇率 / 限红 bet-rate | 平台内部配置,用于报表折算和游戏限红;商户 API 返回原币种金额 |
4. 环境和基础 URL
| 环境 | Base URL | 说明 |
|---|---|---|
| 测试服 | 待分配 | LM 测试环境 |
| 生产 | 待正式分配 | 上线前由平台提供 |
所有商户接口使用 HTTPS JSON:
POST <base>/api/v1/...
Content-Type: application/json5. 通用规则
5.1 请求格式
- 所有接口请求均使用 JSON 格式。
- 请求和响应编码均为 UTF-8。
- 除特别说明外,接口均使用
POST方法。 - 所有业务接口都必须传
currency。 currency必须为大写 ISO 风格币种代码,例如CNY、USD、THB。
5.2 请求头
| Header | 必填 | 说明 |
|---|---|---|
KEY | 是 | 平台分配的 Agent API key 字符串;允许独立于 agentName |
timestamp | 是 | Unix 时间戳,单位:秒 |
sign | 是 | 请求签名,生成方式见“6. 认证与签名” |
5.3 通用响应格式
接口响应为 JSON:
{
"code": 200,
"data": {},
"msg": "成功"
}说明:
code=200表示业务成功。code!=200表示业务失败,失败原因见msg和错误码。data使用 AES 加密响应规则。文档示例为便于阅读展示解密后的 JSON 结构;实际线上
响应中的 data 为 AES 加密串。
5.4 时间规则
- 商户 API 中的业务时间按 GMT+8 解释。
game-records的startTime/endTime格式为yyyy-MM-dd HH:mm:ss。- 日报接口的日期格式为
yyyy-MM-dd。 - 游戏记录详情、注单、投注明细等详细数据保留周期以后端实际策略为准。
6. 认证与签名
Lucky-Mermaid 使用 AES + MD5 签名模型。
6.1 签名流程
- 取业务入参 body。
- 按参数名进行字典序排序。
- 将排序后的参数序列化为 JSON 字符串。
- 使用 AES 加密该 JSON 字符串。
- 将 AES 加密结果与请求头
timestamp拼接。 - 对拼接后的字符串进行 MD5,得到最终
sign。
currency 是业务入参的一部分,必须参与排序和签名。商户不能签名时遗漏
currency,也不能签名后修改 currency。
6.2 AES 规则
| 项目 | 说明 |
|---|---|
| 算法 | AES/ECB/PKCS5Padding |
| 密钥 | 由平台为 Agent 分配并安全交付 |
6.3 签名示例:创建玩家
原始入参:
{
"agentName": "agent01",
"currency": "USD",
"loginName": "player001"
}排序后 JSON 字符串必须稳定生成;示意:
{"agentName":"agent01","currency":"USD","loginName":"player001"}签名:
encrypted = AES(sorted_json, agent_secret)
sign = MD5(encrypted + timestamp)6.4 签名失败常见原因
| 原因 | 说明 |
|---|---|
| 参数排序不一致 | 签名前必须按参数名排序 |
| JSON 序列化不一致 | 空格、数字格式、大小写变化都可能影响签名 |
currency 漏签 | currency 必须参与签名 |
| 时间戳过期 | timestamp 必须在平台允许的时间窗口内 |
| 密钥错误 | Agent API 密钥不匹配 |
| 签名后修改 body | 签名计算后不能再改请求体 |
7. 多币种玩家模型
Lucky-Mermaid 支持同一个 agentName + loginName 在多个币种下存在。
玩家钱包身份由三元组确定:
agentName + loginName + currency示例:
agent01 + player001 + CNY
agent01 + player001 + USD
agent01 + player001 + THB以上三个是独立玩家钱包身份:
- 余额独立。
- 转账订单独立校验。
- 游戏会话必须带
currency。 - 注单和报表必须带
currency。 - 登录、余额、转账、用户信息、强制离线都不能跨币种 fallback。
平台必须校验:
currency是平台支持币种。currency已对 Merchant / Agent 启用。- 游戏已对 Agent 启用。
- 玩家在请求的
agentName + loginName + currency下存在,除创建玩家接口外。
游戏语言代码、游戏类型、游戏列表和支持币种由 LM 后台维护并导出,对接文档和商户后台
展示应以后台导出结果为准。
8. 钱包模式
Lucky-Mermaid 首版支持两种钱包模式:转账钱包和单钱包。
钱包模式在 Agent 或平台分配的接入配置上确定。一个接入通道只能使用一种钱包模式;
同一商户如果同时需要转账钱包和单钱包,应由平台创建独立的接入配置和密钥。
8.1 转账钱包
商户主动调用 LM 钱包接口:
创建玩家 -> 转入额度 -> 查询余额 -> 登录游戏 -> 查询注单 -> 转出额度特点:
- 商户通过
/api/v1/transfer转入/转出。 - LM 保存玩家游戏钱包余额。
- 每个玩家钱包按
agentName + loginName + currency独立。 - 转账、余额、游戏记录和报表全部返回原币种金额。
8.2 单钱包
单钱包进入首版。单钱包模式下,商户保存玩家余额,LM 在游戏过程中回调商户完成余额
查询、下注扣款、派奖加款和异常回滚。
特点:
- 商户不调用
/api/v1/transfer做转入/转出。 - 商户必须提供 HTTPS 钱包回调地址。
- 商户必须实现
balance、debit、credit、rollback回调。 - 商户必须按回调签名规则验证 LM 请求。
- 商户必须用
txnId做幂等,重复回调不能重复扣款或加款。 - 回调和玩家身份同样按
agentName + loginName + currency处理。
9. API 调用流程
9.1 转账钱包推荐流程
1. POST /api/v1/createPlayer
2. POST /api/v1/transfer type=1 转入
3. POST /api/v1/getBalance
4. POST /api/v1/login
5. 玩家进入游戏
6. POST /api/v1/gameRecord
7. POST /api/v1/record_detail_url 需要查明细时
8. POST /api/v1/transfer type=2 转出
9. POST /api/v1/transferRecord 网络超时或未知结果时查单9.2 试玩流程
POST /api/v1/testPlay试玩必须传 currency,用于游戏展示币种、下注单位和限红。试玩不进入真实玩家钱包。
9.3 单钱包推荐流程
1. 平台配置 Agent 钱包模式为 single
2. 平台配置商户 HTTPS 钱包回调地址和回调签名密钥
3. 商户实现 balance / debit / credit / rollback 回调
4. POST /api/v1/createPlayer
5. POST /api/v1/login
6. 游戏过程中 LM 回调商户钱包
7. POST /api/v1/gameRecord 查询注单对账10. 接口清单
10.0 公共目录接口
公共目录接口用于文档展示、接入前配置核对和运营同步,不需要签名,不返回加密 data。
正式业务调用仍必须使用带签名的业务接口。
| 接口 | 用途 | 是否必接 | 说明 |
|---|---|---|---|
GET /api/v1/public/currencyList | 查询平台当前支持币种 | 建议 | 返回 currency, name, betRate |
GET /api/v1/public/gameList | 查询平台当前可用游戏 | 建议 | 返回 gameId, gameName, gameType, gameTypeName, supportCurrencies |
说明:
- 公共目录接口返回平台级目录,不代表某个商户或 Agent 的最终开通权限。
- 商户实际能否使用某个币种或游戏,以后台配置和业务接口校验结果为准。
- 商户系统可以用这两个接口做接入配置初始化,但不应绕过正式业务接口的错误处理。
下方目录由公共接口实时加载,用于快速查询当前可用的 currency 和 gameId。
币种列表
业务接口中的 currency 字段使用这里的币种代码。
| 币种 | 名称 | Bet rate |
|---|---|---|
| 正在加载币种列表... | ||
游戏列表
login 和 testPlay 的 gameId 使用这里的游戏 ID。
| 游戏 ID | 游戏名称 | 类型 | 币种 |
|---|---|---|---|
| 正在加载游戏列表... | |||
10.1 转账钱包接入 API
转账钱包模式下,商户主动调用 LM 完成玩家开户、额度转入、游戏登录、余额查询、转出和
对账。
| 接口 | 用途 | 是否必接 | 关键字段 |
|---|---|---|---|
POST /api/v1/createPlayer | 创建或确认玩家 | 是 | agentName, loginName, currency |
POST /api/v1/transfer | 转入/转出额度 | 是 | agentName, loginName, currency, orderNo, type, amount |
POST /api/v1/getBalance | 查询玩家游戏钱包余额 | 建议 | agentName, loginName, currency |
POST /api/v1/login | 获取正式游戏地址 | 是 | agentName, loginName, currency, gameId, lang |
POST /api/v1/testPlay | 获取试玩地址 | 可选 | agentName, currency, gameId, lang |
POST /api/v1/transferRecord | 查询转账订单 | 建议 | agentName, currency, orderNo |
POST /api/v1/gameRecord | 查询游戏注单 | 建议 | agentName, currency, startTime, endTime, page, pageSize |
POST /api/v1/record_detail_url | 获取注单详情链接 | 建议 | agentName, currency, recordId, recordTime, lang |
POST /api/v1/dailyReportDetail | 单日明细报表 | 可选 | agentName, currency, date, gameType |
POST /api/v1/daily_report_total | 多日汇总报表 | 可选 | agentName, currency, dateStart, dateEnd |
POST /api/v1/userInfo | 查询玩家状态 | 可选 | agentName, loginName, currency |
POST /api/v1/forceLeave | 强制玩家下线 | 可选 | agentName, loginName, currency |
转账钱包不需要商户实现钱包回调。
10.2 单钱包接入 API
单钱包模式下,商户保存玩家余额。商户调用 LM 完成开户、登录、查注单;游戏过程中 LM
调用商户钱包回调完成余额查询、扣款、加款和回滚。
商户调用 LM:
| 接口 | 用途 | 是否必接 | 关键字段 |
|---|---|---|---|
POST /api/v1/createPlayer | 创建或确认玩家 | 是 | agentName, loginName, currency |
POST /api/v1/login | 获取正式游戏地址 | 是 | agentName, loginName, currency, gameId, lang |
POST /api/v1/testPlay | 获取试玩地址 | 可选 | agentName, currency, gameId, lang |
POST /api/v1/getBalance | 主动查询玩家余额;LM 转发为商户 balance 回调 | 可选 | agentName, loginName, currency |
POST /api/v1/gameRecord | 查询游戏注单 | 建议 | agentName, currency, startTime, endTime, page, pageSize |
POST /api/v1/record_detail_url | 获取注单详情链接 | 建议 | agentName, currency, recordId, recordTime, lang |
POST /api/v1/dailyReportDetail | 单日明细报表 | 可选 | agentName, currency, date, gameType |
POST /api/v1/daily_report_total | 多日汇总报表 | 可选 | agentName, currency, dateStart, dateEnd |
POST /api/v1/userInfo | 查询玩家状态 | 可选 | agentName, loginName, currency |
POST /api/v1/forceLeave | 强制玩家下线 | 可选 | agentName, loginName, currency |
单钱包禁用转账接口:
| 接口 | 单钱包规则 |
|---|---|
POST /api/v1/transfer | 禁用。资金动作由 LM 调用商户回调完成。 |
POST /api/v1/transferRecord | 禁用。单钱包对账以游戏注单、回调流水和商户钱包流水为准。 |
LM 调用商户:
| 回调事件 | 用途 | 是否必接 | 关键字段 |
|---|---|---|---|
balance | 查询玩家当前余额 | 是 | event, agentName, loginName, currency, txnId |
debit | 玩家下注扣款 | 是 | event, agentName, loginName, currency, txnId, amount |
credit | 玩家赢分派奖 | 是 | event, agentName, loginName, currency, txnId, amount |
rollback | 冲正原扣款或加款 | 是 | event, agentName, loginName, currency, txnId, origTxnId, amount |
回调详情见“12. 单钱包回调接口要求”。
11. 接口详情
11.1 查询支持币种
GET /api/v1/public/currencyList该接口无需签名,返回明文 JSON。
响应示例:
{
"code": 200,
"data": [
{
"currency": "CNY",
"name": "人民币",
"betRate": 1
},
{
"currency": "USD",
"name": "美元",
"betRate": 7
}
],
"msg": "成功"
}字段说明:
| 字段 | 说明 |
|---|---|
currency | 币种代码 |
name | 币种名称 |
betRate | 游戏限红/下注档位换算参考值 |
11.2 查询游戏列表
GET /api/v1/public/gameList该接口无需签名,返回明文 JSON。
响应示例:
{
"code": 200,
"data": [
{
"gameId": 1000,
"gameName": "飞龙捕鱼+",
"gameType": 2,
"gameTypeName": "捕鱼",
"supportCurrencies": ["CNY", "USD"]
}
],
"msg": "成功"
}字段说明:
| 字段 | 说明 |
|---|---|
gameId | 游戏 ID,登录和试玩接口使用 |
gameName | 游戏名称 |
gameType | 游戏类型 ID |
gameTypeName | 游戏类型名称 |
supportCurrencies | 当前平台支持币种列表;具体商户权限以业务接口校验为准 |
11.3 创建玩家
POST /api/v1/createPlayer入参:
| 参数 | 必填 | 说明 |
|---|---|---|
agentName | 是 | Agent 账号,varchar(50) |
loginName | 是 | 商户玩家账号,varchar(50) |
currency | 是 | 玩家钱包币种,例如 USD |
请求示例:
{
"agentName": "agent01",
"loginName": "player001",
"currency": "USD"
}响应示例:
{
"code": 200,
"data": {
"agentName": "agent01",
"loginName": "player001",
"currency": "USD",
"created": true
},
"msg": "成功"
}说明:
- 重复创建同一
agentName + loginName + currency会返回用户已存在;商户应把该结果视为玩家已创建,避免重复开户。 - 同一
agentName + loginName可以再创建其它币种。
11.4 登录游戏
POST /api/v1/login入参:
| 参数 | 必填 | 说明 |
|---|---|---|
agentName | 是 | Agent 账号 |
loginName | 是 | 玩家账号 |
currency | 是 | 玩家钱包币种 |
gameId | 是 | 游戏 ID |
lang | 是 | 语言代码 |
from | 否 | 返回按钮目标地址;如游戏支持则生效 |
onReturn | 否 | 返回按钮状态:0 不显示,1 显示 |
notify | 否 | 玩家登出通知地址;如游戏支持则生效 |
请求示例:
{
"agentName": "agent01",
"loginName": "player001",
"currency": "USD",
"gameId": 3006,
"lang": "en",
"from": "https://merchant.example.com",
"onReturn": 1,
"notify": "https://merchant.example.com/lm/offline"
}响应示例:
{
"code": 200,
"data": {
"url": "https://play.example.com/?k=example-token",
"currency": "USD"
},
"msg": "成功"
}说明:
- 登录时必须明确
currency,平台按agentName + loginName + currency找到玩家钱包。 - 如果玩家只创建了
CNY,用USD登录应返回币种/玩家不存在错误。 - 游戏必须已对 Agent 启用。
11.5 获取试玩地址
POST /api/v1/testPlay入参:
| 参数 | 必填 | 说明 |
|---|---|---|
agentName | 是 | Agent 账号 |
currency | 是 | 试玩币种 |
gameId | 是 | 游戏 ID |
lang | 是 | 语言代码 |
请求示例:
{
"agentName": "agent01",
"currency": "USD",
"gameId": 3006,
"lang": "en"
}响应示例:
{
"code": 200,
"data": {
"url": "https://play.example.com/?k=trial-token",
"currency": "USD"
},
"msg": "成功"
}11.6 钱包转账
POST /api/v1/transfer入参:
| 参数 | 必填 | 说明 |
|---|---|---|
agentName | 是 | Agent 账号 |
loginName | 是 | 玩家账号 |
currency | 是 | 玩家钱包币种 |
orderNo | 是 | 商户订单号;唯一范围为 agentName + currency |
type | 是 | 1 转入,2 转出 |
amount | 是 | 转账金额,按原币种,建议保留两位小数 |
请求示例:
{
"agentName": "agent01",
"loginName": "player001",
"currency": "USD",
"orderNo": "M202607030001",
"type": 1,
"amount": 100.00
}响应示例:
{
"code": 200,
"data": {
"orderNo": "M202607030001",
"currency": "USD",
"balance": 100.00
},
"msg": "成功"
}幂等规则:
orderNo是业务幂等号。- 商户必须保证同一
agentName + currency下orderNo唯一。 - 同一
agentName + currency + orderNo重复提交不会重复记账,当前返回订单已存在;商户应通过转账订单查询确认原订单状态。 - 同一
agentName + currency + orderNo重复提交但loginName、type或amount不同,也按订单已存在处理;商户必须保证订单号不复用。
11.7 查询转账订单
POST /api/v1/transferRecord入参:
| 参数 | 必填 | 说明 |
|---|---|---|
agentName | 是 | Agent 账号 |
currency | 是 | 订单币种 |
orderNo | 是 | 商户订单号 |
请求示例:
{
"agentName": "agent01",
"currency": "USD",
"orderNo": "M202607030001"
}响应示例:
{
"code": 200,
"data": {
"orderNo": "M202607030001",
"currency": "USD",
"status": 1,
"balance": 100.00
},
"msg": "成功"
}11.8 查询余额
POST /api/v1/getBalance入参:
| 参数 | 必填 | 说明 |
|---|---|---|
agentName | 是 | Agent 账号 |
loginName | 是 | 玩家账号 |
currency | 是 | 玩家钱包币种 |
请求示例:
{
"agentName": "agent01",
"loginName": "player001",
"currency": "USD"
}响应示例:
{
"code": 200,
"data": {
"currency": "USD",
"balance": 100.00,
"inGame": 0.00
},
"msg": "成功"
}11.9 查询游戏注单
POST /api/v1/gameRecord入参:
| 参数 | 必填 | 说明 |
|---|---|---|
agentName | 是 | Agent 账号 |
currency | 是 | 查询币种 |
page | 是 | 页码,从 1 开始 |
pageSize | 是 | 每页条数,建议 100-2000 |
startTime | 是 | 开始时间,格式 yyyy-MM-dd HH:mm:ss |
endTime | 是 | 结束时间,格式 yyyy-MM-dd HH:mm:ss |
请求示例:
{
"agentName": "agent01",
"currency": "USD",
"startTime": "2026-07-03 00:00:00",
"endTime": "2026-07-03 23:59:59",
"page": 1,
"pageSize": 1000
}响应示例:
{
"code": 200,
"data": {
"current": 1,
"pageSize": 1000,
"total": 1,
"totalPage": 1,
"records": [
{
"agentName": "agent01",
"loginName": "player001",
"currency": "USD",
"recordId": "R202607030001",
"gameId": 3006,
"gameType": 1,
"bet": 1.00,
"validBet": 1.00,
"win": 0.50,
"before": 100.00,
"after": 99.50,
"startTime": 1783008000000,
"endTime": 1783008010000
}
]
},
"msg": "成功"
}查询时间说明:
startTime与endTime按 GMT+8 解释。- 建议按自然日查询,避免单次查询数据量过大。
- 返回金额均为请求
currency的原币种金额。
11.10 获取注单详情链接
POST /api/v1/record_detail_url入参:
| 参数 | 必填 | 说明 |
|---|---|---|
agentName | 是 | Agent 账号 |
currency | 是 | 记录币种 |
recordId | 是 | 游戏记录 ID |
recordTime | 是 | 记录时间戳,单位毫秒;电子通常用创建时间,捕鱼通常用结束时间 |
lang | 是 | 语言代码 |
请求示例:
{
"agentName": "agent01",
"currency": "USD",
"recordId": "R202607030001",
"recordTime": 1783008010000,
"lang": "en"
}响应示例:
{
"code": 200,
"data": {
"url": "https://detail.example.com/?s=example-token",
"currency": "USD"
},
"msg": "成功"
}11.11 单日明细报表
POST /api/v1/dailyReportDetail入参:
| 参数 | 必填 | 说明 |
|---|---|---|
agentName | 是 | Agent 账号 |
currency | 是 | 查询币种 |
date | 是 | 日期,格式 yyyy-MM-dd |
gameType | 是 | 游戏类型 |
请求示例:
{
"agentName": "agent01",
"currency": "USD",
"date": "2026-07-03",
"gameType": 1
}响应示例:
{
"code": 200,
"data": {
"currency": "USD",
"gameId": 3006,
"username": "player001",
"betCount": 10,
"totalBet": 100.00,
"totalValid": 100.00,
"totalProfit": -5.00
},
"msg": "成功"
}11.12 多日汇总报表
POST /api/v1/daily_report_total入参:
| 参数 | 必填 | 说明 |
|---|---|---|
agentName | 是 | Agent 账号 |
currency | 是 | 查询币种 |
dateStart | 是 | 开始日期,格式 yyyy-MM-dd |
dateEnd | 是 | 结束日期,格式 yyyy-MM-dd |
请求示例:
{
"agentName": "agent01",
"currency": "USD",
"dateStart": "2026-07-01",
"dateEnd": "2026-07-03"
}响应示例:
{
"code": 200,
"data": {
"currency": "USD",
"betCount": 100,
"totalBet": 1000.00,
"totalValid": 1000.00,
"totalProfit": -30.00
},
"msg": "成功"
}11.13 查询玩家信息
POST /api/v1/userInfo入参:
| 参数 | 必填 | 说明 |
|---|---|---|
agentName | 是 | Agent 账号 |
loginName | 是 | 玩家账号 |
currency | 是 | 玩家钱包币种 |
请求示例:
{
"agentName": "agent01",
"loginName": "player001",
"currency": "USD"
}响应示例:
{
"code": 200,
"data": {
"agentName": "agent01",
"loginName": "player001",
"currency": "USD",
"online": false,
"status": 1
},
"msg": "成功"
}11.14 强制玩家下线
POST /api/v1/forceLeave入参:
| 参数 | 必填 | 说明 |
|---|---|---|
agentName | 是 | Agent 账号 |
loginName | 是 | 玩家账号 |
currency | 是 | 玩家钱包币种 |
请求示例:
{
"agentName": "agent01",
"loginName": "player001",
"currency": "USD"
}响应示例:
{
"code": 200,
"data": {},
"msg": "成功"
}12. 单钱包回调接口要求
单钱包模式下,商户必须提供一个 HTTPS 回调地址。LM 会向该地址发送 POST JSON
请求,商户根据 body 里的 event 分发处理。
12.1 回调事件
| 事件 | 触发时机 | 商户动作 | 幂等要求 |
|---|---|---|---|
balance | 登录游戏前、余额查询、结算前校验 | 查询玩家当前余额,不改余额 | 可重复请求 |
debit | 玩家下注扣款 | 按 amount 扣减余额 | 以 txnId 幂等,不能重复扣款 |
credit | 玩家赢分派奖 | 按 amount 增加余额 | 以 txnId 幂等,不能重复加款 |
rollback | 冲正原扣款或加款 | 根据 origTxnId 回滚原交易 | 原交易不存在或已回滚也应幂等返回 |
12.2 回调请求头
LM 回调商户时使用同一套签名头:
| Header | 必填 | 说明 |
|---|---|---|
KEY | 是 | LM 分配给该回调配置的 key |
timestamp | 是 | Unix 时间戳,单位:秒 |
sign | 是 | 对回调 body 生成的签名 |
签名规则与商户调用 LM API 一致:回调 body 参数排序后 JSON 序列化,AES 加密后拼接
timestamp,再 MD5。currency 必须参与签名。
12.3 回调请求字段
| 字段 | 必填 | 说明 |
|---|---|---|
event | 是 | balance、debit、credit、rollback |
agentName | 是 | Agent 账号 |
loginName | 是 | 玩家账号 |
currency | 是 | 玩家钱包币种 |
txnId | 是 | LM 回调交易号,商户幂等键 |
amount | 资金事件必填 | 扣款、加款或回滚金额 |
gameId | 否 | 游戏 ID |
roundId | 否 | 游戏局号 |
recordId | 否 | 游戏记录 ID |
origTxnId | rollback 必填 | 需要冲正的原始交易号 |
balance 示例:
{
"event": "balance",
"agentName": "agent01",
"loginName": "player001",
"currency": "USD",
"txnId": "LM-BAL-202607030001"
}debit 示例:
{
"event": "debit",
"agentName": "agent01",
"loginName": "player001",
"currency": "USD",
"txnId": "LM-DB-202607030001",
"amount": 1.00,
"gameId": 3006,
"roundId": "ROUND-001"
}12.4 回调响应格式
商户响应也使用 code/data/msg:
{
"code": 200,
"data": {
"currency": "USD",
"balance": 99.00
},
"msg": "成功"
}要求:
- 成功时
code=200。 balance、debit、credit、rollback成功时应返回当前余额。- 余额不足时不能扣款,应返回非 200 业务码。
- 重复
txnId必须返回第一次处理后的等价结果。 - 回调超时或网络失败时,LM 可以按策略重试;商户必须用
txnId防重复。
13. 错误码
LM API 使用 code/msg/data 响应格式,并定义业务错误码。
| 代码 | 说明 |
|---|---|
| 200 | 请求成功 |
| 503 | 系统维护中 |
| 4000 | Agent 不存在 |
| 4001 | IP 不在 API 白名单 |
| 4002 | 参数错误 |
| 4004 | 未开启此游戏 |
| 4005 | 用户登录失败 |
| 4006 | 用户不存在 |
| 4007 | 转账失败 |
| 4008 | 查询时间间隔超限 |
| 4009 | 时间格式错误,应为 yyyy-MM-dd HH:mm:ss |
| 4010 | 页码从 1 开始 |
| 4011 | 每页条数超出允许范围 |
| 4012 | 不支持的游戏类型 |
| 4013 | 不支持的语言类型 |
| 4014 | 用户已存在 |
| 4015 | 订单不存在 |
| 4016 | 订单已存在或订单参数冲突 |
| 4017 | 金额错误 |
| 4018 | 金额不足 |
| 4019 | 签名错误 |
| 4020 | 时间戳已失效 |
| 4021 | 日期格式错误,应为 yyyy-MM-dd |
| 4024 | 游戏仍在进行中,无法转出金额 |
| 4025 | 错误的时间范围 |
| 4100 | currency 必填 |
| 4101 | 不支持的币种 |
| 4102 | Agent 未启用该币种 |
| 4103 | 玩家币种不存在或不匹配 |
| 4104 | 币种汇率未配置 |
| 4105 | 币种限红 bet-rate 未配置 |
| 4110 | 单钱包回调失败 |
| 4111 | 单钱包余额不足 |
| 4112 | 单钱包回调签名错误 |
最终错误码应以实现和 OpenAPI 合同为准。
14. IP 白名单和安全要求
- 商户调用 LM API 的服务器出口 IP 应加入平台白名单。
- 不要把玩家真实 IP 当作商户服务器 IP 提交。
- Agent API 密钥必须保存在商户服务端,不能下发到浏览器、App 或前端页面。
- 生产密钥和测试密钥应分开。
- 网络超时后,转账接口不要换
orderNo直接重试;应先用
/api/v1/transferRecord 查询原订单结果。
- 单钱包回调密钥也必须保存在商户服务端,不能和商户调用 LM 的 API 密钥混用。
15. 联调检查清单
15.1 基础检查
- Agent 已创建。
- Agent API 密钥已交付。
- Agent 已启用至少一个币种。
- Agent 已授权至少一个游戏。
- 商户服务器出口 IP 已加入白名单。
- 商户能正确使用平台分配的
KEY生成timestamp、sign。
15.2 多币种检查
- 使用
agent01 + player001 + CNY创建玩家成功。 - 使用
agent01 + player001 + USD创建玩家成功。 - 两个币种余额互不影响。
USD玩家不能用CNY钱包余额进入游戏。- 转账、余额、游戏记录、日报按请求
currency返回原币种金额。
15.3 转账钱包检查
type=1转入成功。- 查询余额正确。
- 登录游戏成功。
- 游戏下注后余额变化正确。
- 注单能按币种查到。
type=2转出成功。- 网络超时场景能用
transfer-record查单。 - 重复
orderNo不会重复加款或扣款。
15.4 单钱包检查
- 商户回调地址可通过公网 HTTPS 访问。
- 商户能正确验证 LM 回调签名。
balance回调返回正确余额。debit扣款成功且重复txnId不重复扣款。- 余额不足时
debit不扣款并返回失败。 credit加款成功且重复txnId不重复加款。rollback能按origTxnId幂等回滚。- 进入游戏、下注、结算、查注单完整链路通过。