84 lines
2.5 KiB
PHP
84 lines
2.5 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Payment;
|
|
|
|
use App\Contracts\PaymentGateway;
|
|
use App\Data\PaymentResponseDTO;
|
|
use App\Data\StripeLineItemDTO;
|
|
use App\Data\StripeSessionDataDTO;
|
|
use App\Enums\PaymentModes;
|
|
use App\Enums\StripeCurrency;
|
|
use App\Enums\StripePaymentMode;
|
|
use App\Models\Order;
|
|
use Exception;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Stripe\Checkout\Session;
|
|
use Stripe\Stripe;
|
|
|
|
class StripePaymentGateway implements PaymentGateway
|
|
{
|
|
public function __construct()
|
|
{
|
|
Stripe::setApiKey(config('services.stripe.secret'));
|
|
}
|
|
|
|
public function charge(Order $order): PaymentResponseDTO
|
|
{
|
|
$cart = $order->cart()->withProducts()->first();
|
|
|
|
$totalAmount = 0;
|
|
$lineItems = [];
|
|
|
|
foreach ($cart->products as $product) {
|
|
$priceInCents = (int) ($product->pivot->price * 100);
|
|
|
|
$totalAmount += ($priceInCents * $product->pivot->quantity);
|
|
|
|
$lineItems[] = new StripeLineItemDTO(
|
|
currency: StripeCurrency::INR,
|
|
price: $priceInCents,
|
|
productName: $product->title,
|
|
productDescription: $product->description,
|
|
quantity: $product->pivot->quantity,
|
|
);
|
|
}
|
|
|
|
$currency = StripeCurrency::INR->value;
|
|
|
|
try {
|
|
$data = new StripeSessionDataDTO(
|
|
lineItems: $lineItems,
|
|
mode: StripePaymentMode::Payment,
|
|
successUrl: config('app.frontend_url').'/order/payment/success?session_id={CHECKOUT_SESSION_ID}"',
|
|
cancelUrl: config('app.frontend_url').'/order/payment/cancel',
|
|
);
|
|
$session = Session::create($data->toArray());
|
|
|
|
// add stripe session to order
|
|
$order->stripeSession()->create(
|
|
[
|
|
'session_id' => $session->id,
|
|
]
|
|
);
|
|
|
|
return PaymentResponseDTO::success(
|
|
transactionId: $session->id,
|
|
amount: $totalAmount,
|
|
currency: $currency,
|
|
method: PaymentModes::StripeCheckout,
|
|
redirectUrl: $session->url,
|
|
);
|
|
|
|
} catch (Exception $e) {
|
|
Log::error('Stripe Checkout session cannot be created.', ['error' => $e->getMessage()]);
|
|
|
|
return PaymentResponseDTO::failure(
|
|
amount: $totalAmount,
|
|
currency: $currency,
|
|
method: PaymentModes::StripeCheckout,
|
|
errorMessage: 'Payment gateway unavailable. Please try again.'
|
|
);
|
|
}
|
|
}
|
|
}
|