All checks were successful
Deploy api / deploy (push) Successful in 22s
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
173 lines
5.1 KiB
PHP
173 lines
5.1 KiB
PHP
<?php
|
||
|
||
namespace App\Services\Wellnet;
|
||
|
||
use Illuminate\Support\Facades\Http;
|
||
use Illuminate\Support\Str;
|
||
use RuntimeException;
|
||
|
||
/**
|
||
* Wellnet クレジットAPIサービス(CAFIS外部インターフェース)
|
||
*/
|
||
class WellnetCreditService
|
||
{
|
||
private string $baseUrl;
|
||
private string $companyCode;
|
||
private string $authKey;
|
||
private int $timeout;
|
||
|
||
public function __construct()
|
||
{
|
||
$this->baseUrl = config('wellnet.credit_api.base_url');
|
||
$this->companyCode = config('wellnet.credit_api.company_code');
|
||
$this->authKey = config('wellnet.credit_api.auth_key');
|
||
$this->timeout = config('wellnet.credit_api.timeout', 120);
|
||
}
|
||
|
||
/**
|
||
* 与信照会要求(Authorize)
|
||
*
|
||
* @param string $memberNo 会員番号
|
||
* @param int $payAmount 決済金額
|
||
* @param int|null $cardNoSeq カード連番(未指定時はデフォルト使用)
|
||
* @return array レスポンスデータ
|
||
* @throws RuntimeException APIエラー時
|
||
*/
|
||
public function authorize(string $memberNo, int $payAmount, ?int $cardNoSeq = null): array
|
||
{
|
||
$payload = [
|
||
'requestId' => $this->generateRequestId(),
|
||
'companyCode' => $this->companyCode,
|
||
'authKey' => $this->authKey,
|
||
'memberNo' => $memberNo,
|
||
'payAmount' => $payAmount,
|
||
];
|
||
|
||
if ($cardNoSeq !== null) {
|
||
$payload['cardNoSeq'] = $cardNoSeq;
|
||
}
|
||
|
||
return $this->post('/api/authori', $payload);
|
||
}
|
||
|
||
/**
|
||
* 売上確定要求(Capture)
|
||
*
|
||
* @param string $paymentNumber 決済番号
|
||
* @return array レスポンスデータ
|
||
* @throws RuntimeException APIエラー時
|
||
*/
|
||
public function capture(string $paymentNumber): array
|
||
{
|
||
$payload = [
|
||
'requestId' => $this->generateRequestId(),
|
||
'companyCode' => $this->companyCode,
|
||
'authKey' => $this->authKey,
|
||
'paymentNumber' => $paymentNumber,
|
||
];
|
||
|
||
return $this->post('/api/definiteTanking', $payload);
|
||
}
|
||
|
||
/**
|
||
* 与信取消要求(全額取消)
|
||
*
|
||
* @param string $paymentNumber 決済番号
|
||
* @return array レスポンスデータ
|
||
* @throws RuntimeException APIエラー時
|
||
*/
|
||
public function cancelAuthorize(string $paymentNumber): array
|
||
{
|
||
$payload = [
|
||
'requestId' => $this->generateRequestId(),
|
||
'companyCode' => $this->companyCode,
|
||
'authKey' => $this->authKey,
|
||
'paymentNumber' => $paymentNumber,
|
||
];
|
||
|
||
try {
|
||
return $this->post('/api/cancelAuthori', $payload);
|
||
} catch (RuntimeException $e) {
|
||
if ((int) $e->getCode() === 404) {
|
||
return $this->post('/api/cancelPayment', $payload);
|
||
}
|
||
throw $e;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 差額返金要求(部分返金/全額返金)
|
||
*
|
||
* @param string $paymentNumber 決済番号
|
||
* @param int $afterRefundPayAmount 返金後の残額(全額返金時は0)
|
||
* @return array レスポンスデータ
|
||
* @throws RuntimeException APIエラー時
|
||
*/
|
||
public function refund(string $paymentNumber, int $afterRefundPayAmount): array
|
||
{
|
||
$payload = [
|
||
'requestId' => $this->generateRequestId(),
|
||
'companyCode' => $this->companyCode,
|
||
'authKey' => $this->authKey,
|
||
'paymentNumber' => $paymentNumber,
|
||
'afterRefundPayAmount' => $afterRefundPayAmount,
|
||
];
|
||
|
||
try {
|
||
return $this->post('/api/refund', $payload);
|
||
} catch (RuntimeException $e) {
|
||
if ((int) $e->getCode() === 404) {
|
||
return $this->post('/api/refundPayment', $payload);
|
||
}
|
||
throw $e;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* HTTP POST送信
|
||
*
|
||
* @param string $path APIパス
|
||
* @param array $payload リクエストボディ
|
||
* @return array レスポンスデータ
|
||
* @throws RuntimeException 通信エラー・APIエラー時
|
||
*/
|
||
private function post(string $path, array $payload): array
|
||
{
|
||
$url = rtrim($this->baseUrl, '/') . $path;
|
||
|
||
$response = Http::timeout($this->timeout)
|
||
->acceptJson()
|
||
->post($url, $payload);
|
||
|
||
if (!$response->successful()) {
|
||
$body = $response->json() ?? [];
|
||
$errorDesc = $body['errorDescription'] ?? $body['result'] ?? 'HTTP ' . $response->status();
|
||
throw new RuntimeException(
|
||
'クレジットAPIエラー: ' . $errorDesc,
|
||
$response->status()
|
||
);
|
||
}
|
||
|
||
$data = $response->json();
|
||
|
||
if (isset($data['result']) && $data['result'] !== 'SUCCESS') {
|
||
throw new RuntimeException(
|
||
'クレジットAPIエラー: ' . ($data['errorDescription'] ?? $data['result']),
|
||
400
|
||
);
|
||
}
|
||
|
||
return $data;
|
||
}
|
||
|
||
/**
|
||
* リクエストID自動採番
|
||
*
|
||
* @return string 一意のリクエストID
|
||
*/
|
||
private function generateRequestId(): string
|
||
{
|
||
return 'REQ-' . date('YmdHis') . '-' . Str::random(6);
|
||
}
|
||
}
|