data->{$name} ?? null; } public function __isset(string $name): bool { return isset($this->data->{$name}); } /** * Change a subscription that wasn't checked out yet. * * @throws ApiException */ public function update(array $attributes): self { return $this->send('PUT', '', $attributes); } /** * Activate the subscription and bill its first period. * * $startsAt (in the past) books a service that is already running, e.g. a domain registered * earlier: the first period runs from $startsAt, is billed now and renews when it ends. * * @throws ApiException 409 "already_active", "billing_address_missing", "period_already_ended", … */ public function checkout(DateTimeInterface|string|null $startsAt = null): self { if ($startsAt instanceof DateTimeInterface) { $startsAt = $startsAt->format(DateTimeInterface::ATOM); } return $this->send('PUT', '/checkout', $startsAt === null ? null : ['starts_at' => $startsAt]); } /** * Cancel the subscription. With $refund (only within 14 days of its start), its not yet * charged usage is credited. * * @throws ApiException 409 "already_cancelled", 404 "subscription_not_found", … */ public function revoke(bool $refund = false): self { return $this->send('PUT', '/revoke', ['refund' => $refund]); } /** * Stop renewing; the subscription expires when its paid period ends. * * @throws ApiException */ public function pause(): self { return $this->send('PUT', '/pause'); } /** * Renew again (an expired subscription starts a new period). * * @throws ApiException */ public function resume(): self { return $this->send('PUT', '/resume'); } /** * @throws ApiException */ public function refresh(): self { return $this->send('GET', ''); } public function toArray(): array { return (array) $this->data; } public function jsonSerialize(): array { return $this->toArray(); } /** * @throws ApiException */ private function send(string $method, string $action, ?array $payload = null): self { $this->data = AppRequest::send($method, sprintf('v1/client/subscriptions/%s%s', $this->id, $action), $payload)->data; return $this; } }