billable->{AnikeenId::getUserIdField()} ?? null; if (empty($userId)) { throw new InvalidArgumentException(sprintf('The billable has no Anikeen ID in [%s].', AnikeenId::getUserIdField())); } return (string) $userId; } /** * Create a subscription for the user (it is billed only after checkout()). * * @param array{ * group?: null|string, * name: string, * description?: null|string, * unit: string, * price: float|string, * monthly_cap?: null|float|string, * predecessor_id?: null|string, * vat_rate?: float, * payload?: null|array, * ends_at?: null|string, * idempotency_key?: null|string * } $attributes With an idempotency_key (max. 191 characters), a retried call returns the * subscription created by the first one instead of a duplicate. * monthly_cap: net, at most this per calendar month (hour and day units only, * at most 2 decimals, not below price; null = no cap). * predecessor_id: the subscription this one replaces (a resize; same user and * app, checked out, not cancelled): both share the monthly cap within a month. * * @throws ApiException */ public function create(array $attributes): AppSubscription { return new AppSubscription(AppRequest::send('POST', 'v1/client/subscriptions', [ ...$attributes, 'user_id' => $this->userId(), ])->data); } /** * Find one of the user's subscriptions; null when it doesn't exist (or belongs to someone else). * * @throws ApiException */ public function find(string $id): ?AppSubscription { try { $subscription = new AppSubscription(AppRequest::send('GET', sprintf('v1/client/subscriptions/%s', $id))->data); } catch (ApiException $e) { if ($e->isNotFound()) { return null; } throw $e; } return $subscription->user_id === $this->userId() ? $subscription : null; } /** * All of the user's subscriptions, optionally filtered. * * @param array{group?: string, active?: bool, cancelled?: bool} $filters * @return list * * @throws ApiException */ public function all(array $filters = []): array { $subscriptions = []; $page = 1; do { $result = AppRequest::send('GET', 'v1/client/subscriptions', null, [ ...array_map(fn ($value) => is_bool($value) ? (int) $value : $value, $filters), 'user_id' => $this->userId(), 'per_page' => 100, 'page' => $page, ]); foreach ($result->data as $data) { $subscriptions[] = new AppSubscription($data); } $lastPage = (int) ($result->meta->last_page ?? $page); } while ($page++ < $lastPage); return $subscriptions; } }