customers->ensureCustomerId($tenant); $successUrl = $options['success_url'] ?? route('marketing.success', ['packageId' => $package->id]); $returnUrl = $options['return_url'] ?? route('packages', ['highlight' => $package->slug]); $metadata = $this->buildMetadata($tenant, $package, $options['metadata'] ?? []); $payload = [ 'customer_id' => $customerId, 'items' => [ [ 'price_id' => $package->paddle_price_id, 'quantity' => 1, ], ], 'metadata' => $metadata, 'success_url' => $successUrl, 'cancel_url' => $returnUrl, ]; if ($tenant->contact_email) { $payload['customer_email'] = $tenant->contact_email; } $response = $this->client->post('/checkout/links', $payload); $checkoutUrl = 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.expires_at') ?? Arr::get($response, 'expires_at'), 'id' => Arr::get($response, 'data.id') ?? Arr::get($response, 'id'), ]; } /** * @param array $extra * @return array */ 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; } }