《支付系统》

设置监听

支付系统存在回调信息,需要设置监听。

std::map<std::string , ProtocolIAP*>* _pluginsIAPMap= AgentManager::getInstance()->getIAPPlugin();
std::map<std::string , ProtocolIAP*>::iterator iter;
for(iter = _pluginsIAPMap->begin(); iter != _pluginsIAPMap->end(); iter++)
{
    (iter->second)->setResultListener(this);
}

开发者需要重写 onPayResult 回调方法

class PluginChannel:public PayResultListener
{
public:
    virtual void onPayResult(PayResultCode ret, const char* msg, TProductInfo info);
};

支付流程

流程图

支付流程

文字描述

  1. 游戏客户端 APP 调用 AnySDK 框架支付接口请求订单号
  2. AnySDK 框架获取订单号
  3. AnySDK 框架向渠道平台服务器请求支付
  4. 支付成功后,渠道平台服务器同步通知 AnySDK 框架(游戏客户端)
    注意,此步 SDK 返回的成功回调只是指交易已经成功提交给渠道服务器,并不表示此笔订单已经支付成功,有一些渠道支付 SDK 是只要进去支付选择界面,SDK 生成订单就会返回支付成功回调,即使玩家取消支付或者支付失败,因此,订单的支付结果只能以游戏服务器是否接收到渠道服务器的支付订单回调信息为准,而不能以本地支付回调为准
  5. 渠道平台服务器会异步通知 AnySDK 服务器
  6. AnySDK 服务器响应渠道平台服务器
  7. AnySDK 服务器将支付结果通知到游戏服务器
  8. 游戏服务器响应 AnySDK 支付通知
  9. 游戏服务器验证支付通知并发放道具

多种支付方式

AnySDK 框架支持多个支付插件,AnySDK 客户端选择多少个支付,getIAPPlugin 就能获取到多少个。一般情况只会选择一个支付插件,如果选择多个支付插件需要开发者自己提供相关界面完成多支付的逻辑展示。

std::map<std::string , ProtocolIAP*>::iterator it = _pluginsIAPMap->begin();
if(_pluginsIAPMap)
{
    if(_pluginsIAPMap->size() == 1)//只存在一种支付方式
    {
        (it->second)->payForProduct(productInfo);
    }
    else //多种支付方式
    {
        //开发者需要自己设计多支付方式的逻辑及UI
    }
}

相关接口

初始化

在加载插件的同时已经对所有 SDK 进行了初始化,开发者不需要额外再进行初始化。支付系统初始化后,会有相关信息的回调,如下:

回调信息 code msg
初始化成功 kPayInitSuccess null或者错误信息的简单描述
初始化失败 kPayInitFail null或者错误信息的简单描述

支付

void payForProduct(TProductInfo productInfo);
TProductInfo 实际上是一个 map,productInfo 记录了支付的一些相关的信息,开发者需要提供支付的如下参数:
注意:调用支付函数时需要传入的一些玩家信息参数(如角色名称,ID,等级)都是渠道强制需求(如 UC,小米等),并非 AnySDK 收集所用,如果开发者不填或者填假数据都会导致渠道上架无法通过。
必传参数不能为空,若当前没有可用的值可以写任意值上去。
个别渠道可能还需要添加其他参数,请参考常见问题中的渠道说明,根据渠道判断并添加上相应参数。

参数 是否必传 参数说明
Product_Id Y 商品 ID(联想、七匣子、酷派等商品 ID 要与在渠道后台配置的商品 ID 一致)
Product_Name Y 商品名
Product_Price Y 商品价格(元),可能有的 SDK 只支持整数
Product_Count Y 商品份数(除非游戏需要支持一次购买多份商品,否则传 1 即可)
Product_Desc N 商品描述(不传则使用 Product_Name)
Coin_Name Y 虚拟币名称(如金币、元宝)
Coin_Rate Y 虚拟币兑换比例(例如 100,表示 1 元购买 100 虚拟币)
Role_Id Y 游戏角色 ID
Role_Name Y 游戏角色名
Role_Grade Y 游戏角色等级
Role_Balance Y 用户游戏内虚拟币余额,如元宝,金币,符石
Vip_Level Y VIP 等级
Party_Name Y 帮派、公会等
Server_Id Y 服务器 ID,若无填 "1"
Server_Name Y 服务器名
EXT Y 扩展字段

因有些 SDK 不支持浮点数,Product_Price 请传入整数。

回调信息:

回调信息 code msg
支付成功 kPaySuccess null或者错误信息的简单描述
支付取消 kPayCancel null或者错误信息的简单描述
支付失败 kPayFail null或者错误信息的简单描述
支付网络出现错误 kPayNetworkError null或者错误信息的简单描述
支付信息提供不完全 kPayProductionInforIncomplete null或者错误信息的简单描述

举例说明:

void PluginChannel::pay()
{
    std::map<std::string , ProtocolIAP*>::iterator it = _pluginsIAPMap->begin();
    if(_pluginsIAPMap)
    {
        productInfo["Product_Id"] = "1";
        productInfo["Product_Name"] = "10元宝";
        productInfo["Product_Price"] = "1";
        productInfo["Product_Count"] = "1";
        productInfo["Product_Desc"] = "gold";
        productInfo["Coin_Name"] = "元宝";
        productInfo["Coin_Rate"] = "10";
        productInfo["Role_Id"] = "123456";
        productInfo["Role_Name"] = "test";
        productInfo["Role_Grade"] = "1";
        productInfo["Role_Balance"] = "1";
        productInfo["Vip_Level"] = "1";
        productInfo["Party_Name"] = "test";
        productInfo["Server_Id"] = "1";
        productInfo["Server_Name"] = "test";
        productInfo["EXT"] = "test";
        if(_pluginsIAPMap->size() == 1)//只存在一种支付方式
        {
            (it->second)->payForProduct(productInfo);
        }
        else //多种支付方式
        {
            //开发者需要自己设计多支付方式的逻辑及UI
        }
    }

}
//支付回调
//处理回调函数    
switch(code)
{
case kPaySuccess://支付成功回调
    //支付成功后,游戏相关处理
     break;
case kPayNetworkError://支付网络出错回调
case kPayCancel://支付取消回调
case kPayProductionInforIncomplete://支付信息填写不完整回调
case kPayFail://支付失败回调
    //支付失败后,游戏相关处理
    break;
case kPayNowPaying:
    /**
     * 正在进行中回调
     * 支付过程中若 SDK 没有回调结果,就认为支付正在进行中
     * 游戏开发商可让玩家去判断是否需要等待,若不等待则进行下一次的支付
     */
    break;
}

获取订单号

std::string getOrderId()
用户可通过该函数获取到订单号。

string order_id = iap_plugin->getOrderId();

注意:调用 payForProduct 后立即调用 getOrderId 的话是获取不到该次支付的订单号的,因为此时客户端还没收到服务端返回的订单号,请在收到支付回调后调用 getOrderId。

重置支付状态

void resetPayState()
支付过程中若 SDK 没有回调结果,就认为支付正在进行中,再次调用支付的时候会回调 kPayNowPaying,可以调用该函数重置支付状态。

ProtocolIAP::resetPayState();

退出界面

void exit()
游戏退出时调用该函数(有的 SDK 没有用户系统,所以就得从支付系统来调用函数)。
注意:部分渠道 SDK 要求必须显示渠道的退出界面,例如在返回键或游戏退出按钮调用此接口。

回调信息:

回调信息 code msg
渠道退出界面回调 kPayExtension+1 null 或者错误信息的简单描述

举例说明:

if (iap_plugin->isFunctionSupported("exit")) {
    iap_plugin->callFuncWithParam("exit",NULL);
}