Add PayPal checkout provider

This commit is contained in:
Codex Agent
2026-02-04 12:18:14 +01:00
parent 56a39d0535
commit fc5dfb272c
33 changed files with 1586 additions and 571 deletions

View File

@@ -69,7 +69,8 @@ class CheckoutAssignmentService
?? ($metadata['lemonsqueezy_order_id'] ?? $metadata['lemonsqueezy_checkout_id'] ? CheckoutSession::PROVIDER_LEMONSQUEEZY : null)
?? CheckoutSession::PROVIDER_FREE;
$totals = $this->resolveLemonSqueezyTotals($session, $options['payload'] ?? []);
$provider = $providerName ?: $session->provider;
$totals = $this->resolveProviderTotals($session, $options['payload'] ?? [], $provider);
$currency = $totals['currency'] ?? $session->currency ?? $package->currency ?? 'EUR';
$price = array_key_exists('total', $totals) ? $totals['total'] : (float) $session->amount_total;
@@ -88,7 +89,8 @@ class CheckoutAssignmentService
'payload' => $options['payload'] ?? null,
'checkout_session_id' => $session->id,
'consents' => $consents ?: null,
'lemonsqueezy_totals' => $totals !== [] ? $totals : null,
'lemonsqueezy_totals' => $provider === CheckoutSession::PROVIDER_LEMONSQUEEZY && $totals !== [] ? $totals : null,
'paypal_totals' => $provider === CheckoutSession::PROVIDER_PAYPAL && $totals !== [] ? $totals : null,
'currency' => $currency,
], static fn ($value) => $value !== null && $value !== ''),
]
@@ -219,6 +221,19 @@ class CheckoutAssignmentService
])->save();
}
/**
* @param array<string, mixed> $payload
* @return array{currency?: string, subtotal?: float, discount?: float, tax?: float, total?: float}
*/
protected function resolveProviderTotals(CheckoutSession $session, array $payload, ?string $provider): array
{
if ($provider === CheckoutSession::PROVIDER_PAYPAL) {
return $this->resolvePayPalTotals($session, $payload);
}
return $this->resolveLemonSqueezyTotals($session, $payload);
}
/**
* @param array<string, mixed> $payload
* @return array{currency?: string, subtotal?: float, discount?: float, tax?: float, total?: float}
@@ -252,6 +267,34 @@ class CheckoutAssignmentService
], static fn ($value) => $value !== null);
}
/**
* @param array<string, mixed> $payload
* @return array{currency?: string, total?: float}
*/
protected function resolvePayPalTotals(CheckoutSession $session, array $payload): array
{
$metadataTotals = $session->provider_metadata['paypal_totals'] ?? null;
if (is_array($metadataTotals) && $metadataTotals !== []) {
return $metadataTotals;
}
$amount = Arr::get($payload, 'purchase_units.0.payments.captures.0.amount')
?? Arr::get($payload, 'purchase_units.0.amount');
if (! is_array($amount)) {
return [];
}
$currency = Arr::get($amount, 'currency_code');
$total = Arr::get($amount, 'value');
return array_filter([
'currency' => is_string($currency) ? strtoupper($currency) : null,
'total' => is_numeric($total) ? (float) $total : null,
], static fn ($value) => $value !== null);
}
protected function convertMinorAmount(mixed $value): ?float
{
if ($value === null || $value === '') {