Created
November 8, 2014 11:53
-
-
Save Ulv/ee3d53efe730dbe39d7d to your computer and use it in GitHub Desktop.
Класс для работы с робокассой с обновлением курса с ЦБРФ для yii
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* класс для работы с робокассой | |
* | |
* PHP version 5.3 | |
* | |
* @author ladamalina | |
* @author Vladimir Chmil <[email protected]> | |
* | |
* @link https://github.com/ladamalina/yii-robokassa | |
*/ | |
class Robokassa extends CApplicationComponent { | |
/** | |
* код рубля на сайте робокассы | |
*/ | |
const CUR_RUB = 'R01235'; | |
/** | |
* данные робокассы | |
* @var | |
*/ | |
public $sMerchantLogin; | |
public $sMerchantPass1; | |
public $sMerchantPass2; | |
public $sCulture = 'ru'; | |
public $resultMethod = 'post'; | |
public $sIncCurrLabel = 'QiwiR'; | |
public $orderModel; | |
public $priceField; | |
public $isTest = false; | |
public $crossCourse = "37"; // RUB TO USD | |
public $params; | |
/** | |
* @var | |
*/ | |
protected $_order; | |
/** | |
* инициализация класса. Получение кросс-курса USD/RUB с сайта ЦБРФ | |
*/ | |
public function init() { | |
parent::init(); | |
$this->crossCourse = $this->getCBRFCourse(array(self::CUR_RUB)); | |
$this->crossCourse = array_shift($this->crossCourse); | |
$this->crossCourse = $this->crossCourse['today']; | |
if (!$this->crossCourse) { | |
$this->crossCourse = 37; | |
} | |
$this->sMerchantLogin = Yii::app()->config->get('sMerchantLogin'); | |
$this->sMerchantPass1 = Yii::app()->config->get('sMerchantPass1'); | |
$this->sMerchantPass2 = Yii::app()->config->get('sMerchantPass2'); | |
} | |
/** | |
* @param $nOutSum | |
* @param $nInvId | |
* @param $sInvDesc | |
* @param $sUserEmail | |
*/ | |
public function pay($nOutSum, $nInvId, $sInvDesc, $sUserEmail) { | |
$nOutSum = ceil($nOutSum * $this->crossCourse); | |
$sign = $this->getPaySign($nOutSum, $nInvId, $sUserEmail); | |
$url = $this->isTest | |
? 'http://test.robokassa.ru/Index.aspx?' | |
: 'https://merchant.roboxchange.com/Index.aspx?'; | |
$url .= "MrchLogin={$this->sMerchantLogin}&"; | |
$url .= "OutSum={$nOutSum}&"; | |
$url .= "InvId={$nInvId}&"; | |
$url .= "Desc={$sInvDesc}&"; | |
$url .= "SignatureValue={$sign}&"; | |
$url .= "IncCurrLabel={$this->sIncCurrLabel}&"; | |
$url .= "Email={$sUserEmail}&"; | |
$url .= "Culture={$this->sCulture}"; | |
Yii::app()->controller->redirect($url); | |
} | |
/** | |
* @param $nOutSum | |
* @param $nInvId | |
* | |
* @return string | |
*/ | |
private function getPaySign($nOutSum, $nInvId) { | |
$keys = array( | |
$this->sMerchantLogin, | |
$nOutSum, | |
$nInvId, | |
$this->sMerchantPass1, | |
); | |
return md5(implode(':', $keys)); | |
} | |
/** | |
* | |
*/ | |
public function result() { | |
$var = $_GET + $_POST; | |
extract($var); | |
$event = new CEvent($this); | |
$valid = true; | |
if (!$valid || !isset($OutSum, $InvId, $SignatureValue)) { | |
$this->params = array('reason' => 'Dont set need value'); | |
$valid = false; | |
} | |
if (!$valid || !$this->checkResultSignature($OutSum, $InvId, $SignatureValue)) { | |
$this->params = array('reason' => 'Signature fail'); | |
$valid = false; | |
} | |
if (!$valid || !$this->isOrderExists($InvId)) { | |
$this->params = array('reason' => 'Order not exists'); | |
$valid = false; | |
} | |
if (!$valid || $this->_order->{$this->priceField} != $OutSum) { | |
$this->params = array('reason' => 'Order price error'); | |
$valid = false; | |
} | |
if ($valid) { | |
if ($this->hasEventHandler('onSuccess')) { | |
$this->params = array('order' => $this->_order); | |
$this->onSuccess($event); | |
} | |
} else { | |
if ($this->hasEventHandler('onFail')) { | |
return $this->onFail($event); | |
} | |
} | |
echo "OK{$InvId}\n"; | |
} | |
/** | |
* @param $id | |
* | |
* @return bool | |
*/ | |
private function isOrderExists($id) { | |
$this->_order = CActiveRecord::model($this->orderModel)->findByPk((int)$id); | |
if ($this->_order) | |
return true; | |
return false; | |
} | |
/** | |
* @param $OutSum | |
* @param $InvId | |
* @param $SignatureValue | |
* | |
* @return bool | |
*/ | |
private function checkResultSignature($OutSum, $InvId, $SignatureValue) { | |
$keys = array( | |
$OutSum, | |
$InvId, | |
$this->sMerchantPass2, | |
); | |
$sign = strtoupper(md5(implode(':', $keys))); | |
if ($SignatureValue == $sign) | |
return true; | |
return false; | |
} | |
/** | |
* @param $event | |
* | |
* @throws \CException | |
*/ | |
public function onSuccess($event) { | |
$this->raiseEvent('onSuccess', $event); | |
} | |
/** | |
* @param $event | |
* | |
* @throws \CException | |
*/ | |
public function onFail($event) { | |
$this->raiseEvent('onFail', $event); | |
} | |
/** | |
* получение курса ЦБРФ | |
* | |
* @param $currency | |
* | |
* @return array | |
*/ | |
private function getCBRFCourse($currency) { | |
$date = getdate(); // получаем ассоциативный массив с данными по дате | |
$day_of_the_week = $date['wday']; // день недели | |
//расчет коэффициента смещения | |
switch ($day_of_the_week) { | |
case 0: | |
$k1 = 2; | |
$k2 = 1; | |
break; // воскресенье | |
case 1: | |
$k1 = 3; | |
$k2 = 2; | |
break; // понедельник | |
case 2: | |
$k1 = 3; | |
$k2 = 0; | |
break; // вторник | |
default: | |
$k1 = 1; | |
$k2 = 0; | |
break; // среда, четверг, пятница, суббота | |
} | |
$month = $date['mon']; // месяц | |
$day = $date['mday']; // число сегодня | |
$yesterday = $day - $k1; // число для получения курса на предыдущий день | |
$today = $day - $k2; // число для получения курса на сегодня | |
$year = $date['year']; // год | |
$date_yesterday = date("d/m/Y", mktime(0, 0, 0, $month, $yesterday, $year)); // Генерация даты для курса предыдущего дня | |
$date_today = date("d/m/Y", mktime(0, 0, 0, $month, $today, $year)); // Генерация даты для курса на сегодня | |
$rate = array(); | |
foreach ($currency as $key => $value) { | |
$url = 'http://www.cbr.ru/scripts/XML_dynamic.asp?date_req1=' . $date_yesterday . '&date_req2=' . $date_today . '&VAL_NM_RQ=' . $value; | |
$xml = simplexml_load_file($url); | |
$rate_today = round(str_replace(',', '.', $xml->Record[1]->Value), 2); | |
$rate_yesterday = round(str_replace(',', '.', $xml->Record[0]->Value), 2); | |
$range = round($rate_today - $rate_yesterday, 2); | |
if ($range > 0) { | |
$range = '+' . $range; | |
$img = 'up'; | |
} elseif ($range == 0) { | |
$range = 0; | |
$img = 0; | |
} else { | |
$img = 'down'; | |
} | |
$rate[$key] = array( | |
'today' => $rate_today, | |
'change' => $range, | |
'img' => $img | |
); | |
} | |
return $rate; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment