<?php
/**
 * JYmusic音乐管理系统
 *
 * @version     2.0
 * @author      战神~~巴蒂 <jyuucn@163.com>
 * @license     http://jyuu.cn/license
 * @copyright   2014 - 2017 JYmusic
 */

namespace Addons\Pay\controller;

use app\services\Actions;
use app\common\api\Notice;
use app\common\model\Member;
use addons\Pay\model\PayHistory;
use mytharcher\sdk\alipay\Alipay;
use app\common\controller\AddonsController;

class AlipayController extends AddonsController
{
    protected  $config;

    protected  $payRatio;

    public function _initialize()
    {
        parent::_initialize();

        $conf = get_addon_config('Pay');
        //支付比例
        $this->payRatio = intval($conf['pay_ratio']);
        $this->config = [
            //合作身份者id，以2088开头的16位纯数字
            'partner' => trim($conf['alipay_partner']),
            //安全检验码，以数字和字母组成的32位字符
            'key'     => trim($conf['alipay_key']),

            'seller_email'  => trim($conf['alipay_seller_email']),
            //支付类型
            'payment_type'  => "1",
            //签名方式 不需修改
            'sign_type'    => strtoupper('MD5'),
            //ca证书路径地址，用于curl中ssl校验
            //请保证cacert.pem文件在当前文件夹目录中
            'cacert'    => __DIR__ . '/cacert.pem',
            
            //字符编码格式 目前支持 gbk 或 utf-8
            'input_charset'=> strtolower('utf-8'),
            
            //访问模式,根据自己的服务器是否支持ssl访问，若支持请选择https；若不支持请选择http
            'transport' => $this->request->scheme(),

            //必填，不能修改
            //服务器异步通知页面路径
            //需http://格式的完整路径，不能加?id=123这类自定义参数，不能写成http://localhost/

            'notify_url' => addons_url('pay/alipay/notify', '', '', true),
            //需http://格式的完整路径，不能加?id=123这类自定义参数
            //页面跳转同步通知页面路径
            'return_url' => addons_url('pay/alipay/back', '', '', true)
        ];
    }


    public function index()
    {
        if(Actions::isBan('pay')) {
            $this->error('操作过于频繁');
        }

        $post = $this->request->post();

        $uid = is_login();
        $post['uid'] = $uid? $uid : $post['uid'];

        $rule = [
            'out_trade_no'  => 'require|alphaNum',
            'price'  => 'require|number',
            'uid'    => 'require|number',
        ];

        $msg = [
            'out_trade_no.require' => '订单号不能为空',
            'out_trade_no.alphaNum'  => '订单号错误',
            'price.require' => '充值的金额不能为空',
            'price.number'  => '充值的金额只能为数字',
            'uid.require'   => '你还没有登录请登录',
            'uid.number'    => '你还没有登录请登录',
        ];
        
        $result = $this->validate($post, $rule, $msg);
        if (true !== $result) {
            // 验证失败 输出错误信息
            $this->error($result);
        }

        $map['price'] = $post['price'];
        $map['uid'] = $post['uid'];
        $map['type'] = 0;
        $map['status'] = 0;
        $map['create_time'] = ['gt', strtotime(date('Y-m-d'))];
        
        $model = new PayHistory();

        if ($history = $model->where($map)->find()) {
            $res = $model->setField('create_time', time());
        } else {
            $post['type'] = 'alipay';
            $post['out_trade_no'] = 'alipay';
            $post['body']   = $post['nickname'].'充值'.($this->payRatio*$map['price']).'金币';
            $res = $model->allowField(true)->save($post);
        }

        if (!$res) {
            $this->error('支付发起失败，请稍后重试');
        }

        $detector = new \Detection\MobileDetect();
        $isMobile = $detector->isMobile();
        
        //建立请求
        $pay = new Alipay($this->config, $isMobile);
        
        if ($isMobile) {
            $params = $pay->prepareMobileTradeData(array(
                'out_trade_no' => $post['out_trade_no'],
                'subject'      => '账户金币充值',
                'body'         => $post['body'],
                'total_fee'    => $post['price'],
                'merchant_url' => 'http://'.$_SERVER['HTTP_HOST'],
                'req_id'       => date('Ymdhis-')
            ));
            echo $pay->buildRequestFormHTML($params, 'get');
        } else {
            echo $pay->buildRequestFormHTML(array(
                "service"       => "create_direct_pay_by_user",
                "partner"       => $this->config['partner'],
                "payment_type"  => $this->config['payment_type'],
                "notify_url"    => $this->config['notify_url'],
                "return_url"    => $this->config['return_url'],
                "seller_id"     => $this->config['partner'],
                "out_trade_no"  => $post['out_trade_no'],
                "subject"       => '账户金币充值',
                "total_fee"     => $post['price'],
                "body"          => $post['body'],
                "_input_charset"    => trim(strtolower($this->config['input_charset']))
            ), "post");
        }
        die;
    }

    //异步通知
    public function notify()
    {
        $post = $this->request->post();
        if (empty($post)) {
            $this->error('您查看的页面不存在');
        }
        
        //计算得出通知验证结果
        $result = (new Alipay($this->config))->verifyCallback();

        if($result && ($post['seller_id'] == $this->config['seller_id'])) {//验证成功
             //交易状态
            $trade_status   = $post['trade_status'];
            if ($trade_status == 'TRADE_SUCCESS' || $trade_status == 'TRADE_FINISHED') {    
                $this->orderHandle($post, true);
            }
            echo "success";
        }else{
            $this->orderHandle($post, false);
            echo "fail";
        }
        die;
    }

    //同步通知
    public function back()
    {
        $get = $this->request->get();
        if (empty($get) ) {
            $this->error('您查看的页面不存在');
        }

        $detector = new \Detection\MobileDetect();
        $isMobile = $detector->isMobile();
    
        $result = (new Alipay($this->config, $isMobile))->verifyCallback();
        if($result) {//验证成功
            if($get['trade_status'] == 'TRADE_FINISHED' || $get['trade_status'] == 'TRADE_SUCCESS') {
                $this->orderHandle($get, true);
                $this->success('支付成功', 'user/Account/index');
            } else {
                $this->orderHandle($get, false);
                $this->error('交易失败', 'user/Account/charge', '', 5);
            }
        } else {
            $this->error('交易失败');
        }
    }

    //更新支付记录 并执行对应操作
    protected function orderHandle($post, $status = false)
    {
        $model = new PayHistory();
        $trade  = $model->where('out_trade_no', $post['out_trade_no'])->find();
        
        if (!$trade){
            $this->error('交易不存在');
        }

        //交易还没有处理过
        if ($trade->status == 0 && ($post['total_fee'] == $trade->price)) {
            $model->total_fee = $post['total_fee'];
            $trade->status  = $status? 1 : -1;
            //更新订单信息
            $model->save();
            //增加用户金币数量
            if ($status) {
                $price  = intval($model->price);
                //更新用户金币
                $coin   = $price * $this->ratio;
                $member = new Member();
                $res = $member->where('uid', $trade->uid)->setInc('coin', $coin);

                //发送提醒
                $notice = (new Notice())->to($trade->uid)->title('金币充值通知');
                if ($res) {
                    $content    = '你在【'.time_format($trade->create_time).'】,充值金币支付成功，金币增加['.$coin.']';      
                } else {
                    $content    = '你在【'.time_format($trade->create_time).'】,充值金额为['.$$total_fee.']，金币增加失败请联系管理手动添加';
                }                   
                $notice->content($content)->send();
            }
        }
    }
}
