668 lines
20 KiB
PHP
Executable File
668 lines
20 KiB
PHP
Executable File
<?php
|
|
|
|
/**
|
|
* @property ModelCheckoutOrder $model_checkout_order
|
|
* @property ModelAccountOrder $model_account_order
|
|
* @property ModelLocalisationOrderStatus $model_localisation_order_status
|
|
*/
|
|
class ControllerExtensionPaymentPayanyway extends Controller {
|
|
const PAYMENT_SERVER_PROD = 'prod';
|
|
const PAYMENT_URL_PROD = 'https://www.payanyway.ru/assistant.htm';
|
|
const PAYMENT_URL_DEMO = 'https://demo.moneta.ru/assistant.htm';
|
|
|
|
const TRANSACTION_ID_STRING_DELIMITER = '|';
|
|
const DESCRIPTION_MAX_LENGTH = 500;
|
|
|
|
const INVENTORY_ITEM_NAME_MAX_LENGTH = 128;
|
|
const INVENTORY_ITEM_DEFAULT_PAYMENT_METHOD = 'full_payment';
|
|
const INVENTORY_ITEM_DEFAULT_PAYMENT_OBJECT = 'commodity';
|
|
const INVENTORY_ITEM_DEFAULT_MEASURE = 'unit';
|
|
|
|
/** @var int */
|
|
private $mntId;
|
|
|
|
/** @var string */
|
|
private $integrityCode;
|
|
|
|
/** @var string */
|
|
private $server;
|
|
|
|
/** @var string */
|
|
private $vatRate;
|
|
|
|
/** @var string */
|
|
private $currency;
|
|
|
|
/** @var int */
|
|
private $pendingOrderStatusId;
|
|
|
|
/** @var int */
|
|
private $successOrderStatusId;
|
|
|
|
/** @var int */
|
|
private $errorOrderStatusId;
|
|
|
|
/** @var string */
|
|
private $cmsModuleVersion;
|
|
|
|
/** @var int|null */
|
|
private $orderId;
|
|
|
|
/** @var array<string, mixed> */
|
|
private $orderInfo;
|
|
|
|
/** @throws \Exception */
|
|
public function __construct($registry) {
|
|
parent::__construct($registry);
|
|
|
|
$this->initializeModule();
|
|
|
|
$this->orderId = $this->getOrderId();
|
|
$this->orderInfo = $this->getOrderInfo();
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
* @throws \Exception
|
|
*/
|
|
public function index() {
|
|
$this->load->language('extension/payment/payanyway');
|
|
$this->document->setTitle($this->language->get('heading_title'));
|
|
|
|
$data['action'] = (self::PAYMENT_SERVER_PROD === $this->server) ? self::PAYMENT_URL_PROD : self::PAYMENT_URL_DEMO;
|
|
|
|
$orderTotal = (float)(isset($this->orderInfo['total']) ? $this->orderInfo['total'] : 0);
|
|
|
|
$data['MNT_ID'] = $this->mntId;
|
|
$data['MNT_TRANSACTION_ID'] = $this->createTransactionId();
|
|
$data['MNT_AMOUNT'] = $this->formatPrice($orderTotal);
|
|
$data['MNT_CURRENCY_CODE'] = $this->currency;
|
|
$data['MNT_TEST_MODE'] = '0';
|
|
$data['MNT_DESCRIPTION'] = $this->getDescription();
|
|
$data['MNT_SUBSCRIBER_ID'] = $this->getSubscriberId();
|
|
|
|
$signature = md5(
|
|
$data['MNT_ID'] .
|
|
$data['MNT_TRANSACTION_ID'] .
|
|
$data['MNT_AMOUNT'] .
|
|
$data['MNT_CURRENCY_CODE'] .
|
|
$data['MNT_SUBSCRIBER_ID'] .
|
|
$data['MNT_TEST_MODE'] .
|
|
$this->integrityCode
|
|
);
|
|
$data['MNT_SIGNATURE'] = $signature;
|
|
$data['MNT_SUCCESS_URL'] = $this->url->link('extension/payment/payanyway/success', 'language=' . $this->config->get('config_language'), true);
|
|
$data['MNT_FAIL_URL'] = $this->url->link('extension/payment/payanyway/fail', 'language=' . $this->config->get('config_language'), true);
|
|
$data['MNT_RETURN_URL'] = $this->url->link('checkout/checkout', 'language=' . $this->config->get('config_language'), true);
|
|
$data['MNT_CMS'] = $this->cmsModuleVersion;
|
|
|
|
$data['btn_confirm'] = $this->language->get('text_paw_pay');
|
|
|
|
$data['confirm_url'] = $this->url->link('extension/payment/payanyway/confirm', 'language=' . $this->config->get('config_language'), true);
|
|
|
|
return $this->load->view('extension/payment/payanyway', $data);
|
|
}
|
|
|
|
/**
|
|
* @return void
|
|
* @throws \Exception
|
|
*/
|
|
public function confirm() {
|
|
$json = array();
|
|
|
|
$this->load->language('extension/payment/payanyway');
|
|
$this->addOrderHistory($this->pendingOrderStatusId, $this->language->get('text_order_confirmed'));
|
|
|
|
$json['success'] = true;
|
|
|
|
$this->response->addHeader('Content-Type: application/json');
|
|
$this->response->setOutput(json_encode($json));
|
|
}
|
|
|
|
/**
|
|
* @return void
|
|
* @throws \Exception
|
|
*/
|
|
public function success() {
|
|
$this->load->language('extension/payment/payanyway');
|
|
$this->addOrderHistory($this->pendingOrderStatusId, $this->language->get('text_payment_processing'));
|
|
|
|
$this->response->redirect($this->url->link('checkout/success', '', true));
|
|
}
|
|
|
|
/**
|
|
* @return void
|
|
* @throws \Exception
|
|
*/
|
|
public function fail() {
|
|
$this->load->language('extension/payment/payanyway');
|
|
$this->addOrderHistory($this->errorOrderStatusId, $this->language->get('text_payment_error'));
|
|
|
|
$this->response->redirect($this->url->link('checkout/failure', '', true));
|
|
}
|
|
|
|
/** @return int|null */
|
|
private function getOrderId() {
|
|
$orderId = $this->getOrderIdFromTransactionId();
|
|
if (null !== $orderId) {
|
|
return $orderId;
|
|
}
|
|
|
|
return $this->getOrderIdFromSession();
|
|
}
|
|
|
|
/**
|
|
* @return false|array
|
|
* @throws \Exception
|
|
*/
|
|
private function getOrderInfo() {
|
|
if (null === $this->orderId) {
|
|
return array();
|
|
}
|
|
|
|
$this->load->model('checkout/order');
|
|
return $this->model_checkout_order->getOrder($this->orderId);
|
|
}
|
|
|
|
/** @return string */
|
|
private function createTransactionId() {
|
|
$date = date('YmdHis');
|
|
return $this->orderId . self::TRANSACTION_ID_STRING_DELIMITER . $date;
|
|
}
|
|
|
|
/**
|
|
* @param float $price
|
|
* @return string
|
|
*/
|
|
private function formatPrice($price) {
|
|
return number_format($price, 2, '.', '');
|
|
}
|
|
|
|
/** @return string */
|
|
private function getDescription() {
|
|
$clientFirstName = isset($this->orderInfo['firstname']) ? $this->orderInfo['firstname'] : '';
|
|
$clientLastName = isset($this->orderInfo['lastname']) ? $this->orderInfo['lastname'] : '';
|
|
$clientName = trim($clientFirstName . ' ' . $clientLastName);
|
|
|
|
$orderId = isset($this->orderInfo['order_id']) ? $this->orderInfo['order_id'] : null;
|
|
$description = "Оплата заказа" . (!empty($orderId) ? " №{$orderId}" : '');
|
|
|
|
if ('' !== $clientName) {
|
|
$description .= " от {$clientName}";
|
|
}
|
|
|
|
$comment = isset($this->orderInfo['comment']) ? $this->orderInfo['comment'] : '';
|
|
if ('' !== $comment) {
|
|
$description .= ': ' . htmlspecialchars($comment, ENT_QUOTES, 'UTF-8');
|
|
}
|
|
|
|
return $this->validateString($description, self::DESCRIPTION_MAX_LENGTH);
|
|
}
|
|
|
|
/**
|
|
* @param string $value
|
|
* @param int $maxLength
|
|
* @return string
|
|
*/
|
|
private function validateString($value, $maxLength) {
|
|
$maxLength = max(0, $maxLength);
|
|
$value = $this->sanitizeString($value);
|
|
|
|
if (mb_strlen($value, 'UTF-8') <= $maxLength) {
|
|
return $value;
|
|
}
|
|
|
|
$trimLength = max(0, $maxLength - 3);
|
|
return mb_substr($value, 0, $trimLength, 'UTF-8') . ($maxLength > 3 ? '...' : '');
|
|
}
|
|
|
|
/**
|
|
* @param string $value
|
|
* @return string
|
|
*/
|
|
private function sanitizeString($value) {
|
|
$decoded = html_entity_decode($value, ENT_QUOTES | ENT_HTML5, 'UTF-8');
|
|
$cleaned = preg_replace('/[^\p{L}\p{N}\s.,()_№+-]/u', '', $decoded);
|
|
$cleaned = str_replace(['&', '/', '\\', ';', '%', '#', '"', "'"], '', $cleaned);
|
|
|
|
return trim(preg_replace('/\s+/', ' ', $cleaned));
|
|
}
|
|
|
|
/** @return string */
|
|
private function getSubscriberId() {
|
|
$email = isset($this->orderInfo['email'])
|
|
? filter_var($this->orderInfo['email'], FILTER_SANITIZE_EMAIL)
|
|
: '';
|
|
if ('' !== $email) {
|
|
return $email;
|
|
}
|
|
|
|
return isset($this->orderInfo['telephone'])
|
|
? preg_replace('/[^0-9+]/', '', $this->orderInfo['telephone'])
|
|
: '';
|
|
}
|
|
|
|
/**
|
|
* @param int $orderStatusId
|
|
* @param string $comment
|
|
* @return void
|
|
* @throws \Exception
|
|
*/
|
|
private function addOrderHistory($orderStatusId, $comment) {
|
|
$this->load->model('checkout/order');
|
|
$this->model_checkout_order->addOrderHistory($this->orderId, $orderStatusId, $comment);
|
|
}
|
|
|
|
/**
|
|
* @return void
|
|
* @throws \Exception
|
|
*/
|
|
public function callback() {
|
|
if (null === $this->orderId) {
|
|
$this->sendResponse('FAIL');
|
|
}
|
|
if (false === $this->orderInfo) {
|
|
$this->sendResponse('FAIL');
|
|
}
|
|
|
|
$requestData = ($_SERVER['REQUEST_METHOD'] === 'POST') ? $_POST : $_GET;
|
|
$callbackData = $this->getCallbackData($requestData);
|
|
|
|
(isset($callbackData['MNT_COMMAND'])) && ('CHECK' === $callbackData['MNT_COMMAND'])
|
|
? $this->handleCheckCallback($callbackData)
|
|
: $this->handlePayCallback($callbackData);
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $requestData
|
|
* @return array<string, mixed>
|
|
*/
|
|
private function getCallbackData(array $requestData) {
|
|
return array(
|
|
'MNT_COMMAND' => $this->getOptionalStringWithDefault($requestData, 'MNT_COMMAND'),
|
|
'MNT_ID' => $this->getRequiredString($requestData, 'MNT_ID'),
|
|
'MNT_TRANSACTION_ID' => $this->getRequiredString($requestData, 'MNT_TRANSACTION_ID'),
|
|
'MNT_OPERATION_ID' => $this->getOptionalStringWithDefault($requestData, 'MNT_OPERATION_ID'),
|
|
'MNT_AMOUNT' => $this->getOptionalStringWithDefault($requestData, 'MNT_AMOUNT'),
|
|
'MNT_CURRENCY_CODE' => $this->getRequiredString($requestData, 'MNT_CURRENCY_CODE'),
|
|
'MNT_SUBSCRIBER_ID' => $this->getOptionalStringWithDefault($requestData, 'MNT_SUBSCRIBER_ID'),
|
|
'MNT_TEST_MODE' => $this->getRequiredString($requestData, 'MNT_TEST_MODE'),
|
|
'MNT_SIGNATURE' => $this->getRequiredString($requestData, 'MNT_SIGNATURE'),
|
|
);
|
|
}
|
|
|
|
/** @return int|null */
|
|
private function getOrderIdFromTransactionId() {
|
|
if (!isset($_REQUEST['MNT_TRANSACTION_ID'])) {
|
|
return null;
|
|
}
|
|
$transactionIdData = explode(self::TRANSACTION_ID_STRING_DELIMITER, $_REQUEST['MNT_TRANSACTION_ID'], 2);
|
|
|
|
return isset($transactionIdData[0]) ? (int)$transactionIdData[0] : null;
|
|
}
|
|
|
|
/** @return int|null */
|
|
private function getOrderIdFromSession() {
|
|
return isset($this->session->data['order_id']) ? (int)$this->session->data['order_id'] : null;
|
|
}
|
|
|
|
/**
|
|
* @param string $response
|
|
* @param int $statusCode
|
|
* @return void
|
|
*/
|
|
private function sendResponse($response, $statusCode = 200) {
|
|
http_response_code($statusCode);
|
|
|
|
if (strpos($response, '<?xml') === 0 || strpos($response, '<MNT_RESPONSE') !== false) {
|
|
header('Content-Type: application/xml');
|
|
} else {
|
|
header('Content-Type: text/plain; charset=UTF-8');
|
|
}
|
|
|
|
echo $response;
|
|
exit();
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $data
|
|
* @return bool
|
|
*/
|
|
private function checkSignature(array $data, $callbackSignature) {
|
|
$baseFields = array(
|
|
'MNT_ID',
|
|
'MNT_TRANSACTION_ID',
|
|
'MNT_OPERATION_ID',
|
|
'MNT_AMOUNT',
|
|
'MNT_CURRENCY_CODE',
|
|
'MNT_SUBSCRIBER_ID',
|
|
'MNT_TEST_MODE',
|
|
);
|
|
|
|
$fields = isset($data['MNT_COMMAND']) && ('CHECK' === $data['MNT_COMMAND'])
|
|
? array_merge(['MNT_COMMAND'], $baseFields)
|
|
: $baseFields;
|
|
|
|
$signatureString = array_reduce($fields, function ($carry, $field) use ($data) {
|
|
return $carry . $data[$field];
|
|
}, '') . $this->integrityCode;
|
|
|
|
return hash_equals(md5($signatureString), $callbackSignature);
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $callbackData
|
|
* @return void
|
|
* @throws \Exception
|
|
*/
|
|
private function handleCheckCallback(array $callbackData) {
|
|
if (!$this->checkSignature($callbackData, $callbackData['MNT_SIGNATURE'])) {
|
|
$this->sendResponse('FAIL');
|
|
}
|
|
|
|
list($resultCode, $description) = $this->determineCheckResult($callbackData);
|
|
$responseData = $this->buildResponseData($callbackData, $resultCode, $description);
|
|
|
|
$this->sendResponse($this->buildXMLResponse($responseData));
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $callbackData
|
|
* @return void
|
|
* @throws \Exception
|
|
*/
|
|
private function handlePayCallback(array $callbackData) {
|
|
$orderTotal = (float)(isset($this->orderInfo['total']) ? $this->orderInfo['total'] : 0);
|
|
$currencyCode = isset($this->orderInfo['currency_code']) ? $this->orderInfo['currency_code'] : 'RUB';
|
|
$shopData = array(
|
|
'MNT_ID' => $this->mntId,
|
|
'MNT_TRANSACTION_ID' => $callbackData['MNT_TRANSACTION_ID'],
|
|
'MNT_OPERATION_ID' => $callbackData['MNT_OPERATION_ID'],
|
|
'MNT_AMOUNT' => $this->formatPrice($orderTotal),
|
|
'MNT_CURRENCY_CODE' => $currencyCode,
|
|
'MNT_SUBSCRIBER_ID' => $callbackData['MNT_SUBSCRIBER_ID'],
|
|
'MNT_TEST_MODE' => $callbackData['MNT_TEST_MODE'],
|
|
);
|
|
|
|
if (!$this->checkSignature($shopData, $callbackData['MNT_SIGNATURE'])) {
|
|
$this->sendResponse('FAIL');
|
|
}
|
|
|
|
$isPayedOrder = $this->isOrderPaid();
|
|
if (!$isPayedOrder) {
|
|
$this->load->language('extension/payment/payanyway');
|
|
$this->addOrderHistory($this->successOrderStatusId, $this->language->get('text_payment_completed'));
|
|
}
|
|
|
|
$resultCode = 200;
|
|
$description = $isPayedOrder ? 'Order already paid' : 'Order success paid';
|
|
$responseData = $this->buildResponseData($callbackData, $resultCode, $description);
|
|
|
|
$this->sendResponse($this->buildXMLResponse($responseData));
|
|
}
|
|
|
|
/**
|
|
* @param array $callbackData
|
|
* @param int $resultCode
|
|
* @param string $description
|
|
* @return array<string, mixed>
|
|
* @throws \Exception
|
|
*/
|
|
private function buildResponseData(array $callbackData, $resultCode, $description) {
|
|
$orderTotal = (float)(isset($this->orderInfo['total']) ? $this->orderInfo['total'] : 0);
|
|
|
|
$data = array(
|
|
'MNT_ID' => $this->mntId,
|
|
'MNT_TRANSACTION_ID' => $callbackData['MNT_TRANSACTION_ID'],
|
|
'MNT_RESULT_CODE' => $resultCode,
|
|
'MNT_DESCRIPTION' => $description,
|
|
'MNT_AMOUNT' => $this->formatPrice($orderTotal),
|
|
'MNT_CURRENCY_CODE' => $callbackData['MNT_CURRENCY_CODE'],
|
|
);
|
|
|
|
$signatureSource = $resultCode . $this->mntId . $callbackData['MNT_TRANSACTION_ID'] . $this->integrityCode;
|
|
$data['MNT_SIGNATURE'] = md5($signatureSource);
|
|
|
|
$this->load->model('account/order');
|
|
$products = $this->model_account_order->getOrderProducts($this->orderId);
|
|
$deliveryPrice = $this->getDeliveryPrice();
|
|
|
|
$data['inventory'] = $this->getInventoryJson($products) ?: null;
|
|
$data['client'] = $callbackData['MNT_SUBSCRIBER_ID'];
|
|
$data['sno'] = null;
|
|
$data['delivery'] = (null !== $deliveryPrice) ? $this->formatPrice($deliveryPrice) : null;
|
|
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $callbackData
|
|
* @return array<int|string>
|
|
* @throws \Exception
|
|
*/
|
|
private function determineCheckResult(array $callbackData) {
|
|
$orderStatusId = isset($this->orderInfo['order_status_id']) ? (int)$this->orderInfo['order_status_id'] : null;
|
|
if (null === $orderStatusId) {
|
|
return array(500, 'Order status not set');
|
|
}
|
|
$orderStatus = $this->getOrderStatusById($orderStatusId);
|
|
|
|
if (empty($callbackData['MNT_AMOUNT'])) {
|
|
return array(100, "Order status is '{$orderStatus}'");
|
|
}
|
|
|
|
if ($this->successOrderStatusId === $orderStatusId) {
|
|
return array(200, 'Order Paid');
|
|
}
|
|
|
|
if (in_array($orderStatusId, array(7, 9, 16), true)) {
|
|
return array(500, "Order status is '{$orderStatus}'");
|
|
}
|
|
|
|
return array(402, 'Order created, but not paid');
|
|
}
|
|
|
|
/** @return bool */
|
|
private function isOrderPaid() {
|
|
if (!isset($this->orderInfo['order_status_id'])) {
|
|
return false;
|
|
}
|
|
|
|
return $this->successOrderStatusId === (int)$this->orderInfo['order_status_id'];
|
|
}
|
|
|
|
/**
|
|
* @return float|null
|
|
* @throws \Exception
|
|
*/
|
|
private function getDeliveryPrice() {
|
|
$this->load->model('account/order');
|
|
foreach ($this->model_account_order->getOrderTotals($this->orderId) as $orderTotal) {
|
|
if (isset($orderTotal['code']) && ($orderTotal['code'] === 'shipping')) {
|
|
$deliveryPrice = isset($orderTotal['value']) ? (float)$orderTotal['value'] : 0;
|
|
return ($deliveryPrice !== 0.0) ? $deliveryPrice : null;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $products
|
|
* @return false|string
|
|
*/
|
|
private function getInventoryJson(array $products) {
|
|
if (empty($products)) {
|
|
return false;
|
|
}
|
|
|
|
$inventory = array();
|
|
foreach ($products as $product) {
|
|
$name = isset($product['name']) ? $product['name'] : '';
|
|
$price = isset($product['price']) ? (float)$product['price'] : 0;
|
|
$quantity = isset($product['quantity']) ? (float)$product['quantity'] : 0;
|
|
|
|
$inventory[] = array(
|
|
'name' => $this->validateString($name, self::INVENTORY_ITEM_NAME_MAX_LENGTH),
|
|
'price' => $this->formatPrice($price),
|
|
'quantity' => $this->formatQuantity($quantity),
|
|
'vatTag' => $this->vatRate,
|
|
'pm' => self::INVENTORY_ITEM_DEFAULT_PAYMENT_METHOD,
|
|
'po' => self::INVENTORY_ITEM_DEFAULT_PAYMENT_OBJECT,
|
|
'measure' => self::INVENTORY_ITEM_DEFAULT_MEASURE,
|
|
);
|
|
}
|
|
|
|
return json_encode($inventory, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
|
}
|
|
|
|
/**
|
|
* @param int $orderStatusId
|
|
* @return string
|
|
* @throws \Exception
|
|
*/
|
|
public function getOrderStatusById($orderStatusId) {
|
|
$this->load->model('localisation/order_status');
|
|
/**@var array<int, array{order_status_id: string, name: string}> $orderStatuses */
|
|
$orderStatuses = $this->model_localisation_order_status->getOrderStatuses();
|
|
|
|
$orderStatus = 'unknown';
|
|
foreach ($orderStatuses as $orderStatus) {
|
|
$statusId = isset($orderStatus['order_status_id']) ? (int)$orderStatus['order_status_id'] : null;
|
|
if ($statusId === $orderStatusId) {
|
|
$orderStatus = $orderStatus['name'];
|
|
break;
|
|
}
|
|
}
|
|
|
|
return $orderStatus;
|
|
}
|
|
|
|
/**
|
|
* @param float $quantity
|
|
* @return string
|
|
*/
|
|
private function formatQuantity($quantity) {
|
|
$quantityString = number_format($quantity, 3, '.', '');
|
|
return rtrim(rtrim($quantityString, '0'), '.');
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $data
|
|
* @return false|string
|
|
* @return bool|string
|
|
* @throws \Exception
|
|
*/
|
|
private function buildXMLResponse(array $data) {
|
|
$dom = new \DOMDocument('1.0', 'UTF-8');
|
|
$dom->formatOutput = false;
|
|
|
|
$root = $dom->createElement('MNT_RESPONSE');
|
|
$dom->appendChild($root);
|
|
|
|
$requiredFields = array(
|
|
'MNT_ID',
|
|
'MNT_TRANSACTION_ID',
|
|
'MNT_RESULT_CODE',
|
|
'MNT_DESCRIPTION',
|
|
'MNT_AMOUNT',
|
|
'MNT_CURRENCY_CODE',
|
|
'MNT_SIGNATURE',
|
|
);
|
|
|
|
foreach ($requiredFields as $field) {
|
|
if (isset($data[$field]) && ($data[$field] !== '')) {
|
|
$root->appendChild($dom->createElement($field, (string)$data[$field]));
|
|
}
|
|
}
|
|
|
|
$attributes = $dom->createElement('MNT_ATTRIBUTES');
|
|
$root->appendChild($attributes);
|
|
|
|
$attributeMap = array(
|
|
'INVENTORY' => isset($data['inventory']) ? $data['inventory'] : null,
|
|
'CLIENT' => isset($data['client']) ? $data['client'] : null,
|
|
'SNO' => isset($data['sno']) ? $data['sno'] : null,
|
|
'DELIVERY' => isset($data['delivery']) ? $data['delivery'] : null,
|
|
);
|
|
|
|
foreach ($attributeMap as $key => $value) {
|
|
if (!empty($value)) {
|
|
$attrElement = $dom->createElement('ATTRIBUTE');
|
|
$attrElement->appendChild($dom->createElement('KEY', $key));
|
|
$attrElement->appendChild($dom->createElement('VALUE', (string)$value));
|
|
$attributes->appendChild($attrElement);
|
|
}
|
|
}
|
|
|
|
$xml = $dom->saveXML();
|
|
return (false !== $xml) ? $xml : 'FAIL';
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $params
|
|
* @param string $key
|
|
* @param string $default
|
|
* @return string
|
|
*/
|
|
private function getOptionalStringWithDefault(array $params, $key, $default = '') {
|
|
$optionalString = $this->getOptionalString($params, $key);
|
|
if (null !== $optionalString) {
|
|
return $optionalString;
|
|
}
|
|
|
|
return $default;
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $params
|
|
* @param string $key
|
|
* @return string|null
|
|
*/
|
|
private function getOptionalString(array $params, $key) {
|
|
$value = isset($params[$key]) ? $params[$key] : null;
|
|
if (!is_string($value) || trim($value) === '') {
|
|
return null;
|
|
}
|
|
|
|
return $value;
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $params
|
|
* @param string $key
|
|
* @return string
|
|
* @throws \InvalidArgumentException
|
|
*/
|
|
private function getRequiredString(array $params, $key) {
|
|
if (!isset($params[$key])) {
|
|
throw new \InvalidArgumentException('Missing required field: ' . $key);
|
|
}
|
|
|
|
$value = $params[$key];
|
|
if (!is_string($value)) {
|
|
throw new \InvalidArgumentException(
|
|
sprintf('Field "%s" must be a string, %s given', $key, gettype($value))
|
|
);
|
|
}
|
|
|
|
if ('' === $value) {
|
|
throw new \InvalidArgumentException(sprintf('Field "%s" must be a non-empty string', $key));
|
|
}
|
|
|
|
return $value;
|
|
}
|
|
|
|
private function initializeModule() {
|
|
$this->mntId = (int)$this->config->get('payment_payanyway_account');
|
|
$this->integrityCode = (string)$this->config->get('payment_payanyway_integrity_code');
|
|
$this->server = (string)$this->config->get('payment_payanyway_server');
|
|
$this->vatRate = (string)$this->config->get('payment_payanyway_vat_rate');
|
|
$this->currency = $this->config->get('payment_payanyway_currency');
|
|
$this->pendingOrderStatusId = (int)$this->config->get('payment_payanyway_pending_order_status_id');
|
|
$this->successOrderStatusId = (int)$this->config->get('payment_payanyway_success_order_status_id');
|
|
$this->errorOrderStatusId = (int)$this->config->get('payment_payanyway_error_order_status_id');
|
|
$this->cmsModuleVersion = (string)$this->config->get('payment_payanyway_cms_module_version');
|
|
}
|
|
}
|