转载于:http://blog.youkuaiyun.com/looksunli/article/details/16945501
上一篇文章主要介绍了充值系统的基本概要说明和数据库设计。
这篇文章主要讨论充值的基本流程和系统架构。简单来说,充值的基本流程就是:玩家选择一个支付平台,选择这个平台下面出售的某个商品,付款成功后玩家会得到所购买的商品。
数据交互图
玩家客户端指的是浏览器或者SDK。
上面数据交互图中需要有几点注意:
(1)玩家客户端,游戏服务器,支付平台这三者之间扮演的角色
游戏服务器只是提供数据的提供者和数据的处理者,游戏服务器不会直接把订单提交给支付平台. 订单由玩家客户端提交.
一般来说,如果是网页支付,那么客户端就是浏览器,提交订单信息给支付平台的方式有两种:
A: 以HTML表单格式自动提交GET/POST请求 (使用javascript自动提交)
B:以URL信号的方式重新跳转
如果是SDK支付,那客户端就是SDK,SDK首先需要从游戏服务器中获取订单信息,然后把订单信息传给支付平台。
(2)支付平台处理订单之后如何通知游戏服务器和玩家客户端。
一般来说,当支付平台处理完订单后,会有两个动作:
A: 异步通知游戏的服务器。把订单的处理结果返回给游戏服务器,游戏服务器接收到这个信息后,判断如果支付成功,则把玩家购买的商品发给玩家(如发给玩家500金块)。
B:同步通知客户端。例如一般支付平台支付处理完成后,页面中会有一个“返回商家网站”的按钮,点击这个按钮的时候,就可以返回游戏。这就是同步通知。
这里,我们需要认识到的是,同步是不可靠的(用户没有点击),订单必须在异步的时候处理。还有一点需要注意的是,同步和异步发生的时间不同。可能异步处理慢于同步跳转,所以在同步跳转提示玩家充值信息的时候(假设充值成功的话),我们会提示:“订单成功,你购买的商品将在5分钟内到账!”。
基本流程图
MVC模型图
控制器方法
- function createOrderAction()
- {
- // 玩家ID
- $uid = $this->getInt('uid');
- // 要购买的产品Id
- $productId = $this->getInt('product_id');
- // 当前充值渠道
- $channelId = $this->getInt('channel_id');
- // 其它信息
- $postData = $this->getQueryPostx()
- // TODO 各种数据合法性验证
- try {
- // 实例化操作对象
- $user = new Model($uid);
- // 实例化产品对象
- $product = new Model_Payment_Product($productId);
- // 实例化支付模型
- $payment = Model_Payment::factroy($channelId);
- $result = $payment->createOrder($user, $product, $payment, $postData);
- }
- // 输出通知错误和异常
- catch (Exception $e) {
- $this->jsonx($e->getMessage(), 'error');
- }
- // 如果返回内容是一个URL,则直接跳转
- if ($url = Model_Payment_Util::getUrlFromSignal($result)) {
- $this->redirect($url);
- }
- else {
- // 如果客户端是SDK的话,以JSON的形式把订单信息输出给SDK。
- exit($result);
- }
- // 注意:如果是表单自动提交,这提交过程发生在MODEL层。所以,控制器中只有两种提交方式
- }
- function respNotifyAction()
- {
- // 注意,这个参数不是支付平台提交过来的,而是自己配置的
- $channelId = $this->getInt('channel_id');
- $postData = $this->getQueryPostx();
- // TODO 各种数值验证
- try {
- $payment = Model_Payment::factory($channelId);
- $payment->respnotify($postData);
- }
- // 输出通知错误和异常
- catch (Exception $e) {
- $this->jsonx($e->getMessage(), 'error');
- }
- // 需要把结果返回给支付平台,例如360支付需要输出“ok”,否则,360会继续请求这个URL
- // 这是支付的具体细节问题,以后还会讨论
- exit($result);
- }
同步响应