155 lines
5.2 KiB
PHP
155 lines
5.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 WireGateway
|
|
{
|
|
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 $buyer): array
|
|
{
|
|
$c = $this->cfg->wiretransfer();
|
|
$userAgent = $isMobile ? 'MW' : 'PC';
|
|
|
|
// wire 라우트 네이밍은 web.php 그대로 사용
|
|
$returnUrl = route('wire.return', ['a' => $attemptToken], true);
|
|
$cancelUrl = route('web.payments.danal.cancel', ['a' => $attemptToken], true);
|
|
$notiUrl = route('wire.noti', [], true);
|
|
|
|
$req = [
|
|
'TXTYPE' => 'AUTH',
|
|
'SERVICETYPE' => 'WIRETRANSFER',
|
|
|
|
'ORDERID' => $order->oid,
|
|
'ITEMNAME' => $this->safeItemName($this->orderTitle($order)),
|
|
'AMOUNT' => (string)$order->pay_money,
|
|
|
|
'USERNAME' => (string)($buyer['user_name'] ?? ''),
|
|
'USERID' => (string)($buyer['user_id'] ?? (string)$order->mem_no),
|
|
'USEREMAIL' => (string)($buyer['user_email'] ?? ''),
|
|
'USERPHONE' => (string)($buyer['user_phone'] ?? ''),
|
|
'USERAGENT' => $userAgent,
|
|
|
|
'RETURNURL' => $returnUrl,
|
|
'CANCELURL' => $cancelUrl,
|
|
|
|
'ISNOTI' => (string)($c['is_noti'] ?? 'Y'),
|
|
'NOTIURL' => $notiUrl,
|
|
|
|
// NOTI에서 token 추출(권장)
|
|
'BYPASSVALUE' => 'AT=' . $attemptToken,
|
|
];
|
|
|
|
\Log::info('danal_wire_auth_req', [
|
|
'cpid' => $c['cpid'] ?? null,
|
|
'key_len' => isset($c['key']) ? strlen((string)$c['key']) : null,
|
|
'iv_len' => isset($c['iv']) ? strlen((string)$c['iv']) : null,
|
|
'req' => $req,
|
|
]);
|
|
|
|
$res = $this->client->call((string)$c['tx_url'], (string)$c['cpid'], $req, (string)$c['key'], (string)$c['iv']);
|
|
|
|
$params = ['STARTPARAMS' => (string)($res['STARTPARAMS'] ?? '')];
|
|
if (!empty($c['ci_url'])) $params['CIURL'] = (string)$c['ci_url'];
|
|
if (!empty($c['color'])) $params['COLOR'] = (string)$c['color'];
|
|
|
|
return [
|
|
'req' => $req,
|
|
'res' => $res,
|
|
'start' => [
|
|
'actionUrl' => (string)($res['STARTURL'] ?? ''),
|
|
'params' => $params,
|
|
'acceptCharset' => 'EUC-KR',
|
|
],
|
|
];
|
|
}
|
|
|
|
public function decryptReturn(string $returnParams): array
|
|
{
|
|
$c = $this->cfg->wiretransfer();
|
|
return $this->client->decryptReturnParams($returnParams, (string)$c['key'], (string)$c['iv']);
|
|
}
|
|
|
|
public function bill(GcPinOrder $order, string $tid): array
|
|
{
|
|
$c = $this->cfg->wiretransfer();
|
|
|
|
$req = [
|
|
'TXTYPE' => 'BILL',
|
|
'SERVICETYPE' => 'WIRETRANSFER',
|
|
'TID' => $tid,
|
|
// AUTH 금액과 반드시 동일
|
|
'AMOUNT' => (string)$order->pay_money,
|
|
];
|
|
|
|
$res = $this->client->call((string)$c['tx_url'], (string)$c['cpid'], $req, (string)$c['key'], (string)$c['iv']);
|
|
return ['req' => $req, 'res' => $res];
|
|
}
|
|
|
|
public function decryptNotiData(string $data): array
|
|
{
|
|
$c = $this->cfg->wiretransfer();
|
|
return $this->client->decryptReturnParams($data, (string)$c['key'], (string)$c['iv']);
|
|
}
|
|
|
|
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)) ?: '상품권';
|
|
}
|
|
|
|
public function cancel(
|
|
GcPinOrder $order,
|
|
string $tid,
|
|
?int $amount = null,
|
|
string $cancelType = 'C',
|
|
string $requester = '',
|
|
string $desc = ''
|
|
): array {
|
|
$c = $this->cfg->wiretransfer();
|
|
|
|
$amt = $amount ?? (int)$order->pay_money;
|
|
|
|
$req = [
|
|
'TXTYPE' => 'CANCEL',
|
|
'SERVICETYPE' => 'WIRETRANSFER',
|
|
'TID' => $tid,
|
|
'AMOUNT' => (string)$amt,
|
|
'CANCELTYPE' => $cancelType, // C:전체, P:부분
|
|
];
|
|
|
|
// optional
|
|
$requester = trim($requester);
|
|
$desc = $this->safeCancelDesc($desc);
|
|
|
|
if ($requester !== '') $req['CANCELREQUESTER'] = $requester;
|
|
if ($desc !== '') $req['CANCELDESC'] = $desc;
|
|
|
|
$res = $this->client->call((string)$c['tx_url'], (string)$c['cpid'], $req, (string)$c['key'], (string)$c['iv']);
|
|
return ['req' => $req, 'res' => $res];
|
|
}
|
|
|
|
private function safeCancelDesc(string $s): string
|
|
{
|
|
$s = str_replace(["&","'","\"","\\","<",">","|","\r","\n","," , "+"], " ", $s);
|
|
return trim(preg_replace('/\s+/', ' ', $s));
|
|
}
|
|
}
|