GHOME SDK 开发手册 for Unity C
1. 前言
本文用于指导游戏开发商接入GHome-Unity PC 版本SDK,文中包含客户端的接入说明,以及服务器接口的介绍;
2. SDK接入流程概述
-
完成隐私政策展示逻辑(请务必在完成隐私的展示逻辑之后再进行调用初始化)
-
初始化SDK
-
初始化成功,调用账号功能相关接口
-
用户在进行购买时,调用支付功能相关接口
- 接入注销接口
* 其他功能接口,可根据业务需要适时调用
3. 开发环境要求
3.1. 集成SDK文件到游戏工程
- 项目属性设置中-Scripting Runtime Version使用4.x版本
- 导入GhomeUnity.unitypackage 包 (该package包中包含JsonDotNet,若游戏项目中已有改包则导入时注意不够选JsonDotNet)
- 导入插件Embedded_Browser_3.1.0.unitypackage (若游戏项目中已有该库的话 则该包无需导入)
4. 隐私政策功能
游戏可调用该接口展示隐私政策同意与否弹框
-
接口:
GPrivacyAgreement(string appId, GCallback gCallback);
-
参数说明:
appId: 游戏的appId
gCallback: 回调对象,用来回调执行结果,详情请参考代码事例。
- 注意事项:
请确保初始化接口成功之后再调用其他接口。
- 代码示例:
GHSDK.Instance.GPrivacyAgreement("791000008", (code, msg, dicData) =>
{
if (code == 0)
{
//同意隐私 初始化
if (!isInit)
{
GHSDK.Instance.GInit("791000008", (code1, msg1, dicData1) =>
{
if (code1 == 0)//初始化成功
{
isInit = true;
//...
GHomeUtils.ShowToastUI(msg1);
}
else
{
GHomeUtils.ShowToastUI(msg1);
}
});
}
}
else
{
//不同意则退出游戏
Application.Quit();
}
});
5. 基础功能(必接)
5.1. SDK初始化接口
游戏在初始场景调用,初始化接口返回成功方可调用后续的登录等功能接口
-
接口:
GInit(string appId, GCallback gCallback);
-
参数说明:
appId: 游戏的appId
gCallback: 回调对象,用来回调执行结果,详情请参考代码事例。
- 注意事项:
请确保初始化接口成功之后再调用其他接口。
- 代码示例:
GHSDK.Instance.GInit("791000008",(code,msg,dicData)=>
{
if (code == 0) {
isInit = true;
//...
GHomeUtils.ShowToastUI(msg);
} else {
GHomeUtils.ShowToastUI(msg);
}
});
6. 账号功能(必接)
6.1. 账号体系说明
-
注册&登录原理
1) 在游戏登录界面打开SDK注册&登录界面;
2) 用户完成注册&登录之后,SDK会把用户id和ticket票据返回游戏;
3) 游戏如果有服务器,需要把客户端获取到ticket票据发送到“登录票据验证接口”(参考4.4节)进行验证,然后把返回的用户信息(用户id和账号)保存到游戏服务器;
- 注册&登录时线图
6.2. 客户端登录
6.2.1 客户端登录接口
游戏客户端可以调用登录接口为玩家提供登录功能。若用户第一次登录,将显示登录和注册的界面。若用户上次使用账号成功登录过,则调用登录接口之后会用该账号自动登录。
-
接口:
GLogin(GCallback gCallback)
-
参数说明:
gCallback: 回调对象,用来回调执行结果,详情请参考代码事例。
- 注意事项:
无
- 代码示例:
GHSDK.Instance.GLogin((code, msg, dicData) => {
if (code == 0)
{
GHomeUtils.ShowToastUI(msg + ", userid: " + dicData["userid"] + ", ticket: " + dicData["ticket"]);
//请求区数据
GetAreaInfo();
}
else if (code == GUnityConstants.ERROR_CODE_LOGIN_CANCEL)
{
GHomeUtils.ShowToastUI(msg);
}
else
{
GHomeUtils.ShowToastUI(msg);
}
}
);
6.3. 客户端注销接口
游戏客户端可以在游戏内需要注销账号的地方调用该接口,执行成功将删除自动登录的记录信息,玩家下次登录后将不再自动登录,而是显示出登录界面。
-
接口:
GLogout(GCallback gCallback)
-
参数说明:
activity: Activity对象。
-
注意事项:
暂无
- 代码示例:
GHSDK.Instance.GLogout((code, msg, dicData) => {
if (code == 0)
{
GHomeUtils.ShowToastUI(msg);
//跳转去登录主页
SceneManager.LoadScene("LoginScene");
}
else { }
}
);
6.4. 服务器登录票据验证接口
-
用法说明
为了保证游戏服务器的安全性,游戏服务器在登记用户登录信息之前需要到G家平台服务器做一个验证
-
接口地址
-
传值方式
GET
-
参数列表
appid: 游戏对应的APPID
timestamp: 精确到秒的unix时间戳
sequence: 不重复的请求序列号(全局唯一)
ticket_id: 从客户端登录接口返回的ticket字符串;
sign: 签名串(参考:“附录A:服务器端签名算法”,签名原始串示例:appid=xxx&sequence=xxx&ticket_id=xxx & timestamp=xxxappsecretkey)
-
返回结果
返回结果按json编码,数据格式为:
{
code:0, #返回状态,0为成功,1为失败,2 签名错误7 osap商户不存在,3001 票据不存在或超过有效期或被反复验证,1003 票据申请的appId和验证的APPID不一致
msg:"ok", #错误信息
data:{
userid:123456, #平台用户id,纯数字,无类型。
token:"40E00263-16A7-8CFA-D0E8-C951D683EA24", #平台TOKEN,36位字符串,暂时不用
phone:"+86-139****6893" #手机帐号,带国际区号,可用于显示帐号
invitation_code:"34343" #邀请码
thirdId:'34343' #第三方账号ID
companyId:"172" #第三方公司ID
"userAttribute": "6" #6表示游客,其他值表示非游客
}
}
7. 支付功能(必接)
7.1. 支付原理说明
-
支付原理
1) 游戏客户端发起支付请求;
2) SDK服务器收到请求,并发送至第三方支付;
3) 第三方支付成功收费以后通知SDK服务器,再由SDK服务器通知游戏服务器发货至游戏,需要游戏提供“订单通知接口”进行接受(参考6.3节);
-
支付时线图
7.2. 客户端支付接口
游戏客户端可以在购买道具的地方调用该接口。这将打开支付界面,引导玩家支付该订单。用户结束支付操作后,SDK会回调游戏客户端,告知支付结果是否已经成功。
-
接口:
GPay(string orderId, string groupId, string areaId, string productId, string extend, GCallback gCallback)
-
参数说明:
orderId: 必传,游戏订单号。如果游戏需要记录订单号,可以传入唯一的字符串来标识此订单。
groupId: 必传,组ID。没有则传空串
areaId: 必传,在手游直通车平台上设置的区服的ID 区服ID不可为0
productId: 必传,在手游直通车平台上设置的商品的ID
extend: 扩展参数,游戏可用于自行扩展,平台发货通知时将原样返回给游戏服务器,无需要则传空。
gCallback: 回调对象,用来回调执行结果,详情请参考代码事例。
-
注意事项:
由于可能发生网络延迟等等原因,有时候客户端返回的支付结果可能与实际情况有出入,所以最终订单是否支付成功,建议以平台服务器端的通知为准,客户端的通知结果仅作为参考。
- 代码示例:
GHSDK.Instance.GPay("order123456123456", "", "1", "test.1", "payextentstr", (code,msg,dicData)=>
{
if (code == 0) {
//......
GHomeUtils.ShowToastUI(msg);
} else {
GHomeUtils.ShowToastUI(msg);
}
}
);
7.3. 服务器订单通知接口
-
用法说明
用于将用户支付结果通知给游戏。
-
接口地址
接口地址需要游戏提供,可以在开发商后台“我的游戏 > 区服管理”中配置。
-
传值方式
POST
-
参数列表
orderNo: 服务器的订单号
userId:用户ID
gameOrderNo: 游戏的订单号
product: 商品ID(在开发商后台“我的游戏 > 充值管理”中配置)当游戏服务器发货是按照游戏自己记录的商品id发货时,请保证这里返回的商品id是否与游戏自己记录的商品id一致,方可发货;如不一致,游戏可以拒绝发货!
extend:游戏发送过来的扩展信息,原格式返回
sign:签名串(参考“附录A:服务器端签名算法”)
time:到账时间
- 参数示例
orderNo=791000012PP016140210105937000001&userId=18178&gameOrderNo=NONE&product=com.winggod.jingzhuan&extend=NONE&time=1392004960&sign=ad08d9e2d7b7df6603bc431392d1c707
-
返回结果
返回字符串:success,表示成功
返回字符串:refund,表示需要退款,目前支持的退款渠道有:官方支付宝、官方微信
其他表示失败。
8. 扩展功能(可选)
8.1. 客户端获取游戏区服列表接口
游戏客户端可以调用该接口获取游戏在G家平台登记的区服配置。
-
接口:
GGetAreas(GCallback
- > gCallback)
-
参数说明:
gCallback: 回调对象,用来回调执行结果,详情请参考代码事例。
-
注意事项:
暂无
- 代码示例:
GHSDK.Instance.GGetAreas((code,msg,data)=>
{
if (data != null) {
areaData = data;
foreach(GHAreaInfoDetail areaInfo in data)
{
OptionData temoData = new OptionData
{
text = areaInfo.name
} ;
mAreas.options.Add(temoData);
}
mAreas.captionText.text = data[0].name;
selectedAreaId = data[0].area_code;
selectedGroupId = data[0].group_id;
}
});
8.2. 客户端设置区服信息接口
游戏客户端需要在选择了区服之后调用该接口上报一下区服信息
-
接口:
GSetLoginArea(string areaId, string groupId)
-
参数说明:
areaId: 区服id。
groupId: 组id。 -
注意事项:
暂无
- 代码示例:
//上报选择的区服信息
GHSDK.Instance.GSetLoginArea(selectedAreaId, selectedGroupId);
8.3. 客户端获取游戏商品列表接口
游戏客户端可以调用该接口获取游戏在G家平台登记的商品配置。
-
接口:
GGetProducts(GCallback
- > gCallback)
-
参数说明:
gCallback: 回调对象,用来回调执行结果,详情请参考代码事例。
-
注意事项:
暂无
- 代码示例:
GHSDK.Instance.GGetProducts((code,msg,data)=>
{
if (data != null) {
foreach(GHProductInfoDetail productInfo in data)
{
Debug.Log("productName: " + productInfo.item_name);
}
}
});
8.4. 客户端获取一次性票据接口
游戏客户端可以调用该接口获取用于游戏登录的一次性票据。
-
接口:
GGetTicket(GCallback gCallback)
-
参数说明:
gCallback: 回调对象,用来回调执行结果,详情请参考代码事例。
-
注意事项:
暂无
- 代码示例:
GHSDK.Instance.GGetTicket((code, msg, dicData) => {
Debug.Log("ticket: " + dicData["ticket"]);
});
9. 附录A:服务器端签名算法
-
参数说明:
1) timestamp为调用接口时的unix时间戳(精确到秒)
2) sequence为请求序列号(游戏服务器端需要保证两次调用接口生成的sequence不重复)
-
签名算法:
1) 调用方首先需要将请求的参数根据参数的key(ASCII码值)进行升序排序
2) 将排序好的接口请求参数和参数值按key=val&key2=val2…这样得格式拼装成一个字符串,并在最后加上与APPID对应的APPKEY
3) 对上述拼接好的字符串进行md5编码,获得最终的签名串
- 代码示例(PHP):
public function sign ($params, $secret_key) { // $params数组必须包含timestamp
ksort($params);
$pair = array();
foreach($in as $k => $v){
$pair[] = $k. '=' .$v;
}
$str = implode('&', $pair); // 拼接字符串
$str = $str.$secret_key; // 把APPKEY补充到最后
return md5($str);
}
10. 附录B:特殊说明
-
订单重发机制:
平台对所有发货状态非“success”的订单,采取统一的重发机制。具体的重发策略为:每60秒重发1次,最大重发次数为60次。
对尝试重发后,最终失败的订单,我们会隔天通过报表机制发现,由平台方补发货,游戏方不需要参与。
-
发货重复处理机制:
基于订单重发机制,可能导致游戏方重复收到相同orderNo的发货通知,此时要求游戏检查orderNo实际到货情况,避免重复向玩家发放游戏币等虚拟货品。建议对一个月内的orderNo做唯一性检查。
针对已发货成功的订单,要求游戏方收到重复通知时,请务必返回success,状态为“success”的订单,将不会继续触发重发机制。