《插件自助开发——服务端概述》

服务端插件开发文档已经发布新版本,请前往如下链接体验。>>>新版文档入口

渠道类SDK服务端插件开发概述(文档中会以琵琶网为例)

准备工作

1. 确定用户SDK标识(sdk name)
2. 确定支付订单类型 (由AnySDK官方提供)

AnySDK PHP SDK说明

登录验证

基本上所有渠道类SDK都会要求在服务端进行登录验证,AnySDK为开发者提供市场上大部分渠道的登录验证,为开发者免去了对接各种渠道登录验证繁琐细节及维护;
开发者只需要对接AnySDK的验证;

支付通知

AnySDK为开发者提供了市场上大部分支付SDK的支付通知统一验证及再通知服务,为开发者免去了对接各种支付SDK的支付通知开发及维护;
开发者只需要对接AnySDK的支付通知;

特殊订单

大部分支付SDK支付前不需要申请渠道订单或验签;有部分支付SDK在支付前要求通过游戏服务器向渠道服务器申请订单或验签;
接入AnySDK后,游戏服务器不需要关心渠道方面的订单生成,只需要关注自己游戏服务器的订单,支付时AnySDK会替游戏服务器向渠道申请订单或验签,并完成支付环节,支付成功后,进入支付通知环节;
AnySDK提供了特殊订单扩展机制,在某一特殊支付SDK申请订单时,AnySDK会根据支付订单类型申请渠道订单号或验签,并将渠道订单号或验签token,放到订单对象的扩展字段中;

登录验证

登录验证类名及文件名

类名:PipawLoginController 格式:SDK标识(第一个字母大写)+Login+Controller
文件名:PipawLogin.php 格式:SDK标识(第一个字母大写)+Login
注意:【在AnySDK开发者调试环境中会根据类名会生成文件名:PipawLogin.php】

继承SdkLogin类

AnySDK要求实现登陆验证时继承SdkLogin类

登录验证需要实现的方法说明

/**
 * 主要逻辑方法
 * check main function
 * The main logic flow
 */
public function check($params);
/**
 * 初始化
 * to initialize 
 * you must implement this function in your class
 * you can call these common functions setSdkName/logLoginTime/logRequestParams/toSetCustomErrors in init
 */
protected function init($params);
 
      /**
        * 检查请求参数
        * to check the request parameters 
        * you must implement this function in your class
        * you can call the common  function checkParams() to check parameters or do it yourself
        */
       protected function toCheckParams($params);
 
      /**
        * 验证AnySDK app合法
        * to check the AnySDK app is normal
        * you must implement this function in your class
        * you had better call the common function checkApp()
        */
       protected function toCheckApp();

      /**
        * 验证登录合法
        * to check user login is legitimate
        * you can do it yourself for different algorithms of different channels
        */
       protected function toCheckLogin($params);

      /**
        * 自定义错误信息
        * to set custom errors key and message
        * you can set custome your errors key and message
        * eg. array('nd_login_check_sign_failed'=>'nd91_1001','nd_error2'=>'nd91_1002'), and call responseError('nd_login_check_sign_failed');
        */
       protected function toSetCustomErrors();
   /**   
      * 设置用户ID
      * to set user id from channel server
      */
     protected function toSetUserId($userId);

主要逻辑方法check实现

验证基本流程都写在该方法中:

public function check($params) {
        $this->init($params);
        $this->toCheckParams($params);
        $this->toCheckApp();
        $this->toCheckLogin($params);
 }

注意:$params 该数组为请求的参数数组,所有通过GET或POST的参数都可以在该数组中获取;

初始化init实现

一般可以在init方法中记录原始请求参数、设置SDK 标识、设置自定义错误信息、获取参数如:

public function init($params) {
        $this->logRequestParams($params);   //记录登陆验证的所有参数信息:
        $this->setSdkName(self::SDK_NAME);  //定义登陆验证的SDK名称标识
        $this->toSetCustomErrors();         //定义该登陆验证的错误信息
        //以下三个参数为根据服务端验证需要要求客户端请求的参数
        //username(ext1):登录用户名,客户端获取
        //sid(ext2): 签名,客户端获取
        //time(ext3):用户登录时间,客户端获取
        $this->_username = isset($params['username']) ? $params['username'] : $params['ext1'];
        $this->_sid = isset($params['sid']) ? $params['sid'] : $params['ext2'];
        $this->_time = isset($params['time']) ? $params['time'] : $params['ext3'];
 }

自定义错误信息toSetCustomErrors实现

AnySDK定义了一部分通用错误信息及编号,开发者也可以定义SDK中自己的错误信息及编号;
格式:错误标识=>错误编号

public function toSetCustomErrors() {
        $errors = array(
          'login_check_fail_1' => $this->getSdkName() . '1001',
           'username_not_match' => $this->getSdkName() . '1002',
        );
        $this->setCustomErrors($errors);
 }

如何使用自定义错误信息:

$this->responseError('login_check_fail_1');

关于错误信息还提供了:

getCustomErrors():获取用户自定义所有错误信息;    
getErrors():获取所有错误信息含AnySDK通用错误信息;

验证请求参数方法toCheckParams实现

开发者可以根据子需要验证参数合法性,AnySDK提供了checkParams方法检查指定参数是否设置或为空;

public function toCheckParams($params) {
        $keys = array('username', 'sid', 'time');
        $compatibleKeys = array('username' => 'ext1', 'sid' => 'ext2', 'time' => 'ext3');
        $this->checkParams($params, $keys, $compatibleKeys, true);
}

验证AnySDK App方法toCheckApp实现

AnySDK建议使用官方提供的checkApp方法

public function toCheckApp() {
         $this->checkApp();
 }

登录验证实现

在这个环节,每个渠道SDK的验证实现方式不一样,需要开发者根据渠道SDK文档去实现相应的验证逻辑:
比如琵琶网的登录验证:

  
   public function toCheckLogin($params) {
               $appId = $this->getSdkParameter('PipawAppId');
               $merchantId = $this->getSdkParameter('PipawMerchantId');
               $merchantAppId = $this->getSdkParameter('PipawMerchantAppId');
               $postData = array('username' => $this->_username, 'appId' => $appId, 'merchantId' => $merchantId, 'merchantAppId' => $merchantAppId, 'sid' => $this->_sid, 'time' => $this->_time);
               $url = PIPAW_USER_URL;
               $result = $this->getHttp()->post($url, $postData);
               $this->logSdkCheckUrl($url . "?" . http_build_query($postData));
               $this->logSdkCheckReturn($result);

   $resultArr = json_decode($result, true);
  
     if (isset($resultArr['result']) && $resultArr['result'] == '1') {
             if ($this->_username != $resultArr['username']) {
                     $this->responseError('username_not_match');
              }
              //$this->setUserId($resultArr['uid']);//也可以直接使用该方式,但一定要记得设置用户ID
              $this->toSetUserId($resultArr['uid']);      
              $this->logSdkUserName($this->_username);
              $this->responseSuccess($resultArr);
         } else {
                $this->responseError('login_check_fail_1');
         }
     }

设置渠道平台用户ID方法toSetUserId实现

在登录验证成功后(3.9)设置用户ID,AnySDK才会将用户ID响应给游戏服务器;游戏用户ID在客户端登录时就已经获取到,有些必须服务端验证后才会获取;

 
     public function toSetUserId($userId) {
              $this->setUserId($userId);
     }

如何使用:
在登录验证过成功后(3.9)调用该方法:

     $this->setUserId($resultArr['uid']);

获取渠道参数接口

一般在登陆验证环节(3.9)中会使用到渠道申请的参数;
AnySDK提供getSdkParameter方法用于获取开发者在AnySDK打包工具上保存的渠道参数信息;

 $merchantId = $this->getSdkParameter('PipawMerchantId');

注意:像PipawMerchantId这样的key值是在AnySDK SDK插件开发过程中定义的,key值可以详见手机端插件开发说明;

日志方法

在登录验证过程中,为了开发者方便调试,AnySDK将记录验证过程中的一些关键数据,如请求参数及验证时的URL等:

 
    /**
        * 记录登录验证时间
        * records login time
        * @uses logLoginTime()
        */
      protected function logLoginTime() {
       }

    /**
        * 记录请求参数
        * records request params
        * @uses logRequestParams(array('a'=>1,'b'=>2))
        * @param array $params request params (array('a'=>1,'b'=>2))
        */
      protected function logRequestParams($params) {
       }
 
    /**
        * 记录AnySDK app部分信息,一般不使用
        * records AnySDK app data
        * @uses logAppInfo(array('app_id'=>1,'channel_id'=>2,....))
        * @param array $app app info (array('app_id'=>1,'channel_id'=>2,....))
        */
      protected function logAppInfo($app = array()) {
       }

    /**
        * 记录验证地址及验证参数
        * records the verification url 
        * @uses logSdkCheckUrl('http://xxx.xxx',array('a'=>1,'b'=>2))
        * @param type $url url(http://xxx.xxx?a=1&b=2)
        * @param mixed $params params (array('a'=>1,'b'=>2)) || a=1&b=2
        */
      protected function logSdkCheckUrl($url, $params = null) {
       }
 
    /**
        * 记录验证结果
        * records the validation results
        * @uses logSdkCheckReturn('data')
        * @param mixed $data  string that sdk server response
        */
      protected function logSdkCheckReturn($data = ) {
       }

    /**
        * 记录渠道用户ID (在设置用户ID时,AnySDK已经记录了一次用户ID,可以不再记录)
        * records the user id from channel server
        * @uses logSdkUserId('id')
        * @param string $userId userId=123456789
        */
      protected function logSdkUserId($userId = ) {
       }
 
    /**
        * 记录渠道用户名(有用户名时才记录)
        * records the user name from channel server
        * @uses logSdkUserName('name')
        * @param string $userName userName on channel
        */
      protected function logSdkUserName($userName = ) {
       }
 
    /**
        * 记录AnySDK响应给CP服务器数据
        * records the data responsed by AnySDK
        * @uses logAnySDKReturn('anysdkReturnString')
        * @param array $return return will be json encode to string 
        */
      protected function logAnySDKReturn($return) {
       }

响应方法


      /*
        * 响应错误信息
        * response error data
        * @uses responseError($error, $more)
        * @param string $error common error key or customer error key
        * @param array $more array('ext'=>array(...),'common'=>array(...))
        /
       protected function responseError($error, $more = null) {
       }

 
       /**
        * 响应成功信息
        * response success data
        * @uses responseSuccess($data, $more)
        * @param mixed $data the response data
        * @param array $more array('ext2'=>array(...),'common2'=>array(...))
        */
       protected function responseSuccess($data, $more = null) {
       }
 
       /**
        * 响应信息
        * response data
        * @uses returnResponse('returnString')
        * @param mixed $return the response data
        * @return string
        */
       public function returnResponse($return) {
       }

其他方法


       /*
        * HTTP工具 【详见Http类提供的方法】
        * http Object
        * http helper suporrt get/post
        * @uses getHttp()
        * @return HttpHelper
        /
       protected function getHttp() {
       }


       /**
        * 获取所有在AnySDK打包工具上配置的渠道参数key及value
        * get the paramters set in anysdk pc tools
        * @uses getSdkParams() ,call this function after checkApp or initApp
        * @return array
        *       (

        *               [PID] => 103889                                 

        *               [PKEY] => 383dbc5d4084ea056f7e29f20b5f0aa9      

        *               [Version] => 0.72                               

        *               [callback] => http://dj.qudao.info/anysdk_gov_ne/api/payment/callback   

        *               [introduction] => 0                             

        *       )
        */
       protected function getSdkParams() {
       }

       /**
        * 获取指定key的渠道参数value(在AnySDK打包工具上SDK参数配置)
        * get the paramter set in anysdk pc tools
        * @uses getSdkParameter('PID'), call this function after checkApp or initApp
        * @return string | null
        *       (

        *               [PID] => 103889                                 

        *               [PKEY] => 383dbc5d4084ea056f7e29f20b5f0aa9      

        *               [Version] => 0.72                               

        *               [callback] => http://dj.qudao.info/anysdk_gov_ne/api/payment/callback   

        *               [introduction] => 0                             

        *       )           
        */
       protected function getSdkParameter($key) {
       }
 
       /**
        * 设置SDK标识
        * set the user sdk identity (sdk name)
        * @uses setSdkName('coco')
        */
       protected function setSdkName($tag) {
       }
 
       /**
        * 获取SDK标识
        * get the user sdk identity (sdk name)
        * @uses getSdkName()
        * eg. 360 gfan coco
        */
       protected function getSdkName() {
       }
 
       /**
        * 设置自定义错误信息
        * set the custom errors
        * @param array $errors
        * @uses setCustomErrors(array('coco_login_error_1'=>'100001'))
        */
       protected function setCustomErrors($errors) {
       }
 
       /**
        * 获取所有自定义错误信息
        * get the custom errors
        * @uses getCustomErrors()
        * @return array
        */
       protected function getCustomErrors() {
       }
 
       /**
        * 获取所有错误信息 ,包括AnySDK通用错误信息
        * get the errors (include AnySDK common errors and sdk custom errors)
        * @uses getErrors()
        * @return array
        */
       protected function getErrors() {
       }
 
       /**
        * 设置渠道用户ID
        * set the user id from channel server
        * @uses setUserId('id')
        * @param string $userId user id from channel server
        */
       protected function setUserId($userId = ) {
       }
 
       /**
        * 获取渠道用户Id
        * get the user id from channel server
        * @uses getUserId()
        * @return string
        */
       protected function getUserId() {
       }
 
       /**
        * 获取渠道编号 (非使用SDK编号)
        * get the channel number defined by AnySDK
        * like 000000  
        * @uses getChannelId()
        * @return string
        */
       protected function getChannelId() {
       }
 
       /**
        * 获取所有请求参数 与$params值一样
        * get the request parameters(include post and get parameters)
        * @return array
        */
       protected function getParams() {
       }

支付通知

支付通知类名

类名:PipawPayNoticeController 格式:SDK标识(首字母大写)+PayNotice+Controller
文件名:PipawPayNotice.php 格式:SDK标识(首字母大写)+PayNotice
注意:有关通知地址的生成,AnySDK提供给开发者的调试环境会生成相应的通知地址【根据类名会生成文件名:PipawPayNotice.php】

支付通知需要实现的方法说明

 
       /*
        * 支付通知主要逻辑方法
        * payNotice main function
        * The main logic flow
        /
       public function payNotice($params);

 
       /**
        * 初始化
        * to initialize 
        * you must implement this function in your class
        * you can call teh following common functions in init         
        * logNoticeTime\logRequestParams
        * setOrderType\setReturn\setOrderId\setPayTime\setAmount
        */
       protected function init($params);
 
       /**
        * 验证请求参数合法
        * to check the request parameters
        * you must implement this function in your class
        * you can call the common  function checkParams() to check parameters or do it yourself
        */
       protected function toCheckParams($params);
 
       /**
        * 验证AnySDK app 合法
        * to check the AnySDK app is normal
        * you must implement this function in your class
        * you had better call the common function checkApp()
        */
       protected function toCheckApp($params);
 
       /**
        * 验签
        * to check payment sign is legitimate
        * you can do it yourself for different algorithms of different channels
        */
       protected function toCheckSign($params);
 
       /**
        * 设置支付状态
        * to set payment status
        * you had better call the common function  setPayStatusSuccess()
        */
       protected function toSetPayStatus($params);
 
       /**
        * 验证订单信息
        * to check order more info on anysdk 
        * you had better call the common function checkOrder()
        */
       protected function toCheckOrder($params);
 
       /**
        * 通知游戏服务器
        * to notify game server
        * you had better call the common function notifyGameServer()
        */
       protected function toNotifyGameServer();

主要逻辑方法实现

 
       public function payNotice($params) {
               $this->init($params);
               $this->toCheckParams($params);
               $this->toCheckApp($params);
               $this->toCheckSign($params);
               $this->toSetPayStatus($params);
               $this->toCheckOrder();
               $this->toNotifyGameServer();
               $this->noticeResponse($this->getSuccessReturn());
       }

初始化init实现

一般可以在init方法中记录原始请求参数、设置支付订单类型、设置渠道指定返回成功或错误信息、设置AnySDK订单、支付时间(时间戳)、金额(元):

 
    protected function init($params) {
               //记录通知参数
               $this->logRequestParams($params);
               //设置支付订单类型
               $this->setOrderType(self::ORDER_TYPE);
               //设置通知成功和失败返回信息
               $this->setReturn($this->_returnSuccess, $this->_returnFailure);
               //设置本次通知的AnySDK订单号(可以根据手机端插件实现时透传的AnySDK订单号):
               $this->setOrderId($params['order']);
               //设置本次支付的时间(一般会提供支付时间戳,没有的话可以不设置,默认当前时间)

// $this->setPayTime(strtotime($params['time']));

 
               //设置本次支付的金额,单位元,渠道方通知金额不为元则需要手动转换为以元为单位。如果渠道方没有提供则AnySDK默认使用AnySDK订单金额
               $this->setAmount($params['amount']);
               //如果渠道有提供订单号,设置渠道订单号

// $this->setChannelTradeNo($params['ConsumeStreamId']);

 
       }

验证支付通知参数方法toCheckParams实现

开发者可以根据需要验证参数的合法性,AnySDK提供了checkParams方法检查指定参数是否设置或为空;

 
       protected function toCheckParams($params) {
               $keys = array('order', 'pipaworder', 'subject', 'amount', 'player_id', 'sign');
               if (!$this->checkParams($params, $keys)) {
                       $this->noticeResponse($this->getFailureReturn(), $this->getLastError());
               }
       }

验证AnySDK App方法toCheckApp实现

建议使用AnySDK提供的方法:

 
       protected function toCheckApp($params) {
               if (!$this->checkApp()) {
                       $this->noticeResponse($this->getFailureReturn(), $this->getLastError());
               }
       }

验签或支付验证方法toCheckSign实现

支付通知验证不同渠道使用不同的验证方式,由开发者根据渠道要求自行实现,AnySDK提供目前常用的一些方法,如http请求封装及获取AnySDK打包工具渠道SDK参数配置信息方法等(详见其他方法):

 
       protected function toCheckSign($params) {
               $app_secret = $this->getSdkParameter('PipawPrivateKey');
               $sign = $params['sign'];
               unset($params['sign']);
               unset($params['version']);      
 
               ksort($params);
               $sign_str = ;
               foreach ($params as $k => $v) {
                       $sign_str .= '&' . $k . '=' . $v;
               }
               $sign_str = substr(trim($sign_str), 1) . $app_secret;
               $my_sign = md5(trim($sign_str));
               if ($my_sign != $sign) {
                       $this->noticeResponse($this->getFailureReturn(), "[sign is not matched:" . $my_sign . "]");
               }
       }

确认并设置支付状态方法toSetPayStatus实现

AnySDK会根据该状态通知游戏服务器支付是否成功,并记录日志:

 
       protected function toSetPayStatus($params) {
               // 琵琶网只在支付成功时通知,失败是不通知的,所以这里都是设置为成功
               //如果有渠道通知时带了支付状态的一定要判断支付状态并调用setPayStatusSuccess()或setPayStatusFail()
               $this->setPayStatusSuccess();
       }

验证订单信息方法toCheckOrder实现

验证订单前需要正确设置订单号(在初始化的时候),AnySDK才能正常的检测订单是否合法:

 
       protected function toCheckOrder($params) {
               if (!$this->checkOrder()) {
                       $this->noticeResponse($this->getFailureReturn(), $this->getLastError());
               }
       }   

加入通知游戏服务器队列方法toNotifyGameServer实现

AnySDK再接收并成功处理渠道支付通知后,会再通知游服(通知地址在AnySDK打包工具SDK参数中配置):

 
       protected function toNotifyGameServer() {
               $this->notifyGameServer();
       }

日志方法

 
       /** 
        * 记录支付通知时间
        * records payment notice time
        */
       protected function logNoticeTime() {
       }
 
       /**
        * 记录支付通知参数
        * records payment request parameters
        * simple:array('amount'=>1,'order_id'=>'14000001212'...);
        * complex:some channel may mixed use get\post=> array('get'=>array('a'=>1...),'input'=>'xxxxxxx',"post"=>array('b'=>2))
        * @param array $params request params (array('a'=>1,'b'=>2))
        */
       protected function logRequestParams($params) {
       }
 
       /**
        * 记录AnySDK订单号(在设置订单号时已经记录,不需再次记录)
        * records AnySDK order id 
        * @param type $orderId order id
        */
       protected function logOrderId($orderId) {
       }
 
       /**
        * 记录AnySDK响应给渠道服务器的数据
        * record the data AnySDK response to channel server
        * @param string $return return
        */
       protected function logAnySDKReturn($return) {
       }

响应方法

 
       /*
        * 响应方法
        * payment notice response
        * @param string $responseMessage response message
        * @param sting $noticeError error message
        /
       protected function noticeResponse($responseMessage = , $noticeError = ) {
       }

其他方法

 
       /*
        * Http工具  【详见Http类提供的方法】
        * Http helper suporrt get/post
        * @return HttpHelper
        /
       protected function getHttp() {
               return $this->_http;
       }

 
       /**
        * 设置AnySDK订单号
        * set the AnySDK order id
        * @param string $orderId
        */
       protected function setOrderId($orderId) {
       }
 
       /**
        * 获取AnySDK订单号
        * get the AnySDK order id
        * @return string
        */
       protected function getOrderId() {
       }
 
       /**
        * 设置支付时间
        * set the Payment time
        * @param int $time current timestamp default 
        */
       protected function setPayTime($time = 0) {
       }
 
       /**
        * 设置支付金额
        * set the payment amount
        * @param float $amount unit yuan
        */
       protected function setAmount($amount = 0) {
       }
 
       /**
        * 设置渠道流水号
        * set the channel server transaction serial number
        * @param string $number
        */
       protected function setChannelTradeNo($number = ) {
       }
 
       /**
        * 获取所有渠道参数 (在AnySDK打包工具SDK参数配置)
        * get the paramters set in anysdk pc tools
        * @uses getSdkParams() ,call this function after checkApp or initApp
        * @return array
        *       (

        *               [PID] => 103889                                 

        *               [PKEY] => 383dbc5d4084ea056f7e29f20b5f0aa9      

        *               [Version] => 0.72                               

        *               [callback] =>http://dj.qudao.info/anysdk_gov_ne/api/payment/callback

        *               [introduction] => 0                             

        *       )
        */
       protected function getSdkParams() {
       }
 
       /**
        * 获取指定key值的渠道参数value (在AnySDK打包工具上SDK参数配置)
        * get the paramter set in anysdk pc tools
        * @uses getSdkParameter('PID'), call this function after checkApp or initApp
        * @return string | null
        *       (

        *               [PID] => 103889                                 

        *               [PKEY] => 383dbc5d4084ea056f7e29f20b5f0aa9      

        *               [Version] => 0.72                               

        *               [callback] =>http://dj.qudao.info/anysdk_gov_ne/api/payment/callback 

        *               [introduction] => 0                             

        *       )           
        */
       protected function getSdkParameter($key) {
       }
 
       /**
        * 设置支付订单类型
        * set the order type
        * @param int $orderType
        */
       protected function setOrderType($orderType) {
       }
 
       /**
        * 获取支付订单类型
        * get the order type
        * @return int order type
        */
       protected function getOrderType() {
       }
 
       /**
        * 设置成功及失败响应渠道服务器信息
        * set the success and failure response to channel server
        * @param mixed $success success return
        * @param mixed $failure failure return
        */
       protected function setReturn($success = , $failure = ) {
       }
 
       /**
        * 获取响应渠道服务器成功信息
        * get the success respopnse to the channel server
        * @return mixed
        */
       protected function getSuccessReturn() {
       }
 
       /**
        * 获取响应渠道服务器失败信息
        * get the failure respopnse to the channel server
        * @return mixed
        */
       protected function getFailureReturn() {
       }
 
       /**
        * 设置支付成功状态
        * set the payment successful status
        */
       protected function setPayStatusSuccess() {
       }
 
       /**
        * 设置支付失败状态
        * set the payment failed status
        */
       protected function setPayStatusFail() {
       }
 
       /**
        * 获取支付状态
        * get the payment status
        * @return int 1 for success,2 for failed, 0 for in paying
        */
       protected function getPayStatus() {
       }
 
       /**
        * 获取最近一次错误信息
        * get the last error message
        * @return mixed
        */
       protected function getLastError() {
       }
 
       /**
        * 获取支付通知请求URL域名之后被'/'字符分割成的数组
        * get the parameters array generation from AnySDK payment notice url explode by '/' 
        * http://pay.xxx.com/v/AnzhiPayNotice/payNotice/coco/  
        * array('v','AnzhiPayNotice','payNotice','coco')
        * @return array
        */
       protected function getUrlExplodeParams() {
       }
       /**
        * 对数组中的value进行urldecode
        * 有些渠道接收到参数后,需要对所有的参数值urldecode处理
        * urldecode parameters values
        * @param array $params array('a'=>'%21ab') => array('a'=>'!ab')
        * @return array
        */
       protected function urldecodeParams($params = array()) {
       }

特殊订单

类名:SubOrder 主方法:static deal() 文件名:SubOrder.php

支付订单类型确定

可以到AnySDK官方wiki上获取,或向AnySDK产品组获取:

订单请求参数$params说明

在请求订单时,AnySDK框架提供的参数:

 
 Array
 (
   [game_user_id] => 1     //游戏用户id
   [game_server_id] => 0   //游戏服务器id
   [product_id] => 1       //道具id
   [private_data] =>       //透传参数,在客户端参数为EXT
   [product_name] => gold  //道具名称
   [money] => 1.00         //道具金额
   [uapi_key] => A9A9F42Cx //AnySDK app标识2
   [user_id] =>            //用户id
   [order_type] => 70      //订单支付类型
   [app_id] => 9x8         //AnySDK app标识1
 )

订单生成参数$orderId说明

 
 Array
 (
   [order_id] => PB500114xx25153651480xx   //订单号
   [create_time] => 140000000          //订单创建时间
 )

AnySDK App 参数$appData说明

请求订单时,所在AnySDK app信息:

 
 Array
 (
   [order_type] => 70      //支付订单状态
   [app_name] => xxx-琵琶网渠道号-00xxx0-琵琶网SDK
   [sdk_params] => Array(set in AnySDK pc tools)   //在AnySDK打包工具上配置的支付sdk参数
       (
           [Orientation] => landscape
           [PipawAppId] => 10051403005xx0
           [PipawMerchantAppId] => 1xx4
           [PipawMerchantId] => 10xx
           [PipawPrivateKey] => 4fcf587688810c7fd6e8a4b97a92exxx
           [callback] => http://pay.ment.com/anysdk_gov_ne/api/payment/callback 
       )
)

订单插件返回信息说明

订单插件返回的信息会被追加到AnySDK生成的订单对象的order_expand域中:

 
 {"status":"ok","data":{
            "order_id":"PB5001141025154918xxxx4",
            "order_name":"punchbox_PB5001141025154918xxxx4",
            "order_time":14xxx23358,
            "order_money":"1.00",
            "order_expand":"614c4df2f8705c6e3175d84e10d40f8b"
 }}

order_expand的用处:在支付时order_expand域提供给AnySDK Framework向渠道服务器验证订单,并进行支付操作;

Http工具

 
       /*
        * 设置http连接超时时间
        * set connect timeout  - s
        * @param int $time secconds
        * @return \HttpHelper
        /
       public function setConnectTimeOut($time = 30) {
       }

 
       /**
        * 设置http请求超时时间
        * set timeout - s
        * @param int $time seconds
        * @return \HttpHelper
        */
       public function setTimeOut($time = 30) {
       }
 
       /**
        * 获取请求URL
        * get the request url
        * @return string
        */
       public function getUrl() {
       }
 
       /**
        * 发起一个post请求
        * Make a POST request.
        * @param string $url      url like "http://example.com".
        * @param array  $data     An array to make query string like "example1=&example2=" .
        * @return mixed the response results
        */
       public function post($url, $data = array()) {
       }
 
       /**
        * 发起一个post请求
        * make a post request 
        * the same with $this->post except return array include errno\error\result
        * @param string $url request url
        * @param array $data An array to make query string like "example1=&example2=" .
        * @param int $connectTimeOut connect timeout default 30 seconds
        * @return array array('errno' => 0, 'error' => , 'result' => 'success')
        */
       public function post2($url, $data, $connectTimeOut = 30) {
       }
 
       /**
        * 发起一个post请求(注意$body直接写入post body中)
        * make a post request with raw post body string
        * @param striing $url request url
        * @param string $body query string like "example1=&example2=" .
        * @return string the respons results
        */
       public function postBody($url, $body) {
       }
 
       /**
        * postBody别名
        * the same with postBody
        * @param striing $url request url
        * @param string $body query string like "example1=&example2=" .
        * @return string the respons results
        */
       public function input($url, $data) {
       }
 
       /**
        * 发起一个get的请求
        * Make a GET request.
        * @param string $url     url like "http://example.com".
        * @param array  $data    An array to make query string like "example1=&example2=" .
        * @return mixed the response results
        */
       public function get($url, $data = array()) {
       }

开发、调试环境使用说明

按照前述内容开发完服务端插件之后,就需要对代码进行调试了,AnySDK提供了可方便进行调试的在线环境。
首先需要使用cocos开发者平台帐号登陆sh-dev.anysdk.com,如下图。
下载页面

温馨提示:此处使用的cocos开发者平台帐号最好是客户端插件开发人员在客户端登陆使用的帐号。
【可选步骤】如果使用的cocos开发者平台帐号是第一次在AnySDK自助开发dev后台(sh-dev.anysdk.com)登陆,则会要求加入一个公司或者自己创建一个新公司。如下图:
下载页面
登陆成功之后会跳转到【游戏列表】页面,若页面上没有任何游戏,那么你需要登陆AnySDK打包工具,配置游戏-渠道-SDK等信息。如下图:
下载页面
进入【插件开发】->【SDK列表】,点击【添加SDK】标签,会进入【添加SDK】页面。如下图:
下载页面
选择一个需要自助开发的SDK,填写【SDK版本号】,点击【添加】按钮。如下图:
下载页面
下载页面
添加成功之后,刚添加的SDK将会显示在【插件开发】->【SDK列表】页面。如下图:
下载页面
在【SDK列表】页面中,【编辑接口】一列是快速进入各接口代码编辑器的快捷方式。我们以点击【登陆验证】接口为例,将会跳入如下图所示的页面:
下载页面
如上图这个就是代码编辑器页面,初次打开,代码编辑框都会加载系统自动生成的模版代码。您可以基于这些模版代码来开发自己的接口。把页面往下滚动会有保存和重置按钮,如下图:
下载页面
点击【保存】按钮会将代码保存一个文件。以后打开代码编辑页面,都会加载您保存的代码。
代码编辑页面【接口类型】右边有一个示例代码的链接,不同的接口类型有不同的示例代码,您可以点击链接查看示例代码。如下图:
下载页面
下载页面
如下图,已经保存了代码的接口, 接口的链接颜色是黑色的, 要使代码可以被调试, 需要点击【操作】一栏的【生效】链接。生效链接可以无限次重复操作。
下载页面