Files
fotospiel-app/app/Services/Paddle/PaddleCheckoutService.php
Codex Agent 5f521d055f Änderungen (relevant):
- Add‑on Checkout auf Transactions + Transaction‑ID speichern: app/Services/Addons/EventAddonCheckoutService.php
  - Paket/Marketing Checkout auf Transactions: app/Services/Paddle/PaddleCheckoutService.php
  - Gift‑Voucher Checkout: Customer anlegen/finden + Transactions: app/Services/GiftVouchers/
    GiftVoucherCheckoutService.php
  - Tests aktualisiert: tests/Feature/Tenant/EventAddonCheckoutTest.php, tests/Unit/PaddleCheckoutServiceTest.php,
tests/Unit/GiftVoucherCheckoutServiceTest.php
2025-12-29 18:04:28 +01:00

89 lines
2.6 KiB
PHP

<?php
namespace App\Services\Paddle;
use App\Models\Package;
use App\Models\Tenant;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Log;
class PaddleCheckoutService
{
public function __construct(
private readonly PaddleClient $client,
private readonly PaddleCustomerService $customers,
) {}
/**
* @param array{success_url?: string|null, return_url?: string|null, discount_id?: string|null, metadata?: array, custom_data?: array} $options
*/
public function createCheckout(Tenant $tenant, Package $package, array $options = []): array
{
$customerId = $this->customers->ensureCustomerId($tenant);
$customData = $this->buildMetadata(
$tenant,
$package,
array_merge($options['metadata'] ?? [], $options['custom_data'] ?? [])
);
$payload = [
'customer_id' => $customerId,
'items' => [
[
'price_id' => $package->paddle_price_id,
'quantity' => 1,
],
],
'custom_data' => $customData,
];
if (! empty($options['discount_id'])) {
$payload['discount_id'] = $options['discount_id'];
}
$response = $this->client->post('/transactions', $payload);
$checkoutUrl = Arr::get($response, 'data.checkout.url')
?? Arr::get($response, 'checkout.url')
?? Arr::get($response, 'data.url')
?? Arr::get($response, 'url');
if (! $checkoutUrl) {
Log::warning('Paddle checkout response missing url', ['response' => $response]);
}
return [
'checkout_url' => $checkoutUrl,
'expires_at' => Arr::get($response, 'data.checkout.expires_at')
?? Arr::get($response, 'data.expires_at')
?? Arr::get($response, 'expires_at'),
'id' => Arr::get($response, 'data.id') ?? Arr::get($response, 'id'),
];
}
/**
* @param array<string, mixed> $extra
* @return array<string, string>
*/
protected function buildMetadata(Tenant $tenant, Package $package, array $extra = []): array
{
$metadata = [
'tenant_id' => (string) $tenant->id,
'package_id' => (string) $package->id,
];
foreach ($extra as $key => $value) {
if (! is_string($key)) {
continue;
}
if (is_scalar($value) || (is_object($value) && method_exists($value, '__toString'))) {
$metadata[$key] = (string) $value;
}
}
return $metadata;
}
}