103 lines
3.2 KiB
PHP

<?php
namespace App\Providers\Danal\Gateways;
use App\Models\Payments\GcPinOrder;
use App\Providers\Danal\Clients\DanalCpcgiClient;
use App\Providers\Danal\DanalConfig;
use App\Support\Danal\EucKr;
final class VactGateway
{
public function __construct(
private readonly DanalConfig $cfg,
private readonly DanalCpcgiClient $client,
private readonly EucKr $euc,
) {}
public function auth(GcPinOrder $order, string $attemptToken, bool $isMobile): array
{
$c = $this->cfg->vact();
$userAgent = $isMobile ? 'MW' : 'PC';
$returnUrl = route('web.payments.danal.vact.return', ['a' => $attemptToken], true);
$cancelUrl = route('web.payments.danal.cancel', ['a' => $attemptToken], true);
$notiUrl = route('web.payments.danal.vact.noti', [], true);
$req = [
'CPID' => (string)$c['cpid'],
'SUBCPID' => '',
'ACCOUNTHOLDER' => (string)$c['holder'],
'EXPIREDATE' => now()->addHours(23)->format('Ymd'),
'ORDERID' => $order->oid,
'ITEMNAME' => $this->safeItemName($this->orderTitle($order)),
'AMOUNT' => (string)$order->pay_money,
'ISCASHRECEIPTUI' => 'N',
'USERNAME' => '',
'USERID' => (string)$order->mem_no,
'USEREMAIL' => '',
'USERPHONE' => '',
'USERAGENT' => $userAgent,
'TXTYPE' => 'AUTH',
'SERVICETYPE' => 'DANALVACCOUNT',
'RETURNURL' => $returnUrl,
'NOTIURL' => $notiUrl,
'CANCELURL' => $cancelUrl,
'BYPASSVALUE' => 'AT=' . $attemptToken,
];
$res = $this->client->call($c['url'], $c['cpid'], $req, $c['key'], $c['iv']);
return [
'req' => $req,
'res' => $res,
'start' => [
'actionUrl' => (string)($res['STARTURL'] ?? ''),
'params' => ['STARTPARAMS' => (string)($res['STARTPARAMS'] ?? '')],
'acceptCharset' => 'EUC-KR',
],
];
}
public function decryptReturn(string $returnParams): array
{
$c = $this->cfg->vact();
return $this->client->decryptReturnParams($returnParams, $c['key'], $c['iv']);
}
public function issue(GcPinOrder $order, string $tid): array
{
$c = $this->cfg->vact();
$req = [
'CPID' => (string)$c['cpid'],
'TID' => $tid,
'AMOUNT' => (string)$order->pay_money,
'TXTYPE' => 'ISSUEVACCOUNT',
'SERVICETYPE' => 'DANALVACCOUNT',
];
$res = $this->client->call($c['url'], $c['cpid'], $req, $c['key'], $c['iv']);
return ['req' => $req, 'res' => $res];
}
private function orderTitle(GcPinOrder $order): string
{
$items = $order->items()->limit(2)->get();
if ($items->count() === 0) return '상품권';
if ($items->count() === 1) return (string)$items[0]->item_name;
return (string)$items[0]->item_name . ' 외';
}
private function safeItemName(string $s): string
{
$s = str_replace(["&","'","\"","\\","<",">","|","\r","\n","," , "+"], " ", $s);
return trim(preg_replace('/\s+/', ' ', $s)) ?: '상품권';
}
}