buildCustomData( $tenant, $package, array_merge( $options['metadata'] ?? [], $options['custom_data'] ?? [], array_filter([ 'success_url' => $options['success_url'] ?? null, 'return_url' => $options['return_url'] ?? null, ], static fn ($value) => $value !== null && $value !== '') ) ); return $this->createVariantCheckout((string) $package->lemonsqueezy_variant_id, $customData, $options + [ 'customer_email' => $options['customer_email'] ?? null, 'customer_name' => $options['customer_name'] ?? null, 'store_id' => $storeId, ]); } /** * @param array{success_url?: string|null, return_url?: string|null, discount_code?: string|null, customer_email?: string|null, customer_name?: string|null, store_id?: string|null} $options */ public function createVariantCheckout(string $variantId, array $customData, array $options = []): array { $storeId = $options['store_id'] ?? (string) config('lemonsqueezy.store_id'); $attributes = array_filter([ 'checkout_data' => array_filter([ 'custom' => $customData, 'email' => $options['customer_email'] ?? null, 'name' => $options['customer_name'] ?? null, 'discount_code' => $options['discount_code'] ?? null, ], static fn ($value) => $value !== null && $value !== ''), 'checkout_options' => [ 'embed' => true, ], 'product_options' => array_filter([ 'redirect_url' => $options['success_url'] ?? null, ], static fn ($value) => $value !== null && $value !== ''), 'test_mode' => (bool) config('lemonsqueezy.test_mode', false), ], static fn ($value) => $value !== null && $value !== ''); $payload = [ 'data' => [ 'type' => 'checkouts', 'attributes' => $attributes, 'relationships' => [ 'store' => [ 'data' => [ 'type' => 'stores', 'id' => $storeId, ], ], 'variant' => [ 'data' => [ 'type' => 'variants', 'id' => $variantId, ], ], ], ], ]; $response = $this->client->post('/checkouts', $payload); $checkoutUrl = Arr::get($response, 'data.attributes.url') ?? Arr::get($response, 'data.attributes.checkout_url') ?? Arr::get($response, 'data.url') ?? Arr::get($response, 'url'); if (! $checkoutUrl) { Log::warning('Lemon Squeezy checkout response missing url', ['response' => $response]); } return [ 'checkout_url' => $checkoutUrl, 'expires_at' => Arr::get($response, 'data.attributes.expires_at'), 'id' => Arr::get($response, 'data.id') ?? Arr::get($response, 'id'), ]; } /** * @param array $extra * @return array */ protected function buildCustomData(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; } }