feat: 增强玩家 API,新增 locale 和时间字段,更新钱包 API 以支持可用余额计算,添加错误码与多语言支持
This commit is contained in:
150
app/Services/Wallet/HttpMainSiteWalletGateway.php
Normal file
150
app/Services/Wallet/HttpMainSiteWalletGateway.php
Normal file
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Wallet;
|
||||
|
||||
use App\Models\Player;
|
||||
use GuzzleHttp\Exception\ConnectException;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
/**
|
||||
* 通过 HTTP 调用主站钱包 API(路径见 config lottery.main_site.wallet_*_path)。
|
||||
*/
|
||||
final class HttpMainSiteWalletGateway implements MainSiteWalletGateway
|
||||
{
|
||||
public function debitMainForLotteryDeposit(
|
||||
Player $player,
|
||||
string $currencyCode,
|
||||
int $amountMinor,
|
||||
string $idempotentKey,
|
||||
): MainSiteWalletResult {
|
||||
return $this->post(
|
||||
(string) config('lottery.main_site.wallet_debit_path'),
|
||||
$player,
|
||||
$currencyCode,
|
||||
$amountMinor,
|
||||
$idempotentKey,
|
||||
);
|
||||
}
|
||||
|
||||
public function creditMainForLotteryWithdraw(
|
||||
Player $player,
|
||||
string $currencyCode,
|
||||
int $amountMinor,
|
||||
string $idempotentKey,
|
||||
): MainSiteWalletResult {
|
||||
return $this->post(
|
||||
(string) config('lottery.main_site.wallet_credit_path'),
|
||||
$player,
|
||||
$currencyCode,
|
||||
$amountMinor,
|
||||
$idempotentKey,
|
||||
);
|
||||
}
|
||||
|
||||
private function post(
|
||||
string $path,
|
||||
Player $player,
|
||||
string $currencyCode,
|
||||
int $amountMinor,
|
||||
string $idempotentKey,
|
||||
): MainSiteWalletResult {
|
||||
$base = rtrim((string) config('lottery.main_site.wallet_api_url'), '/');
|
||||
$url = $base.'/'.ltrim($path, '/');
|
||||
$timeout = (int) config('lottery.main_site.wallet_timeout', 10);
|
||||
$apiKey = config('lottery.main_site.wallet_api_key');
|
||||
|
||||
$requestBody = [
|
||||
'site_code' => $player->site_code,
|
||||
'site_player_id' => $player->site_player_id,
|
||||
'player_id' => $player->id,
|
||||
'currency_code' => $currencyCode,
|
||||
'amount_minor' => $amountMinor,
|
||||
'idempotent_key' => $idempotentKey,
|
||||
];
|
||||
|
||||
$requestSnapshot = array_merge($requestBody, [
|
||||
'_meta' => [
|
||||
'method' => 'POST',
|
||||
'path' => '/'.ltrim($path, '/'),
|
||||
],
|
||||
]);
|
||||
|
||||
$headers = [];
|
||||
if (is_string($apiKey) && $apiKey !== '') {
|
||||
$headers['Authorization'] = 'Bearer '.$apiKey;
|
||||
}
|
||||
|
||||
try {
|
||||
$response = Http::withHeaders($headers)
|
||||
->timeout($timeout)
|
||||
->acceptJson()
|
||||
->asJson()
|
||||
->post($url, $requestBody);
|
||||
} catch (\Throwable $e) {
|
||||
return MainSiteWalletResult::failure(
|
||||
$e->getMessage(),
|
||||
null,
|
||||
self::isUncertainTransportFailure($e),
|
||||
$requestSnapshot,
|
||||
);
|
||||
}
|
||||
|
||||
$payload = $response->json();
|
||||
if (! is_array($payload)) {
|
||||
$payload = ['raw' => $response->body()];
|
||||
}
|
||||
|
||||
$status = $response->status();
|
||||
if ($status === 408 || $status === 504) {
|
||||
return MainSiteWalletResult::failure(
|
||||
'HTTP '.$status,
|
||||
$payload,
|
||||
true,
|
||||
$requestSnapshot,
|
||||
);
|
||||
}
|
||||
|
||||
if (! $response->successful()) {
|
||||
return MainSiteWalletResult::failure(
|
||||
is_string(data_get($payload, 'message'))
|
||||
? (string) data_get($payload, 'message')
|
||||
: ('HTTP '.$status),
|
||||
$payload,
|
||||
false,
|
||||
$requestSnapshot,
|
||||
);
|
||||
}
|
||||
|
||||
$ok = (bool) data_get($payload, 'success', true);
|
||||
if (! $ok) {
|
||||
return MainSiteWalletResult::failure(
|
||||
is_string(data_get($payload, 'message'))
|
||||
? (string) data_get($payload, 'message')
|
||||
: 'main_site_rejected',
|
||||
$payload,
|
||||
false,
|
||||
$requestSnapshot,
|
||||
);
|
||||
}
|
||||
|
||||
$ref = data_get($payload, 'external_ref_no')
|
||||
?? data_get($payload, 'data.external_ref_no')
|
||||
?? data_get($payload, 'ref');
|
||||
|
||||
return MainSiteWalletResult::success(is_string($ref) ? $ref : null, $payload, $requestSnapshot);
|
||||
}
|
||||
|
||||
private static function isUncertainTransportFailure(\Throwable $e): bool
|
||||
{
|
||||
if ($e instanceof ConnectException) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$msg = strtolower($e->getMessage());
|
||||
|
||||
return str_contains($msg, 'curl error 28')
|
||||
|| str_contains($msg, 'connection timed out')
|
||||
|| str_contains($msg, 'timed out')
|
||||
|| str_contains($msg, 'operation timed out');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user