162 lines
6.5 KiB
PHP
162 lines
6.5 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace Esun\Oceanpayment\Model\Gateway;
|
|
|
|
use Esun\Oceanpayment\Model\Config;
|
|
use Esun\Oceanpayment\Model\Signature;
|
|
use Magento\Framework\UrlInterface;
|
|
use Magento\Sales\Model\Order;
|
|
use Magento\Sales\Model\Order\Address;
|
|
|
|
class RequestBuilder
|
|
{
|
|
public function __construct(
|
|
private readonly Config $config,
|
|
private readonly Signature $signature,
|
|
private readonly UrlInterface $urlBuilder
|
|
) {
|
|
}
|
|
|
|
public function build(Order $order): array
|
|
{
|
|
$method = (string)$order->getPayment()->getMethod();
|
|
if ($method !== Config::METHOD_CODE && $method !== Config::LEGACY_METHOD_CODE) {
|
|
throw new \InvalidArgumentException('The order does not use Oceanpayment Hosted.');
|
|
}
|
|
|
|
$data = $this->buildBase($order, $method);
|
|
$data['backUrl'] = $this->urlBuilder->getUrl(
|
|
'oceanpayment/payment/back',
|
|
['_secure' => true, '_nosid' => true]
|
|
);
|
|
$data['signValue'] = $this->signature->createRequest(
|
|
$data,
|
|
$this->config->getSecret('secure_code', (int)$order->getStoreId(), $method)
|
|
);
|
|
|
|
return array_filter($data, static fn ($value): bool => $value !== '');
|
|
}
|
|
|
|
public function buildEmbedded(Order $order): array
|
|
{
|
|
$method = (string)$order->getPayment()->getMethod();
|
|
if ($method !== Config::ONEPAGE_METHOD_CODE) {
|
|
throw new \InvalidArgumentException('The order does not use Oceanpayment OnePage.');
|
|
}
|
|
|
|
$data = $this->buildBase($order, $method);
|
|
$data['backUrl'] = $this->urlBuilder->getUrl(
|
|
'oceanpayment/payment/back',
|
|
['_secure' => true, '_nosid' => true]
|
|
);
|
|
$data['signValue'] = $this->signature->createEmbeddedRequest(
|
|
$data,
|
|
$this->config->getSecret('secure_code', (int)$order->getStoreId(), $method)
|
|
);
|
|
|
|
return array_filter($data, static fn ($value): bool => $value !== '');
|
|
}
|
|
|
|
private function buildBase(Order $order, string $method): array
|
|
{
|
|
$storeId = (int)$order->getStoreId();
|
|
$billing = $order->getBillingAddress();
|
|
if (!$billing) {
|
|
throw new \InvalidArgumentException('The order has no billing address.');
|
|
}
|
|
$shipping = $order->getShippingAddress() ?: $billing;
|
|
|
|
$data = [
|
|
'account' => $this->config->getSecret('account', $storeId, $method),
|
|
'terminal' => $this->config->getSecret('terminal', $storeId, $method),
|
|
'noticeUrl' => $this->urlBuilder->getUrl(
|
|
'oceanpayment/payment/notify',
|
|
['_secure' => true, '_nosid' => true]
|
|
),
|
|
'methods' => $this->clean($this->config->getValue('methods', $storeId, $method), 50),
|
|
'order_number' => $this->clean((string)$order->getIncrementId(), 50),
|
|
'order_currency' => strtoupper($this->clean((string)$order->getOrderCurrencyCode(), 3)),
|
|
'order_amount' => number_format((float)$order->getGrandTotal(), 2, '.', ''),
|
|
'billing_firstName' => $this->clean((string)$billing->getFirstname(), 50),
|
|
'billing_lastName' => $this->clean((string)$billing->getLastname(), 50),
|
|
'billing_email' => $this->clean((string)$billing->getEmail(), 50),
|
|
'billing_phone' => $this->clean((string)$billing->getTelephone(), 50),
|
|
'billing_country' => strtoupper($this->clean((string)$billing->getCountryId(), 100)),
|
|
'billing_state' => $this->clean($this->getRegion($billing), 100),
|
|
'billing_city' => $this->clean((string)$billing->getCity(), 500),
|
|
'billing_address' => $this->clean(implode(' ', $billing->getStreet()), 500),
|
|
'billing_zip' => $this->clean((string)$billing->getPostcode(), 50),
|
|
'billing_ip' => $this->clean((string)$order->getRemoteIp(), 50),
|
|
'ship_firstName' => $this->clean((string)$shipping->getFirstname(), 50),
|
|
'ship_lastName' => $this->clean((string)$shipping->getLastname(), 50),
|
|
'ship_email' => $this->clean((string)$shipping->getEmail(), 50),
|
|
'ship_phone' => $this->clean((string)$shipping->getTelephone(), 50),
|
|
'ship_country' => strtoupper($this->clean((string)$shipping->getCountryId(), 100)),
|
|
'ship_state' => $this->clean($this->getRegion($shipping), 100),
|
|
'ship_city' => $this->clean((string)$shipping->getCity(), 500),
|
|
'ship_addr' => $this->clean(implode(' ', $shipping->getStreet()), 500),
|
|
'ship_zip' => $this->clean((string)$shipping->getPostcode(), 50),
|
|
'order_notes' => '',
|
|
];
|
|
|
|
$data += $this->getProductData($order);
|
|
|
|
$language = $this->clean($this->config->getValue('language', $storeId, $method), 50);
|
|
if ($language !== '') {
|
|
$data['language'] = $language;
|
|
}
|
|
|
|
$key = $this->config->getSecret('public_key', $storeId, $method);
|
|
if ($key !== '') {
|
|
$data['key'] = $key;
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
private function getProductData(Order $order): array
|
|
{
|
|
$names = [];
|
|
$quantities = [];
|
|
$skus = [];
|
|
$prices = [];
|
|
|
|
foreach ($order->getAllVisibleItems() as $item) {
|
|
$names[] = $this->cleanListValue((string)$item->getName(), 120);
|
|
$quantities[] = $this->cleanListValue((string)(float)$item->getQtyOrdered(), 20);
|
|
$skus[] = $this->cleanListValue((string)$item->getSku(), 120);
|
|
$prices[] = number_format((float)$item->getPrice(), 2, '.', '');
|
|
}
|
|
|
|
if ($names === []) {
|
|
$names[] = 'Magento Order';
|
|
$quantities[] = '1';
|
|
$skus[] = (string)$order->getIncrementId();
|
|
$prices[] = number_format((float)$order->getGrandTotal(), 2, '.', '');
|
|
}
|
|
|
|
return [
|
|
'productName' => mb_substr(implode(',', $names), 0, 500),
|
|
'productNum' => mb_substr(implode(',', $quantities), 0, 50),
|
|
'productSku' => mb_substr(implode(',', $skus), 0, 500),
|
|
'productPrice' => mb_substr(implode(',', $prices), 0, 500),
|
|
];
|
|
}
|
|
|
|
private function getRegion(Address $address): string
|
|
{
|
|
return (string)($address->getRegionCode() ?: $address->getRegion() ?: '-');
|
|
}
|
|
|
|
private function cleanListValue(string $value, int $length): string
|
|
{
|
|
return str_replace(',', ' ', $this->clean($value, $length));
|
|
}
|
|
|
|
private function clean(string $value, int $length): string
|
|
{
|
|
return mb_substr($this->signature->sanitize($value), 0, $length);
|
|
}
|
|
}
|