Service.php 7.32 KB
<?php

namespace WebPlugin\Pay\Alipay;

use WebPlugin\Pay\PayAbstract;
use WebPlugin\Pay\Reqparams;
use WebPlugin\Pay\Rspparams;
use WebPlugin\PhpLog;

class Service extends PayAbstract
{

    public $config;
    private $log;

    public function __construct(array $paymentParams)
    {
        $this->logProjectPrefix = 'alipay';
        $this->config = new Config();
        $myConfig = json_decode($paymentParams["pay_params"]);
        $this->config->partner = $myConfig->merchant_id;
        $this->config->alipay_key = $myConfig->merchant_key;
        $this->config->sellerMail = $myConfig->merchant_other_code;

        $this->log = new PhpLog($this->config->logDir, 'PRC', $this->config->logLevel);
    }

    /**
     * 获取时间戳
     */
    private function getTimestamp()
    {
        $url = "https://mapi.alipay.com/gateway.do?service=query_timestamp&partner=" . trim(strtolower($this->config->partner)) . "&_input_charset=" . trim(strtolower($this->config->input_charset));

        $doc = new DOMDocument();
        $doc->load($url);
        $itemEncrypt_key = $doc->getElementsByTagName("encrypt_key");
        $encrypt_key = $itemEncrypt_key->item(0)->nodeValue;

        return $encrypt_key;
    }

    /**
     * @param Reqparams $params
     * @return array
     */
    public function getPayRequestPars(Reqparams $params)
    {
        $this->log->LogInfo("===开始处理支付宝的请求参数===");
        $this->log->LogInfo("-----请求参数为---");
        $this->log->LogInfo(var_export($params, true));

        $baseUrl = $this->getBaseNoticeUrl($params->isTest);
//		$loseTime = intval(($params->orderTime + 7200 -time())/60);
//		$loseTime = intval((strtotime(date("Y-m-d 10:00:00", strtotime("+1 day")))-time())/60); //第二天十点
        $parameter = array(
            'service' => $this->config->service,
            'partner' => $this->config->partner,
            '_input_charset' => $this->config->input_charset,
            'notify_url' => $baseUrl . $this->config->notify_url,
            'return_url' => $baseUrl . $this->config->return_url,
            /* 业务参数 */
            'subject' => $params->goodsName,
            'out_trade_no' => $params->orderCode,
//			'it_b_pay'  =>  $loseTime . 'm',
            'total_fee' => $params->totalFee / 100,   //单位为元
            'payment_type' => $this->config->payment_type,
            'seller_email' => $this->config->sellerMail,
            'sign_id_ext' => $params->uid,
            'sign_name_ext' => $params->userName
        );
        if ($this->config->anti_fishing['timestamp_enable']) {
            $anti_phishing_key = $this->getTimestamp();
            if (!empty($anti_phishing_key)) {
                $parameter['anti_phishing_key'] = $anti_phishing_key;
            }
        }
        if ($this->config->anti_fishing['ip_enable']) {
            $parameter['exter_invoke_ip'] = $params->spbill_create_ip;
        }

        if (!empty($params->paymentParameter)) {
            //使用快捷支付
            $parameter['token'] = $params->paymentParameter;
        }
        ksort($parameter);
        reset($parameter);

        $param = '';
        $sign = '';
        foreach ($parameter AS $key => $val) {
            $param .= "$key=" . urlencode($val) . "&";
            $sign .= "$key=$val&";
        }
        $param = substr($param, 0, -1);
        $sign = substr($sign, 0, -1) . $this->config->alipay_key;

        $result = array(
            'pay_url' => $this->config->pay_url,
            'pars' => $param . "&sign=" . md5($sign) . "&sign_type=" . $this->config->sign_type,
            'reqType' => 'get'
        );

        $this->log->LogInfo('----支付宝请求处理结果为----');
        $this->log->LogInfo(var_export($result, true));

        return $result;
    }

    public function parseResponse(array $arrResponse)
    {
        /* 返回示例
         * http://www.yohobuy.com/pay/notice/alipayreturn?buyer_email=tds%40smartunite.com&buyer_id=2088302294447308&exterface=create_direct_pay_by_user&is_success=T&notify_id=RqPnCoPT3K9%252Fvwbh3I7xtEV5W65QRToFQ5fPrXsVxt12e%252FExCtC1XNiKnuRwupLaVLAR&notify_time=2011-06-11+07%3A48%3A10&notify_type=trade_status_sync&out_trade_no=1061003000&payment_type=1&seller_email=shop%40yoho.cn&seller_id=2088001550230585&subject=YOHO%E5%95%86%E5%93%81&total_fee=0.01&trade_no=2011061199833830&trade_status=TRADE_SUCCESS&sign=ca1c49f58d17eaa57aac308d0ac64434&sign_type=MD5
         */
        $this->log->LogInfo("===开始解析支付宝的回调参数===");
        $this->log->LogInfo("-----回调参数为---");
        $this->log->LogInfo(var_export($arrResponse, true));

        if (isset($arrResponse['q'])) {
            unset($arrResponse['q']);
        }
        $rsp = new Rspparams();
        if (!$this->checkResponse($arrResponse)) {
            $this->log->LogInfo("-----支付宝回调参数验证签名失败---");
            //验证不成功
            $rsp->payResult = -1;
        } else {
            $this->log->LogInfo("-----支付宝回调参数验证签名成功---");
            $rsp->bankName = "";
            $outTradeNo = $arrResponse["out_trade_no"];
            $rsp->orderCode = $outTradeNo;
            $rsp->payResult = $this->convertResult($arrResponse["trade_status"]);
            $rsp->payTime = isset($arrResponse["gmt_payment"]) ? $arrResponse["gmt_payment"] : '';
            $rsp->totalFee = $arrResponse["total_fee"];
            $rsp->resultMsg = $arrResponse["notify_type"];
            //添加支付订单号和交易号
            $rsp->payOrderCode = $outTradeNo;
            $rsp->tradeNo = $arrResponse['trade_no'];
            $rsp->bankBillNo = "";
        }

        $this->log->LogInfo("-----解析支付宝回调参数的结果为---");
        $this->log->LogInfo(var_export($rsp, true));

        return $rsp;
    }

    protected function convertResult($resultCode)
    {
        if ($resultCode == "TRADE_SUCCESS") {
            return 200;
        }
        return 400;
    }

    /**
     * 除去数组中的空值和签名参数
     * @param $para 签名参数组
     * return 去掉空值与签名参数后的新签名参数组
     */
    private function paraFilter($para)
    {
        $para_filter = array();
        foreach ($para as $key => $val) {
            if ($key == "sign" || $key == "sign_type" || $val == "") continue;
            else    $para_filter[$key] = $para[$key];
        }
        return $para_filter;
    }

    /**
     * 对数组排序
     * @param $para 排序前的数组
     * return 排序后的数组
     */
    private function argSort($para)
    {
        ksort($para);
        reset($para);
        return $para;
    }

    /**
     * 验证回复的正确性
     * @see QPay_Utils_Abstract::verifResponse()
     */
    protected function checkResponse(array $arrResponse)
    {
        ksort($arrResponse);
        reset($arrResponse);
        $sign = '';
        foreach ($arrResponse AS $key => $val) {
            if ($key != 'sign' && $key != 'sign_type' && $key != 'code') {
                $sign .= "$key=$val&";
            }
        }
        $sign = substr($sign, 0, -1) . $this->config->alipay_key;

        return md5($sign) != $arrResponse['sign'] ? false : true;

    }
}