From 410ca84bf162c01550ec493b36711ccc27ab06d4 Mon Sep 17 00:00:00 2001 From: Jepp9350 <2jepp9350@gmail.com> Date: Tue, 18 Feb 2025 18:31:23 +0100 Subject: [PATCH] Add Stripe integration for customers, payments, and products This commit introduces a comprehensive Stripe module with support for managing customers, products, prices, and payment links. It also includes endpoint routes, helpers, and database updates to support Stripe operations, such as creating and retrieving entities or handling payment workflows. Additionally, a stripe module was integrated into existing routes and objects to enable seamless interaction with Stripe APIs. --- services/nginx/app/classes/stripe.php | 127 +++++++++++++++++ services/nginx/app/index.php | 1 + services/nginx/app/interfaces/stripe_i.php | 32 +++++ .../stripe/config/stripe_enabled_c.php | 29 ++++ .../config/stripe_publishable_key_c.php | 29 ++++ .../stripe/config/stripe_secret_key_c.php | 29 ++++ .../endpoints/stripe_endpoint_customers.php | 74 ++++++++++ .../stripe_endpoint_payment_link.php | 75 ++++++++++ .../endpoints/stripe_endpoint_prices.php | 49 +++++++ .../endpoints/stripe_endpoint_product.php | 54 ++++++++ .../stripe/helpers/stripe_line_item.php | 109 +++++++++++++++ .../stripe/helpers/stripe_line_items.php | 32 +++++ .../modules/stripe/helpers/stripe_price.php | 36 +++++ .../modules/stripe/helpers/stripe_product.php | 50 +++++++ .../nginx/app/modules/stripe/stripe_c.php | 45 ++++++ services/nginx/app/objects/orders_o.php | 129 ++++++++++-------- .../app/objects/stripe_module_orders_o.php | 93 +++++++++++++ .../nginx/app/routes/moduleConfigRoute.php | 33 +++++ .../nginx/app/routes/moduleStripeRoute.php | 105 ++++++++++++++ .../nginx/app/traits/stripe_endpoint_t.php | 38 ++++++ 20 files changed, 1114 insertions(+), 55 deletions(-) create mode 100644 services/nginx/app/classes/stripe.php create mode 100644 services/nginx/app/interfaces/stripe_i.php create mode 100644 services/nginx/app/modules/stripe/config/stripe_enabled_c.php create mode 100644 services/nginx/app/modules/stripe/config/stripe_publishable_key_c.php create mode 100644 services/nginx/app/modules/stripe/config/stripe_secret_key_c.php create mode 100644 services/nginx/app/modules/stripe/endpoints/stripe_endpoint_customers.php create mode 100644 services/nginx/app/modules/stripe/endpoints/stripe_endpoint_payment_link.php create mode 100644 services/nginx/app/modules/stripe/endpoints/stripe_endpoint_prices.php create mode 100644 services/nginx/app/modules/stripe/endpoints/stripe_endpoint_product.php create mode 100644 services/nginx/app/modules/stripe/helpers/stripe_line_item.php create mode 100644 services/nginx/app/modules/stripe/helpers/stripe_line_items.php create mode 100644 services/nginx/app/modules/stripe/helpers/stripe_price.php create mode 100644 services/nginx/app/modules/stripe/helpers/stripe_product.php create mode 100644 services/nginx/app/modules/stripe/stripe_c.php create mode 100644 services/nginx/app/objects/stripe_module_orders_o.php create mode 100644 services/nginx/app/routes/moduleStripeRoute.php create mode 100644 services/nginx/app/traits/stripe_endpoint_t.php diff --git a/services/nginx/app/classes/stripe.php b/services/nginx/app/classes/stripe.php new file mode 100644 index 00000000..30b3e44f --- /dev/null +++ b/services/nginx/app/classes/stripe.php @@ -0,0 +1,127 @@ +config = new stripe_c(); + $this->customers = new stripe_endpoint_customers(); + $this->payment_link = new stripe_endpoint_payment_link(); + $this->product = new stripe_endpoint_product(); + $this->prices = new stripe_endpoint_prices(); + } + + /** + * @inheritDoc + * @throws Exception + */ + public function getClient(): StripeClient + { + // Get the stripe client + if (!isset($this->client)) { + // Require the module to be enabled + self::requireModuleEnabled(); + // Require the secret key to be set + self::requireValidSecretKey(); + // Require the publishable key to be set + self::requireValidPublishableKey(); + // Create the client + $this->client = new StripeClient([ + 'api_key' => $this->config->secret_key->getVariableValue() + ]); + } + return $this->client; + } + + /** + * @inheritDoc + * @throws Exception + */ + function requireModuleEnabled(): void + { + // Check if the module is enabled + if (!$this->config->enabled->isTrue()) { + throw new Exception('The Stripe module is not enabled'); + } + } + + /** + * @inheritDoc + * @throws Exception + */ + function requireValidSecretKey(): void + { + // Check if the secret key is valid + if ($this->config->secret_key->getVariableValue() === null) { + throw new Exception('Invalid secret key'); + } + } + + /** + * @inheritDoc + * @throws Exception + */ + public function requireValidPublishableKey(): void + { + // Check if the publishable key is valid + if ($this->config->publishable_key->getVariableValue() === null) { + throw new Exception('Invalid publishable key'); + } + } +} \ No newline at end of file diff --git a/services/nginx/app/index.php b/services/nginx/app/index.php index 47a9dde3..fd11e5f1 100644 --- a/services/nginx/app/index.php +++ b/services/nginx/app/index.php @@ -59,6 +59,7 @@ require_once 'classes/recaptcha.php'; require_once 'classes/email.php'; require_once 'classes/backup_store.php'; require_once 'classes/motorapi.php'; +require_once 'classes/stripe.php'; /** * Modules diff --git a/services/nginx/app/interfaces/stripe_i.php b/services/nginx/app/interfaces/stripe_i.php new file mode 100644 index 00000000..e2122967 --- /dev/null +++ b/services/nginx/app/interfaces/stripe_i.php @@ -0,0 +1,32 @@ +customers->create($data); + } + + /** + * Retrieve a customer + * @param string $id + * @return Customer + * @throws ApiErrorException + * @throws Exception + */ + public function retrieve(string $id): Customer + { + return self::getClient()->customers->retrieve($id); + } + + /** + * Update a customer + * @param string $id + * @param array $data + * @return Customer + * @throws ApiErrorException + * @throws Exception + */ + public function update(string $id, array $data): Customer + { + return self::getClient()->customers->update($id, $data); + } + + /** + * Delete a customer + * @param string $id + * @return Customer + * @throws Exception + */ + public function delete(string $id): Customer + { + return self::getClient()->customers->delete($id); + } + + /** + * List all customers + * @return Collection + * @throws ApiErrorException + * @throws Exception + */ + public function list(): Collection + { + return self::getClient()->customers->all(); + } + +} \ No newline at end of file diff --git a/services/nginx/app/modules/stripe/endpoints/stripe_endpoint_payment_link.php b/services/nginx/app/modules/stripe/endpoints/stripe_endpoint_payment_link.php new file mode 100644 index 00000000..e4703ad7 --- /dev/null +++ b/services/nginx/app/modules/stripe/endpoints/stripe_endpoint_payment_link.php @@ -0,0 +1,75 @@ +paymentLinks->retrieve($id); + } + + /** + * @throws ApiErrorException + * @throws Exception + */ + public function generate(int $order_id, string $email): PaymentLink + { + $order = (new orders_o())->select($order_id); + $order->requireSelected(); + // Get the order items + $order_items = $order->getOrderItems($order_id); + // Create a new line items object + $line_items = new stripe_line_items(); + // Loop through the order items + foreach ( $order_items as $order_item ) { + // Add the order item to the line items + $line_items->add( + new stripe_line_item( + $order_item['product_id'], + $order_item['price'], + $order_item['quantity'] + ) + ); + } + // Create the payment link + return $this->create($line_items, [ + 'order_id' => $order_id, + 'email' => $email + ]); + } + + /** + * Create a new payment link + * @param stripe_line_items $line_items + * @param array $metadata Additional metadata + * @return PaymentLink + * @throws ApiErrorException + * @throws Exception + */ + public function create(stripe_line_items $line_items, array $metadata = []): PaymentLink + { + return self::getClient()->paymentLinks->create([ + 'line_items' => $line_items->get(), + 'metadata' => $metadata + ]); + } + +} \ No newline at end of file diff --git a/services/nginx/app/modules/stripe/endpoints/stripe_endpoint_prices.php b/services/nginx/app/modules/stripe/endpoints/stripe_endpoint_prices.php new file mode 100644 index 00000000..053db290 --- /dev/null +++ b/services/nginx/app/modules/stripe/endpoints/stripe_endpoint_prices.php @@ -0,0 +1,49 @@ +prices->all(); + } + + /** + * @throws ApiErrorException + * @throws Exception + */ + public function create(stripe_price $stripe_price): \Stripe\Price + { + return self::getClient()->prices->create([ + 'unit_amount' => $stripe_price->getUnitAmount(), + 'currency' => $stripe_price->getCurrency(), + 'product' => $stripe_price->getProductID(), + ]); + } + + /** + * @throws ApiErrorException + * @throws Exception + */ + public function retrieve(string $id): \Stripe\Price + { + return self::getClient()->prices->retrieve($id); + } + + +} \ No newline at end of file diff --git a/services/nginx/app/modules/stripe/endpoints/stripe_endpoint_product.php b/services/nginx/app/modules/stripe/endpoints/stripe_endpoint_product.php new file mode 100644 index 00000000..38696ca7 --- /dev/null +++ b/services/nginx/app/modules/stripe/endpoints/stripe_endpoint_product.php @@ -0,0 +1,54 @@ +products->all(); + } + + /** + * Create a new product + * @param stripe_product $product + * @return Product + * @throws ApiErrorException + * @throws Exception + */ + public function create(stripe_product $product): Product + { + return self::getClient()->products->create( + $product->get() + ); + } + + /** + * Retrieve a product + * @param string $id + * @return Product + * @throws ApiErrorException + * @throws Exception + */ + public function retrieve(string $id): Product + { + return self::getClient()->products->retrieve($id); + } + + +} \ No newline at end of file diff --git a/services/nginx/app/modules/stripe/helpers/stripe_line_item.php b/services/nginx/app/modules/stripe/helpers/stripe_line_item.php new file mode 100644 index 00000000..def695af --- /dev/null +++ b/services/nginx/app/modules/stripe/helpers/stripe_line_item.php @@ -0,0 +1,109 @@ +product_id = $product_id; + $this->price = $price; + $this->quantity = $quantity; + } + + /** + * Check if a product exists + * @param int $product_id + * @return bool + */ + public static function doesProductExist(int $product_id): bool + { + // Check if the product exists + $stripe = new stripe(); + try { + $stripe->product->retrieve($product_id); + return true; + } catch (ApiErrorException|Exception $e) { + return false; + } + } + + /** + * Create a product + * @param int $product_id + * @throws ApiErrorException + * @throws Exception + */ + public static function createProduct(int $product_id): void + { + // Create a new product + $stripe = new stripe(); + $stripe->product->create( + new stripe_product($product_id) + ); + } + + /** + * Create a price + * @param int $product_id + * @param int $unit_amount + * @throws ApiErrorException + */ + private function createPrice(int $product_id, int $unit_amount): void + { + // Create a new price + $stripe = new stripe(); + $price = $stripe->prices->create( + new stripe_price($product_id, $unit_amount) + ); + $this->price_id = $price->id; + } + + public function __toString(): string + { + // Return the line item as a JSON string + return json_encode( + self::get() + ); + } + + public function get(): array + { + return [ + //'product' => (int)$this->product_id, + 'price' => (string)$this->price_id, + 'quantity' => (int)$this->quantity, + ]; + } +} \ No newline at end of file diff --git a/services/nginx/app/modules/stripe/helpers/stripe_line_items.php b/services/nginx/app/modules/stripe/helpers/stripe_line_items.php new file mode 100644 index 00000000..0c82621e --- /dev/null +++ b/services/nginx/app/modules/stripe/helpers/stripe_line_items.php @@ -0,0 +1,32 @@ +line_items as $line_item ) { + $line_items[] = is_array($line_item) ? $line_item : $line_item->get(); + } + return $line_items; + } + + public function add(stripe_line_item|array $line_item): void + { + $this->line_items[] = $line_item; + } +} \ No newline at end of file diff --git a/services/nginx/app/modules/stripe/helpers/stripe_price.php b/services/nginx/app/modules/stripe/helpers/stripe_price.php new file mode 100644 index 00000000..eb221102 --- /dev/null +++ b/services/nginx/app/modules/stripe/helpers/stripe_price.php @@ -0,0 +1,36 @@ +product_id = $product_id; + $this->unit_amount = $unit_amount; + $this->currency = $currency; + } + + public function getProductID(): int + { + return $this->product_id; + } + + public function getUnitAmount(): int + { + return $this->unit_amount; + } + + public function getCurrency(): string + { + return $this->currency; + } + + +} \ No newline at end of file diff --git a/services/nginx/app/modules/stripe/helpers/stripe_product.php b/services/nginx/app/modules/stripe/helpers/stripe_product.php new file mode 100644 index 00000000..39950802 --- /dev/null +++ b/services/nginx/app/modules/stripe/helpers/stripe_product.php @@ -0,0 +1,50 @@ +select($id); + $product->requireSelected(); + $this->id = $id; + $this->product = $product; + } + + public function __toString(): string + { + // Return the line item as a JSON string + return json_encode( + self::get() + ); + } + + public function get(): array + { + return [ + 'name' => $this->product->name->value(), + 'id' => $this->id, + ]; + } +} \ No newline at end of file diff --git a/services/nginx/app/modules/stripe/stripe_c.php b/services/nginx/app/modules/stripe/stripe_c.php new file mode 100644 index 00000000..69360d31 --- /dev/null +++ b/services/nginx/app/modules/stripe/stripe_c.php @@ -0,0 +1,45 @@ +setupConfig('Stripe'); + $this->allowUpdate([ + stripe_enabled_c::class, + stripe_publishable_key_c::class, + stripe_secret_key_c::class + ]); + $this->enabled = new stripe_enabled_c(); + $this->publishable_key = new stripe_publishable_key_c(); + $this->secret_key = new stripe_secret_key_c(); + } +} \ No newline at end of file diff --git a/services/nginx/app/objects/orders_o.php b/services/nginx/app/objects/orders_o.php index a1d78048..2328b102 100644 --- a/services/nginx/app/objects/orders_o.php +++ b/services/nginx/app/objects/orders_o.php @@ -22,57 +22,13 @@ class orders_o extends db public economic_module_orders $economic_module_orders; public object_property $created_at; public object_property $deleted_at; + public stripe_module_orders_o $stripe_module_orders; public function structure(): void { $this->setTable('orders'); } - public function objectChanged(): void - { - // Since the orders object is not cached, there is no need to invalidate the cache - } - - public function add(int $customer_id, int $cashier_id, string $reference, string $notes, int $department_id, string $reg_1 = '', string $reg_2 = '', string $reg_3 = ''): orders_o - { - global $db, $response; - try { - // Avoid SQL injection - $reference = $db->escape_string($reference); - $notes = $db->escape_string($notes); - $reg_1 = $db->escape_string($reg_1); - $reg_2 = $db->escape_string($reg_2); - $reg_3 = $db->escape_string($reg_3); - // Create a new record in the database - $sql = "INSERT INTO $this->table (customer_id, cashier_id, reference, notes, department_id, reg_1, reg_2, reg_3) VALUES ($customer_id, $cashier_id, '$reference', '$notes', $department_id, '$reg_1', '$reg_2', '$reg_3')"; - $db->query($sql); - - // Get the id of the new record - $this->id = $db->insert_id(); - - // Set the values of the object properties - $this->getObjectProperties(); - return $this; - } catch (\Exception $e) { - $response->error($e->getMessage()); - } - } - - public function getObjectProperties(): void - { - $this->customer_id = new object_property($this->table, $this->id, 'customer_id', 'int', true); - $this->cashier_id = new object_property($this->table, $this->id, 'cashier_id', 'int', true); - $this->reference = new object_property($this->table, $this->id, 'reference', 'string', true); - $this->notes = new object_property($this->table, $this->id, 'notes', 'string', false); - $this->department_id = new object_property($this->table, $this->id, 'department_id', 'int', true); - $this->reg_1 = new object_property($this->table, $this->id, 'reg_1', 'string', false); - $this->reg_2 = new object_property($this->table, $this->id, 'reg_2', 'string', false); - $this->reg_3 = new object_property($this->table, $this->id, 'reg_3', 'string', false); - $this->created_at = new object_property($this->table, $this->id, 'created_at', 'timestamp', false); - $this->economic_module_orders = (new economic_module_orders())->getByOrderId($this->id); - $this->deleted_at = new object_property($this->table, $this->id, 'deleted_at', 'timestamp', false); - } - public function edit(int $id, int $customer_id, int $cashier_id, string $reference, string $notes, int $department_id): void { global $db, $response; @@ -92,6 +48,22 @@ class orders_o extends db } } + public function getObjectProperties(): void + { + $this->customer_id = new object_property($this->table, $this->id, 'customer_id', 'int', true); + $this->cashier_id = new object_property($this->table, $this->id, 'cashier_id', 'int', true); + $this->reference = new object_property($this->table, $this->id, 'reference', 'string', true); + $this->notes = new object_property($this->table, $this->id, 'notes', 'string', false); + $this->department_id = new object_property($this->table, $this->id, 'department_id', 'int', true); + $this->reg_1 = new object_property($this->table, $this->id, 'reg_1', 'string', false); + $this->reg_2 = new object_property($this->table, $this->id, 'reg_2', 'string', false); + $this->reg_3 = new object_property($this->table, $this->id, 'reg_3', 'string', false); + $this->created_at = new object_property($this->table, $this->id, 'created_at', 'timestamp', false); + $this->economic_module_orders = (new economic_module_orders())->getByOrderId($this->id); + $this->stripe_module_orders = (new stripe_module_orders_o())->select($this->id); + $this->deleted_at = new object_property($this->table, $this->id, 'deleted_at', 'timestamp', false); + } + public function includeIncludes(): orders_o { global /** @var response $response */ @@ -117,6 +89,12 @@ class orders_o extends db if ($response->getRequestParameter('includeEconomicModuleOrders') || $includeEverything) { $response->add_include('economicModuleOrders', $this->economic_module_orders->getByOrderId($this->id)->asArray()); } + /** + * stripeModuleOrders + */ + if ($response->getRequestParameter('includeStripeModuleOrders') || $includeEverything) { + $response->add_include('stripeModuleOrders', $this->stripe_module_orders->exists() ? $this->stripe_module_orders->asArray() : []); + } return $this; } @@ -172,6 +150,16 @@ class orders_o extends db ]; } + public function exists(): bool + { + // Check if the id is greater than 0, and that the deleted_at property is null + if ($this->id > 0) { + $this->getObjectProperties(); + return $this->deleted_at->value() === null; + } + return false; + } + public function getCustomerByOrderId(?string $order_id): users_o { global $db; @@ -285,16 +273,6 @@ class orders_o extends db $this->{$data['field']}->set($data['value']); } - public function exists(): bool - { - // Check if the id is greater than 0, and that the deleted_at property is null - if ($this->id > 0) { - $this->getObjectProperties(); - return $this->deleted_at->value() === null; - } - return false; - } - /** * Get the order history for a vehicle plate * @param string $plate The vehicle plate @@ -320,5 +298,46 @@ class orders_o extends db throw new \Exception('Order not found'); } + /** + * Set the stripe invoicing for an order + * @throws \Exception + */ + public function setStripeInvoicing(string $payment_link_id, string $email, string $url): void + { + self::requireSelected(); + $this->stripe_module_orders->add($this->id, $email, $payment_link_id, $url); + self::objectChanged(); + } + + public function add(int $customer_id, int $cashier_id, string $reference, string $notes, int $department_id, string $reg_1 = '', string $reg_2 = '', string $reg_3 = ''): orders_o + { + global $db, $response; + try { + // Avoid SQL injection + $reference = $db->escape_string($reference); + $notes = $db->escape_string($notes); + $reg_1 = $db->escape_string($reg_1); + $reg_2 = $db->escape_string($reg_2); + $reg_3 = $db->escape_string($reg_3); + // Create a new record in the database + $sql = "INSERT INTO $this->table (customer_id, cashier_id, reference, notes, department_id, reg_1, reg_2, reg_3) VALUES ($customer_id, $cashier_id, '$reference', '$notes', $department_id, '$reg_1', '$reg_2', '$reg_3')"; + $db->query($sql); + + // Get the id of the new record + $this->id = $db->insert_id(); + + // Set the values of the object properties + $this->getObjectProperties(); + return $this; + } catch (\Exception $e) { + $response->error($e->getMessage()); + } + } + + public function objectChanged(): void + { + // Since the orders object is not cached, there is no need to invalidate the cache + } + } \ No newline at end of file diff --git a/services/nginx/app/objects/stripe_module_orders_o.php b/services/nginx/app/objects/stripe_module_orders_o.php new file mode 100644 index 00000000..85c1066a --- /dev/null +++ b/services/nginx/app/objects/stripe_module_orders_o.php @@ -0,0 +1,93 @@ +setTable('stripe_module_orders'); + } + + /** + * Add a payment link to the database + * @param int $order_id + * @param string $email + * @param string $payment_link_id + * @param string $url The URL of the payment link + * @return void + * @throws Exception If the object was not created successfully + */ + public function add(int $order_id, string $email, string $payment_link_id, string $url): void + { + $tmp_id = self::add_object([ + 'id' => $order_id, + 'email' => $email, + 'payment_link_id' => $payment_link_id, + 'url' => $url, + ]); + $this->id = $tmp_id; + self::getObjectProperties(); + self::objectChanged(); + } + + public function getObjectProperties(): void + { + $this->payment_link_id = new object_property($this->table, $this->id, 'payment_link_id', 'string', false); + $this->email = new object_property($this->table, $this->id, 'email', 'string', false); + $this->email_sent = new object_property($this->table, $this->id, 'email_sent', 'timestamp', false); + $this->url = new object_property($this->table, $this->id, 'url', 'string', false); + $this->created_at = new object_property($this->table, $this->id, 'created_at', 'timestamp', false); + } + + public function objectChanged(): void + { + //TODO: Add cache invalidation + } + + /** + * @throws ApiErrorException + */ + public function asArray(): array + { + return [ + 'id' => (int)$this->id, + 'payment_link_id' => (string)$this->payment_link_id->value(), + 'email' => (string)$this->email->value(), + 'email_sent' => $this->email_sent->value() ? (string)$this->email_sent->value() : null, + 'url' => (string)$this->url->value(), + 'created_at' => (string)$this->created_at->value(), + 'object' => self::retrievePaymentLink() + ]; + } + + /** + * @throws ApiErrorException + * @throws Exception + */ + public function retrievePaymentLink(): object + { + // Validate the object + self::requireSelected(); + // Return the payment link + return (new stripe())->payment_link->retrieve($this->payment_link_id->value()); + } + +} \ No newline at end of file diff --git a/services/nginx/app/routes/moduleConfigRoute.php b/services/nginx/app/routes/moduleConfigRoute.php index 512a48a6..a0106210 100644 --- a/services/nginx/app/routes/moduleConfigRoute.php +++ b/services/nginx/app/routes/moduleConfigRoute.php @@ -10,6 +10,7 @@ use classes\motorapi; use classes\recaptcha; use classes\response; use classes\router; +use classes\stripe; use objects\logs_o; use traits\route_t; @@ -208,5 +209,37 @@ class moduleConfigRoute $response->error('Invalid session', 400); } }); + + /** Stripe config > GET */ + $this->get('/stripe/config', function () { + global $response; + $this->requirePermission('stripe_config'); + $user = (new authentication())->get_user(); + if ($user) { + (new logs_o())->add('stripe_config', 'global', 1, $user->id, 'STRIPE_CONFIG', 'Successfully fetched stripe config'); + $response->success( + (new stripe())->config->getConfigRequest() + ); + } else { + (new logs_o())->add('stripe_config', 'global', 1, 0, 'STRIPE_CONFIG', 'No user found, or invalid session'); + $response->error('Invalid session', 400); + } + }); + + /** Stripe config > POST */ + $this->post('/stripe/config', function () { + global $response; + $this->requirePermission('stripe_config'); + $user = (new authentication())->get_user(); + if ($user) { + (new logs_o())->add('stripe_config', 'global', 1, $user->id, 'STRIPE_CONFIG', 'Successfully updated stripe config'); + $response->success( + (new stripe())->config->postConfigRequest() + ); + } else { + (new logs_o())->add('stripe_config', 'global', 1, 0, 'STRIPE_CONFIG', 'No user found, or invalid session'); + $response->error('Invalid session', 400); + } + }); } } \ No newline at end of file diff --git a/services/nginx/app/routes/moduleStripeRoute.php b/services/nginx/app/routes/moduleStripeRoute.php new file mode 100644 index 00000000..0aca95f0 --- /dev/null +++ b/services/nginx/app/routes/moduleStripeRoute.php @@ -0,0 +1,105 @@ + Stripe > Customers > List */ + $this->get('/modules/stripe/customers', function () { + global $response; + self::requirePermission('modules_stripe_customers_list'); + $user = (new authentication())->get_user(); + if ($user) { + (new logs_o())->add('modules_stripe', 'global', 1, 0, 'MODULES_STRIPE', 'User accessed the customers list'); + $result = (new stripe())->customers->list(); + $response->success((object)$result); + } else { + (new logs_o())->add('modules_stripe', 'global', 0, 0, 'MODULES_STRIPE', 'User tried to access the customers list without a valid session'); + $response->error('Invalid session', 400); + } + }); + + /** Modules > Stripe > Products > List */ + $this->get('/modules/stripe/products', function () { + global $response; + self::requirePermission('modules_stripe_products_list'); + $user = (new authentication())->get_user(); + if ($user) { + (new logs_o())->add('modules_stripe', 'global', 1, 0, 'MODULES_STRIPE', 'User accessed the products list'); + $result = (new stripe())->product->list(); + $response->success((object)$result); + } else { + (new logs_o())->add('modules_stripe', 'global', 0, 0, 'MODULES_STRIPE', 'User tried to access the products list without a valid session'); + $response->error('Invalid session', 400); + } + }); + + /** Modules > Stripe > Prices > List */ + $this->get('/modules/stripe/prices', function () { + global $response; + self::requirePermission('modules_stripe_prices_list'); + $user = (new authentication())->get_user(); + if ($user) { + (new logs_o())->add('modules_stripe', 'global', 1, 0, 'MODULES_STRIPE', 'User accessed the prices list'); + $result = (new stripe())->prices->list(); + $response->success((object)$result); + } else { + (new logs_o())->add('modules_stripe', 'global', 0, 0, 'MODULES_STRIPE', 'User tried to access the prices list without a valid session'); + $response->error('Invalid session', 400); + } + }); + + /** Modules > Stripe > Send Invoice */ + $this->post('/modules/stripe/invoice', function () { + global $response; + self::requirePermission('modules_stripe_invoice_send'); + $user = (new authentication())->get_user(); + if ($user) { + self::requireParameters(['email', 'order_id']); + self::requireType(self::fromRequest('email'), 'string'); + self::requireType((int)self::fromRequest('order_id'), self::TYPE_INT()); + self::requireMinLength('email', 4); + self::requireMaxLength('email', 255); + self::requireMinLength('order_id', 1); + self::requireMaxLength('order_id', 255); + // Check if the email is valid + if (!filter_var(self::fromRequest('email'), FILTER_VALIDATE_EMAIL)) { + $response->error('Invalid email', 400); + } + // Check if the order exists + $order = (new orders_o())->select((int)self::fromRequest('order_id')); + $order->requireSelected(); + // Log the action + (new logs_o())->add('modules_stripe', 'global', 1, $user->id, 'MODULES_STRIPE', 'User sent an invoice'); + $result = (new stripe())->payment_link->generate( + (int)self::fromRequest('order_id'), + (string)self::fromRequest('email') + ); + // Set the order stripe invoice details + $order->setStripeInvoicing($result->id, (string)self::fromRequest('email'), $result->url); + // Return the result + $response->success((object)$result); + } else { + (new logs_o())->add('modules_stripe', 'global', 0, 0, 'MODULES_STRIPE', 'User tried to send an invoice without a valid session'); + $response->error('Invalid session', 400); + } + }); + } +} \ No newline at end of file diff --git a/services/nginx/app/traits/stripe_endpoint_t.php b/services/nginx/app/traits/stripe_endpoint_t.php new file mode 100644 index 00000000..cf49c3bc --- /dev/null +++ b/services/nginx/app/traits/stripe_endpoint_t.php @@ -0,0 +1,38 @@ +Stripe()->getClient(); + } + + /** + * Get the stripe class + * @return stripe + */ + public function Stripe(): stripe + { + if (!isset($this->stripe)) { + $this->stripe = new stripe(); + } + return $this->stripe; + } +} \ No newline at end of file