SDK联运平台搭建
如果想创建自己的联运发行平台SDK系统, 那么至少需要满足平台需求:
- Android平台接入包, 尽可能用比较少的依赖传统来接入包
- iOS平台接入包, 按照平台SDK包直接接入IOS工程
- 业务API系统, 主要处理与客户端的协议,比如登陆注册,支付等核心逻辑
- 后台管理系统, 用于自动化和市场创建自己生成接入应用
- 作业调度系统, 批量作业,定时任务等做可视化的管理以及告警配置等
这些都是作为发行平台所需要处理的, 这里需要先说明下 业务API系统 和 后台管理系统, 启动依赖包接入和作业调度系统等则需要另外处理.
业务API系统
业务 API 相对来说只需要处理以下接口:
- 登录认证
- 支付回调
一般来说接入包唤起登录之后走 HTTP 推送请求登录参数, 如下图情况:
所以按照需求来说后台需要帮其生成接入包应用,
比如后台手动创建 appid=1001,key=xxx,secret=yyy(appid用于标识应用,key用于登录参与加密,secret用于支付),
所以一般来说CP方可以获取到我们以下内容:
而支付回调流程则是如下流程:
支付必须先让实际第三方支付地址填写到我们的发行方回调地址, 之后验证支付完成之后转发到 CP 方面( 这里用到定时任务不断的推送 CP 消息等待确实修改已完成的标识 ).
最终 CP 方会获得以下参数:
- appid, 后台创建的应用
- key, 参与登录哈希处理
- secret, 用于支付回调
- Android/Ios接入包, 用于客户端调用登录和支付到接口
登录接口请求
认证地址: https://www.自己的域名.com/v1/user/login
请求方式: POST
请求参数:
uid, 客户端登录之后CP方系统推送自家系统数据库玩家id
token, 客户端登录之后CP方系统自己登录会话的token标识
appid, 我们自己发行平台生成 appid
timestamp, 时间戳用于参与加密保证有效实时性
sign, 以上参数加上我们自己发行平台生成key以key从小到大正序排序参与哈希
生成签名:
// 构建请求参数
$fields = [
'uid' => '100111_1', // 有的应用是单游戏多服务器类型, 所以会出现uid+服务器id混合这种字段, 所以这里最好采用字符串形式
'token' => 'token', // 一般来说推送过来是玩家在登录之后会话token
'appid' => 1001, // 申请的自己发行 appid
'timestamp' => 10000000, // 当前时间戳
];
ksort($fields); // 以 key 做正序排序
$fields_query = http_build_query($fields);// 构建成 xxx1=yyy1&xxx2=yyy2
// 哈希处理sign
$key = "test_key"; // 申请的自己发行 key 参数
$fields_str = sprintf("%s%s%s",$key,$fields_query,$key);// 用 key 包围准备合并哈希
$sign = md5($fields_str);// 最后哈希得出 0b9a596f404cd9df2c23ee384b34e560
$fields['sign'] = $sign; // 合并作为参数提交
// 最后得出的请求参数
// array(5) {
// ["appid"]=>
// int(1001)
// ["timestamp"]=>
// int(10000000)
// ["token"]=>
// string(5) "token"
// ["uid"]=>
// string(8) "100111_1"
// ["sign"]=>
// string(32) "0b9a596f404cd9df2c23ee384b34e560"
// }
这里就是标准的登录请求发行流程, 之后就是支付发起问题.
支付接口请求
注: 用的为了防止攻击, 会直接验证支付回调白名单机制, 也就是必须创建发行 app 的同时允许添加白名单注册机制等; 还有的 JS-SDK 回调地址需要客户端推送的时候直接返回, 所以参数会带有
payNotifyUrl直接认准这个参数来做回调推送, 这里建议如果考虑通用可以直接加上类似字段.
这里是其他第三方支付回调过来完成之后, 同时还追加 Web 请求支付的方法:
预下单地址: https://www.自己的域名.com/v1/user/pay
请求方式: POST
请求参数:
appid: 发行申请的应用appid
server_id: 玩家所在服务器的ID
server_name: 玩家所在服务器的名称
role_id: 玩家角色ID
role_name: 玩家角色名称, 注意游戏内大概率是可以修改名称, 所以角色名称不能作为唯一标识查询
role_level: MMO游戏带有等级升级相关属性, 有的需要做统计所以需要追加上
vip: 玩家的会员等级, 有些玩家是带有高级会员需要计算返利折扣的情况, 这时候就需要该值做处理
cp_order_id: CP方面自己的游戏订单号
product_id: CP方面自己的支付订单物品ID
product_name: CP方面自己的支付订单物品名称
product_desc: CP方面自己的支付订单描述信息
price: 支付金额, 以分作为基础单位
currency: 支付货币单位, 默认CNY
notify_url: 这里是扩展字段, 可有可无主要是兼容有的JS-SDK的回调链接, 可留空
extra: 扩展信息, 可以让CP将所属的服务器信息用JSON方式包装保存之后回调取出
这里发起支付之后就是返回比较多样, 可以有的唤起 H5 支付然后调用本地APP(支付宝), 有的直接唤起应用扣除游戏点数(Google), 具体返回统一JSON即可.
----------------------------------------------------
之后就是我们发行方的回调给CP方的消息结构, 这里一般以后台或者请求参数 notify_url 定时转发推送, 直到最后返回准确的响应:
appid: 发行申请的应用appid
order_id: 这里是作为我们发行方自己数据库的订单ID
price: 支付金额, 以分作为基础单位
currency: 支付货币单位, 默认CNY
cp_order_id: CP方面自己的游戏订单号
extra: 扩展信息, 可以让CP将所属的服务器信息用JSON方式包装保存之后回调取出
order_time: 支付订单的时间戳
timestamp: 响应时时间戳
product_id: CP方面自己的支付订单物品ID
sign: 所有参数按照key正序之后格式化哈希
生成签名:
参照登录验签方式, 实现数据验签
$fields = [
// ... 以上的参数(sign除外)
];
ksort($fields); // 以 key 做正序排序
$fields_query = http_build_query($fields);// 构建成 xxx1=yyy1&xxx2=yyy2
// 哈希处理sign
$key = "test_key"; // 申请的自己发行 key 参数
$fields_str = sprintf("%s%s%s",$key,$fields_query,$key);// 用 key 包围准备合并哈希
$sign = md5($fields_str);// 最后哈希得出 0b9a596f404cd9df2c23ee384b34e560
$fields['sign'] = $sign; // 合并作为参数提交
// 之后不断推送给 notify_url 地址, 等待返回响应 SUCCESS 文本, 其他则默认为 FAIL
这里就是服务端需要处理相关接口, 基本上没有什么太大问题.