add controllers, servoices
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Payments;
|
||||
|
||||
use App\Models\Payment;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class PaypalPaymentService
|
||||
{
|
||||
public function getRedirectUrl(): string
|
||||
{
|
||||
return (string) (config('services.paypal.payment_url')
|
||||
?: env('PAYPAL_PAYMENT_URL')
|
||||
?: 'https://www.paypal.com/ncp/payment/87FJL3EV8C7NE');
|
||||
}
|
||||
|
||||
public function createPayment(int $paymentId): array
|
||||
{
|
||||
$payment = Payment::query()->find($paymentId);
|
||||
if (!$payment) {
|
||||
throw new \RuntimeException('Payment not found.');
|
||||
}
|
||||
|
||||
if (!$this->sdkAvailable()) {
|
||||
return [
|
||||
'redirect_url' => $this->getRedirectUrl(),
|
||||
'mode' => 'hosted',
|
||||
'message' => 'PayPal SDK not installed; using hosted redirect URL.',
|
||||
];
|
||||
}
|
||||
|
||||
try {
|
||||
$apiContext = $this->buildApiContext();
|
||||
|
||||
$payer = new \PayPal\Api\Payer();
|
||||
$payer->setPaymentMethod('paypal');
|
||||
|
||||
$amount = new \PayPal\Api\Amount();
|
||||
$amount->setCurrency('USD')->setTotal($payment->balance ?? $payment->total_amount ?? 0);
|
||||
|
||||
$transaction = new \PayPal\Api\Transaction();
|
||||
$transaction->setAmount($amount)
|
||||
->setDescription('Payment for school fees')
|
||||
->setInvoiceNumber(uniqid('inv_', true));
|
||||
|
||||
$paypalPayment = new \PayPal\Api\Payment();
|
||||
$paypalPayment->setIntent('sale')
|
||||
->setPayer($payer)
|
||||
->setTransactions([$transaction]);
|
||||
|
||||
$redirectUrls = new \PayPal\Api\RedirectUrls();
|
||||
$redirectUrls->setReturnUrl(url('/api/v1/finance/paypal/execute'))
|
||||
->setCancelUrl(url('/api/v1/finance/paypal/cancel'));
|
||||
|
||||
$paypalPayment->setRedirectUrls($redirectUrls);
|
||||
$paypalPayment->create($apiContext);
|
||||
|
||||
session()->put('paypalPaymentId', $paypalPayment->getId());
|
||||
session()->put('paymentId', $paymentId);
|
||||
|
||||
return [
|
||||
'redirect_url' => $paypalPayment->getApprovalLink(),
|
||||
'mode' => 'sdk',
|
||||
];
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('PayPal create payment failed: ' . $e->getMessage());
|
||||
throw new \RuntimeException('Unable to create PayPal payment.');
|
||||
}
|
||||
}
|
||||
|
||||
public function executePayment(string $payerId, ?string $paypalPaymentId = null): void
|
||||
{
|
||||
if (!$this->sdkAvailable()) {
|
||||
throw new \RuntimeException('PayPal SDK not installed.');
|
||||
}
|
||||
|
||||
$paymentId = $paypalPaymentId ?: (string) session()->get('paypalPaymentId');
|
||||
if (!$paymentId) {
|
||||
throw new \RuntimeException('Missing PayPal payment ID.');
|
||||
}
|
||||
|
||||
$apiContext = $this->buildApiContext();
|
||||
$payment = \PayPal\Api\Payment::get($paymentId, $apiContext);
|
||||
$execution = new \PayPal\Api\PaymentExecution();
|
||||
$execution->setPayerId($payerId);
|
||||
|
||||
$payment->execute($execution, $apiContext);
|
||||
|
||||
$internalPaymentId = (int) session()->get('paymentId');
|
||||
if ($internalPaymentId) {
|
||||
Payment::query()->whereKey($internalPaymentId)->update(['status' => 'Completed']);
|
||||
}
|
||||
}
|
||||
|
||||
public function cancelPayment(): void
|
||||
{
|
||||
// no-op (client handles redirect)
|
||||
}
|
||||
|
||||
private function sdkAvailable(): bool
|
||||
{
|
||||
return class_exists(\PayPal\Rest\ApiContext::class)
|
||||
&& class_exists(\PayPal\Auth\OAuthTokenCredential::class);
|
||||
}
|
||||
|
||||
private function buildApiContext(): \PayPal\Rest\ApiContext
|
||||
{
|
||||
$clientId = (string) (config('services.paypal.client_id') ?: env('PAYPAL_CLIENT_ID'));
|
||||
$secret = (string) (config('services.paypal.secret') ?: env('PAYPAL_SECRET'));
|
||||
$mode = (string) (config('services.paypal.mode') ?: env('PAYPAL_MODE') ?: 'sandbox');
|
||||
|
||||
$apiContext = new \PayPal\Rest\ApiContext(
|
||||
new \PayPal\Auth\OAuthTokenCredential($clientId, $secret)
|
||||
);
|
||||
|
||||
$apiContext->setConfig([
|
||||
'mode' => $mode,
|
||||
'http.headers' => ['Connection' => 'Close'],
|
||||
]);
|
||||
|
||||
return $apiContext;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user