Initialer Laravel Commit für BetiX
This commit is contained in:
213
app/Services/NowPaymentsClient.php
Normal file
213
app/Services/NowPaymentsClient.php
Normal file
@@ -0,0 +1,213 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class NowPaymentsClient
|
||||
{
|
||||
private string $baseUrl;
|
||||
private string $apiKey;
|
||||
private string $jwtToken; // Added for operations that might need JWT auth (payouts)
|
||||
private float $timeout;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$cfg = config('services.nowpayments');
|
||||
// Prefer DB-stored API key from admin settings over config/env
|
||||
$dbSettings = \App\Models\AppSetting::get('payments.nowpayments', []);
|
||||
$this->baseUrl = rtrim((string) ($cfg['base_url'] ?? 'https://api.nowpayments.io/v1'), '/');
|
||||
$this->apiKey = (string) ($dbSettings['api_key'] ?? $cfg['api_key'] ?? '');
|
||||
$this->jwtToken = (string) ($dbSettings['jwt_token'] ?? $cfg['jwt_token'] ?? '');
|
||||
$this->timeout = (float) ($cfg['timeout'] ?? 10.0);
|
||||
}
|
||||
|
||||
private function client(bool $useJwt = false)
|
||||
{
|
||||
$headers = [
|
||||
'x-api-key' => $this->apiKey,
|
||||
'Accept' => 'application/json',
|
||||
'Content-Type' => 'application/json',
|
||||
];
|
||||
|
||||
if ($useJwt && $this->jwtToken) {
|
||||
$headers['Authorization'] = 'Bearer ' . $this->jwtToken;
|
||||
}
|
||||
|
||||
return Http::timeout($this->timeout)
|
||||
->retry(2, 150, throw: false)
|
||||
->baseUrl($this->baseUrl)
|
||||
->withHeaders($headers);
|
||||
}
|
||||
|
||||
public function listCurrencies(): array
|
||||
{
|
||||
$res = $this->client()->get('/currencies');
|
||||
if (!$res->ok()) {
|
||||
Log::warning('NOWPayments listCurrencies failed', ['status' => $res->status(), 'body' => $res->body()]);
|
||||
return [];
|
||||
}
|
||||
$json = $res->json();
|
||||
return is_array($json) ? ($json['currencies'] ?? $json) : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get available checked currencies (merchant/coins)
|
||||
* https://api.nowpayments.io/v1/merchant/coins
|
||||
*/
|
||||
public function getAvailableCoins(): array
|
||||
{
|
||||
$res = $this->client()->get('/merchant/coins');
|
||||
if (!$res->ok()) {
|
||||
Log::warning('NOWPayments getAvailableCoins failed', ['status' => $res->status(), 'body' => $res->body()]);
|
||||
return [];
|
||||
}
|
||||
$json = $res->json();
|
||||
return is_array($json) ? ($json['selectedCurrencies'] ?? $json) : [];
|
||||
}
|
||||
|
||||
public function estimate(float $priceAmount, string $priceCurrency, string $payCurrency): ?array
|
||||
{
|
||||
$payload = [
|
||||
'amount' => $priceAmount,
|
||||
'currency_from' => strtoupper($priceCurrency),
|
||||
'currency_to' => strtoupper($payCurrency),
|
||||
];
|
||||
$res = $this->client()->post('/estimate', $payload);
|
||||
if (!$res->ok()) {
|
||||
Log::warning('NOWPayments estimate failed', ['status' => $res->status(), 'body' => $res->body(), 'payload' => $payload]);
|
||||
return null;
|
||||
}
|
||||
return $res->json();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the minimum payment amount
|
||||
* https://api.nowpayments.io/v1/min-amount?currency_from=eth¤cy_to=trx
|
||||
*/
|
||||
public function getMinAmount(string $currencyFrom, string $currencyTo, ?string $fiatEquivalent = null, bool $isFixedRate = false, bool $isFeePaidByUser = false): ?array
|
||||
{
|
||||
$query = [
|
||||
'currency_from' => strtolower($currencyFrom),
|
||||
'currency_to' => strtolower($currencyTo),
|
||||
'is_fixed_rate' => $isFixedRate ? 'True' : 'False',
|
||||
'is_fee_paid_by_user' => $isFeePaidByUser ? 'True' : 'False',
|
||||
];
|
||||
|
||||
if ($fiatEquivalent) {
|
||||
$query['fiat_equivalent'] = strtolower($fiatEquivalent);
|
||||
}
|
||||
|
||||
$res = $this->client()->get('/min-amount', $query);
|
||||
if (!$res->ok()) {
|
||||
Log::warning('NOWPayments getMinAmount failed', ['status' => $res->status(), 'body' => $res->body(), 'query' => $query]);
|
||||
return null;
|
||||
}
|
||||
return $res->json();
|
||||
}
|
||||
|
||||
public function createInvoice(array $data): ?array
|
||||
{
|
||||
// Expected keys: price_amount, price_currency, pay_currency, order_id, order_description, success_url, cancel_url, ipn_callback_url
|
||||
$res = $this->client()->post('/invoice', $data);
|
||||
if (!$res->ok()) {
|
||||
Log::error('NOWPayments createInvoice failed', ['status' => $res->status(), 'body' => $res->body(), 'data' => $data]);
|
||||
return null;
|
||||
}
|
||||
return $res->json();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get payment status
|
||||
* https://api.nowpayments.io/v1/payment/:payment_id
|
||||
*/
|
||||
public function getPayment(string $paymentId): ?array
|
||||
{
|
||||
$res = $this->client()->get('/payment/' . urlencode($paymentId));
|
||||
if (!$res->ok()) {
|
||||
Log::warning('NOWPayments getPayment failed', ['status' => $res->status(), 'body' => $res->body(), 'payment_id' => $paymentId]);
|
||||
return null;
|
||||
}
|
||||
return $res->json();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of payments
|
||||
* https://api.nowpayments.io/v1/payment/?limit=10&page=0&sortBy=created_at&orderBy=asc&dateFrom=2020-01-01&dateTo=2021-01-01&invoiceId=6200264890
|
||||
*/
|
||||
public function listPayments(array $params = []): ?array
|
||||
{
|
||||
$res = $this->client()->get('/payment/', $params);
|
||||
if (!$res->ok()) {
|
||||
Log::warning('NOWPayments listPayments failed', ['status' => $res->status(), 'body' => $res->body(), 'params' => $params]);
|
||||
return null;
|
||||
}
|
||||
return $res->json();
|
||||
}
|
||||
|
||||
public function getInvoice(string $invoiceId): ?array
|
||||
{
|
||||
$res = $this->client()->get('/invoice/' . urlencode($invoiceId));
|
||||
if (!$res->ok()) {
|
||||
Log::warning('NOWPayments getInvoice failed', ['status' => $res->status(), 'body' => $res->body(), 'invoice_id' => $invoiceId]);
|
||||
return null;
|
||||
}
|
||||
return $res->json();
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate address
|
||||
* https://api.nowpayments.io/v1/payout/validate-address
|
||||
*/
|
||||
public function validateAddress(string $currency, string $address, ?string $extraId = null): ?array
|
||||
{
|
||||
$payload = [
|
||||
'currency' => strtolower($currency),
|
||||
'address' => $address,
|
||||
];
|
||||
if ($extraId !== null) {
|
||||
$payload['extra_id'] = $extraId;
|
||||
}
|
||||
|
||||
// According to NOWPayments docs, this uses the standard client
|
||||
$res = $this->client()->post('/payout/validate-address', $payload);
|
||||
if (!$res->ok()) {
|
||||
Log::warning('NOWPayments validateAddress failed', ['status' => $res->status(), 'body' => $res->body(), 'payload' => $payload]);
|
||||
return null;
|
||||
}
|
||||
return $res->json();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify payout
|
||||
* https://api.nowpayments.io/v1/payout/:batch-withdrawal-id/verify
|
||||
*/
|
||||
public function verifyPayout(string $batchWithdrawalId, string $verificationCode): ?array
|
||||
{
|
||||
$payload = [
|
||||
'verification_code' => $verificationCode
|
||||
];
|
||||
|
||||
$res = $this->client(true)->post('/payout/' . urlencode($batchWithdrawalId) . '/verify', $payload);
|
||||
if (!$res->ok()) {
|
||||
Log::warning('NOWPayments verifyPayout failed', ['status' => $res->status(), 'body' => $res->body(), 'batch_id' => $batchWithdrawalId]);
|
||||
return null;
|
||||
}
|
||||
return $res->json();
|
||||
}
|
||||
|
||||
/**
|
||||
* List of payouts
|
||||
* https://api.nowpayments.io/v1/payout
|
||||
*/
|
||||
public function listPayouts(array $params = []): ?array
|
||||
{
|
||||
$res = $this->client(true)->get('/payout', $params);
|
||||
if (!$res->ok()) {
|
||||
Log::warning('NOWPayments listPayouts failed', ['status' => $res->status(), 'body' => $res->body(), 'params' => $params]);
|
||||
return null;
|
||||
}
|
||||
return $res->json();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user