Skip to content

Instantly share code, notes, and snippets.

@Ulv
Created November 8, 2014 11:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Ulv/ee3d53efe730dbe39d7d to your computer and use it in GitHub Desktop.
Save Ulv/ee3d53efe730dbe39d7d to your computer and use it in GitHub Desktop.
Класс для работы с робокассой с обновлением курса с ЦБРФ для yii
<?php
/**
* класс для работы с робокассой
*
* PHP version 5.3
*
* @author ladamalina
* @author Vladimir Chmil <vladimir.chmil@gmail.com>
*
* @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