# H5 游戏 SDK 对接文档

# 注意

此SDK对接文档,标注必接的接口请在第一次接入时则必须接入,其余未标注说明必接的接口,可视运营情况及相关说明,再进行对接。

# 获取对接物料

开始对接时,我方会提供SDK地址和如下3个参数,如未获取,请联系我方运营或技术获取

参数字段 参数说明 示例
unionPacketCode 对接的唯一包ID 10000
gameId 游戏ID 10000
gameKey 登录加密Key 1111
gamePayKey 支付加密Key 1111

# 引入SDK


<script src="https://h5union.minwoods.com/javascripts/unionsdk/v1/unionsdk.min.js"></script>

后续调用其他接口使用UnionSDK对象进行调用即可

# 接口调用说明

接口调用都以下面格式进行调用:

/**
 * 方法调用示例
 * {string} apiName 方法名
 * {object|any} data 调用参数
 * {function} success 成功回调
 * {function} fail 失败回调
 **/
UnionSDK[apiName]({data, success, fail}) 

如调用支付接口:

UnionSDK.purchase({
    data: {
        count: 1,
        ...
    },
    success: ({code, msg, data}) => {
        // code 状态码 200-成功
        // msg 状态说明
        // data 返回数据
    },
    fail: ({code, msg}) => {
        // code 状态码
        // msg 状态说明
    }
});

# 初始化接口(必接)

游戏方可根据此接口返回的字段做一些特殊处理,比如开启VIP,显示相关ICON以及功能

# 调用示例

UnionSDK.init({
    success: ({code, msg, data}) => {
        // 初始化成功
        const {authNo, icp, isbn, operName, privacyUrl, serviceUrl, publishName, softName, softNo, extend} = data;
    }, fail: ({msg}) => {
        // 失败
        console.log(msg);
    }
});

# 初始化返回字段说明

参数 类型 例子 备注
authNo string 111 批文号
icp string 111 ICP备案号
isbn string 111 版号信息
operName string 111 运营单位名称
publishName string 111 出版单位名称
softName string 111 著作权人名称
softNo string 111 软著登记号
privacyUrl string https:// 隐私政策协议地址
serviceUrl string https:// 用户服务政策地址
extend string {} 扩展参数,看接口实际返回

# 登录接口(必接)

需要在初始化接口成功后调用

# 登录示例

UnionSDK.login({
    success: ({code, msg, data}) => {
        // 登录成功
        const {auth, cid, gameId, isbn, openId, privacyUrl, serviceUrl, sign, signVer, tags, ts} = data;
    }, fail: ({msg}) => {
        // 登录失败
        console.log(msg);
    }
});

# 登录返回字段说明

参数 类型 例子 备注
openId string u-10000-579b2fe6d188e1a82dcb06cfff96ebf 用户唯一标识
unionPacketCode string 对接的唯一包ID 对接的唯一包ID
gameId number 100000 游戏ID
ts string 1701931432675 毫秒级时间戳
signVer number 1 签名版本,当前默认1
sign string 642029cf0c290e38a95ef59d232b338f 登录签名
cid string 10000 渠道标识
tags string tags 用户标签
isbn string 111 版号信息
privacyUrl string https:// 隐私政策协议地址
serviceUrl string https:// 用户服务政策地址
pcode String pcode 渠道包标识

# 服务端登录验证(必接)

验证登录接口返回后的sign满足以下字段签名,是则验证通过

sign = md5(`${openId}|${gameId}|${ts}|${gameKey}`)

# 支付接口(必接)

需要在登录成功后调用

# 支付示例

UnionSDK.purchase({
    data: {
        openId: "u12317272",
        gameId: 100000,
        roleId: "147176212",
        roleName: "齐天大圣",
        roleLevel: "10",
        roleVipLevel: "2",
        roleFight: "12612",
        serverId: "1001",
        serverName: "1001服",
        gameOrderCode: "16253651265x17631221231212",
        gameOrderCustomInfo: "16253651265x17631221231212",
        gameProductCode: "1001",
        gameProductName: "100元宝",
        gameProductPrice: 100,
        ts: "1699349488262",
        signVer: 1,
        sign: "c9889204a2860cfd6938fec8a51c78ec"
    },
    success: ({code, msg, data}) => {
        // 支付成功
    },
    fail: ({msg}) => {
        // 支付失败|取消支付
        console.log(msg);
    }
});

# 支付请求参数字段说明

参数 类型 例子 备注
openId string u-10000-579b2fe6d188e1a82dcb06cfff96ebf 用户唯一标识
gameId number 100000 游戏ID
ts string 1701931432675 毫秒级时间戳
signVer number 1 签名版本,当前默认1
sign string 642029cf0c290e38a95ef59d232b338f 支付下单签名,看下面签名规则
roleId string 147176212 角色ID
roleName string 齐天大圣 角色名称
roleLevel string 10 角色等级
roleVipLevel string 2 角色VIP等级
roleFight string 12612 角色战力
serverId string 1001 区服ID
serverName string 1001服 区服名称
gameOrderCode string 16253651265x17631212 游戏订单号
gameOrderCustomInfo string 16253651265x17631212 订单自定义字符串,支付回调时会原样返回
gameProductCode string 1001 游戏商品计费点
gameProductName string 100元宝 游戏商品名称
gameProductPrice number 100 支付金额,单位(分)

# 服务端支付签名及回调接入(必接)

# 支付调起签名字段

// gamePayKey,支付加密Key 参考2.1对接物料获取 
sign = md5(`${gameId}|${openId}|${roleId}|${serverId}|${gameOrderCode}|${gameProductCode}|${gameProductPrice}|${ts}|${gamePayKey}`);

# 支付回调接口

游戏方需要根据下面文档对接完成后提供URL地址给到我方进行配置,游戏在正常支付完成后,游戏方会收到我方接口调用。

# 通知方式

HTTP POST

# 通知格式

application/json

# 请求参数说明

本协议中所有字符串使用UTF8编码

参数 类型 例子 备注
openId string u-10000-579b2fe6d188e1a82dcb06cfff96ebf 用户唯一标识
gameId number 100000 游戏ID
ts string 1701931432675 毫秒级时间戳
signVer number 1 签名版本,当前默认1
sign string 642029cf0c290e38a95ef59d232b338f 支付下单签名,看下面签名规则
roleId string 147176212 角色ID
serverId string 1001 区服ID
orderCode string i-10000010000-20231109150147645-745gm 我方订单号
gameOrderCode string 16253651265x17631212 游戏方调起支付时传入的游戏订单号
gameOrderCustomInfo string 16253651265x17631212 游戏方调起支付时传入的游戏自定义参数
gameProductCode string 1001 游戏商品计费点
gameProductPrice number 100 支付金额,单位(分)
isSandBox number 0 是否测试订单,1-是测试订单,0-否
discountPrice number 0 优惠金额,单位(分)

# 回调签名字段说明

sign=md5(`${gameId}|${gameOrderCode}|${orderCode}|${gameProductPrice}|${gameProductCode}|${serverId}|${roleId}|${openId}|${ts}|${gamePayKey}`);

# 回调返回说明

返回类型:字符串

  1. 成功返回小写字母:"ok"
  2. 失败返回:"失败原因"

# 回调接口其他注意事项

  1. 游戏接入时,必须验证订单信息跟游戏方本地下订单信息进行匹配,防止中途被人串改
  2. sign值必须要验证,gamePayKey必须由服务端保存,防止泄漏
  3. 订单有可能会出现多次同步,请做好幂等性,并返回“ok”
  4. 同步失败情况,我方会根据定义好的规则进行多次尝试

# 上报角色数据(必接)

# 示例

UnionSDK.report({
    data: {
        type: 2,
        openId: "u-128312",
        gameId: 100000,
        roleId: "147176212",
        roleName: "齐天大圣",
        roleLevel: "10",
        roleVipLevel: "2",
        roleFight: "12612",
        serverId: "1001",
        serverName: "1001服",
        ts: "1699349488262",
        signVer: 1,
        sign: "7cf7446ea63561f55f061be48fb6442d"
    },
    success: ({code, msg, data}) => {
        // code 状态码 200-成功
        // msg 状态说明
        // data 返回数据
    },
    fail: ({msg}) => {
        // 失败
    }
});

# 参数字段说明

参数 类型 例子 备注
type int 1 角色上报类型,1-选服,2-创角,3-登录,4-升级,5-退出
openId String u-10000-579b2fe6d188e1a82dcb06cfff96ebf 用户唯一标识
gameId int 100000 游戏ID
ts String 1701931432675 毫秒级时间戳
signVer int 1 签名版本,当前默认1
sign String 642029cf0c290e38a95ef59d232b338f 支付下单签名,看下面签名规则
roleId String 147176212 角色ID
roleName String 齐天大圣 角色名称
roleLevel String 10 角色等级
roleVipLevel String 2 角色VIP等级
roleFight String 12612 角色战力
serverId String 1001 区服ID
serverName String 1001服 区服名称

# 服务端签名

sign = md5(`${gameId}|${openId}|${roleId}|${serverId}|${ts}|${gameKey}`);

# 判断接口是否可用(必接)

除初始化、登录、支付、上报接口外,其余的接口调用需要调用此接口进行判断,包括功能开关是否显示的判断也可以根据此接口返回判断

// apiName 可传入 
// login, purchase, report, initShare, share, reportEvent, customService, switchAccount, logout
// isSubscribed, subscribe, isRealNameAuthenticated, authenticate, isBindPhone, bindPhone,
// collect, rewardVideo, 
// vip, store, resource, discount,
UnionSDK.isAvailable({
    data: {
        apiName: "share",
    },
    success: ({code}) => {
        // 支持
    },
    fail: () => {
        // 不支持,do something
    }
});

# 设置分享参数

UnionSDK.isAvailable({
    data: {
        apiName: "initShare",
    },
    success: ({code}) => {
        UnionSDK.initShare({
            data: {
                title: "分享标题",
                content: "分享内容",
                icon: "默认图标",
                ext: "uid=24993", //多个参数使用&分割,如: uid=24993&activeId=8381
            },
            success: () => {
                // 分享成功,做发放奖励操作
            }
        });
    }
});

# 分享接口(必接)

UnionSDK.isAvailable({
    data: {
        apiName: "share",
    },
    success: ({code}) => {
        UnionSDK.share({
            data: {
                title: "分享标题",
                content: "分享内容",
                icon: "默认图标",
                ext: "uid=24993", //多个参数使用&分割,如: uid=24993&activeId=8381
            },
            success: () => {
                // 分享成功,做发放奖励操作
            }
        });
    }
});

# 退出登录(必接)

游戏内含有退出登录及被顶号时调用

UnionSDK.logout();

# 自定义事件上报接口

# 示例

UnionSDK.isAvailable({
    data: {
        apiName: "reportEvent",
    },
    success: ({code}) => {
        UnionSDK.reportEvent({
            data: {
                eventName: "game-res-loading-start"
            },
        });
    },
});

# eventName可传值

事件名称 eventName说明
game-res-loading-start 游戏资源开始加载
game-res-loading-end 游戏资源加载完成
server-res-loading-start 选服后资源开始加载
server-res-loading-end 选服后资源加载完成

# 判断是否关注

UnionSDK.isAvailable({
    data: {
        apiName: "isSubscribed"
    }, success: () => {
        UnionSDK.isSubscribed({
            success: () => {
                console.log("已关注");
            }, fail: () => {
                console.log("未关注");
            }
        });
    }, fail: () => {
        console.log("不支持判断是否关注");
    }
});

# 关注

UnionSDK.isAvailable({
    data: {
        apiName: "subscribe"
    }, success: () => {
        UnionSDK.subscribe({
            success: () => {
                console.log("关注成功");
            }, fail: ({code, msg}) => {
                console.log("未关注", msg);
            }
        });
    }, fail: () => {
        console.log("不支持关注");
    }
});

# 判断是否已实名

UnionSDK.isAvailable({
    data: {
        apiName: "isRealNameAuthenticated"
    }, success: () => {
        UnionSDK.isRealNameAuthenticated({
            success: () => {
                console.log("已实名");
            }, fail: ({code, msg}) => {
                console.log("未实名", msg);
            }
        });
    }, fail: () => {
        console.log("不支持判断是否实名");
    }
});

# 实名认证

UnionSDK.isAvailable({
    data: {
        apiName: "authenticate"
    }, success: () => {
        UnionSDK.authenticate({
            success: () => {
                console.log("实名成功");
            }, fail: ({code, msg}) => {
                console.log("实名失败", msg);
            }
        });
    }, fail: () => {
        console.log("不支持实名");
    }
});

# 判断是否绑定手机号

UnionSDK.isAvailable({
    data: {
        apiName: "isBindPhone"
    }, success: () => {
        UnionSDK.isBindPhone({
            success: () => {
                console.log("已绑定");
            }, fail: ({code, msg}) => {
                console.log("未绑定", msg);
            }
        });
    }, fail: () => {
        console.log("不支持判断是否绑定手机号");
    }
});

# 绑定手机号

UnionSDK.isAvailable({
    data: {
        apiName: "bindPhone"
    }, success: () => {
        UnionSDK.bindPhone({
            success: () => {
                console.log("绑定成功");
            }, fail: ({code, msg}) => {
                console.log("绑定失败", msg);
            }
        });
    }, fail: () => {
        console.log("不支持绑定手机号");
    }
});

# 跳转客服接口

UnionSDK.isAvailable({
    data: {
        apiName: "jumpService",
    },
    success: ({code}) => {
        UnionSDK.jumpService();
    },
});

# 收藏有礼

UnionSDK.isAvailable({
    data: {
        apiName: "collect"
    }, success: () => {
        UnionSDK.collect({
            data: {
                title: "发送到桌面标题",
                content: "发送到桌面内容",
                icon: "https://staticweb.ewan.cn/OpenPlaUnionSDKorm/upload/images/20180126/C0B6C8B939EFDDB2B45D175FDE785DA5.jpg",
                ext: "发送到桌面透传参数",
            }, success: () => {
                console.log("收藏成功");
            }
        });
    }, fail: () => {
        console.log("不支持收藏");
    }
});

# 监听暂停|播放声音

部分端有特殊需求,可以在相关功能里监听相关

UnionSDK.listenPauseAudio({
    success: function () {
        console.log("游戏内需要关闭声音");
    }
});

UnionSDK.listenResumeAudio({
    success: function () {
        console.log("游戏内需要打开声音");
    }
});

# VIP客服

UnionSDK.isAvailable({
    data: {
        apiName: "vip",
    },
    success: () => {
        UnionSDK.vip();
    },
});

# 活动商城

UnionSDK.isAvailable({
    data: {
        apiName: "store",
    },
    success: () => {
        UnionSDK.store();
    },
});

# 无限资源阁

UnionSDK.isAvailable({
    data: {
        apiName: "resource",
    },
    success: () => {
        UnionSDK.resource();
    },
});

# 超级折扣

UnionSDK.isAvailable({
    data: {
        apiName: "discount",
    },
    success: () => {
        UnionSDK.discount();
    },
});

# 切换帐号

UnionSDK.isAvailable({
    data: {
        apiName: "switchAccount",
    },
    success: () => {
        UnionSDK.switchAccount();
    },
});

# 游戏内打开网页

接口可不用判断,SDK默认支持

UnionSDK.showWebWithURL({
    data: {
        url: ""
    }
});