<?php
/**
 * 杉德支付
 * User: Ocean
 * Date: 2018/4/23
 * Time: 10:30 
 */

namespace common\pay\sand;

use backend\models\Config;
use backend\models\Deposit;
use backend\models\SyncDesposit;
use common\helpers\Utils;
use common\pay\BasePayHandler;
use Yii;
use yii\helpers\VarDumper;


class PayHandler extends BasePayHandler
{
    public $payUrl;
    public $mid;
    public $certPwd;
    public $pubCert;
    public $priCert;


    /**
     * @inheritdoc
     */
    public function init()
    {
        parent::init();
        if ($this->payUrl == null) {
            $this->payUrl = Yii::$app->params['sand.payUrl'];
        }
        if ($this->mid == null) {
            $this->mid = Yii::$app->params['sand.mid'];
        }
        if ($this->certPwd == null) {
            $this->certPwd = Yii::$app->params['sand.certPwd'];
        }
        if ($this->pubCert == null) {
            $this->pubCert = __DIR__ . '/cert/sand.cer';
        }
        if ($this->priCert == null) {
            $this->priCert = __DIR__ . '/cert/private.pfx';
        }
    }


    /**
     * 去支付
     * @param array $params
     * @return array
     */
    public function outPay($deposit, $params)
    {
        $data['head'] = [
            'version' => '1.0',
            'method' => 'sandpay.trade.pay',
            'accessType' => '1',
            'productId' => '00000007',
            'mid' => $this->mid,
            'channelType' => '07',
            'reqTime' => date('YmdHis', time())

        ];

        $data['body'] = [
            'orderCode' => $deposit['order_sn'],
            'totalAmount' => sprintf('%012s', $deposit['rmb'] * 100),
            'subject' => 'RJ' . $deposit['order_sn'],
            'body' => 'RJ' . $deposit['order_sn'],
            'txnTimeOut' => date('YmdHis', time()+3600*10),
            'payMode' => 'bank_pc',
            'payExtra' => json_encode(['payType'=> 1,'bankCode' => $params['bankCode']]),
            'clientIp' => isset($params['ip']) ? $params['ip'] : Utils::getClientIp(),
            //'notifyUrl' => $this->notifyUrl,
            //'frontUrl' => $this->returnUrl,
			'notifyUrl' => 'http://crm.aremeok.com/pay/notify/3',
            'frontUrl' => 'http://crm.aremeok.com/pay/return/3',
            'extend' => ''
        ];

        $prikey = PayUtils::loadPk12Cert($this->priCert,$this->certPwd);
        $sign = PayUtils::sign($data, $prikey);
        $postData = [
            'charset' => 'utf-8',
            'signType' => '01',
            'data' => json_encode($data),
            'sign' => $sign
        ];

        Yii::warning('支付请求参数，' . VarDumper::dumpAsString($data), __METHOD__);
        $result = PayUtils::http_post_json( $this->payUrl,$postData);
        parse_str(urldecode($result), $arr);
        $arr['data'] = str_replace(array("  ","\t","\n","\r"),array('','','',''),$arr['data']);
        $data = json_decode($arr['data'],true);
        $credential = json_decode($data['body']['credential'],true);
        if(isset($credential['params']['orig']) && isset($credential['params']['sign']) ){
            $arr['data']= PayUtils::mb_array_chunk($data);
            $arr['data'] = str_replace(array("\\\/","\\/","\/"),array("/","/","/"), $arr['data']);
        }else {
            $data['body']['credential'] = PayUtils::json_encodes($credential);
            $arr['data'] = str_replace(array("\\\/","\\/","\/"," "),array("/","/","/","+"),PayUtils::json_encodes($data));
        }
        $arr['sign'] = preg_replace('/\s/', '+', $arr['sign']);
        try{
           PayUtils::verify($arr['data'], $arr['sign'], $this->pubCert);
        }catch (\Exception  $e){
            Yii::warning('签名失败，' . VarDumper::dumpAsString($e->getMessage()), __METHOD__);
        }
        $data = json_decode($arr['data'],320);
       // return $data;
        if ($data['head']['respCode']  == "000000" ) {
            $credential = str_replace(array('"{','}"'),array('{','}'),stripslashes($data['body']['credential']));
        }
        Yii::warning('支付请求结果，' . VarDumper::dumpAsString($credential), __METHOD__);

        return $credential;
        return $this->payJump($credential);

    }

    /**
     * 支付跳转HTML拼接
     * @param $credential
     * @return string
     */
    public function payJump($credential)
    {
        $html = <<<eot
<script>
    function wap_pay() {
        var responseText = $("#credential").text();
        //console.log(responseText);
        paymentjs.createPayment(responseText, function(result, err) {
            //console.log(result);
            //console.log(err.msg);
            //console.log(err.extra);
        });
    }
</script>
<div style="display: none" >
    <p id="credential">$credential</p>
</div>

eot;
        return $html;
    }


    /**
     * 处理异步回调
     * @param array $params
     * @return array
     */
    public function handleNotify($params)
    {
        Yii::warning('支付异步通知参数，' . VarDumper::dumpAsString($params), __METHOD__);

        $sign = $params['sign']; //签名
        $signType = $params['signType']; //签名方式
        $data = stripslashes($params['data']); //支付数据
        $charset = $params['charset']; //支付编码
        $result = json_decode($data,true); //data数据
        Yii::warning('支付异步通知参数sand，' . VarDumper::dumpAsString($result), __METHOD__);
        $merOrderId = $result['body']['orderCode'];
        if (PayUtils::verify($data, $sign, $this->pubCert)) {
            Yii::warning('支付异步通知认证签名成功，' . VarDumper::dumpAsString($data), __METHOD__);
            $reuslt = Deposit::find()->where(['order_sn' => $merOrderId])->asArray()->limit(1)->one();
            if ($reuslt['type'] != 1) {
                $res = Deposit::updateAll(['type' => 1], "order_sn = $merOrderId");
                $configData = Config::find()->asArray()->one();
                if ($configData['auto_deposit'] == 1 && $res) {
                    $syncDespositModel = new SyncDesposit();
                    $syncDespositModel->login = $reuslt['login'];
                    $syncDespositModel->amount = $reuslt['amount'];
                    $syncDespositModel->comment = 'Deposit';
                    $syncDespositModel->memo = $merOrderId;
                    $syncDespositModel->type = 2;
                    $syncDespositModel->in_time = time();
                    $syncDespositModel->save();
                }
                return true;
            }

        } else {
            Yii::warning('支付异步通知认证签名失败，' . VarDumper::dumpAsString($data), __METHOD__);
            return false;
        }
        return false;
    }

    /**
     * @param bool $success
     * @return string
     */
    public function outNotify($success)
    {
        if ($success == true) {
            return 'respCode=000000';
        } else {
            return 'fail';
        }
    }

    /**
     * 处理同步回调
     * @param array $params
     * @return array
     */
    public function handleReturn($params)
    {
        Yii::warning('支付同步通知参数，' . VarDumper::dumpAsString($params), __METHOD__);
        $sign = $params['sign']; //签名
        $signType = $params['signType']; //签名方式
        $data = stripslashes($params['data']); //支付数据
        $charset = $params['charset']; //支付编码
        $result = json_decode($data,true); //data数据
        $merOrderId = $result['body']['orderCode'];
        if (PayUtils::verify($data, $sign, $this->pubCert)) {
            $reuslt = Deposit::find()->where(['order_sn' => $merOrderId])->asArray()->limit(1)->one();
            if ($reuslt['type'] != 1) {
                Deposit::updateAll(['type' => 1], "order_sn = $merOrderId");
                $configData = Config::find()->asArray()->one();
                if ($configData['auto_deposit'] == 1) {
                    $syncDespositModel = new SyncDesposit();
                    $syncDespositModel->login = $reuslt['login'];
                    $syncDespositModel->amount = $reuslt['amount'];
                    $syncDespositModel->comment = 'Deposit';
                    $syncDespositModel->memo = $merOrderId;
                    $syncDespositModel->type = 2;
                    $syncDespositModel->in_time = time();
                    $syncDespositModel->save();
                }
                return true;
            }
        } else {
            Yii::warning('支付同步通知认证签名失败，' . VarDumper::dumpAsString($params), __METHOD__);
            return false;
        }
        return false;
    }

    /**
     * @param bool $success
     */
    public function outReturn($success)
    {
    }

    /**
     * 退款接口
     * @return mixed
     */
    public function outRefund()
    {
        $data = array(
            'head' => array(
                'version' => '1.0',
                'method' => 'sandpay.trade.refund',
                'productId' => '00000007',
                'accessType' => '1',
                'mid' => $this->mid,
                'channelType' => '07',
                'reqTime' => date('YmdHis', time())
            ),
            'body' => array(
                'orderCode' => 'r'.date('YmdHis').rand(100,999),
                'oriOrderCode' => '201808311527289902',
                'refundAmount' => sprintf('%012s', 3420 * 100),
                'notifyUrl' => 'http://crm.handz-fx.com/test/notify',
                'refundReason' => 'test',
                'extend' => ''
            )
        );

        $prikey = PayUtils::loadPk12Cert($this->priCert,$this->certPwd);
        $sign = PayUtils::sign($data, $prikey);
        $post = array(
            'charset' => 'utf-8',
            'signType' => '01',
            'data' => json_encode($data),
            'sign' => $sign
        );

        $result = PayUtils::http_post_json('https://cashier.sandpay.com.cn/gateway/api/order/refund',$post);
        parse_str(urldecode($result),$arr);
        return $arr['data'];
    }
}