米洛SDK产品概述
米洛SDK是一款专业的手游聚合发行平台SDK,为游戏开发者提供从渠道接入、用户管理、支付聚合到数据分析的一站式解决方案。
为什么选择米洛SDK?
- 一次接入,多渠道分发 -无需重复开发
- 快速上线 - 标准化接口,按接入范围推进联调
- 稳定可靠 - 99.99%系统可用性,7×24小时技术支持
- 完全免费 - 无前期接入费用,降低开发成本
适用场景
重度RPG
高并发支付保障、跨服交易、深度运营体系
休闲游戏
批量管理、广告聚合、轻量级SDK
出海发行
多币种支付、多语言本地化、全球渠道对接
核心功能
1. 聚合渠道SDK
一次接入即可多渠道分发
2. 支持滚动预付
为各中小研发发行解决结算问题
3. 智能数据平台
全方位数据分析,驱动精细化运营:
- 实时数据监控,秒级延迟
- 多维度分析报表(留存、付费、LTV等)
- AI驱动的运营决策支持
- 自定义事件追踪与漏斗分析
4. 用户管理中心
多端用户统一
快速接入指南
按4步完成接入准备、接口联调和上线检查。
需求沟通
联系商务团队,明确您的游戏类型与发行需求,我们将量身定制最优方案。
获取SDK
从开发者平台下载对应平台的SDK包,包含SDK文件、Demo示例和完整文档。
// Android SDK
implementation 'com.miluosdk:core:5.0.0'
implementation 'com.miluosdk:payment:5.0.0'
// iOS (CocoaPods)
pod 'MiluoSDK', '~> 5.0.0'
pod 'MiluoSDK/Payment', '~> 5.0.0'
技术对接
按照文档指引完成SDK初始化、登录、支付等核心功能接入。我们提供一对一技术支持。
联调上线
完成联合测试后,提交审核上线。整个过程有专属技术团队全程跟进。
Android SDK 接入文档
米洛SDK Android SDK 完整接入指南,包含环境搭建、接口调用、服务器对接等内容。
快速开始
环境搭建与基础配置
SDK接口
登录、充值、登出等核心接口
服务器对接
充值回调与登录校验
iOS SDK 接入文档
米洛SDK iOS SDK 完整接入指南,包含开发环境配置、接口说明、SDK通知等内容。
环境配置
Framework集成与项目配置
用户系统
登录、注销、角色上报
充值支付
IAP支付与订单处理
H5 SDK 接入文档
米洛SDK H5 游戏SDK接入指南,包含JS类库引入、初始化、登录、支付等完整接口说明。
快速接入
引入JS类库与初始化
用户系统
登录、注销接口
充值支付
支付接口与异步回调
常见问题 - Android SDK
以下是Android SDK接入过程中常见问题及解决方案
【配置问题】SDK初始化失败或没有回调
问题原因:
- Application未正确继承
WSdkApplication - AndroidManifest.xml中缺少meta-data配置
- 未在Activity的onCreate中调用初始化方法
- 未设置初始化回调监听器
解决方案:
- 确保游戏Application继承
WSdkApplication - 检查是否添加了
mlsdk_gameId、mlsdk_ChannelName等参数 - 在Activity的
onCreate中调用WsdkManger.getInstance(this).init(this) - 在初始化前必须调用
setInitLinstener设置回调
【配置问题】HTTP请求在Android 9.0+设备上失败
问题原因:Android 9.0默认禁止明文HTTP请求,targetVersion为28时会出现此问题
解决方案:
在AndroidManifest.xml的application节点下添加:
<application android:usesCleartextTraffic="true">
【配置问题】屏幕适配问题,部分设备显示异常
问题原因:未配置屏幕适配参数,导致部分分辨率设备显示异常
解决方案:
在AndroidManifest.xml的<manifest>内添加:
<supports-screens
android:anyDensity="true"
android:largeScreens="true"
android:normalScreens="true"
android:resizeable="true"
android:smallScreens="true" />
【登录问题】登录成功后如何正确进入游戏
接入要求:
- 必须在登录界面获取到
setLoginLinstener成功回调后,才能进入游戏界面 - 从
UserInfo中获取username、token、logintime username是SDK返回的唯一ID,用于服务器验证用户- 调用登录接口前必须保证SDK已初始化成功
建议:在游戏登录界面调用SDK登录,成功后再跳转到游戏主界面
【账号问题】切换账号后游戏角色信息如何处理
处理流程:
- 收到
setSwitchUserLinstener回调 - 清除当前游戏角色信息
- 使用新的
UserInfo回到游戏界面 - 重新选择区服角色进入游戏
注意:此回调内不需要再次调用登录接口
【账号问题】注销账号后游戏应该如何处理
处理流程:
- 获取到
setLoginOutLinstener退出成功回调 - 游戏回到登录界面
- 重新调用登录方法
- 清除当前游戏角色数据
【数据上报】角色信息上报时机和必填字段
上报时机:
- 创建角色后立即上报
- 进入游戏后上报
- 角色升级时上报(升级过快可升10级上报一次)
必填字段:
ServerId- 服务器IDServerName- 服务器名称RoleName- 角色名RoleId- 角色IDRoleLevel- 角色等级sign- 加密字段(必传,建议在服务端生成)
sign加密规则:
sign = md5(username + "#" + roleId + "#" + serverId + "#" + roleLevel + "#" + gameRolePower + "#" + mlsdk_appKey)
建议:无对应字段传空字符串,不要传null
【退出问题】退出游戏时如何正确处理
正确做法:
在Activity的onBackPressed方法中调用:
@Override
public void onBackPressed() {
WsdkManger.getInstance(this).showExitDialod(this);
}
说明:
- 如果SDK没有弹框返回-1,游戏需调用自己的弹框
- 有弹框时调用
ExitLinstener.onSuccess()执行游戏退出逻辑
【生命周期】为什么必须实现所有生命周期方法
原因:SDK需要在各个生命周期节点执行相应操作,如暂停统计、恢复统计等
必须实现的方法:
- onCreate、onStart、onRestart
- onPause、onResume、onStop、onDestroy
- onNewIntent、onActivityResult
- onConfigurationChanged
- onRequestPermissionsResult
建议:直接复制文档中的生命周期代码,不要遗漏任何方法
常见问题 - iOS SDK
以下是iOS SDK接入过程中常见问题及解决方案
【配置问题】SDK初始化失败
常见原因及解决方案:
- 初始化时机错误 - 必须在应用加载完成回调中调用(建议在初始化系统window之后)
- Framework配置错误 - 确保
MYWanSdk.framework状态设置为Embed && Sign - 架构设置错误 - 在Build Settings中将Architectures设置为
armv7+arm64 - 未等待初始化完成 - 必须收到
kMYWanSDKNotiInitDidFinished通知后才能调用登录
建议:严格按照文档中的6个配置步骤逐一检查
【配置问题】屏幕方向配置导致崩溃或显示异常
问题原因:同时勾选横竖屏会导致SDK界面显示异常
解决方案:
- Device Orientation中只选中游戏兼容的方向
- 不要同时勾选横竖屏
- 如果游戏需要横竖屏切换,使用代码动态控制
【配置问题】HTTP访问或设备码权限问题
解决方案:
- 在info.plist中添加允许HTTP访问的配置
- 在info.plist中添加允许获取设备码权限
注意:iOS 9.0+默认禁止HTTP请求,必须配置ATS
【登录问题】如何正确获取登录用户信息
获取方式:
- 收到
kMYWanSDKNotiLogin登录成功通知 - 从通知的
userInfo中取得username、token、logintime - 或调用接口获取:
username、token、logintime
重要说明:
username是SDK的用户唯一标识,服务端的username就是这个值- 必须以收到登录通知为准
【登录问题】登录接口调用失败或无响应
排查步骤:
- 确认已收到初始化成功通知
kMYWanSDKNotiInitDidFinished - 检查gameid是否正确配置
- 确认Framework已正确添加到工程
- 查看Xcode控制台是否有错误日志
关键:登录接口必须在初始化成功后调用,否则会失败
【账号问题】注销账号后如何处理
触发场景:
- 调用
logout接口 - 用户从渠道SDK内的用户管理界面注销
处理流程:
- 收到
kMYWanSDKNotiLogout通知 - 回到游戏登录界面
- 重新调用登录接口
- 清除当前游戏角色信息
建议:一般认为注销成功,不用考虑失败情况
【数据上报】角色信息上报时机和注意事项
上报时机:
- 每次登录进入游戏后先调用一次
updateRoleInfoWith:isCreate: - 角色信息发生变化时调用
必填字段:
serverId- 服务器idserverName- 服务器名称gameRoleName- 角色名gameRoleID- 角色idgameUserLevel- 玩家等级(没有传0)fightPower- 玩家战力(没有传0)sign- 加密sign(必传)
sign加密规则:
sign = md5(username + "#" + roleId + "#" + serverId + "#" + roleLevel + "#" + fightPower + "#" + mlsdk_appKey)
参数说明:
isCreate表示是否为刚刚创建的角色- 如果游戏没有某些字段,传空字符串即可
建议:登录成功后立即上报一次角色信息
【生命周期】AppDelegate需要转发哪些事件
必须转发的事件:
applicationWillResignActiveapplicationDidEnterBackgroundapplicationWillEnterForegroundapplicationDidBecomeActiveapplicationWillTerminatedidRegisterForRemoteNotificationsWithDeviceTokendidFailToRegisterForRemoteNotificationsWithErrorsupportedInterfaceOrientationsForWindowopenURL相关方法(3个)continueUserActivity
建议:直接复制文档中的AppDelegate代码,确保所有方法都已转发
【功能使用】浮动工具栏和用户中心如何使用
使用方法:
- 显示浮动条:登录成功后调用
showToolBar: - 隐藏浮动条:调用
hideToolBar - 进入用户中心:调用
enterUserCenter
注意:若渠道无对应接口,调用无效,不会报错
建议:用户登录成功后显示浮动工具栏,便于用户访问SDK功能
常见问题 - H5 SDK
以下是H5 SDK接入过程中常见问题及解决方案
【接入准备】接入前需要提供哪些信息
必须提供的信息:
- 商家名称
- 游戏名称
- 游戏登录地址
- 充值回调地址
米洛SDK会提供:
- 密钥对:
mlsdk_Gameid、mlsdk_payKey、mlsdk_appKey - 游戏测试地址
注意:必须先在测试地址中进行对接,才能唤起支付
【安全问题】密钥对如何保管
重要安全提示:
- 每款游戏对应一组密钥对
mlsdk_payKey、mlsdk_appKey不可直接暴露在前端- 请妥善保存密钥对
- 如发现泄露,请尽快联系米洛SDK进行更换
建议:密钥相关操作应在服务端完成,前端只传递必要参数
【初始化】如何正确引入和初始化SDK
引入JS类库:
<script src="https://unify.wancms.com/static/channel/libWancmsnewSDK.js"></script>
初始化:
var mlsdkgameid = '1'; // 后台自动分配
mlSDK.init(mlsdkgameid, true, function(){
console.log("init success");
})
注意:必须先初始化,再调用其他接口
【登录问题】登录失败或获取不到用户信息
排查步骤:
- 确保SDK已正确初始化
- 检查
callbackData.status是否为true - 从
callbackData.data中获取uid、username、token
重要说明:
- 同一个用户对同一款游戏,
username是固定不变的 - 可以将
username与游戏自身的用户系统绑定 - 研发调用登录接口时返回username(用户唯一识别ID)及token(用户登录口令可以用于二次校验使用)),uid等信息
【支付问题】支付无法唤起或支付失败
常见问题及解决方案:
- 未在测试环境 - 必须在米洛SDK提供的测试地址中进行才能唤起支付
- 缺少必填参数 - 确保所有必填参数正确传入
- 参数类型错误 -
rolelevel需为int,amount需为整数或浮点数 - 订单号重复 -
cpOrderNo每次支付必须生成新的唯一订单号
必填参数:
mlsdkgameid、uid、username、roleid、rolename、serverid、servername、rolelevel、cpOrderNo、amount、goodsname
【数据上报】角色信息上报的必填字段
必填字段:
isCreateRole- 创建角色时true,其他传falseuid、usernameserverid、servernamerolename、roleidrolelevel- 类型需为introlebalance- 角色用户余额,类型需为intviplevel- 类型需为intpartyname- 公会社团
建议:选填字段没有则填空字符串,不要传null
【回调配置】充值异步回调通知如何配置
配置方式:
- 游戏方需提供充值异步通知地址
- 充值成功后由米洛SDK服务端请求至游戏方服务器
- 异步get/post请求
- 请求参数详见服务端对接文档
注意:必须在接入前提供充值回调地址,否则无法完成支付流程
【账号问题】如何正确处理注销
主动注销:
mlSDK.logout(function(logoutObject){
console.log('Game:成功退出游戏');
})
监听注销通知:
mlSDK.setLogoutNotification(function(logoutObject){
console.log('Game:玩家点击注销帐号');
})
处理流程:收到注销通知后,游戏应回到登录界面并清除角色数据
常见问题 - 支付相关
支付是SDK接入的核心功能,以下是最常见的支付问题
【核心问题】充值成功但游戏未到账怎么办
重要原则:游戏充值是否到账,只能以服务器通知为准!
原因说明:
- 部分渠道SDK客户端不会发送正确的支付结果通知
- 客户端的支付回调仅供参考,不可依赖
- 必须通过服务端异步回调确认支付结果
正确做法:
- 游戏服务端提供充值回调地址
- 米洛SDK支付成功后调用该地址
- 游戏服务端验证签名后发放道具
- 返回成功响应
建议:客户端只负责唤起支付,不要根据客户端回调发放道具
【签名问题】支付参数中的sign如何生成
Android签名规则:
sign = md5(username+"#"+roleid+"#"+cporderid+"#"+amount+"#"+mlsdk_appKey)
iOS签名规则:
sign = md5(username+'#'+roleid+'#'+cporderid+'#'+amount+'#'+mlsdk_appKey)
强烈建议:签名加密必须在服务端完成,不要在前端生成
原因:
- 前端代码容易被反编译,密钥会泄露
- 服务端生成更安全
- 便于统一管理和更换密钥
【订单问题】订单号重复导致支付失败
问题原因:每次支付必须使用唯一的订单号
解决方案:
- Android:
cpOrderID每次支付生成新的唯一订单号 - iOS:
cpOrderID每次支付生成新的唯一订单号 - H5:
cpOrderNo每次支付生成新的唯一订单号
建议:使用时间戳+随机数生成订单号,例如:
// Java示例
String cpOrderId = "CP" + System.currentTimeMillis() + new Random().nextInt(1000);
【参数问题】支付参数缺少字段怎么办
处理原则:如果游戏没有某些字段,传空字符串
Android必填字段:
amount- 总金额(保留两位小数)ServerId、ServerNameRoleId、RoleNamegoodsName- 产品名称cpOrderID- 游戏订单号count- 游戏币数量goodsdesc- 产品描述extrasParams- 透传参数sign- 加密信息
建议:不要传null,传空字符串""
【测试问题】如何在测试环境进行支付
Android/iOS:
- 使用运营提供的测试地址
- 使用测试账号进行测试
- 测试环境不会产生真实扣费
- 正式上线前务必切换到生产环境
H5:
- 必须在米洛SDK提供的测试地址中进行才能唤起支付
- 游戏开发对接需在测试环境中完成
注意:测试完成后,记得切换到正式环境
【回调问题】服务端回调地址如何配置和验证
配置步骤:
- 接入前向米洛SDK提供充值回调地址
- 确保URL可公网访问
- 建议使用HTTPS协议
- 米洛SDK会在后台配置该回调地址
验证步骤:
- 接收米洛SDK的回调请求
- 验证签名(防止伪造回调)
- 验证时间戳(防止重放攻击)
- 处理业务逻辑(发放道具)
- 返回成功响应
响应格式:返回success表示处理成功
常见问题 - 签名验签
签名验签是保障交易安全的核心机制
【验签失败】服务端验签失败怎么办
常见原因:
- 密钥配置错误 - 服务器端配置的密钥与后台不一致
- 参数被篡改 - 回调参数不完整或被修改
- 签名算法错误 - 未使用正确的签名算法(MD5)
- 编码问题 - 参数未使用UTF-8编码
- 参数排序错误 - 参数未按字母顺序排序
- sign参数参与签名 - sign本身不应参与签名计算
排查步骤:
- 检查密钥是否正确
- 打印参与签名的原始字符串
- 对比签名算法实现
- 使用文档提供的示例代码
建议:使用SDK提供的验签工具,避免手动实现出错
【签名规则】签名时是否包含sign参数本身
答案:不包含
正确步骤:
- 从请求参数中取出sign值
- 移除参数中的sign字段
- 对其余参数进行签名计算
- 将计算结果与sign值对比
注意:sign参数本身不参与签名计算
【安全问题】密钥泄露了怎么办
应急处理:
- 立即联系米洛SDK更换密钥
- 检查是否有异常订单
- 排查密钥泄露原因
预防措施:
- 不要在前端代码中使用密钥
- 签名操作在服务端完成
- 不要在代码仓库中提交密钥
- 使用环境变量或配置文件管理密钥
建议:定期更换密钥,提高安全性
【重放攻击】如何防止回调被重放攻击
防护方法:
- 验证时间戳:检查请求时间,超过5分钟的请求视为无效
- 验证签名:确保请求参数未被篡改
- 订单幂等性:同一订单号只处理一次
代码示例:
// 验证时间戳
long timestamp = Long.parseLong(params.get("timestamp"));
long currentTime = System.currentTimeMillis() / 1000;
if (Math.abs(currentTime - timestamp) > 300) {
return "fail: timestamp expired";
}
建议:同时实现以上三种防护措施
【幂等性】如何保证回调的幂等性
问题背景:由于网络重试机制,同一订单可能收到多次回调
解决方案:
- 数据库唯一约束 - 订单号设置唯一索引
- 状态检查 - 处理前检查订单当前状态
- 分布式锁 - 高并发场景使用Redis锁
代码示例:
// 检查订单状态
if ("PAID".equals(order.getStatus())) {
return "success"; // 已处理,直接返回成功
}
建议:至少实现状态检查,高并发场景加分布式锁
【回调超时】如何处理回调超时问题
问题说明:米洛SDK服务器等待回调响应的时间有限,超时会自动重试
正确做法:
// 推荐做法:先返回成功,再异步处理
app.post('/callback', (req, res) => {
// 1. 快速验证签名
if (!verifySign(req)) {
return res.send('fail');
}
// 2. 异步处理业务逻辑
async(() => {
processOrder(req);
});
// 3. 立即返回成功
res.send('success');
});
建议:耗时操作(如发送通知)异步处理,快速返回响应
下载中心
请根据您的目标平台选择对应的SDK对接包和打包工具。
iOS SDK (App Store上架版)
近期上线 - 符合Apple审核规范的官方版本,支持App Store分发。
预计发布时间:请关注后续通知
下载说明
- 下载后请查看包内的
README.md文件了解接入步骤 - 每个游戏需要使用专属的GameId和密钥对,请联系运营获取
- 如有接入问题,请参考上方的常见问题或联系技术支持
- iOS上架版提交Apple审核前,请确保已移除所有测试代码和调试日志
技术支持
遇到技术问题?我们的技术团队随时为您服务。
邮件支持
767146962@qq.com
工作日24小时内回复
QQ技术支持
767146962
工作日 9:00-18:00
电话咨询
18905733489
工作日 9:00-18:00
微信支持
18905733489
扫码添加客服微信
专属技术支持
对于已接入的游戏,我们提供一对一专属技术顾问,确保您在接入和运营过程中遇到的任何问题都能得到及时响应和解决。