Pay.php 9.44 KB
<?php

use Action\AbstractAction;
use Plugin\Helpers;
use LibModels\Wap\Home\OrderData;
use LibModels\Wap\Home\CartData;
use Plugin\Pay\weixin\JsApiPay;
use Plugin\Pay\weixin\lib\WxPayUnifiedOrder;
use Plugin\Pay\weixin\lib\WxPayApi;
use Plugin\Pay\weixin\lib\WxPayConfig;
use Plugin\Pay\aliwap\AliwapReqparams;
use Plugin\Pay\aliwap\AliwapService;
use Plugin\UdpLog;

/**
 * 支付相关的控制器
 * 
 * @name PayController
 * @package Shopping
 * @copyright yoho.inc
 * @version 1.0 (2016-1-23 13:12:40)
 * @author fei.hong <fei.hong@yoho.cn>
 */
class PayController extends AbstractAction
{
    /**
     * 支付宝跳转页
     * 
     * @param int order_code 订单号
     */
    public function indexAction()
    {
        do {
            /* 判断是否有订单号参数 */
            $orderCode = $this->get('order_code');
            if (empty($orderCode)) {
                $this->go(SITE_MAIN);
                break;
            }
            
            /* 判断用户是否登录 */
            $uid = $this->getUid(true);
            if (!$uid) {
                $this->go( Helpers::url('/signin.html', array('refer' => $this->server('HTTP_REFERER', SITE_MAIN))));
                break;
            }
            
            /* 判断订单信息是否存在 */
            $orderDetail = OrderData::viewOrderData($orderCode, $uid, $this->_usession);
            if (empty($orderDetail['data'])) {
                UdpLog::info("【支付宝支付】校验订单信息,orderCode:{$orderCode},uid:{$uid},返回:", $orderDetail);
                $this->helpJsRedirect('没有找到该订单');
                break;
            }
            
            /* 判断订单是否已取消 */
            if (isset($orderDetail['data']['is_cancel']) && $orderDetail['data']['is_cancel'] === 'Y') {
                $this->helpJsRedirect('订单已经取消', 'window.location="' . Helpers::url('/home/orders/detail', array('order_code' => $orderCode)) .'";');
                break;
            }

            //锁单接口
            $paymentId = $this->get('payment_type', 0);
            $prePayInfo = CartData::savePrePayInfo($uid, $orderCode, $paymentId);
            UdpLog::info("【锁订单接口】,orderCode:{$orderCode}", array('prePayInfo' => $prePayInfo));
            
            $totalFee = $orderDetail['data']['payment_amount'] * 100;
            $reqParams = new AliwapReqparams($orderCode, $totalFee, '有货订单号:' . $orderCode, '',
                $orderDetail['data']['create_time'], '', false, $orderDetail['data']['pay_expire']
            );
            $aliwapService = new AliwapService();
            $payRequestPars = $aliwapService->getPayRequestPars($reqParams);
            if (empty($payRequestPars)) {
                UdpLog::info("【支付宝支付】提交支付宝端口无响应,orderCode:{$orderCode}", array('orderDetail' => $orderDetail, 'payRequestPars' => $payRequestPars));
                $this->helpJsRedirect('支付系统繁忙,请稍后再试');
                break;
            }

            //更改支付方式,支付宝为18
            $paymentRecod = OrderData::updateOrderPayment($orderCode, $paymentId, $uid);
            if (empty($paymentRecod) || $paymentRecod['code'] != 200) {
                $this->helpJsRedirect('系统繁忙,请稍后再试');
                break;
            }
            
            $this->go($payRequestPars['pay_url'] . $payRequestPars['pars']);
        }
        while (false);
    }

    /**
     * 微信支付 - 获取JSAPI参数
     * 
     * @param int order_code 订单号
     * @return json | void
     */
    public function wechatwapapiAction()
    {
        do {
            if (!$this->isAjax()) {
                break;
            }

            $uid = $this->getUid(true);
            if (!$uid) {
                UdpLog::info('【wechat支付】参数校验', 'uid为空');
                break;
            }

            $orderCode = $this->get('order_code');
            if (empty($orderCode)) {
                UdpLog::info('【wechat支付】参数校验', 'orderCode为空');
                break;
            }

            /* 判断订单信息不存在 */
            $orderDetail = OrderData::viewOrderData($orderCode, $uid, $this->_usession);
            if (empty($orderDetail['data'])) {
                UdpLog::info("【wechat支付】校验订单信息,orderCode:{$orderCode},uid:{$uid},返回:", $orderDetail);
                break;
            }

            $totalFee = strval($orderDetail['data']['payment_amount'] * 100);
            $openId = $this->getSession('weixinOpenId' . $orderCode);

            if (empty($openId)) {
                UdpLog::info('【wechat支付】获取wechat标识为空', array('orderCode' => $orderCode, 'uid' => $uid, 'openId' => $openId));
                break;
            }
            
            //更改支付方式,微信为22
            $paymentRecod = OrderData::updateOrderPayment($orderCode, 22, $uid);
            if (empty($paymentRecod) || $paymentRecod['code'] != 200) {
                break;
            }

            //锁单接口
            $prePayInfo = CartData::savePrePayInfo($uid, $orderCode, 22);
            UdpLog::info("【微信锁订单接口】,orderCode:{$orderCode}", array('prePayInfo' => $prePayInfo));
            //到期时间
            $_payExpire = empty($orderDetail['data']['pay_expire']) ?
                $orderDetail['data']['create_time'] + 7200 : strtotime($orderDetail['data']['pay_expire']);

            //统一下单
            $tools = new JsApiPay();
            $input = new WxPayUnifiedOrder();
            $input->SetBody('有货订单号:' . $orderCode);
            $input->SetOut_trade_no('YOHOBuy_' . $orderCode); // 商户订单号
            $input->SetTotal_fee($totalFee);
            $input->SetTime_start(date("YmdHis", (int) $orderDetail['data']['create_time']));
            $input->SetTime_expire(date("YmdHis", $_payExpire));
            $input->SetTrade_type("JSAPI");
            $input->SetOpenid($openId);
            $order = WxPayApi::unifiedOrder($input);
            UdpLog::info('【微信支付下单】统一下单时返回结果,', array('input' => $input, 'order' => $order));
            $jsApiParameters = $tools->GetJsApiParameters($order);
            UdpLog::info('【微信支付下单】支付参数,', array('order' => $order, 'jsApiParameters' => $jsApiParameters));

            $this->echoJson(array('code' => 200, 'data' => array('jsApiParameters' => json_decode($jsApiParameters))));
            
        } while (false);
    }
    /**
     * 微信支付发送确认
     */
    public function wechatPayConfirmAction()
    {
        $result = array('code' => '400', 'message' => '支付确认发送失败!');
        do {
            if (!$this->isAjax()) {
                break;
            }

            $uid = $this->getUid();
            $orderCode = $this->get('order_code', '');
            if (empty($uid) || empty($orderCode)) {
                break;
            }

            $result = OrderData::payConfirm($orderCode, 22, $uid);
        } while (false);

        $this->echoJson($result);
    }

    /**
    * 选择支付时,时间间隔校验插入
    */
    public function addPaymentIntervalAction()
    {
        $data = array('code'=>400,'message'=>'','data'=>'');

        do {
            if (!$this->isAjax()) {
                break;
            }

            $uid = $this->getUid(TRUE);
            $orderCode = $this->get('orderCode','');
            $payment = $this->get('payment',0);
            
            if (!$uid || !$orderCode || !$payment) {
                UdpLog::info('【支付时间校验】参数校验', 'orderCode:'.$orderCode.'uid:'.$uid.'payment:'.$payment);
                break;
            }

            $res = CartData::savePrePayInfo($uid, $orderCode, $payment);
            $data = array('code'=>$res['code'],'message'=>$res['message'],'data'=>$res['data']);
            
        } while (false);

        $this->echoJson($data);
    }

    /**
     * 支付成功回调页面
     */
    public function aliwapreturnAction()
    {
        $aliwapService = new AliwapService();
        $payRequestPars = $aliwapService->parseResponse($_GET);
        $this->commonShowResult($payRequestPars, 18);
    }

    /**
     * 通用显示结果的方法
     * @param type $payResult
     * @param type $payment
     */
    private function commonShowResult($payResult, $payment)
    {
        $orderCode = '';
        $this->setTitle('支付中心');
        $this->setNavHeader('支付中心', Helpers::url('/home/orders'), false);
        
        $view = 'notneedpay';
        if ($payResult->payResult === 200) {
            $view = 'index';
            if (!empty($payResult->orderCode)) {
                $orderCode = $payResult->orderCode;
                //支付成功,发送一次支付确认
                $uid = $this->getUid();
                OrderData::payConfirm($payResult->orderCode, $payment, $uid);
            }
        }

        $payOrderCode = $payResult->orderCode;
        $payAmount = $payResult->totalFee;

        if ($view === 'notneedpay') {
            $payBack = 'failure';
        } else {
            $payBack = 'success';
        }

        $data = array(
            'payBackPage' => true,
            'pageFooter' => true,
            'order_code' => $orderCode,
            'payBack' => $payBack,
            'payOrderCode' => $payOrderCode,
            'payAmount' => $payAmount
        );
        $this->_view->display($view, $data);
    }
}