米洛SDK H5 SDK 接入文档
本文档用于H5游戏接入米洛SDK平台,包含完整的JS接口说明、代码示例和注意事项。
接入描述
游戏对接时游戏方提供商家名称、游戏名称、游戏登录地址、支付异步通知地址(或者在后台添加获取相应的参数),米洛SDK向游戏方提供mlsdk_Gameid、mlsdk_payKey、mlsdk_appKey(应用加密字段,请妥善保管mlsdk_Gameid、mlsdk_payKey、mlsdk_appKey)及游戏测试地址(具体地址问运营获取)。
用户访问游戏时米洛SDK会在研发调用登录接口时返回username(用户唯一识别ID)及token(用户登录口令可以用于二次校验使用)),uid等信息,游戏请求各个接口时需取得用户授权参数username及token。请求校验参数token为请求参数与值加mlsdk_appKey(具体参见服务端对接文件)
特别注意
重要事项
- 所有接口接入之前必须先提供(商家名称、游戏名称、游戏登录地址、充值回调地址),米洛SDK提供该游戏的密钥对(mlsdk_Gameid、mlsdk_payKey、mlsdk_appKey)和游戏测试地址。
- 游戏开发对接需在米洛SDK提供的测试地址中进行才能唤起支付。
- 每款游戏对应一组密钥对(mlsdk_Gameid、mlsdk_payKey、mlsdk_appKey)。
- 米洛SDK用户登录游戏后,会分配给游戏该用户的username及token。其中,同一个用户对同一款游戏来说,username是固定不变的,游戏方可以将username与自身的用户系统username绑定。因此,可对同一个米洛SDK用户做游戏存档等操作。
- 请妥善保存游戏的密钥对。mlsdk_payKey、mlsdk_appKey不可直接暴露在前端。如发现泄露,请尽快联系米洛SDK进行更换。
- 如果研发需要跳转url地址请务必带上url的参数,url参数并不固定不同渠道对应的参数可能不同,千万别固定写死
接入流程
1. 引入JS类库
<script src="https://sdk.wancms.com/static/channel/WancmsSDK.v2.js"></script>
2. 初始化mlSDK
游戏应调用mlSDK的init接口,同时传入mlSDK后台分配给游戏的参数.
/*初始化以及登录*/
var mlgameid = '1';//后台自动分配
mlSDK.init(mlgameid, true, function(){
console.log("init success");
})
3. 调用login方法
调用示例如下:
var uid;
var username;
mlSDK.login(function(callbackData){
var message;
if(callbackData.status){
uid = callbackData.data.uid;
username = callbackData.data.username;
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);
}
})
登录返回数据说明
| 字段 | 说明 |
|---|---|
status |
登录状态,true表示成功 |
data.uid |
用户ID |
data.username |
用户名 |
data.token |
登录令牌 |
message |
提示信息 |
4. 调用支付接口
当用户点击购买时,游戏可调用pay方法传入orderInfo对象调起各渠道的支付页面.
function pay(){
/*充值*/
orderInfo = new Object();
orderInfo.mlgameid = '1';//必传
orderInfo.uid = uid;//必传
orderInfo.username = username;//必传
orderInfo.roleid = '角色id';//必传
orderInfo.rolename = '角色名';//必传
orderInfo.serverid = 1;//区服id 必传
orderInfo.servername = '内测1区';//区服名必传
orderInfo.rolelevel = 1;//角色等级 必传 类型需为int
orderInfo.cpOrderNo = 'w123456789ss';//cp订单号必传
orderInfo.amount = '1';//总金额 必传 amount金额需为整数或浮点数
orderInfo.viplevel = '111';//vip等级 没有则填空
orderInfo.rolebalance = '111';//角色余额 没有则填空
orderInfo.partyname = '公会社团';//公会社团 没有则填空
orderInfo.goodsname = '商品名';//商品名 必传
orderInfo.extrasparams = '';//透传参数 没有则填空
orderInfo.goodsid = '222';//产品ID 没有则填空
orderInfo.count = '';//数量 没有则填空
orderInfo.callbackUrl = '';//回调地址 没有则填空
var orderInfoJson = JSON.stringify(orderInfo);
mlSDK.pay(orderInfoJson, function(payStatusObject){
console.log('GameDemo:下单通知' + payStatusObject.message);
})
}
支付参数说明
| 参数名 | 说明 | 是否必填 |
|---|---|---|
mlgameid |
游戏ID | 必填 |
uid |
用户ID | 必填 |
username |
用户名 | 必填 |
roleid |
角色ID | 必填 |
rolename |
角色名 | 必填 |
serverid |
区服ID | 必填 |
servername |
区服名 | 必填 |
rolelevel |
角色等级(类型需为int) | 必填 |
cpOrderNo |
CP订单号 | 必填 |
amount |
总金额(需为整数或浮点数) | 必填 |
goodsname |
商品名 | 必填 |
viplevel |
VIP等级 | 选填 |
rolebalance |
角色余额 | 选填 |
partyname |
公会社团 | 选填 |
extrasparams |
透传参数 | 选填 |
goodsid |
产品ID | 选填 |
count |
数量 | 选填 |
callbackUrl |
回调地址 | 选填 |
4.1 充值异步回调通知
| 项目 | 说明 |
|---|---|
| 请求地址 | 由游戏方提供通知地址 |
| 请求方 | 充值成功后由米洛SDK服务端请求至游戏方服务器 |
| 请求方式 | 异步get/post请求 |
| 请求参数 | 详见服务端对接文档 |
5. 上传角色信息接口
游戏需要在玩家登录或角色发生变化调用此接口.
function uploadGameRoleInfo(){
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 = '';//好友关系列表
var roleInfoJson = JSON.stringify(roleInfo);
mlSDK.uploadGameRoleInfo(roleInfoJson, function(response){
if(response.status){
console.log('uploadMessage:' + response.message);
}else{
console.log('uploadMessage:' + response.message);
}
});
}
角色信息参数说明
| 参数名 | 说明 | 是否必填 |
|---|---|---|
isCreateRole |
创建角色时true其他传false | 必填 |
uid |
用户ID | 必填 |
username |
用户名 | 必填 |
serverid |
区服ID | 必填 |
servername |
区服名 | 必填 |
rolename |
角色名 | 必填 |
roleid |
角色ID | 必填 |
rolelevel |
角色等级(类型需为int) | 必填 |
rolebalance |
角色用户余额(类型需为int) | 必填 |
viplevel |
VIP等级(类型需为int) | 必填 |
partyname |
公会社团 | 必填 |
partyid |
帮派ID | 选填 |
rolegender |
性别 | 选填 |
rolepower |
战力 | 选填 |
partyroleid |
角色在帮派中的ID | 选填 |
partyrolename |
角色在帮派中的名称 | 选填 |
profession |
职业名 | 选填 |
professionid |
职业ID | 选填 |
friendlist |
好友关系列表 | 选填 |
6. 调用注销接口
退出登录
mlSDK.logout(function(logoutObject){
console.log('Game:成功退出游戏');
})
注册退出通知
mlSDK.setLogoutNotification(function(logoutObject){
console.log('Game:玩家点击注销帐号');
})
7. Token 使用建议
登录成功后获得的 token 用于二次校验,建议妥善保存:
// 登录成功后保存 token
mlSDK.login(function(data) {
if (data.status) {
sessionStorage.setItem('token', data.data.token);
}
});
// 请求接口时使用 token
function makeAPIRequest() {
var token = sessionStorage.getItem('token');
// 在请求头或参数中带上 token 进行二次校验
}
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://sdk.wancms.com/static/channel/WancmsSDK.v2.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. 常见问题
🔧 初始化相关
Q1: 初始化失败怎么办?
A: 检查以下几点:
- 确认已正确引入 jQuery/Zepto 和 mlSDK
- 确认游戏测试地址在米洛SDK提供的域名下
- 打开浏览器控制台查看详细错误信息
- 确认 mlgameid 正确
// 开启调试模式查看详细日志
mlSDK.init('1', true, function() {
console.log("init success");
});
Q2: 初始化回调没有触发?
A: 可能原因:
- 网络请求超时 - 检查网络连接
- 渠道脚本加载失败 - v2.1.1 已修复,即使失败也会继续初始化
- URL 参数格式错误 - 确保 URL 中只有一个
?
🔐 登录相关
Q3: 登录失败或返回空数据?
A: 检查:
- 必须先调用
init()成功后才能调用login() - 确认游戏地址带有正确的 URL 参数(username、token)
- 查看控制台日志确认错误信息
// 正确的调用顺序
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 新增登录状态检查。确保:
- 已成功调用
login()方法 - 登录成功后再调用
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:
- 开启调试模式(isDebug = true)
- 打开浏览器开发者工具(F12)
- 查看 Console 面板的日志
- 红色日志为错误信息
⚠️ 常见错误
Q17: 提示 "mlSDK is not defined"?
A: 检查:
- 是否引入了 mlSDK 文件
- 引入顺序是否正确(jQuery → mlSDK)
- 文件路径是否正确
<!-- ✅ 正确顺序 -->
<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);
10. 参数速查表
10.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 | ❌ | '' |
10.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 | ❌ | '' |
11. 更新日志
v2.1.1 (2026-02-19)
Bug 修复:
- ✅ 修复未登录时调用支付方法导致崩溃的问题
- ✅ 修复未登录时调用角色上传方法导致崩溃的问题
- ✅ 修复渠道脚本加载失败导致 SDK 初始化卡住的问题
优化:
- ✅ 支付方法增加登录状态检查
- ✅ 角色上传方法增加登录状态检查
- ✅ 渠道脚本加载失败改为警告并继续初始化
📞 技术支持
- 官方文档: https://unify.wancms.com/h5-sdk.html
- 🌐 测试地址: 请联系运营获取
- 📧 技术支持: 767146962
- 🐛 Bug 反馈: 请提供浏览器控制台日志