classify admin

This commit is contained in:
Husanjonazamov
2026-02-24 12:52:01 +05:00
commit e0f1989655
769 changed files with 1263008 additions and 0 deletions

View File

@@ -0,0 +1,251 @@
<?php
namespace App\Services\Payment;
use Exception;
use GuzzleHttp\Client;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Throwable;
class PayPalPayment implements PaymentInterface
{
private string $clientId;
private string $secretKey;
private string $currencyCode;
private string $paymentmode;
private Client $http;
private string $baseUrl;
public function __construct($clientId, $secretKey, $currencyCode, $paymentmode)
{
$this->clientId = $clientId;
$this->secretKey = $secretKey;
$this->currencyCode = $currencyCode;
$this->paymentmode = $paymentmode;
$this->http = new Client([
'base_uri' => ($paymentmode == "UAT") ? 'https://api.sandbox.paypal.com' : 'https://api-m.paypal.com',
'timeout' => 30,
]);
$this->baseUrl = ($paymentmode == "UAT")
? 'https://api.sandbox.paypal.com'
: 'https://api.paypal.com';
}
private function generateAccessToken(): string
{
$response = $this->http->post('/v1/oauth2/token', [
'auth' => [$this->clientId, $this->secretKey],
'form_params' => ['grant_type' => 'client_credentials'],
'headers' => [
'Accept' => 'application/json',
'Accept-Language' => 'en_US'
]
]);
$data = json_decode((string)$response->getBody(), true);
return $data['access_token'] ?? throw new Exception("Unable to generate PayPal token");
}
/**
* Create a PayPal Order (Payment Intent equivalent)
*/
public function createPaymentIntent($amount, $customMetaData)
{
$amount = $this->minimumAmountValidation($this->currencyCode, $amount);
$accessToken = $this->generateAccessToken();
if($customMetaData['platform_type'] == 'app') {
$callbackUrl = route('paypal.success') ;
}else{
$callbackUrl = route('paypal.success.web');
}
$metaData = 't' . '-' . $customMetaData['payment_transaction_id'] . '-' . 'p' . '-' . $customMetaData['package_id'];
$response = $this->http->post('/v2/checkout/orders', [
'headers' => [
'Authorization' => "Bearer {$accessToken}",
'Content-Type' => 'application/json'
],
'json' => [
'intent' => 'CAPTURE',
'purchase_units' => [[
'amount' => [
'currency_code' => $this->currencyCode,
'value' => number_format($amount, 2, '.', '')
],
'custom_id' => $metaData,
'description' => $customMetaData['description'] ?? null,
]],
'application_context' => [
'return_url' => $callbackUrl,
'cancel_url' => $callbackUrl,
]
]
]);
$data = json_decode((string)$response->getBody(), true);
return $data;
}
/**
* ✅ Matches PaymentInterface (like Stripe)
*/
public function createAndFormatPaymentIntent($amount, $customMetaData): array
{
$order = $this->createPaymentIntent($amount, $customMetaData);
// Extract approve link from PayPal response
$approveLink = null;
if (isset($order['links']) && is_array($order['links'])) {
foreach ($order['links'] as $link) {
if ($link['rel'] === 'approve') {
$approveLink = $link['href'];
break;
}
}
}
$formatted = $this->formatPaymentIntent(
$order['id'],
$amount,
$this->currencyCode,
$order['status'] ?? 'CREATED',
$customMetaData,
$order
);
// Add approval link for frontend
$formatted['approval_url'] = $approveLink;
return $formatted;
}
/**
* ✅ Retrieve order details (similar to Stripes retrievePaymentIntent)
*/
public function retrievePaymentIntent($paymentId): array
{
$accessToken = $this->generateAccessToken();
$response = $this->http->get("/v2/checkout/orders/{$paymentId}", [
'headers' => [
'Authorization' => "Bearer {$accessToken}",
'Content-Type' => 'application/json'
]
]);
$data = json_decode((string)$response->getBody(), true);
return $this->formatPaymentIntent(
$data['id'],
$data['purchase_units'][0]['amount']['value'] ?? 0,
$data['purchase_units'][0]['amount']['currency_code'] ?? $this->currencyCode,
$data['status'],
[],
$data
);
}
public function capturePayment($orderId): array
{
$accessToken = $this->generateAccessToken();
$response = $this->http->post("/v2/checkout/orders/{$orderId}/capture", [
'headers' => [
'Authorization' => "Bearer {$accessToken}",
'Content-Type' => 'application/json'
]
]);
$data = json_decode((string)$response->getBody(), true);
return $this->formatPaymentIntent(
$data['id'] ?? $orderId,
$data['purchase_units'][0]['payments']['captures'][0]['amount']['value'] ?? 0,
$data['purchase_units'][0]['payments']['captures'][0]['amount']['currency_code'] ?? $this->currencyCode,
$data['status'] ?? 'FAILED',
[],
$data
);
}
public function refund($captureId, $amount, $currency = null): array
{
$accessToken = $this->generateAccessToken();
$currency = $currency ?? $this->currencyCode;
$response = $this->http->post("/v2/payments/captures/{$captureId}/refund", [
'headers' => [
'Authorization' => "Bearer {$accessToken}",
'Content-Type' => 'application/json'
],
'json' => [
'amount' => [
'value' => number_format($amount, 2, '.', ''),
'currency_code' => $currency
]
]
]);
return json_decode((string)$response->getBody(), true);
}
public function formatPaymentIntent($id, $amount, $currency, $status, $metadata, $paymentIntent): array
{
return [
'id' => $id,
'amount' => $amount,
'currency' => $currency,
'metadata' => $metadata,
'status' => match (strtolower($status)) {
"completed" => "succeed",
"approved" => "pending",
"created" => "pending",
default => "failed",
},
'payment_gateway_response' => $paymentIntent
];
}
public function minimumAmountValidation($currency, $amount)
{
$minimumAmount = 0.50;
return max($amount, $minimumAmount);
}
public function verifyWebhookSignature(array $headers, string $payload, string $webhookId): bool
{
try {
$accessToken = $this->generateAccessToken();
if($this->baseUrl == 'https://api.sandbox.paypal.com'){
return true;
}
$verification = Http::withToken($accessToken)
->post($this->baseUrl . '/v1/notifications/verify-webhook-signature', [
'auth_algo' => $headers['paypal-auth-algo'][0] ?? '',
'cert_url' => $headers['paypal-cert-url'][0] ?? '',
'transmission_id' => $headers['paypal-transmission-id'][0] ?? '',
'transmission_sig' => $headers['paypal-transmission-sig'][0] ?? '',
'transmission_time' => $headers['paypal-transmission-time'][0] ?? '',
'webhook_id' => $webhookId,
'webhook_event' => json_decode($payload, true),
]);
if (!$verification->successful()) {
Log::error('PayPal verifyWebhookSignature failed: ' . $verification->body());
return false;
}
return ($verification->json()['verification_status'] ?? '') === 'SUCCESS';
} catch (Throwable $e) {
Log::error('PayPal verifyWebhookSignature exception: ' . $e->getMessage());
return false;
}
}
}