<?php
namespace Models;

class tinkoff_sbp {
	public $f3, $sets, $config, $web;
	public $status=array(
		'NEW'=>array('txt'=>'Платеж зарегистрирован в шлюзе, но его обработка в процессинге не начата', 'end'=>0),
		'CANCELED'=>array('txt'=>'Платеж отменен Продавцом', 'end'=>1, 'success'=>false),
		'PREAUTHORIZING'=>array('txt'=>'Проверка платежных данных Покупателя', 'end'=>0),
		'FORMSHOWED'=>array('txt'=>'Покупатель переправлен на страницу оплаты', 'end'=>0),
		'FORM_SHOWED'=>array('txt'=>'Покупатель переправлен на страницу оплаты', 'end'=>0),
		'AUTHORIZING'=>array('txt'=>'Покупатель начал аутентификацию', 'end'=>0),
		'3DS_CHECKING'=>array('txt'=>'Покупатель начал аутентификацию по протоколу 3-D Secure. Сессии, находящиеся в статусе 3DS_CHECKING более 36 часов, будут автоматически закрываться', 'end'=>0),
		'3DS_CHECKED'=>array('txt'=>'Покупатель завершил аутентификацию по протоколу 3-D Secure', 'end'=>0),
		'AUTH_FAIL'=>array('txt'=>'Не пройдена проверка по протоколу 3-D Secure', 'end'=>1, 'success'=>false),
		'PAY_CHECKING'=>array('txt'=>'Платеж обрабатывается', 'end'=>0),
		'AUTHORIZED'=>array('txt'=>'Средства заблокированы, но не списаны', 'end'=>1, 'success'=>false),
		'REVERSING'=>array('txt'=>'Начало отмены блокировки средств','end'=>0),
		'REVERSED'=>array('txt'=>'Денежные средства разблокированы', 'end'=>0),
		'CONFIRMING'=>array('txt'=>'Начало списания денежных средств', 'end'=>0),
		'CONFIRM_CHECKING'=>array('txt'=>'Платеж обрабатывается', 'end'=>0),
		'CONFIRMED'=>array('txt'=>'Денежные средства списаны', 'end'=>1, 'success'=>true),
		'REFUNDING'=>array('txt'=>'Начало возврата денежных средств', 'end'=>0),
		'ASYNC_REFUNDING'=>array('txt'=>'Обработка возврата денежных средств по QR', 'end'=>0),
		'PARTIAL_REFUNDED'=>array('txt'=>'Произведен частичный возврат денежных средств', 'end'=>1, 'success'=>true),
		'REFUNDED'=>array('txt'=>'Произведен возврат денежных средств', 'end'=>1, 'success'=>true),
		'REJECTED'=>array('txt'=>'Платеж отклонен Банком', 'end'=>1, 'success'=>false),
		'UNKNOWN'=>array('txt'=>'Статус не определен', 'end'=>0),
		'DEADLINE_EXPIRED'=>array('txt'=>'Платежная сессия закрыта в связи с превышением срока
отсутствия активности по текущему статусу', 'end'=>1, 'success'=>false),
	);
	
	function __construct($f3, $sets, $config) {
		$this->f3=$f3;
		$this->sets=$sets;
        $this->config=$config;
        $this->web=\Web::instance();
	}

	function get_token($data) {
		$data['Password']=$this->config['password'];
		ksort($data, SORT_STRING);
		$token=implode('', $data);
		return hash('sha256', $token);
	}

	function create_cancel_qr($sum, $return_epay) {
		$val=array(
			'TerminalKey'=>$this->config['TerminalKey'],
			'PaymentId'=>$return_epay['transid'],
			'Amount'=>$sum,
		);
		$val['Token']=$this->get_token($val);
		$options=array( // Данные для отправки на сервер
			'timeout'=>2,
    		'method'=>'POST',
    		'header'=>array(
    			'Content-type: application/json',
    		),
    		'content'=>json_encode($val)
		);
		$url=$this->config['TinkoffPath'].'/Cancel';
		$res=$this->web->request($url, $options);
		$json=json_decode($res['body'], true);
		if((int)$json['ErrorCode']>0) {
			return array(
				'success'=>false,
				'txt'=>'Код ошибки '.$json['ErrorCode'].'. '.$json['Message'].' '.$json['Details']
			);
		}
		if(mb_strpos($res['headers'][0], '200')===false && mb_strpos($res['headers'][0], '201')===false) {
			return array(
				'success'=>false,
				'txt'=>$res['body']
			);
		}
		$stop=0;
		while ($stop<10) {
			$res=$this->paycontrol_qr(array('order_id'=>$return_epay['transid']));
			if($res['success'] || $res['show_error']) {
				$stop=true;
				return $res;
			}
			$stop++;
			sleep(2);
		}
	}

	function create_sale_qr($sum) {
		$receipt_id=$this->f3->get('COOKIE.receipt_id');
		$val=array(
			'TerminalKey'=>$this->config['TerminalKey'],
			'OrderId'=>$receipt_id,
			'Amount'=>$sum,
			'Description'=>'Оплата по чеку '.$receipt_id
		);
		$val['Token']=$this->get_token($val);

		$options=array( // Данные для отправки на сервер
			'timeout'=>2,
    		'method'=>'POST',
    		'header'=>array(
    			'Content-type: application/json',
    		),
    		'content'=>json_encode($val)
		);
		$url=$this->config['TinkoffPath'].'/Init';
		$res=$this->web->request($url, $options);
		$json=json_decode($res['body'], true);
		if((int)$json['ErrorCode']>0) {
			return array(
				'success'=>false,
				'txt'=>'Код ошибки '.$json['ErrorCode'].'. '.$json['Message'].' '.$json['Details']
			);
		}
		if(mb_strpos($res['headers'][0], '200')===false && mb_strpos($res['headers'][0], '201')===false) {
			return array(
				'success'=>false,
				'txt'=>$res['body']
			);
		}

		$json['Status']=mb_strtoupper($json['Status']);
		if($json['ErrorCode']==0) {
			if(mb_strtoupper($json['Status'])!='NEW') {
				return array(
					'success'=>false,
					'txt'=>'Оплата отменена'
				);
			}
			$res=$this->create_qr($json['PaymentId']);
			if(!$res['success']) {
				return $res;
			}
			return array(
				'success'=>true,
				'qr'=>$res['qr_url'],
				'sbp_order_id'=>$json['PaymentId'],
				'receipt_id'=>$receipt_id,
				'show_qr'=>'/receipts/show_qr?receipt_id='.$receipt_id.'&order_id='.$json['PaymentId'].'&epay='.$this->sets['id'].'&sum='.$sum.'&url='.urlencode($res['qr_url'])
			);
		}
		return array(
			'success'=>false,
			'txt'=>'Неудается отправить запрос на создание QR-кода'
		);
	}

	function create_qr($PaymentId) {
		$val=array(
			'TerminalKey'=>$this->config['TerminalKey'],
			'PaymentId'=>$PaymentId
		);
		$val['Token']=$this->get_token($val);

		$options=array( // Данные для отправки на сервер
			'timeout'=>2,
    		'method'=>'POST',
    		'header'=>array(
    			'Content-type: application/json',
    		),
    		'content'=>json_encode($val)
		);
		$url=$this->config['TinkoffPath'].'/GetQr';
		$res=$this->web->request($url, $options);
		$json=json_decode($res['body'], true);
		if((int)$json['ErrorCode']>0) {
			return array(
				'success'=>false,
				'txt'=>'Код ошибки '.$json['ErrorCode'].'. '.$json['Message'].' '.$json['Details']
			);
		}
		if(mb_strpos($res['headers'][0], '200')===false && mb_strpos($res['headers'][0], '201')===false) {
			return array(
				'success'=>false,
				'txt'=>$res['body']
			);
		}

		if($json['ErrorCode']==0) {
			return array(
				'success'=>true,
				'qr_url'=>$json['Data'],
			);
		}
		return array(
			'success'=>false,
			'txt'=>'Неудается отправить запрос на создание QR-кода'
		);
	}


	function ticket($type, $sum, $return_epay=null, $lines=array()) {
		if($type=='sale') {
			return $this->create_sale_qr($sum*100);
		}
		return $this->create_cancel_qr($sum*100, $return_epay);

	}

	function paycontrol_qr($data) {
		$val=array(
			'TerminalKey'=>$this->config['TerminalKey'],
			'PaymentId'=>$data['order_id']
		);
		$val['Token']=$this->get_token($val);

		$options=array( // Данные для отправки на сервер
			'timeout'=>2,
    		'method'=>'POST',
    		'header'=>array(
    			'Content-type: application/json',
    		),
    		'content'=>json_encode($val)
		);
		$url=$this->config['TinkoffPath'].'/GetState';
		$res=$this->web->request($url, $options);
		$json=json_decode($res['body'], true);
		if((int)$json['ErrorCode']>0) {
			return array(
				'success'=>false,
				'txt'=>'Код ошибки '.$json['ErrorCode'].'. '.$json['Message'].' '.$json['Details']
			);
		}
		if(mb_strpos($res['headers'][0], '200')===false && mb_strpos($res['headers'][0], '201')===false) {
			return array(
				'success'=>false,
				'txt'=>$res['body']
			);
		}

		$json['Status']=mb_strtoupper($json['Status']);

		if($this->status[$json['Status']]['end']==1) {
			if($this->status[$json['Status']]['success']==true) {
				$slip="Статус: Успешно\n";
				$slip.="Идентификатор операции\n";
				$slip.=' - в Банке: '.$data['order_id']."\n";
				return array(
					'success'=>true,
					'txt'=>nl2br($slip),
					'slip'=>nl2br($slip),
					'pan'=>'',
					'transid'=>$data['order_id'],
					'authcode'=>'',
				);
			}
			return array(
				'success'=>false,
				'txt'=>$this->status[$json['Status']]['txt'],
				'show_error'=>true
			);
		}
		elseif($this->status[$json['Status']]) {
			return array(
				'success'=>false,
				'txt'=>'Статус платежа: '.$this->status[$json['Status']]['txt']
			);
		}
		elseif(!$this->status[$json['Status']]) {
			return array(
				'success'=>false,
				'txt'=>'Статус платежа: '.$json['Status']
			);
		}

		return array(
			'success'=>false,
			'txt'=>'Неудается проверить статус платежа',
			'show_error'=>true
		);
	}

	function z($change) {
		$cheq=$this->sets['title']."\nСмена успешно закрыта";
		return array(
			'success'=>true,
			'txt'=>nl2br($cheq),
			'slip'=>nl2br($cheq),
			'pan'=>0,
			'transid'=>0,
			'authcode'=>0
		);
	}

	function x($change) {
		$cheq='';
		return array(
			'success'=>true,
			'txt'=>nl2br($cheq),
			'slip'=>nl2br($cheq),
			'pan'=>0,
			'transid'=>0,
			'authcode'=>0
		);
	}
}
