From 4b23f6ddbb825d9a38f6d5f65acdeae68fba46ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maurice=20Preu=C3=9F=20=28envoyr=29?= Date: Wed, 30 Apr 2025 03:45:10 +0200 Subject: [PATCH] refactored code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maurice Preuß (envoyr) --- src/Id/AnikeenId.php | 12 +- src/Id/ApiOperations/Delete.php | 2 +- src/Id/ApiOperations/Get.php | 2 +- src/Id/ApiOperations/Post.php | 2 +- src/Id/ApiOperations/Put.php | 2 +- src/Id/ApiOperations/Request.php | 2 +- src/Id/Billable.php | 8 +- src/Id/Concerns/HasBillable.php | 23 ++ src/Id/Concerns/HasParent.php | 20 ++ src/Id/Concerns/MagicProperties.php | 17 ++ src/Id/Concerns/ManagesAddresses.php | 115 +--------- src/Id/Concerns/ManagesBalance.php | 7 +- src/Id/Concerns/ManagesCountries.php | 25 +++ src/Id/Concerns/ManagesInvoices.php | 31 +-- src/Id/Concerns/ManagesOrders.php | 252 +--------------------- src/Id/Concerns/ManagesPaymentMethods.php | 43 +--- src/Id/Concerns/ManagesProfile.php | 30 +++ src/Id/Concerns/ManagesSshKeys.php | 38 +--- src/Id/Concerns/ManagesSubscriptions.php | 98 +-------- src/Id/Concerns/ManagesTransactions.php | 31 +-- src/Id/Concerns/ManagesUsers.php | 1 + src/Id/Contracts/Billable.php | 28 +++ src/Id/Resources/Address.php | 84 ++++++++ src/Id/Resources/Addresses.php | 91 ++++++++ src/Id/Resources/BaseCollection.php | 51 +++++ src/Id/Resources/BaseResource.php | 33 +++ src/Id/Resources/Countries.php | 18 ++ src/Id/Resources/Invoice.php | 26 +++ src/Id/Resources/Invoices.php | 26 +++ src/Id/Resources/Order.php | 115 ++++++++++ src/Id/Resources/OrderItem.php | 54 +++++ src/Id/Resources/OrderItems.php | 57 +++++ src/Id/Resources/Orders.php | 90 ++++++++ src/Id/Resources/PaymentMethod.php | 10 + src/Id/Resources/PaymentMethods.php | 49 +++++ src/Id/Resources/SshKey.php | 26 +++ src/Id/Resources/SshKeys.php | 43 ++++ src/Id/Resources/Subscription.php | 62 ++++++ src/Id/Resources/Subscriptions.php | 58 +++++ src/Id/Resources/Transaction.php | 10 + src/Id/Resources/Transactions.php | 39 ++++ src/Id/Result.php | 2 +- 42 files changed, 1139 insertions(+), 594 deletions(-) create mode 100644 src/Id/Concerns/HasBillable.php create mode 100644 src/Id/Concerns/HasParent.php create mode 100644 src/Id/Concerns/MagicProperties.php create mode 100644 src/Id/Concerns/ManagesCountries.php create mode 100644 src/Id/Concerns/ManagesProfile.php create mode 100644 src/Id/Contracts/Billable.php create mode 100644 src/Id/Resources/Address.php create mode 100644 src/Id/Resources/Addresses.php create mode 100644 src/Id/Resources/BaseCollection.php create mode 100644 src/Id/Resources/BaseResource.php create mode 100644 src/Id/Resources/Countries.php create mode 100644 src/Id/Resources/Invoice.php create mode 100644 src/Id/Resources/Invoices.php create mode 100644 src/Id/Resources/Order.php create mode 100644 src/Id/Resources/OrderItem.php create mode 100644 src/Id/Resources/OrderItems.php create mode 100644 src/Id/Resources/Orders.php create mode 100644 src/Id/Resources/PaymentMethod.php create mode 100644 src/Id/Resources/PaymentMethods.php create mode 100644 src/Id/Resources/SshKey.php create mode 100644 src/Id/Resources/SshKeys.php create mode 100644 src/Id/Resources/Subscription.php create mode 100644 src/Id/Resources/Subscriptions.php create mode 100644 src/Id/Resources/Transaction.php create mode 100644 src/Id/Resources/Transactions.php diff --git a/src/Id/AnikeenId.php b/src/Id/AnikeenId.php index a91f72c..9c65e75 100644 --- a/src/Id/AnikeenId.php +++ b/src/Id/AnikeenId.php @@ -157,7 +157,7 @@ class AnikeenId * @param string|null $cookie * @return string|static */ - public static function cookie(string $cookie = null): string|static + public static function cookie(?string $cookie = null): string|static { if (is_null($cookie)) { return static::$cookie; @@ -322,7 +322,7 @@ class AnikeenId * @throws GuzzleException * @throws RequestRequiresClientIdException */ - public function request(string $method, string $path, null|array $payload = null, array $parameters = [], Paginator $paginator = null): Result + public function request(string $method, string $path, null|array $payload = null, array $parameters = [], ?Paginator $paginator = null): Result { if ($paginator !== null) { $parameters[$paginator->action] = $paginator->cursor(); @@ -368,7 +368,7 @@ class AnikeenId * @throws GuzzleException * @throws RequestRequiresClientIdException */ - public function get(string $path, array $parameters = [], Paginator $paginator = null): Result + public function get(string $path, array $parameters = [], ?Paginator $paginator = null): Result { return $this->request('GET', $path, null, $parameters, $paginator); } @@ -377,7 +377,7 @@ class AnikeenId * @throws GuzzleException * @throws RequestRequiresClientIdException */ - public function post(string $path, array $payload = [], array $parameters = [], Paginator $paginator = null): Result + public function post(string $path, array $payload = [], array $parameters = [], ?Paginator $paginator = null): Result { return $this->request('POST', $path, $payload, $parameters, $paginator); } @@ -386,7 +386,7 @@ class AnikeenId * @throws GuzzleException * @throws RequestRequiresClientIdException */ - public function put(string $path, array $payload = [], array $parameters = [], Paginator $paginator = null): Result + public function put(string $path, array $payload = [], array $parameters = [], ?Paginator $paginator = null): Result { return $this->request('PUT', $path, $payload, $parameters, $paginator); } @@ -395,7 +395,7 @@ class AnikeenId * @throws GuzzleException * @throws RequestRequiresClientIdException */ - public function delete(string $path, array $payload = [], array $parameters = [], Paginator $paginator = null): Result + public function delete(string $path, array $payload = [], array $parameters = [], ?Paginator $paginator = null): Result { return $this->request('DELETE', $path, $payload, $parameters, $paginator); } diff --git a/src/Id/ApiOperations/Delete.php b/src/Id/ApiOperations/Delete.php index 0b27aca..22df7e0 100644 --- a/src/Id/ApiOperations/Delete.php +++ b/src/Id/ApiOperations/Delete.php @@ -15,5 +15,5 @@ trait Delete * @throws RequestRequiresClientIdException * @throws GuzzleException */ - abstract public function delete(string $path, array $payload = [], array $parameters = [], Paginator $paginator = null): Result; + abstract public function delete(string $path, array $payload = [], array $parameters = [], ?Paginator $paginator = null): Result; } \ No newline at end of file diff --git a/src/Id/ApiOperations/Get.php b/src/Id/ApiOperations/Get.php index 05bf645..9fbc8b6 100644 --- a/src/Id/ApiOperations/Get.php +++ b/src/Id/ApiOperations/Get.php @@ -15,5 +15,5 @@ trait Get * @throws RequestRequiresClientIdException * @throws GuzzleException */ - abstract public function get(string $path, array $parameters = [], Paginator $paginator = null): Result; + abstract public function get(string $path, array $parameters = [], ?Paginator $paginator = null): Result; } \ No newline at end of file diff --git a/src/Id/ApiOperations/Post.php b/src/Id/ApiOperations/Post.php index 9d62c73..deadc80 100644 --- a/src/Id/ApiOperations/Post.php +++ b/src/Id/ApiOperations/Post.php @@ -15,5 +15,5 @@ trait Post * @throws RequestRequiresClientIdException * @throws GuzzleException */ - abstract public function post(string $path, array $payload = [], array $parameters = [], Paginator $paginator = null): Result; + abstract public function post(string $path, array $payload = [], array $parameters = [], ?Paginator $paginator = null): Result; } \ No newline at end of file diff --git a/src/Id/ApiOperations/Put.php b/src/Id/ApiOperations/Put.php index e879d00..14b8b9b 100644 --- a/src/Id/ApiOperations/Put.php +++ b/src/Id/ApiOperations/Put.php @@ -15,5 +15,5 @@ trait Put * @throws RequestRequiresClientIdException * @throws GuzzleException */ - abstract public function put(string $path, array $payload = [], array $parameters = [], Paginator $paginator = null): Result; + abstract public function put(string $path, array $payload = [], array $parameters = [], ?Paginator $paginator = null): Result; } \ No newline at end of file diff --git a/src/Id/ApiOperations/Request.php b/src/Id/ApiOperations/Request.php index d9c0795..1f303d8 100644 --- a/src/Id/ApiOperations/Request.php +++ b/src/Id/ApiOperations/Request.php @@ -15,5 +15,5 @@ trait Request * @throws RequestRequiresClientIdException * @throws GuzzleException */ - abstract public function request(string $method, string $path, null|array $payload = null, array $parameters = [], Paginator $paginator = null): Result; + abstract public function request(string $method, string $path, null|array $payload = null, array $parameters = [], ?Paginator $paginator = null): Result; } \ No newline at end of file diff --git a/src/Id/Billable.php b/src/Id/Billable.php index 626cbb0..3c946e7 100644 --- a/src/Id/Billable.php +++ b/src/Id/Billable.php @@ -5,9 +5,11 @@ namespace Anikeen\Id; use Anikeen\Id\ApiOperations\Request; use Anikeen\Id\Concerns\ManagesAddresses; use Anikeen\Id\Concerns\ManagesBalance; +use Anikeen\Id\Concerns\ManagesCountries; use Anikeen\Id\Concerns\ManagesInvoices; use Anikeen\Id\Concerns\ManagesOrders; use Anikeen\Id\Concerns\ManagesPaymentMethods; +use Anikeen\Id\Concerns\ManagesProfile; use Anikeen\Id\Concerns\ManagesSubscriptions; use Anikeen\Id\Concerns\ManagesTaxation; use Anikeen\Id\Concerns\ManagesTransactions; @@ -20,9 +22,11 @@ trait Billable { use ManagesAddresses; use ManagesBalance; + use ManagesCountries; use ManagesInvoices; use ManagesOrders; use ManagesPaymentMethods; + use ManagesProfile; use ManagesSubscriptions; use ManagesTaxation; use ManagesTransactions; @@ -36,7 +40,7 @@ trait Billable * @throws RequestRequiresClientIdException * @throws GuzzleException */ - protected function getUserData(): stdClass + public function getUserData(): stdClass { if (!$this->userData) { $this->userData = $this->request('GET', 'v1/user')->data; @@ -50,7 +54,7 @@ trait Billable * @throws RequestRequiresClientIdException * @throws GuzzleException */ - protected function request(string $method, string $path, null|array $payload = null, array $parameters = [], Paginator $paginator = null): Result + public function request(string $method, string $path, null|array $payload = null, array $parameters = [], ?Paginator $paginator = null): Result { $anikeenId = new AnikeenId(); $anikeenId->withToken($this->{AnikeenId::getAccessTokenField()}); diff --git a/src/Id/Concerns/HasBillable.php b/src/Id/Concerns/HasBillable.php new file mode 100644 index 0000000..1690854 --- /dev/null +++ b/src/Id/Concerns/HasBillable.php @@ -0,0 +1,23 @@ +billable = $billable; + + return $this; + } + + public function getBillable(): Billable|Model + { + return $this->billable; + } +} \ No newline at end of file diff --git a/src/Id/Concerns/HasParent.php b/src/Id/Concerns/HasParent.php new file mode 100644 index 0000000..844e4d5 --- /dev/null +++ b/src/Id/Concerns/HasParent.php @@ -0,0 +1,20 @@ +parent = $parent; + + return $this; + } + + public function getParent() + { + return $this->parent; + } +} \ No newline at end of file diff --git a/src/Id/Concerns/MagicProperties.php b/src/Id/Concerns/MagicProperties.php new file mode 100644 index 0000000..623e7c9 --- /dev/null +++ b/src/Id/Concerns/MagicProperties.php @@ -0,0 +1,17 @@ + $value) { + if (property_exists($this, $key)) { + $this->{$key} = $value; + } + } + } +} \ No newline at end of file diff --git a/src/Id/Concerns/ManagesAddresses.php b/src/Id/Concerns/ManagesAddresses.php index 2cc3198..7946cb0 100644 --- a/src/Id/Concerns/ManagesAddresses.php +++ b/src/Id/Concerns/ManagesAddresses.php @@ -4,7 +4,7 @@ namespace Anikeen\Id\Concerns; use Anikeen\Id\ApiOperations\Request; use Anikeen\Id\Exceptions\RequestRequiresClientIdException; -use Anikeen\Id\Result; +use Anikeen\Id\Resources\Addresses; use GuzzleHttp\Exception\GuzzleException; trait ManagesAddresses @@ -17,116 +17,9 @@ trait ManagesAddresses * @throws RequestRequiresClientIdException * @throws GuzzleException */ - public function addresses(): Result + public function addresses(): Addresses { - return $this->request('GET', 'v1/addresses'); - } - - /** - * Creates a new address for the current user. - * - * @param array{ - * company_name: null|string, - * first_name: string, - * last_name: string, - * address: string, - * address_2: null|string, - * house_number: null|string, - * postal_code: string, - * city: string, - * state: null|string, - * country_iso: string, - * phone_number: null|string, - * email: null|string, - * primary: bool, - * primary_billing_address: bool - * } $attributes The address data: - *   - company_name: Company name (optional) - *   - first_name: First name - *   - last_name: Last name - *   - address: Address line 1 (e.g. street address, P.O. Box, etc.) - *   - address_2: Address line 2 (optional, e.g. apartment number, c/o, etc.) - *   - house_number: House number (optional) - *   - postal_code: Postal code - *   - city: City - *   - state: State (optional, e.g. province, region, etc.) - *   - country_iso: Country ISO code (e.g. US, CA, etc.) - *   - phone_number: Phone number (optional) - *   - email: Email address (optional, e.g. for delivery notifications) - *   - primary: Whether this address should be the primary address (optional) - *   - primary_billing_address: Whether this address should be the primary billing address (optional) - * @throws RequestRequiresClientIdException - * @throws GuzzleException - */ - public function createAddress(array $attributes = []): Result - { - return $this->request('POST', 'v1/addresses', $attributes); - } - - /** - * Get given address from the current user. - * - * @throws RequestRequiresClientIdException - * @throws GuzzleException - */ - public function address(string $addressId): Result - { - return $this->request('GET', sprintf('v1/addresses/%s', $addressId)); - } - - /** - * Update given address from the current user. - * - * VAT is calculated based on the billing address and shown in the address response. - * - * @param string $addressId The address ID. - * @param array{ - * company_name: null|string, - * first_name: string, - * last_name: string, - * address_2: null|string, - * address: string, - * house_number: null|string, - * postal_code: string, - * city: string, - * state: null|string, - * country_iso: string, - * phone_number: null|string, - * email: null|string, - * primary: bool, - * primary_billing_address: bool - * } $attributes The address data: - * - company_name: Company name (optional) - * - first_name: First name (required when set) - * - last_name: Last name (required when set) - * - address: Address line 1 (e.g. street address, P.O. Box, etc.) - * - address_2: Address line 2 (optional, e.g. apartment number, c/o, etc.) - * - house_number: House number (optional) - * - postal_code: Postal code (required when set) - * - city: City (required when set) - * - state: State (optional, e.g. province, region, etc.) - * - country_iso: Country ISO code (required when set, e.g. US, CA, etc.) - * - phone_number: Phone number (optional) - * - email: Email address (optional, e.g. for delivery notifications) - * - primary: Whether this address should be the primary address (optional) - * - primary_billing_address: Whether this address should be the primary billing address (optional) - * @throws RequestRequiresClientIdException - * @throws GuzzleException - */ - public function updateAddress(string $addressId, array $attributes = []): Result - { - return $this->request('PUT', sprintf('v1/addresses/%s', $addressId), $attributes); - } - - /** - * Delete given address from the current user. - * - * @param string $addressId The address ID. - * @throws RequestRequiresClientIdException - * @throws GuzzleException - */ - public function deleteAddress(string $addressId): Result - { - return $this->request('DELETE', sprintf('v1/addresses/%s', $addressId)); + return (new Addresses($this->request('GET', 'v1/addresses'))) + ->setBillable($this); } } \ No newline at end of file diff --git a/src/Id/Concerns/ManagesBalance.php b/src/Id/Concerns/ManagesBalance.php index 63e4434..0c2150e 100644 --- a/src/Id/Concerns/ManagesBalance.php +++ b/src/Id/Concerns/ManagesBalance.php @@ -4,6 +4,7 @@ namespace Anikeen\Id\Concerns; use Anikeen\Id\ApiOperations\Request; use Anikeen\Id\Exceptions\RequestRequiresClientIdException; +use Anikeen\Id\Resources\Transaction; use Anikeen\Id\Result; use GuzzleHttp\Exception\GuzzleException; @@ -42,12 +43,12 @@ trait ManagesBalance * @throws RequestRequiresClientIdException * @throws GuzzleException */ - public function charge(float $amount, string $paymentMethodId, array $options = []): Result + public function charge(float $amount, string $paymentMethodId, array $options = []): Transaction { - return $this->request('POST', 'billing/charge', [ + return new Transaction($this->request('POST', 'billing/charge', [ 'amount' => $amount, 'payment_method_id' => $paymentMethodId, 'options' => $options, - ]); + ])); } } \ No newline at end of file diff --git a/src/Id/Concerns/ManagesCountries.php b/src/Id/Concerns/ManagesCountries.php new file mode 100644 index 0000000..5792980 --- /dev/null +++ b/src/Id/Concerns/ManagesCountries.php @@ -0,0 +1,25 @@ +request('GET', 'v1/countries'))) + ->setBillable($this); + } +} \ No newline at end of file diff --git a/src/Id/Concerns/ManagesInvoices.php b/src/Id/Concerns/ManagesInvoices.php index c4ff84c..78899b8 100644 --- a/src/Id/Concerns/ManagesInvoices.php +++ b/src/Id/Concerns/ManagesInvoices.php @@ -4,7 +4,7 @@ namespace Anikeen\Id\Concerns; use Anikeen\Id\ApiOperations\Request; use Anikeen\Id\Exceptions\RequestRequiresClientIdException; -use Anikeen\Id\Result; +use Anikeen\Id\Resources\Invoices; use GuzzleHttp\Exception\GuzzleException; trait ManagesInvoices @@ -17,32 +17,9 @@ trait ManagesInvoices * @throws RequestRequiresClientIdException * @throws GuzzleException */ - public function invoices(): Result + public function invoices(): Invoices { - return $this->request('GET', 'v1/invoices'); - } - - /** - * Get given invoice from the current user. - * - * @param string $invoiceId The invoice ID - * @throws RequestRequiresClientIdException - * @throws GuzzleException - */ - public function invoice(string $invoiceId): Result - { - return $this->request('GET', sprintf('v1/invoices/%s', $invoiceId)); - } - - /** - * Get temporary download url from given invoice. - * - * @param string $invoiceId The invoice ID - * @throws RequestRequiresClientIdException - * @throws GuzzleException - */ - public function getInvoiceTemporaryUrl(string $invoiceId): string - { - return $this->request('PUT', sprintf('v1/invoices/%s', $invoiceId))->data->temporary_url; + return (new Invoices($this->request('GET', 'v1/invoices'))) + ->setBillable($this); } } \ No newline at end of file diff --git a/src/Id/Concerns/ManagesOrders.php b/src/Id/Concerns/ManagesOrders.php index e5ae30e..b15ad12 100644 --- a/src/Id/Concerns/ManagesOrders.php +++ b/src/Id/Concerns/ManagesOrders.php @@ -4,6 +4,7 @@ namespace Anikeen\Id\Concerns; use Anikeen\Id\ApiOperations\Request; use Anikeen\Id\Exceptions\RequestRequiresClientIdException; +use Anikeen\Id\Resources\Orders; use Anikeen\Id\Result; use GuzzleHttp\Exception\GuzzleException; @@ -17,254 +18,9 @@ trait ManagesOrders * @throws RequestRequiresClientIdException * @throws GuzzleException */ - public function orders(): Result + public function orders(): Orders { - return $this->request('GET', 'v1/orders'); - } - - /** - * Creates a new order for the current user. - * - * VAT is calculated based on the billing address and shown in the order response. - * - * The billing and shipping addresses are each persisted as standalone Address entities - * in the database, but are also embedded (deep-copied) into the Order object itself - * rather than merely referenced. This guarantees that the order retains its own snapshot - * of both addresses for future reference. - * - * @param array{ - * billing_address: array{ - * company_name: null|string, - * first_name: null|string, - * last_name: null|string, - * address: null|string, - * address_2: null|string, - * house_number: null|string, - * city: null|string, - * state: null|string, - * postal_code: null|string, - * country_iso: string, - * phone_number: null|string, - * email: null|string - * }, - * shipping_address: null|array{ - * company_name: null|string, - * first_name: string, - * last_name: string, - * address: null|string, - * address_2: string, - * house_number: null|string, - * city: string, - * state: string, - * postal_code: string, - * country_iso: string, - * phone_number: null|string, - * email: null|string - * }, - * items: array - * } $attributes The order data: - * - billing_address: Billing address (ISO 3166-1 alpha-2 country code) - * - shipping_address: Shipping address (first name, last name, ISO 3166-1 alpha-2 country code) - * - items: Array of order items (each with type, name, price, unit, units, and quantity) - * @throws RequestRequiresClientIdException - * @throws GuzzleException - */ - public function createOrder(array $attributes = []): Result - { - return $this->request('POST', 'v1/orders', $attributes); - } - - /** - * Get given order from the current user. - * - * @throws RequestRequiresClientIdException - * @throws GuzzleException - */ - public function order(string $orderId): Result - { - return $this->request('GET', sprintf('v1/orders/%s', $orderId)); - } - - /** - * Update given order from the current user. - * - * VAT is calculated based on the billing address and shown in the order response. - * - * The billing and shipping addresses are each persisted as standalone Address entities - * in the database, but are also embedded (deep-copied) into the Order object itself - * rather than merely referenced. This guarantees that the order retains its own snapshot - * of both addresses for future reference. - * - * @param string $orderId The order ID. - * @param array{ - * billing_address: array{ - * company_name: null|string, - * first_name: null|string, - * last_name: null|string, - * address: null|string, - * address_2: null|string, - * house_number: null|string, - * city: null|string, - * state: null|string, - * postal_code: null|string, - * country_iso: string, - * phone_number: null|string, - * email: null|string - * }, - * shipping_address: null|array{ - * company_name: null|string, - * first_name: string, - * last_name: string, - * address: null|string, - * address_2: string, - * house_number: null|string, - * city: string, - * state: string, - * postal_code: string, - * country_iso: string, - * phone_number: null|string, - * email: null|string - * } - * } $attributes The order data: - * - billing_address: Billing address (ISO 3166-1 alpha-2 country code) - * - shipping_address: Shipping address (first name, last name, ISO 3166-1 alpha-2 country code) - * @throws RequestRequiresClientIdException - * @throws GuzzleException - */ - public function updateOrder(string $orderId, array $attributes = []): Result - { - return $this->request('PUT', sprintf('v1/orders/%s', $orderId), $attributes); - } - - /** - * Checkout given order from the current user. - * - * @param string $orderId The order ID. - * @throws RequestRequiresClientIdException - * @throws GuzzleException - */ - public function checkoutOrder(string $orderId): Result - { - return $this->request('PUT', sprintf('v1/orders/%s/checkout', $orderId)); - } - - /** - * Revoke given order from the current user. - * - * @param string $orderId The order ID. - * @throws RequestRequiresClientIdException - * @throws GuzzleException - */ - public function revokeOrder(string $orderId): Result - { - return $this->request('PUT', sprintf('v1/orders/%s/revoke', $orderId)); - } - - /** - * Delete given order from the current user. - * - * @param string $orderId The order ID. - * @throws RequestRequiresClientIdException - * @throws GuzzleException - */ - public function deleteOrder(string $orderId): Result - { - return $this->request('DELETE', sprintf('v1/orders/%s', $orderId)); - } - - /** - * Get order items from given order. - * - * @param string $orderId The order ID. - * @throws RequestRequiresClientIdException - * @throws GuzzleException - */ - public function orderItems(string $orderId): Result - { - return $this->request('GET', sprintf('v1/orders/%s/items', $orderId)); - } - - /** - * Create a new order item for given order. - * - * VAT is calculated based on the billing address and shown in the order item response. - * - * @param string $orderId The order ID. - * @param array{ - * items: array - * } $attributes The order data: - * - items: Array of order items, each with type, name, description, price, unit, and quantity - * @throws RequestRequiresClientIdException - * @throws GuzzleException - */ - public function createOrderItem(string $orderId, array $attributes = []): Result - { - return $this->request('POST', sprintf('v1/orders/%s', $orderId), $attributes); - } - - /** - * Get given order item from given order. - * - * @param string $orderId The order ID. - * @param string $orderItemId The order item ID. - * @throws RequestRequiresClientIdException - * @throws GuzzleException - */ - public function orderItem(string $orderId, string $orderItemId): Result - { - return $this->request('GET', sprintf('v1/orders/%s/items/%s', $orderId, $orderItemId)); - } - - /** - * Update given order item from given order. - * - * VAT is calculated based on the billing address and shown in the order item response. - * - * @param string $orderId The order ID. - * @param string $orderItemId The order item ID. - * @param array{ - * items: array - * } $attributes The order data: - * - items: Array of order items, each with type, name, description, price, unit, and quantity - * @throws RequestRequiresClientIdException - * @throws GuzzleException - */ - public function updateOrderItem(string $orderId, string $orderItemId, array $attributes = []): Result - { - return $this->request('PUT', sprintf('v1/orders/%s/items/%s', $orderId, $orderItemId), $attributes); - } - - /** - * Delete given order item from given order. - * - * @param string $orderId The order ID. - * @param string $orderItemId The order item ID. - * @throws RequestRequiresClientIdException - * @throws GuzzleException - */ - public function deleteOrderItem(string $orderId, string $orderItemId): Result - { - return $this->request('DELETE', sprintf('v1/orders/%s/items/%s', $orderId, $orderItemId)); + return (new Orders($this->request('GET', 'v1/orders'))) + ->setBillable($this); } } \ No newline at end of file diff --git a/src/Id/Concerns/ManagesPaymentMethods.php b/src/Id/Concerns/ManagesPaymentMethods.php index 67a5146..d71c1be 100644 --- a/src/Id/Concerns/ManagesPaymentMethods.php +++ b/src/Id/Concerns/ManagesPaymentMethods.php @@ -4,6 +4,7 @@ namespace Anikeen\Id\Concerns; use Anikeen\Id\ApiOperations\Request; use Anikeen\Id\Exceptions\RequestRequiresClientIdException; +use Anikeen\Id\Resources\PaymentMethods; use Anikeen\Id\Result; use GuzzleHttp\Exception\GuzzleException; @@ -11,59 +12,27 @@ trait ManagesPaymentMethods { use Request; - /** - * Check if current user has at least one payment method. - * - * @throws RequestRequiresClientIdException - * @throws GuzzleException - */ - public function hasPaymentMethod(): bool - { - return $this->paymentMethods()->count() > 0; - } - /** * Get payment methods from the current user. * * @throws RequestRequiresClientIdException * @throws GuzzleException */ - public function paymentMethods(): Result + public function paymentMethods(): PaymentMethods { - return $this->request('GET', 'v1/payment-methods'); - } - - /** - * Get default payment method from the current user. - * - * @throws RequestRequiresClientIdException - * @throws GuzzleException - */ - public function hasDefaultPaymentMethod(): bool - { - return (bool)$this->defaultPaymentMethod()->data; - } - - /** - * Get default payment method from the current user. - * - * @throws RequestRequiresClientIdException - * @throws GuzzleException - */ - public function defaultPaymentMethod(): Result - { - return $this->request('GET', 'v1/payment-methods/default'); + return (new PaymentMethods($this->request('GET', 'v1/payment-methods'))) + ->setBillable($this); } /** * Get billing portal URL for the current user. * - * @param string $returnUrl The URL to redirect to after the user has finished in the billing portal. + * @param string|null $returnUrl The URL to redirect to after the user has finished in the billing portal. * @param array $options Additional options for the billing portal. * @throws RequestRequiresClientIdException * @throws GuzzleException */ - public function billingPortalUrl(string $returnUrl, array $options): string + public function billingPortalUrl(?string $returnUrl = null, array $options = []): string { return $this->request('POST', 'v1/billing/portal', [ 'return_url' => $returnUrl, diff --git a/src/Id/Concerns/ManagesProfile.php b/src/Id/Concerns/ManagesProfile.php new file mode 100644 index 0000000..4dd174a --- /dev/null +++ b/src/Id/Concerns/ManagesProfile.php @@ -0,0 +1,30 @@ +request('POST', 'v1/user/profile', [ + 'return_url' => $returnUrl, + 'options' => $options, + ])->data->url; + } +} \ No newline at end of file diff --git a/src/Id/Concerns/ManagesSshKeys.php b/src/Id/Concerns/ManagesSshKeys.php index 3f6df84..0435e2c 100644 --- a/src/Id/Concerns/ManagesSshKeys.php +++ b/src/Id/Concerns/ManagesSshKeys.php @@ -3,16 +3,14 @@ namespace Anikeen\Id\Concerns; -use Anikeen\Id\ApiOperations\Delete; use Anikeen\Id\ApiOperations\Get; -use Anikeen\Id\ApiOperations\Post; use Anikeen\Id\Exceptions\RequestRequiresClientIdException; -use Anikeen\Id\Result; +use Anikeen\Id\Resources\SshKeys; use GuzzleHttp\Exception\GuzzleException; trait ManagesSshKeys { - use Get, Post, Delete; + use Get; /** * Get currently authed user with Bearer Token. @@ -20,35 +18,9 @@ trait ManagesSshKeys * @throws RequestRequiresClientIdException * @throws GuzzleException */ - public function sshKeysByUserId(string $sskKeyId): Result + public function sshKeysByUserId(string $sskKeyId): SshKeys { - return $this->get(sprintf('v1/users/%s/ssh-keys/json', $sskKeyId)); - } - - /** - * Creates ssh key for the currently authed user. - * - * @param string $publicKey The public key to be added - * @param string|null $name The name of the key (optional) - * @throws RequestRequiresClientIdException - * @throws GuzzleException - */ - public function createSshKey(string $publicKey, string $name = null): Result - { - return $this->post('v1/ssh-keys', [ - 'public_key' => $publicKey, - 'name' => $name, - ]); - } - - /** - * Deletes a given ssh key for the currently authed user. - * - * @throws RequestRequiresClientIdException - * @throws GuzzleException - */ - public function deleteSshKey(int $sshKeyId): Result - { - return $this->delete(sprintf('v1/ssh-keys/%s', $sshKeyId)); + return (new SshKeys($this->get(sprintf('v1/users/%s/ssh-keys/json', $sskKeyId)))) + ->setParent($this); } } \ No newline at end of file diff --git a/src/Id/Concerns/ManagesSubscriptions.php b/src/Id/Concerns/ManagesSubscriptions.php index ad79498..b86d2bf 100644 --- a/src/Id/Concerns/ManagesSubscriptions.php +++ b/src/Id/Concerns/ManagesSubscriptions.php @@ -4,7 +4,7 @@ namespace Anikeen\Id\Concerns; use Anikeen\Id\ApiOperations\Request; use Anikeen\Id\Exceptions\RequestRequiresClientIdException; -use Anikeen\Id\Result; +use Anikeen\Id\Resources\Subscriptions; use GuzzleHttp\Exception\GuzzleException; trait ManagesSubscriptions @@ -17,99 +17,9 @@ trait ManagesSubscriptions * @throws RequestRequiresClientIdException * @throws GuzzleException */ - public function subscriptions(): Result + public function subscriptions(): Subscriptions { - return $this->request('GET', 'v1/subscriptions'); - } - - /** - * Get given subscription from the current user. - * - * @param string $subscriptionId The subscription ID. - * @throws RequestRequiresClientIdException - * @throws GuzzleException - */ - public function subscription(string $subscriptionId): Result - { - return $this->request('GET', sprintf('v1/subscriptions/%s', $subscriptionId)); - } - - /** - * Create a new subscription for the current user. - * - * @param array{ - * name: null, - * description: string, - * unit: string, - * price: float, - * vat: null|float, - * payload: null|array, - * ends_at: null|string, - * webhook_url: null|string, - * webhook_secret: null|string - * } $attributes The subscription data: - * - name: The name - * - description: The description - * - unit: The unit (e.g. "hour", "day", "week", "month", "year") - * - price: The price per unit - * - vat: The VAT (optional) - * - payload: The payload (optional) - * - ends_at: The end date (optional) - * - webhook_url: The webhook URL (optional) - * - webhook_secret: The webhook secret (optional) - * @throws RequestRequiresClientIdException - * @throws GuzzleException - */ - public function createSubscription(array $attributes): Result - { - return $this->request('POST', 'v1/subscriptions', $attributes); - } - - /** - * Force given subscription to check out (trusted apps only). - * - * @param string $subscriptionId The subscription ID. - * @throws RequestRequiresClientIdException - * @throws GuzzleException - */ - public function checkoutSubscription(string $subscriptionId): Result - { - return $this->request('PUT', sprintf('v1/subscriptions/%s/checkout', $subscriptionId)); - } - - /** - * Revoke a given running subscription from the current user. - * - * @param string $subscriptionId The subscription ID. - * @throws RequestRequiresClientIdException - * @throws GuzzleException - */ - public function revokeSubscription(string $subscriptionId): Result - { - return $this->request('PUT', sprintf('v1/subscriptions/%s/revoke', $subscriptionId)); - } - - /** - * Resume a given running subscription from the current user. - * - * @param string $subscriptionId The subscription ID. - * @throws RequestRequiresClientIdException - * @throws GuzzleException - */ - public function resumeSubscription(string $subscriptionId): Result - { - return $this->request('PUT', sprintf('v1/subscriptions/%s/resume', $subscriptionId)); - } - - /** - * Delete a given subscription from the current user. - * - * @param string $subscriptionId The subscription ID. - * @throws RequestRequiresClientIdException - * @throws GuzzleException - */ - public function deleteSubscription(string $subscriptionId): Result - { - return $this->request('DELETE', sprintf('v1/subscriptions/%s', $subscriptionId)); + return (new Subscriptions($this->request('GET', 'v1/subscriptions'))) + ->setBillable($this); } } \ No newline at end of file diff --git a/src/Id/Concerns/ManagesTransactions.php b/src/Id/Concerns/ManagesTransactions.php index 2488f99..d52f64d 100644 --- a/src/Id/Concerns/ManagesTransactions.php +++ b/src/Id/Concerns/ManagesTransactions.php @@ -4,6 +4,7 @@ namespace Anikeen\Id\Concerns; use Anikeen\Id\ApiOperations\Request; use Anikeen\Id\Exceptions\RequestRequiresClientIdException; +use Anikeen\Id\Resources\Transactions; use Anikeen\Id\Result; use GuzzleHttp\Exception\GuzzleException; @@ -17,33 +18,9 @@ trait ManagesTransactions * @throws RequestRequiresClientIdException * @throws GuzzleException */ - public function transactions(): Result + public function transactions(): Transactions { - return $this->request('GET', 'v1/transactions'); - } - - /** - * Create a new transaction for the current user. - * - * @param array $attributes The attributes for the transaction. - * @throws RequestRequiresClientIdException - * @throws GuzzleException - * @todo Add type hinting for the attributes array. - */ - public function createTransaction(array $attributes = []): Result - { - return $this->request('POST', 'v1/transactions', $attributes); - } - - /** - * Get given transaction from current current user. - * - * @param string $transactionId The transaction ID. - * @throws RequestRequiresClientIdException - * @throws GuzzleException - */ - public function transaction(string $transactionId): Result - { - return $this->request('GET', sprintf('v1/transactions/%s', $transactionId)); + return (new Transactions($this->request('GET', 'v1/transactions'))) + ->setBillable($this);; } } \ No newline at end of file diff --git a/src/Id/Concerns/ManagesUsers.php b/src/Id/Concerns/ManagesUsers.php index df68d2f..c99b6fe 100644 --- a/src/Id/Concerns/ManagesUsers.php +++ b/src/Id/Concerns/ManagesUsers.php @@ -12,6 +12,7 @@ use GuzzleHttp\Exception\GuzzleException; trait ManagesUsers { use Get, Post; + use HasParent; /** * Get currently authed user with Bearer Token diff --git a/src/Id/Contracts/Billable.php b/src/Id/Contracts/Billable.php new file mode 100644 index 0000000..2382d39 --- /dev/null +++ b/src/Id/Contracts/Billable.php @@ -0,0 +1,28 @@ +billable->request('PUT', sprintf('v1/addresses/%s', $this->id), $attributes))) + ->setBillable($this->billable); + } + + /** + * Delete given address from the current user. + * + * @throws RequestRequiresClientIdException + * @throws GuzzleException + */ + public function delete(): bool + { + return $this->billable->request('DELETE', sprintf('v1/addresses/%s', $this->id))->success(); + } +} \ No newline at end of file diff --git a/src/Id/Resources/Addresses.php b/src/Id/Resources/Addresses.php new file mode 100644 index 0000000..dd3b5f8 --- /dev/null +++ b/src/Id/Resources/Addresses.php @@ -0,0 +1,91 @@ +billable->request('POST', 'v1/addresses', $attributes))) + ->setBillable($this->billable); + } + + /** + * {@inheritDoc} + */ + public function find(string $id): ?Address + { + $result = $this->billable->request('GET', sprintf('v1/addresses/%s', $id)); + + return $result->success() ? + (new Address($result)) + ->setBillable($this->billable) + : null; + } + + /** + * Get default address from the current user. + * + * @throws RequestRequiresClientIdException + * @throws GuzzleException + */ + public function defaultBillingAddress(): Address + { + return (new Address($this->billable->request('GET', sprintf('v1/addresses/%s', $this->billable->getUserData()->billing_address_id)))) + ->setBillable($this->billable); + } + + /** + * Check if the current user has a default billing address. + * + * @throws RequestRequiresClientIdException + * @throws GuzzleException + */ + public function hasDefaultBillingAddress(): bool + { + return $this->billable->getUserData()->billing_address_id !== null; + } +} \ No newline at end of file diff --git a/src/Id/Resources/BaseCollection.php b/src/Id/Resources/BaseCollection.php new file mode 100644 index 0000000..3b0993d --- /dev/null +++ b/src/Id/Resources/BaseCollection.php @@ -0,0 +1,51 @@ +result; + } + + /** + * Returns the collection of resources as a JSON string. + */ + public function jsonSerialize(): array + { + return $this->toArray(); + } + + /** + * Returns the collection of resources. + * + * @throws RequestRequiresClientIdException + * @throws GuzzleException + */ + public function get(): Result + { + return $this->result; + } + + /** + * Returns the Resource based on the ID. + * + * @throws RequestRequiresClientIdException + * @throws GuzzleException + */ + abstract public function find(string $id): ?BaseResource; +} \ No newline at end of file diff --git a/src/Id/Resources/BaseResource.php b/src/Id/Resources/BaseResource.php new file mode 100644 index 0000000..af2ec5c --- /dev/null +++ b/src/Id/Resources/BaseResource.php @@ -0,0 +1,33 @@ +setMagicProperties($this->result->data); + } + + /** + * Returns the collection of resources as an array. + */ + public function toArray(): array + { + return (array) $this->result->data; + } + + /** + * Returns the collection of resources as a JSON string. + */ + public function jsonSerialize(): array + { + return $this->toArray(); + } +} \ No newline at end of file diff --git a/src/Id/Resources/Countries.php b/src/Id/Resources/Countries.php new file mode 100644 index 0000000..7d7613d --- /dev/null +++ b/src/Id/Resources/Countries.php @@ -0,0 +1,18 @@ +billable->request('PUT', sprintf('v1/invoices/%s', $this->id))->data->temporary_url; + } +} \ No newline at end of file diff --git a/src/Id/Resources/Invoices.php b/src/Id/Resources/Invoices.php new file mode 100644 index 0000000..24606c7 --- /dev/null +++ b/src/Id/Resources/Invoices.php @@ -0,0 +1,26 @@ +billable->request('GET', sprintf('v1/invoices/%s', $id)); + + return $result->success() + ? (new Invoice($result)) + ->setBillable($this->billable) + : null; + } +} \ No newline at end of file diff --git a/src/Id/Resources/Order.php b/src/Id/Resources/Order.php new file mode 100644 index 0000000..2f1e8c7 --- /dev/null +++ b/src/Id/Resources/Order.php @@ -0,0 +1,115 @@ +billable->request('PUT', sprintf('v1/orders/%s', $this->id), $attributes))) + ->setBillable($this->billable); + } + + /** + * Checkout given order from the current user. + * + * @throws RequestRequiresClientIdException + * @throws GuzzleException + */ + public function checkout(string $orderId): self + { + return (new self($this->billable->request('PUT', sprintf('v1/orders/%s/checkout', $this->id)))) + ->setBillable($this->billable); + } + + /** + * Revoke given order from the current user. + * + * @throws RequestRequiresClientIdException + * @throws GuzzleException + */ + public function revoke(string $orderId): self + { + return (new self($this->billable->request('PUT', sprintf('v1/orders/%s/revoke', $this->id)))) + ->setBillable($this->billable); + } + + /** + * Delete given order from the current user. + * + * @throws RequestRequiresClientIdException + * @throws GuzzleException + */ + public function delete(): bool + { + return $this->billable->request('DELETE', sprintf('v1/orders/%s', $this->id))->success(); + } + + /** + * Get order items from given order. + * + * @param string $orderId The order ID. + * @throws RequestRequiresClientIdException + * @throws GuzzleException + */ + public function orderItems(string $orderId): OrderItems + { + return (new OrderItems($this->billable->request('GET', sprintf('v1/orders/%s/items', $this->id)))) + ->setBillable($this->billable) + ->setParent($this); + } +} \ No newline at end of file diff --git a/src/Id/Resources/OrderItem.php b/src/Id/Resources/OrderItem.php new file mode 100644 index 0000000..2cf0e1b --- /dev/null +++ b/src/Id/Resources/OrderItem.php @@ -0,0 +1,54 @@ + + * } $attributes The order data: + * - items: Array of order items, each with type, name, description, price, unit, and quantity + * @throws RequestRequiresClientIdException + * @throws GuzzleException + */ + public function update(array $attributes = []): self + { + return (new self($this->billable->request('PUT', sprintf('v1/orders/%s/items/%s', $this->parent->id, $this->id), $attributes))) + ->setBillable($this->billable) + ->setParent($this->parent); + } + + /** + * Delete given order item from given order. + * + * @throws RequestRequiresClientIdException + * @throws GuzzleException + */ + public function delete(): bool + { + return $this->billable->request('DELETE', sprintf('v1/orders/%s/items/%s', $this->parent->id, $this->id))->success(); + } +} \ No newline at end of file diff --git a/src/Id/Resources/OrderItems.php b/src/Id/Resources/OrderItems.php new file mode 100644 index 0000000..49ffbfc --- /dev/null +++ b/src/Id/Resources/OrderItems.php @@ -0,0 +1,57 @@ + + * } $attributes The order data: + * - items: Array of order items, each with type, name, description, price, unit, and quantity + * @throws RequestRequiresClientIdException + * @throws GuzzleException + */ + public function create(string $orderId, array $attributes = []): OrderItem + { + return (new OrderItem($this->billable->request('POST', sprintf('v1/orders/%s', $orderId), $attributes))) + ->setBillable($this->billable) + ->setParent($this->parent); + } + + /** + * {@inheritDoc} + */ + public function find(string $id): ?OrderItem + { + /** @var Result $result */ + $result = $this->parent->request('GET', sprintf('v1/orders/%s/items/%s', $this->parent->id, $id)); + + return $result->success() ? + (new OrderItem($result)) + ->setBillable($this->billable) + ->setParent($this->parent) + : null; + } +} \ No newline at end of file diff --git a/src/Id/Resources/Orders.php b/src/Id/Resources/Orders.php new file mode 100644 index 0000000..24a1440 --- /dev/null +++ b/src/Id/Resources/Orders.php @@ -0,0 +1,90 @@ + + * } $attributes The order data: + * - billing_address: Billing address (ISO 3166-1 alpha-2 country code) + * - shipping_address: Shipping address (first name, last name, ISO 3166-1 alpha-2 country code) + * - items: Array of order items (each with type, name, price, unit, units, and quantity) + * @throws RequestRequiresClientIdException + * @throws GuzzleException + */ + public function create(array $attributes = []): Order + { + return (new Order($this->billable->request('POST', 'v1/orders', $attributes))) + ->setBillable($this->billable); + } + + /** + * Get given order from the current user. + * + * @throws RequestRequiresClientIdException + * @throws GuzzleException + */ + public function find(string $id): ?Order + { + /** @var Result $result */ + $result = $this->billable->request('GET', sprintf('v1/orders/%s', $id)); + + return $result->success() + ? (new Order($result)) + ->setBillable($this->billable) + : null; + } +} \ No newline at end of file diff --git a/src/Id/Resources/PaymentMethod.php b/src/Id/Resources/PaymentMethod.php new file mode 100644 index 0000000..1d624e6 --- /dev/null +++ b/src/Id/Resources/PaymentMethod.php @@ -0,0 +1,10 @@ +result->count() > 0; + } + + /** + * Get default payment method from the current user. + * + * @throws RequestRequiresClientIdException + * @throws GuzzleException + */ + public function defaultPaymentMethod(): PaymentMethod + { + return (new PaymentMethod($this->billable->request('GET', 'v1/payment-methods/default'))) + ->setBillable($this->billable); + } + + /** + * {@inheritDoc} + */ + public function find(string $id): ?PaymentMethod + { + $result = $this->billable->request('GET', sprintf('v1/payment-methods/%s', $id)); + + return $result->success() + ? (new PaymentMethod($result)) + ->setBillable($this->billable) + : null; + } +} \ No newline at end of file diff --git a/src/Id/Resources/SshKey.php b/src/Id/Resources/SshKey.php new file mode 100644 index 0000000..80b0a6b --- /dev/null +++ b/src/Id/Resources/SshKey.php @@ -0,0 +1,26 @@ +parent->delete(sprintf('v1/ssh-keys/%s', $this->id))->success(); + } +} \ No newline at end of file diff --git a/src/Id/Resources/SshKeys.php b/src/Id/Resources/SshKeys.php new file mode 100644 index 0000000..293895d --- /dev/null +++ b/src/Id/Resources/SshKeys.php @@ -0,0 +1,43 @@ +parent->post('v1/ssh-keys', [ + 'public_key' => $publicKey, + 'name' => $name, + ])))->setParent($this->parent); + } + + /** + * {@inheritDoc} + */ + public function find(string $id): ?SshKey + { + /** @var Result $result */ + $result = $this->parent->get(sprintf('v1/ssh-keys/%s', $id)); + + return $result->success() + ? (new SshKey($result)) + ->setParent($this->parent) + : null; + } +} \ No newline at end of file diff --git a/src/Id/Resources/Subscription.php b/src/Id/Resources/Subscription.php new file mode 100644 index 0000000..f988a55 --- /dev/null +++ b/src/Id/Resources/Subscription.php @@ -0,0 +1,62 @@ +billable->request('PUT', sprintf('v1/subscriptions/%s/checkout', $this->id)))) + ->setBillable($this->billable); + } + + /** + * Revoke a given running subscription from the current user. + * + * @throws RequestRequiresClientIdException + * @throws GuzzleException + */ + public function revoke(): self + { + return (new self($this->billable->request('PUT', sprintf('v1/subscriptions/%s/revoke', $this->id)))) + ->setBillable($this->billable); + } + + /** + * Resume a given running subscription from the current user. + * + * @throws RequestRequiresClientIdException + * @throws GuzzleException + */ + public function resume(): self + { + return (new self($this->billable->request('PUT', sprintf('v1/subscriptions/%s/resume', $this->id)))) + ->setBillable($this->billable); + } + + /** + * Delete a given subscription from the current user. + * + * @throws RequestRequiresClientIdException + * @throws GuzzleException + */ + public function delete(): bool + { + return $this->billable->request('DELETE', sprintf('v1/subscriptions/%s', $this->id))->success(); + } +} \ No newline at end of file diff --git a/src/Id/Resources/Subscriptions.php b/src/Id/Resources/Subscriptions.php new file mode 100644 index 0000000..ca2aa48 --- /dev/null +++ b/src/Id/Resources/Subscriptions.php @@ -0,0 +1,58 @@ +billable->request('POST', 'v1/subscriptions', $attributes))) + ->setBillable($this->billable); + } + + /** + * {@inheritDoc} + */ + public function find(string $id): ?Subscription + { + $result = $this->billable->request('GET', sprintf('v1/subscriptions/%s', $id)); + + return $result->success() + ? (new Subscription($result)) + ->setBillable($this->billable) + : null; + } +} \ No newline at end of file diff --git a/src/Id/Resources/Transaction.php b/src/Id/Resources/Transaction.php new file mode 100644 index 0000000..ffbe0ac --- /dev/null +++ b/src/Id/Resources/Transaction.php @@ -0,0 +1,10 @@ +billable->request('POST', 'v1/transactions', $attributes)); + } + + /** + * {@inheritDoc} + */ + public function find(string $id): ?Transaction + { + $result = $this->billable->request('GET', sprintf('v1/transactions/%s', $id)); + + return $result->success() + ? (new Transaction($result)) + ->setBillable($this->billable) + : null; + } +} \ No newline at end of file diff --git a/src/Id/Result.php b/src/Id/Result.php index 1186680..6824f37 100644 --- a/src/Id/Result.php +++ b/src/Id/Result.php @@ -179,7 +179,7 @@ class Result /** * Rate limit info from headers */ - public function rateLimit(string $key = null): array|int|string|null + public function rateLimit(?string $key = null): array|int|string|null { if (!$this->response) { return null;