米洛SDK H5 API 标准对接文档

📖 完全按照官方 API 文档实现

官方文档: https://unify.wancms.com/h5api.html

1. 接入前准备

1.1 必须提供的信息

对接前需要向米洛SDK提供以下信息:

  • ✅ 商家名称
  • ✅ 游戏名称
  • ✅ 游戏登录地址
  • ✅ 支付异步通知地址(或在后台添加获取相应参数)

1.2 米洛SDK提供的信息

米洛SDK会为您提供:

  • mlsdk_Gameid - 游戏 ID
  • mlsdk_payKey - 支付密钥
  • mlsdk_appKey - 应用加密字段(请妥善保管)
  • ✅ 游戏测试地址
⚠️ 重要提示:
  1. 每款游戏对应一组密钥对(mlsdk_Gameid、mlsdk_payKey、mlsdk_appKey)
  2. 请妥善保存密钥对,mlsdk_payKey、mlsdk_appKey 不可直接暴露在前端
  3. 如发现泄露,请尽快联系米洛SDK进行更换
  4. 游戏开发对接需在 米洛SDK提供的测试地址中进行才能唤起支付

2. 引入 SDK

在 HTML 文件中引入必要的 JS 库:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>游戏名称</title>
    
    <!-- 1. 引入 jQuery 或 Zepto(必须) -->
    <script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
    
    <!-- 2. 引入 mlSDK -->
    <script src="https://unify.wancms.com/static/channel/libWancmsnewSDK.js"></script>
</head>
<body>
    <!-- 游戏内容 -->
</body>
</html>

3. 初始化 SDK

3.1 接口说明

游戏应调用 mlSDK 的 init 接口,同时传入 mlSDK 后台分配给游戏的参数。

3.2 接口定义

mlSDK.init(mlgameid, isDebug, callback)

3.3 参数说明

参数 类型 必填 说明
mlgameid string/number 后台自动分配的游戏 ID
isDebug boolean 是否开启调试模式
callback function 初始化完成回调函数

3.4 调用示例

// 后台自动分配的 mlgameid
var mlgameid = '1';

mlSDK.init(mlgameid, true, function() {
    console.log("init success");
});
✅ 注意事项:
  • mlgameid 由后台自动分配,使用字符串或数字均可
  • 生产环境请将 isDebug 设为 false
  • 初始化成功后才能调用其他接口

4. 调用 login 方法

4.1 接口说明

用户访问游戏时,米洛SDK会采用 iframe 方式访问游戏登录地址,并带上以下参数:

  • username - 用户唯一识别 ID
  • token - 用户登录口令(可以用于二次校验)
重要说明:
  • 同一个用户对同一款游戏来说,username 是固定不变的
  • 游戏方可以将 username 与自身的用户系统 username 绑定
  • 可对同一个米洛SDK用户做游戏存档等操作

4.2 接口定义

mlSDK.login(callback)

4.3 参数说明

参数 类型 必填 说明
callback function 登录结果回调函数

4.4 回调参数

{
    status: true,           // boolean - 登录状态
    data: {
        uid: '123',         // string - 用户 ID
        username: 'user',   // string - 用户名
        token: 'xxx'        // string - 登录令牌(用于二次校验)
    },
    message: ''             // string - 提示信息
}

4.5 调用示例

var uid;
var username;
var token;

mlSDK.login(function(callbackData) {
    var message;
    
    if (callbackData.status) {
        // 登录成功
        uid = callbackData.data.uid;
        username = callbackData.data.username;
        token = callbackData.data.token;
        
        console.log('GameDemo:username:' + uid);
        console.log('GameDemo:SDK登录成功: uid=>' + callbackData.data.uid);
        console.log('GameDemo:SDK登录成功: token=>' + callbackData.data.token);
        console.log('GameDemo:SDK登录成功: username=>' + callbackData.data.username);
        console.log('GameDemo:SDK登录成功: logintime=>' + callbackData.data.logintime);
    } else {
        // 登录失败
        console.log('GameDemo:SDK登录失败:' + callbackData.message);
    }
});

4.6 Token 使用建议

// 建议将 token 保存在 sessionStorage
sessionStorage.setItem('token', token);

// 请求接口时带上 token 进行二次校验
function makeAPIRequest() {
    var token = sessionStorage.getItem('token');
    // 使用 token 进行请求
}

5. 调用支付接口

5.1 接口说明

当用户点击购买时,游戏可调用 pay 方法传入 orderInfo 对象调起各渠道的支付页面。

5.2 接口定义

mlSDK.pay(orderInfoJson, callback)

5.3 参数说明

orderInfo 对象参数

参数名 类型 必填 说明
mlgameid string 游戏 ID
uid string 用户 ID
username string 用户名
roleid string 角色 ID
rolename string 角色名
serverid int 区服 ID
servername string 区服名
rolelevel int 角色等级(类型需为 int)
cpOrderNo string CP 订单号
amount number 总金额(整数或浮点数)
goodsname string 商品名
viplevel string VIP 等级(没有则填空)
rolebalance string 角色余额(没有则填空)
partyname string 公会社团(没有则填空)
extrasparams string 透传参数(没有则填空)
goodsid string 产品 ID(没有则填空)
count string 数量(没有则填空)
callbackUrl string 回调地址(没有则填空)

callback 回调参数

{
    status: true,       // boolean - 支付状态
    message: ''         // string - 提示信息
}

5.4 调用示例

function pay() {
    // 构建 orderInfo 对象
    var orderInfo = new Object();
    orderInfo.mlgameid = '1';              // 必传
    orderInfo.uid = uid;                      // 必传
    orderInfo.username = username;            // 必传
    orderInfo.roleid = 'role_001';            // 必传
    orderInfo.rolename = '角色名';            // 必传
    orderInfo.serverid = 1;                   // 区服id 必传
    orderInfo.servername = '内测1区';         // 区服名 必传
    orderInfo.rolelevel = 1;                  // 角色等级 必传 类型需为int
    orderInfo.cpOrderNo = 'w123456789ss';     // cp订单号 必传
    orderInfo.amount = '1';                   // 总金额 必传
    orderInfo.viplevel = '111';               // vip等级 没有则填空
    orderInfo.rolebalance = '111';            // 角色余额 没有则填空
    orderInfo.partyname = '公会社团';         // 公会社团 没有则填空
    orderInfo.goodsname = '商品名';           // 商品名 必传
    orderInfo.extrasparams = '';              // 透传参数 没有则填空
    orderInfo.goodsid = '222';                // 产品ID 没有则填空
    orderInfo.count = '';                     // 数量 没有则填空
    orderInfo.callbackUrl = '';               // 回调地址 没有则填空
    
    // 转换为 JSON 字符串
    var orderInfoJson = JSON.stringify(orderInfo);
    
    // 调用支付
    mlSDK.pay(orderInfoJson, function(payStatusObject) {
        console.log('GameDemo:下单通知 ' + payStatusObject.message);
        
        if (payStatusObject.status) {
            console.log('✅ 支付成功');
            // 发放商品
        } else {
            console.log('❌ 支付失败: ' + payStatusObject.message);
        }
    });
}
⚠️ 注意事项:
  • serveridrolelevel 必须为 int 类型
  • amount 金额需为 整数或浮点数
  • 可选参数没有值时请传 空字符串 ''
  • cpOrderNo 必须由游戏方生成,建议使用时间戳 + 随机数保证唯一性

5.1 充值异步回调通知

说明

  1. 请求地址:由游戏方提供通知地址
  2. 请求方:充值成功后由米洛SDK服务端请求至游戏方服务器
  3. 请求方式:异步 GET/POST 请求
  4. 请求参数以及加密形式:详见服务端对接文档

6. 上传角色信息接口

6.1 接口说明

游戏需要在玩家登录或角色发生变化时调用此接口。

6.2 接口定义

mlSDK.uploadGameRoleInfo(roleInfoJson, callback)

6.3 参数说明

roleInfo 对象参数

参数名 类型 必填 说明
isCreateRole boolean 创建角色时 true,其他传 false
uid string 用户 ID
username string 用户名
serverid int 区服 ID
servername string 区服名
rolename string 角色名
roleid string 角色 ID
rolelevel int 角色等级(类型需为 int)
rolebalance int 角色用户余额(类型需为 int)
viplevel int VIP 等级(类型需为 int)
partyname string 公会社团
partyid int 帮派 ID
rolegender string 性别
rolepower int 战力
partyroleid int 角色在帮派中的 ID
partyrolename string/int 角色在帮派中的名称
profession string 职业名
professionid string 职业 ID
friendlist string 好友关系列表

6.4 调用示例

function uploadGameRoleInfo() {
    // 构建 roleInfo 对象
    var roleInfo = new Object();
    roleInfo.isCreateRole = false;            // 创建角色时true其他传false
    roleInfo.uid = uid;                       // 必传
    roleInfo.username = username;             // 必传
    roleInfo.serverid = 1;                    // 区服id 必传
    roleInfo.servername = '区服';             // 必传
    roleInfo.rolename = '角色名';             // 必传
    roleInfo.roleid = '角色id';               // 必传
    roleInfo.rolelevel = 1000;                // 角色等级 必传 类型需为int
    roleInfo.rolebalance = 100;               // 角色用户余额 必传 类型需为int
    roleInfo.viplevel = 1;                    // vip等级必传 类型需为int
    roleInfo.partyname = '行会名称';          // 公会社团 必传
    roleInfo.partyid = 1;                     // 帮派Id
    roleInfo.rolegender = '男';               // 性别
    roleInfo.rolepower = 100;                 // 战力
    roleInfo.partyroleid = 100;               // 角色在帮派中的id
    roleInfo.partyrolename = 100;             // 角色在帮派中的名称
    roleInfo.profession = '武士';             // 职业名
    roleInfo.professionid = '32';             // 职业Id
    roleInfo.friendlist = '';                 // 好友关系列表
    
    // 转换为 JSON 字符串
    var roleInfoJson = JSON.stringify(roleInfo);
    
    // 上传角色信息
    mlSDK.uploadGameRoleInfo(roleInfoJson, function(response) {
        if (response.status) {
            console.log('uploadMessage:' + response.message);
        } else {
            console.log('uploadMessage:' + response.message);
        }
    });
}
⚠️ 注意事项:
  • serveridrolelevelrolebalanceviplevel 必须为 int 类型
  • isCreateRoleboolean 类型
  • 调用时机:玩家登录游戏时、角色创建时(isCreateRole = true)、角色信息发生变化时(升级、充值等)

7. 调用注销接口

7.1 退出游戏

mlSDK.logout(function(logoutObject) {
    console.log('Game:成功退出游戏');
});

7.2 注册退出通知

mlSDK.setLogoutNotification(function(logoutObject) {
    console.log('Game:玩家点击注销帐号');
});
说明:
  • logout() - 执行注销操作
  • setLogoutNotification() - 监听玩家点击注销帐号事件

8. 完整示例代码

8.1 完整流程

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
    <script src="https://unify.wancms.com/static/channel/libWancmsnewSDK.js"></script>
</head>
<body>
    <script>
    // 全局变量
    var uid;
    var username;
    var token;
    
    // 1. 初始化 SDK
    var mlgameid = '1';  // 后台自动分配
    mlSDK.init(mlgameid, true, function() {
        console.log("init success");
        
        // 2. 调用 login 方法
        mlSDK.login(function(callbackData) {
            if (callbackData.status) {
                uid = callbackData.data.uid;
                username = callbackData.data.username;
                token = callbackData.data.token;
                
                console.log('SDK登录成功: uid=>' + uid);
                console.log('SDK登录成功: token=>' + token);
                console.log('SDK登录成功: username=>' + username);
                
                // 3. 上传角色信息(登录成功后)
                uploadGameRoleInfo();
            } else {
                console.log('SDK登录失败:' + callbackData.message);
            }
        });
    });
    
    // 上传角色信息
    function uploadGameRoleInfo() {
        var roleInfo = new Object();
        roleInfo.isCreateRole = true;         // 创建角色
        roleInfo.uid = uid;
        roleInfo.username = username;
        roleInfo.serverid = 1;
        roleInfo.servername = '内测1区';
        roleInfo.rolename = '测试角色';
        roleInfo.roleid = 'role_001';
        roleInfo.rolelevel = 1;
        roleInfo.rolebalance = 0;
        roleInfo.viplevel = 0;
        roleInfo.partyname = '';
        
        var roleInfoJson = JSON.stringify(roleInfo);
        mlSDK.uploadGameRoleInfo(roleInfoJson, function(response) {
            console.log('uploadMessage:' + response.message);
        });
    }
    
    // 支付
    function pay() {
        var orderInfo = new Object();
        orderInfo.mlgameid = '1';
        orderInfo.uid = uid;
        orderInfo.username = username;
        orderInfo.roleid = 'role_001';
        orderInfo.rolename = '测试角色';
        orderInfo.serverid = 1;
        orderInfo.servername = '内测1区';
        orderInfo.rolelevel = 1;
        orderInfo.cpOrderNo = 'w' + Date.now();
        orderInfo.amount = '1';
        orderInfo.goodsname = '钻石礼包';
        orderInfo.viplevel = '';
        orderInfo.rolebalance = '';
        orderInfo.partyname = '';
        orderInfo.extrasparams = '';
        orderInfo.goodsid = '';
        orderInfo.count = '';
        orderInfo.callbackUrl = '';
        
        var orderInfoJson = JSON.stringify(orderInfo);
        mlSDK.pay(orderInfoJson, function(payStatusObject) {
            console.log('GameDemo:下单通知 ' + payStatusObject.message);
        });
    }
    
    // 退出
    function logout() {
        mlSDK.logout(function(logoutObject) {
            console.log('Game:成功退出游戏');
        });
    }
    </script>
</body>
</html>

9. 参数速查表

9.1 支付参数速查

参数 类型 必填 示例值
mlgameid string '1'
uid string '123'
username string 'player'
roleid string 'role_001'
rolename string '勇者'
serverid int 1
servername string '内测1区'
rolelevel int 1
cpOrderNo string 'w123456'
amount number '1' 或 '1.5'
goodsname string '钻石礼包'
viplevel string ''
rolebalance string ''
partyname string ''
extrasparams string ''
goodsid string ''
count string ''
callbackUrl string ''

9.2 角色参数速查

参数 类型 必填 示例值
isCreateRole boolean true/false
uid string '123'
username string 'player'
serverid int 1
servername string '内测1区'
rolename string '勇者'
roleid string 'role_001'
rolelevel int 1000
rolebalance int 100
viplevel int 1
partyname string '公会'
partyid int 1
rolegender string '男'
rolepower int 100
partyroleid int 100
partyrolename int 100
profession string '武士'
professionid string '32'
friendlist string ''

10. 常见问题

🔧 初始化相关

Q1: 初始化失败怎么办?

A: 检查以下几点:

  1. 确认已正确引入 jQuery/Zepto 和 mlSDK
  2. 确认游戏测试地址在米洛SDK提供的域名下
  3. 打开浏览器控制台查看详细错误信息
  4. 确认 mlgameid 正确
// 开启调试模式查看详细日志
mlSDK.init('1', true, function() {
    console.log("init success");
});

Q2: 初始化回调没有触发?

A: 可能原因:

  1. 网络请求超时 - 检查网络连接
  2. 渠道脚本加载失败 - v2.1.1 已修复,即使失败也会继续初始化
  3. URL 参数格式错误 - 确保 URL 中只有一个 ?

🔐 登录相关

Q3: 登录失败或返回空数据?

A: 检查:

  1. 必须先调用 init() 成功后才能调用 login()
  2. 确认游戏地址带有正确的 URL 参数(username、token)
  3. 查看控制台日志确认错误信息
// 正确的调用顺序
mlSDK.init('1', true, function() {
    // ✅ 初始化成功后才能登录
    mlSDK.login(function(data) {
        if (data.status) {
            console.log('登录成功');
        }
    });
});

Q4: token 如何使用?

A: token 用于二次校验,建议保存:

// 登录成功后保存
mlSDK.login(function(data) {
    if (data.status) {
        sessionStorage.setItem('token', data.data.token);
    }
});

// 请求接口时使用
var token = sessionStorage.getItem('token');
// 在请求头或参数中带上 token

💰 支付相关

Q5: 支付失败提示"请先登录"?

A: v2.1.1 新增登录状态检查。确保:

  1. 已成功调用 login() 方法
  2. 登录成功后再调用 pay()
// ✅ 正确流程
mlSDK.login(function(data) {
    if (data.status) {
        // 登录成功后才能支付
        pay();
    }
});

Q6: 如何生成唯一的 cpOrderNo?

A: 使用时间戳 + 随机数:

function generateCPOrderNo() {
    var timestamp = Date.now().toString(36);
    var random = Math.random().toString(36).substr(2, 9);
    return 'w' + timestamp + random;
}

// 使用
orderInfo.cpOrderNo = generateCPOrderNo();

Q7: 支付金额格式要求?

A: amount 可以是整数或浮点数:

orderInfo.amount = '1';      // ✅ 整数
orderInfo.amount = '1.5';    // ✅ 浮点数
orderInfo.amount = 1;        // ✅ 数字类型
orderInfo.amount = 1.5;      // ✅ 数字类型

🎭 角色上传相关

Q8: 上传角色失败提示"请先登录"?

A: 同支付,需要先登录:

// ✅ 正确流程
mlSDK.login(function(data) {
    if (data.status) {
        // 登录成功后上传角色
        uploadRoleInfo();
    }
});

Q9: isCreateRole 什么时候传 true?

A:

  • 创建角色时true
  • 角色升级、信息更新时false
// 创建角色
roleInfo.isCreateRole = true;

// 更新角色信息(升级、充值等)
roleInfo.isCreateRole = false;

Q10: 参数类型错误怎么办?

A: 确保以下参数为 int 类型:

// ✅ 正确 - 使用 parseInt()
roleInfo.serverid = parseInt('1');
roleInfo.rolelevel = parseInt('1000');
roleInfo.rolebalance = parseInt('100');
roleInfo.viplevel = parseInt('1');

// ❌ 错误 - 字符串类型
roleInfo.serverid = '1';
roleInfo.rolelevel = '1000';

支付参数中:

orderInfo.serverid = parseInt('1');      // int
orderInfo.rolelevel = parseInt('10');    // int

📦 参数相关

Q11: 可选参数没有值怎么办?

A: 传空字符串 ''不要省略参数

// ✅ 正确 - 传空字符串
orderInfo.viplevel = '';
orderInfo.rolebalance = '';
orderInfo.partyname = '';

// ❌ 错误 - 省略参数
delete orderInfo.viplevel;  // 不要这样做

Q12: 参数是传 JSON 字符串还是对象?

A: SDK 支持两种格式,推荐使用 JSON 字符串

// ✅ 推荐 - JSON 字符串
var orderInfoJson = JSON.stringify(orderInfo);
mlSDK.pay(orderInfoJson, callback);

// ✅ 也支持 - 对象直接传
mlSDK.pay(orderInfo, callback);

🌐 渠道集成相关

Q13: 渠道脚本加载失败怎么办?

A: v2.1.1 已优化处理:

  • 渠道脚本加载失败不会阻断 SDK 初始化
  • 会输出警告日志但继续执行
  • SDK 核心功能仍可正常使用
// 日志输出
[mlSDK 警告] 基础渠道脚本加载失败,继续初始化
[mlSDK 运行日志] SDK 初始化完成

Q14: 如何实现渠道支付回调?

A: 在渠道脚本的 mlcallChannelPay 中回调:

// 渠道脚本中
function mlcallChannelPay(order) {
    // 调起渠道支付
    MyChannelSDK.pay(order, function(result) {
        // 支付完成后必须回调
        if (mlSDK._payCallback) {
            mlSDK._payCallback({
                status: result.success,
                message: result.message
            });
        }
    });
}
⚠️ 重要: 忘记回调会导致游戏无法知道支付结果!

🐛 调试相关

Q15: 如何开启调试模式?

A: 初始化时设置 isDebug = true

mlSDK.init('1', true, function() {
    // true = 开启调试模式
    // 会在控制台输出详细日志
});

开启后可以看到:

[mlSDK 运行日志] SDK 初始化开始, gameId: 1
[mlSDK 运行日志] 已调用渠道初始化 mlcallChannelInit
[mlSDK 运行日志] SDK 初始化完成
[mlSDK 运行日志] 开始登录流程
[mlSDK 运行日志] 登录成功, uid: 123456

Q16: 如何查看详细的错误信息?

A:

  1. 开启调试模式(isDebug = true)
  2. 打开浏览器开发者工具(F12)
  3. 查看 Console 面板的日志
  4. 红色日志为错误信息

⚠️ 常见错误

Q17: 提示 "mlSDK is not defined"?

A: 检查:

  1. 是否引入了 mlSDK 文件
  2. 引入顺序是否正确(jQuery → mlSDK)
  3. 文件路径是否正确
<!-- ✅ 正确顺序 -->
<script src="jquery.min.js"></script>
<script src="./WancmsSDK.v2.js"></script>

<!-- ❌ 错误 - 顺序反了 -->
<script src="./WancmsSDK.v2.js"></script>
<script src="jquery.min.js"></script>

Q18: 支付时提示"订单信息格式错误"?

A: 检查 JSON 格式:

// ✅ 正确
var orderInfo = {
    mlgameid: '1',
    uid: uid,
    // ... 其他参数
};
var orderInfoJson = JSON.stringify(orderInfo);
mlSDK.pay(orderInfoJson, callback);

// ❌ 错误 - 忘记 stringify
mlSDK.pay(orderInfo, callback);  // 虽然支持,但推荐用字符串

Q19: 提示"缺少必需参数"?

A: SDK 会自动填充所有必填参数,游戏方只需提供核心业务参数。

支付接口必填参数(14个):

  • mlgameid, uid, username
  • roleid, rolename
  • serverid, servername
  • rolelevel, cpOrderNo, amount, goodsname
  • goodsid, count, rolepower

推荐最小化调用:

mlSDK.pay({
    amount: 100,
    goodsname: '钻石礼包',
    goodsid: 'goods_001',
    count: '1',
    rolepower: '10000'
}, callback);

角色上传必填参数(11个):

  • isCreateRole, uid, username
  • serverid, servername
  • rolename, roleid
  • rolelevel, rolebalance, viplevel, partyname
💡 提示:所有必填参数如果游戏方未提供,SDK 会自动填充默认值,不会阻止调用。

🚀 最佳实践

Q20: 推荐的对接流程是什么?

A: 完整流程:

// 1. 页面加载后初始化
window.onload = function() {
    mlSDK.init('1', true, function() {
        console.log('SDK 初始化成功');
        
        // 2. 自动调用登录
        mlSDK.login(function(data) {
            if (data.status) {
                console.log('登录成功');
                
                // 3. 上传角色信息(创角)
                uploadRoleInfo(true);  // true = 创建角色
            }
        });
    });
};

// 4. 玩家购买时调用支付
function onPlayerBuy() {
    pay();
}

// 5. 角色升级时上传角色
function onRoleLevelUp() {
    uploadRoleInfo(false);  // false = 更新角色
}

// 6. 玩家退出时
function onPlayerLogout() {
    mlSDK.logout(function() {
        console.log('退出成功');
    });
}

Q21: 如何处理网络异常?

A: SDK 已内置网络错误处理,但建议:

// 添加超时处理
mlSDK.init('1', true, function() {
    console.log('初始化成功');
});

// 30秒后检查是否初始化成功
setTimeout(function() {
    if (!mlSDK._initialized) {
        console.error('初始化超时,请检查网络');
        // 可以提示用户刷新页面
    }
}, 30000);

📞 技术支持

  • 官方文档: https://unify.wancms.com/h5api.html
  • 🌐 测试地址: 请联系运营获取
  • 技术支持:QQ 767146962
  • 🐛 Bug 反馈: 请提供浏览器控制台日志

📝 更新日志

v2.1.1 (2026-02-19)

Bug 修复:

  • ✅ 修复未登录时调用支付方法导致崩溃的问题
  • ✅ 修复未登录时调用角色上传方法导致崩溃的问题
  • ✅ 修复渠道脚本加载失败导致 SDK 初始化卡住的问题

优化:

  • ✅ 支付方法增加登录状态检查
  • ✅ 角色上传方法增加登录状态检查
  • ✅ 渠道脚本加载失败改为警告并继续初始化

祝您对接顺利!🎉