8Main\Localization\Loc::loadMessages(__FILE__);
16 public const CACHE_ID =
'BITRIX_CASHBOX_ROBOKASSA_ID';
18 private const URL =
'https://ws.roboxchange.com/RoboFiscal/Receipt/';
20 private const CODE_VAT_0 =
'vat0';
21 private const CODE_VAT_10 =
'vat10';
22 private const CODE_VAT_20 =
'vat20';
24 private const CHECK_PAYMENT_TYPE = 2;
26 private const MAX_NAME_LENGTH = 128;
30 return Main\Localization\Loc::getMessage(
'SALE_CASHBOX_ROBOKASSA_TITLE');
35 return self::URL .
'Attach';
40 return self::URL .
'Status';
50 if (!$checkParamsResult->isSuccess())
63 $request = Main\Application::getInstance()->getContext()->getRequest();
64 $protocol = $request->isHttps() ?
'https://' :
'http://';
68 'id' => $checkData[
'unique_id'],
69 'originId' => $payment->getId(),
72 'url' => \urlencode($protocol . $request->getHttpHost()),
75 'email' => $checkData[
'client_email'],
76 'phone' => $checkData[
'client_phone'],
83 foreach ($checkData[
'payments'] as $paymentItem)
85 $fields[
'payments'][] = [
86 'type' => self::CHECK_PAYMENT_TYPE,
92 $paymentMethod = $checkTypeMap[$check::getType()];
93 $paymentObjectMap = $this->getPaymentObjectMap();
94 foreach ($checkData[
'items'] as $item)
100 'name' => mb_substr($item[
'name'], 0, self::MAX_NAME_LENGTH),
101 'quantity' => (string)$item[
'quantity'],
102 'sum' => (
string)Sale\PriceMaths::roundPrecision($item[
'sum']),
104 'payment_method' => $paymentMethod,
105 'payment_object' => $paymentObjectMap[$item[
'payment_object']],
108 if (!empty($item[
'marking_code']))
110 $receiptItem[
'nomenclature_code'] = $item[
'marking_code'];
113 $fields[
'items'][] = $receiptItem;
115 $fields[
'vats'][] = [
128 $id = $data[
'CheckId'] ??
null;
139 $result[
'LINK_PARAMS'] = [
147 if (!empty($data[
'FiscalDate']))
166 $data = $result->getData();
167 $resultCode = (int)$data[
'ResultCode'];
171 $processPrintResult->setData([
'UUID' => ($data[
'OpKey'] ??
'')]);
175 $processPrintResult->addError(
new Main\
Error(Main\Localization\
Loc::getMessage(
'SALE_CASHBOX_ROBOKASSA_PRINT_ERROR_FORMAT')));
179 $processPrintResult->addError(
new Main\
Error(Main\Localization\
Loc::getMessage(
'SALE_CASHBOX_ROBOKASSA_PRINT_ERROR_NOT_ENOUGH_MONEY')));
183 $processPrintResult->addError(
new Main\
Error(Main\Localization\
Loc::getMessage(
'SALE_CASHBOX_ROBOKASSA_PRINT_ERROR_INTERNAL')));
187 return $processPrintResult;
194 'id' => $payment->getId(),
202 $data = $result->getData();
203 $resultCode = (int)$data[
'Code'];
207 $processCheckResult->addError(
new Main\
Error(Main\Localization\
Loc::getMessage(
'SALE_CASHBOX_ROBOKASSA_PRINT_ERROR_WAIT')));
212 if (!empty($data[
'Statuses']))
215 foreach ($data[
'Statuses'] as $status)
217 $statuses[] = $status;
220 $processCheckResult->setData($statuses);
225 $processCheckResult->addError(
new Main\
Error(Main\Localization\
Loc::getMessage(
'SALE_CASHBOX_ROBOKASSA_STATUS_ERROR_REGISTER')));
229 $processCheckResult->addError(
new Main\
Error(Main\Localization\
Loc::getMessage(
'SALE_CASHBOX_ROBOKASSA_STATUS_ERROR_PROCESSING')));
233 return $processCheckResult;
243 'ORDER_ID' => $payment->getOrder()->getId(),
249 $statuses = $result->getData();
250 foreach ($statuses as $key => $status)
252 $resultCode = (int)$status[
'Code'];
253 if ($resultCode === 0)
261 $onAfterProcessCheckResult->addError(
new Main\
Error(Main\Localization\
Loc::getMessage(
'SALE_CASHBOX_ROBOKASSA_PRINT_ERROR_WAIT')));
265 $status[
'CheckId'] = $checkList[$key][
'ID'];
266 $applyCheckResult = static::applyCheckResult($status);
267 if (!$applyCheckResult->isSuccess())
269 $onAfterProcessCheckResult->addErrors($applyCheckResult->getErrors());
274 $onAfterProcessCheckResult->addError(
new Main\
Error(Main\Localization\
Loc::getMessage(
'SALE_CASHBOX_ROBOKASSA_STATUS_ERROR_REGISTER')));
278 $onAfterProcessCheckResult->addError(
new Main\
Error(Main\Localization\
Loc::getMessage(
'SALE_CASHBOX_ROBOKASSA_STATUS_ERROR_PROCESSING')));
285 $onAfterProcessCheckResult->addError(
new Main\
Error(Main\Localization\
Loc::getMessage(
'SALE_CASHBOX_ROBOKASSA_CHECK_NOT_FOUND')));
288 return $onAfterProcessCheckResult;
307 $startupHash = self::cutSign(
310 self::encode($fields)
315 $sign = self::cutSign(
325 $response = $httpClient->post($url, $startupHash .
'.' . $sign);
326 if ($response ===
false)
328 $result->addError(
new Main\
Error(Main\Localization\
Loc::getMessage(
'SALE_CASHBOX_ROBOKASSA_ERROR_EMPTY_RESPONSE')));
330 $errors = $httpClient->getError();
331 foreach ($errors as $code => $message)
333 $result->addError(
new Main\
Error($message, $code));
341 $response = static::decode($response);
344 $result->addError(
new Main\
Error(Main\Localization\
Loc::getMessage(
'SALE_CASHBOX_ROBOKASSA_ERROR_DECODE_RESPONSE')));
348 $result->setData($response);
372 private static function cutSign(
string $sign): string
374 return \preg_replace(
'/^(.*?)(=*)$/',
'$1', $sign);
382 private static function encode(array $data)
384 return Main\Web\Json::encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
391 private static function decode($data)
395 return Main\Web\Json::decode($data);
397 catch (Main\ArgumentException $exception)
427 'LABEL' => Main\Localization\Loc::getMessage(
'SALE_CASHBOX_ROBOKASSA_SETTINGS_VAT'),
432 'LABEL' => Main\Localization\Loc::getMessage(
'SALE_CASHBOX_ROBOKASSA_SETTINGS_VAT_LABEL_NOT_VAT'),
438 if (Main\Loader::includeModule(
'catalog'))
440 $dbRes = Catalog\VatTable::getList([
'filter' => [
'ACTIVE' =>
'Y']]);
441 $vatList = $dbRes->fetchAll();
445 0 => self::CODE_VAT_0,
446 10 => self::CODE_VAT_10,
447 20 => self::CODE_VAT_20
450 foreach ($vatList as $vat)
453 if (isset($defaultVatList[(
int)$vat[
'RATE']]))
455 $value = $defaultVatList[(int)$vat[
'RATE']];
458 $settings[
'VAT'][
'ITEMS'][(int)$vat[
'ID']] = [
460 'LABEL' => $vat[
'NAME'].
' ['.(
int)$vat[
'RATE'].
'%]',
468 'LABEL' => Main\Localization\Loc::getMessage(
'SALE_CASHBOX_ROBOKASSA_SETTINGS_SNO'),
473 'LABEL' => Main\Localization\Loc::getMessage(
'SALE_CASHBOX_ROBOKASSA_SETTINGS_SNO_LABEL'),
476 'osn' => Main\Localization\Loc::getMessage(
'SALE_CASHBOX_ROBOKASSA_SNO_OSN'),
477 'usn_income' => Main\Localization\Loc::getMessage(
'SALE_CASHBOX_ROBOKASSA_SNO_UI'),
478 'usn_income_outcome' => Main\Localization\Loc::getMessage(
'SALE_CASHBOX_ROBOKASSA_SNO_UIO'),
479 'envd' => Main\Localization\Loc::getMessage(
'SALE_CASHBOX_ROBOKASSA_SNO_ENVD'),
480 'esn' => Main\Localization\Loc::getMessage(
'SALE_CASHBOX_ROBOKASSA_SNO_ESN'),
481 'patent' => Main\Localization\Loc::getMessage(
'SALE_CASHBOX_ROBOKASSA_SNO_PATENT')
492 return 'ROBOXCHANGE_SHOPLOGIN';
498 private function getPaymentObjectMap(): array
static getMessage($code, $replace=null, $language=null)
const PARAM_CALCULATION_ATTR
const PARAM_FISCAL_DOC_ATTR
const PARAM_FISCAL_DOC_NUMBER
getValueFromSettings($name, $code)
getPaySystemSetting(Sale\Payment $payment, string $code)
checkParams(Check $check)
send(string $url, Sale\Payment $payment, array $fields, string $method=self::SEND_METHOD_HTTP_POST)
static getPaySystemCodeForKkm()
onAfterProcessCheck(Sale\Result $result, Sale\Payment $payment)
static getSettings($modelId=0)
getDataForCheck(Sale\Payment $payment)
buildCheckQuery(Check $check)
static extractCheckData(array $data)
processCheckResult(Sale\Result $result)
static formatSign(string $sign)
processPrintResult(Sale\Result $result)
const PAYMENT_OBJECT_EXCISE
const PAYMENT_OBJECT_LOTTERY
const PAYMENT_OBJECT_SOCIAL_INSURANCE
const PAYMENT_OBJECT_COMPOSITE
const PAYMENT_OBJECT_LOTTERY_PRIZE
const PAYMENT_OBJECT_MEDICAL_INSURANCE_IP
const PAYMENT_OBJECT_COMMODITY_MARKING_EXCISE
const PAYMENT_OBJECT_NON_OPERATING_GAIN
const PAYMENT_OBJECT_COMMODITY_MARKING_NO_MARKING_EXCISE
const PAYMENT_OBJECT_RESORT_FEE
const PAYMENT_OBJECT_PENSION_INSURANCE_IP
const PAYMENT_OBJECT_PROPERTY_RIGHT
const PAYMENT_OBJECT_GAMBLING_PRIZE
const PAYMENT_OBJECT_COMMODITY_MARKING
const PAYMENT_OBJECT_COMMODITY
const PAYMENT_OBJECT_AGENT_COMMISSION
const PAYMENT_OBJECT_ANOTHER
const PAYMENT_OBJECT_DEPOSIT
const PAYMENT_OBJECT_MEDICAL_INSURANCE
const PAYMENT_OBJECT_SERVICE
const PAYMENT_OBJECT_INTELLECTUAL_ACTIVITY
const PAYMENT_OBJECT_PAYMENT
const PAYMENT_OBJECT_EXPENSE
const PAYMENT_OBJECT_GAMBLING_BET
const PAYMENT_OBJECT_CASINO_PAYMENT
const PAYMENT_OBJECT_PENSION_INSURANCE
const PAYMENT_OBJECT_COMMODITY_MARKING_NO_MARKING
const PAYMENT_OBJECT_SALES_TAX
static getPaymentByCheck(Check $check)
static getList(array $parameters=array())
static getObjectById($id)
static addDebugInfo(?string $message, $cashboxId=null)
static roundPrecision($value)