<?php

namespace App\Libs\Pay\Merchants;

use GuzzleHttp\Client;
use Log;

class OriginBank
{
    function __construct($config)
    {
        $this->open_id = $config['open_id'];
        $this->open_key = $config['open_key'];
        $this->sub_appid = $config['sub_appid'];
        $this->PayClient = new client(['base_uri'=>'https://api.orangebank.com.cn/','timeout'=>3]);
    }

    //生成订单
    function send($data)
    {
        $time = time();
        $base_data = [
            'open_id'=>$this->open_id,
            'timestamp'=>$time,
        ];
        $data = [
            'out_no'=>$data['trade_no'],
            'pmt_tag'=>'WeixinOL',
            'ord_name'=>$data['body'],
            'original_amount'=>$data['price'],
            'trade_amount'=>$data['price'],
            'notify_url'=>env('ORIGINBANK_NOFITY_URL'),
            'sub_appid'=>$this->sub_appid,
            'sub_openid'=>$data['openid'],
            'JSAPI'=>1
        ];

        $base_data['data'] = $this->encrypt(json_encode($data),$this->open_key);
        $base_data['sign'] = $this->signs($base_data);

        $response = $this->PayClient->request('POST','/mct1/payorder',['form_params'=>$base_data])->getBody()->getContents();
        return $this->getPayInfo($response);
    }

    function getPayInfo($response)
    {
        try{
            $return_info = json_decode($response,1);
            if($return_info['errcode'] == 0)
            {
                $data = json_decode($this->decrypt($return_info['data'],$this->open_key,true),true);
                $trade_result = json_decode($data['trade_result'],true);
                $wc_pay_data = json_decode($trade_result['wc_pay_data'],true);
                $pay_info = [
                    'appId'=>$wc_pay_data['appId'],
                    'timeStamp'=>$wc_pay_data['timeStamp'],
                    'nonceStr'=>$wc_pay_data['nonceStr'],
                    'signType'=>$wc_pay_data['signType'],
                    'package'=>$wc_pay_data['package'],
                    'paySign'=>$wc_pay_data['paySign']
                ];
                return $pay_info;
            }
            Log::error($return_info);
        }catch (\Exception $e)
        {
            echo $e->getMessage();
            Log::error($response);
            return null;
        }

    }

    //签名
    public function signs($array){
        $signature = array();
        foreach($array as $key=>$value){
            $signature[$key]=$key.'='.$value;
        }
        $signature['open_key']='open_key'.'='.$this->open_key;
        ksort($signature);
        #先sha1加密 在md5加密
        $sign_str = md5(sha1(implode('&', $signature)));
        return $sign_str;
    }

    #@todo AES加解密
    #加密
    private function encrypt($input, $key) {
        $size = @mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
        $input = $this->pkcs5_pad($input, $size);
        $td = @mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
        $iv = @mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
        @mcrypt_generic_init($td, $key, $iv);
        $data = @mcrypt_generic($td, $input);
        @mcrypt_generic_deinit($td);
        @mcrypt_module_close($td);
        $data = strtoupper(bin2hex($data));
        return $data;
    }

    private function pkcs5_pad ($text, $blocksize) {
        $pad = $blocksize - (strlen($text) % $blocksize);
        return $text . str_repeat(chr($pad), $pad);
    }

    public function decrypt($sStr, $sKey) {
        $sStr=hex2bin($sStr);
        $decrypted= @mcrypt_decrypt(
            MCRYPT_RIJNDAEL_128,
            $sKey,
            $sStr,
            MCRYPT_MODE_ECB
        );

        $dec_s = strlen($decrypted);
        $padding = ord($decrypted[$dec_s-1]);
        $decrypted = substr($decrypted, 0, -$padding);
        return $decrypted;
    }
}