充值系列——充值系统的架构(二)

来源:互联网 发布:猴博士爱讲课知乎 编辑:程序博客网 时间:2024/05/21 17:44

转载于:http://blog.csdn.net/looksunli/article/details/16945501

上一篇文章主要介绍了充值系统的基本概要说明和数据库设计。

这篇文章主要讨论充值的基本流程和系统架构。简单来说,充值的基本流程就是:玩家选择一个支付平台,选择这个平台下面出售的某个商品,付款成功后玩家会得到所购买的商品。

数据交互图

玩家客户端指的是浏览器或者SDK。

上面数据交互图中需要有几点注意:

(1)玩家客户端,游戏服务器,支付平台这三者之间扮演的角色

游戏服务器只是提供数据的提供者和数据的处理者,游戏服务器不会直接把订单提交给支付平台.  订单由玩家客户端提交.

一般来说,如果是网页支付,那么客户端就是浏览器,提交订单信息给支付平台的方式有两种:

A: 以HTML表单格式自动提交GET/POST请求 (使用javascript自动提交)

B:以URL信号的方式重新跳转

如果是SDK支付,那客户端就是SDK,SDK首先需要从游戏服务器中获取订单信息,然后把订单信息传给支付平台。

(2)支付平台处理订单之后如何通知游戏服务器和玩家客户端。

一般来说,当支付平台处理完订单后,会有两个动作:

A: 异步通知游戏的服务器。把订单的处理结果返回给游戏服务器,游戏服务器接收到这个信息后,判断如果支付成功,则把玩家购买的商品发给玩家(如发给玩家500金块)。

B:同步通知客户端。例如一般支付平台支付处理完成后,页面中会有一个“返回商家网站”的按钮,点击这个按钮的时候,就可以返回游戏。这就是同步通知。

这里,我们需要认识到的是,同步是不可靠的(用户没有点击),订单必须在异步的时候处理。还有一点需要注意的是,同步和异步发生的时间不同。可能异步处理慢于同步跳转,所以在同步跳转提示玩家充值信息的时候(假设充值成功的话),我们会提示:“订单成功,你购买的商品将在5分钟内到账!”。


基本流程图



支付模块中,控制器需要提供三个方法:
(1)createOrder() 生成订单
(2)respNotify()  异步响应支付平台的支付处理结果,验证支付是否成功。同时处理支付成功后的数据。不同的支付平台异步响应的数据也会不一样
(3) respReturn() 同步响应支付平台的通知(如:玩家点击返回商家网站后,就会访问到这个方法)

MVC模型图


控制器方法

生成订单,如果客户端是浏览器,则是浏览器访问createOrder方法,生成订单后,页面自动跳转都支付平台或者使用表单提交到支付平台。如果客户端是SDK,则由SDK访问createOrder方法,然后返回给SDK一个包含订单信息的JSON,最后由SDK把订单信息提交给支付平台。
[php] view plaincopy在CODE上查看代码片派生到我的代码片
  1. function createOrderAction()  
  2. {  
  3.     // 玩家ID  
  4.     $uid = $this->getInt('uid');  
  5.     // 要购买的产品Id  
  6.     $productId = $this->getInt('product_id');  
  7.     // 当前充值渠道  
  8.     $channelId = $this->getInt('channel_id');  
  9.   
  10.     // 其它信息  
  11.     $postData = $this->getQueryPostx()  
  12.   
  13.     // TODO 各种数据合法性验证  
  14.   
  15.     try {  
  16.         // 实例化操作对象  
  17.         $user = new Model($uid);  
  18.   
  19.         // 实例化产品对象  
  20.         $product = new Model_Payment_Product($productId);  
  21.   
  22.         // 实例化支付模型  
  23.         $payment = Model_Payment::factroy($channelId);  
  24.   
  25.         $result = $payment->createOrder($user$product$payment$postData);  
  26.     }  
  27.     // 输出通知错误和异常  
  28.     catch (Exception $e) {  
  29.         $this->jsonx($e->getMessage(), 'error');  
  30.     }  
  31.   
  32.     // 如果返回内容是一个URL,则直接跳转  
  33.     if ($url = Model_Payment_Util::getUrlFromSignal($result)) {  
  34.         $this->redirect($url);  
  35.     }  
  36.     else {  
  37.         // 如果客户端是SDK的话,以JSON的形式把订单信息输出给SDK。  
  38.         exit($result);  
  39.     }  
  40.   
  41.     // 注意:如果是表单自动提交,这提交过程发生在MODEL层。所以,控制器中只有两种提交方式  
  42. }  

异步响应,这个函数是支付平台处理支付完之后自动访问的,所以,需要事先配置到支付平台中去,例如 redirectUrl= www.example.com/order/respnotify/?channel_id=40;
[php] view plaincopy在CODE上查看代码片派生到我的代码片
  1. function respNotifyAction()   
  2. {  
  3.     // 注意,这个参数不是支付平台提交过来的,而是自己配置的  
  4.     $channelId = $this->getInt('channel_id');  
  5.     $postData = $this->getQueryPostx();  
  6.   
  7.     // TODO 各种数值验证  
  8.   
  9.     try {  
  10.         $payment = Model_Payment::factory($channelId);  
  11.         $payment->respnotify($postData);  
  12.     }       
  13.     // 输出通知错误和异常  
  14.     catch (Exception $e) {  
  15.         $this->jsonx($e->getMessage(), 'error');  
  16.     }  
  17.   
  18.     // 需要把结果返回给支付平台,例如360支付需要输出“ok”,否则,360会继续请求这个URL  
  19.     // 这是支付的具体细节问题,以后还会讨论  
  20.     exit($result);  
  21. }  

同步响应
也是需要事先在支付平台配置好。同步响应和异步响应都会处理支付的结果,验证支付是否成功,主要的区别在于,同步响应后会有一些页面表现,比如验证支付成功后,触发一个动作,提示玩家充值成功。

下一篇会讲解支付模块MODLE层的具体方法实现。

0 0
原创粉丝点击