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.
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
namespace classes;
|
||||
|
||||
require_once WD . '/modules/stripe/stripe_c.php';
|
||||
require_once WD . '/modules/stripe/endpoints/stripe_endpoint_customers.php';
|
||||
require_once WD . '/modules/stripe/endpoints/stripe_endpoint_payment_link.php';
|
||||
require_once WD . '/modules/stripe/endpoints/stripe_endpoint_product.php';
|
||||
require_once WD . '/modules/stripe/endpoints/stripe_endpoint_prices.php';
|
||||
|
||||
|
||||
// Require all helper classes
|
||||
require_once WD . '/modules/stripe/helpers/stripe_line_items.php';
|
||||
require_once WD . '/modules/stripe/helpers/stripe_line_item.php';
|
||||
require_once WD . '/modules/stripe/helpers/stripe_product.php';
|
||||
require_once WD . '/modules/stripe/helpers/stripe_price.php';
|
||||
|
||||
|
||||
use Exception;
|
||||
use interfaces\stripe_i;
|
||||
use stripe\endpoints\stripe_endpoint_customers;
|
||||
use stripe\endpoints\stripe_endpoint_payment_link;
|
||||
use stripe\endpoints\stripe_endpoint_prices;
|
||||
use stripe\endpoints\stripe_endpoint_product;
|
||||
use stripe\stripe_c;
|
||||
use Stripe\StripeClient;
|
||||
|
||||
class stripe implements stripe_i
|
||||
{
|
||||
/**
|
||||
* Configuration of the stripe module
|
||||
* @var stripe_c
|
||||
*/
|
||||
public stripe_c $config;
|
||||
/**
|
||||
* Customers endpoint
|
||||
* @var stripe_endpoint_customers
|
||||
*/
|
||||
public stripe_endpoint_customers $customers;
|
||||
/**
|
||||
* Payment link endpoint
|
||||
* @var stripe_endpoint_payment_link
|
||||
*/
|
||||
public stripe_endpoint_payment_link $payment_link;
|
||||
/**
|
||||
* Product endpoint
|
||||
* @var stripe_endpoint_product
|
||||
*/
|
||||
public stripe_endpoint_product $product;
|
||||
/**
|
||||
* Prices endpoint
|
||||
* @var stripe_endpoint_prices
|
||||
*/
|
||||
public stripe_endpoint_prices $prices;
|
||||
/**
|
||||
* Stripe client
|
||||
* @var StripeClient
|
||||
*/
|
||||
protected StripeClient $client;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->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');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace interfaces;
|
||||
|
||||
use Stripe\StripeClient;
|
||||
|
||||
interface stripe_i
|
||||
{
|
||||
/**
|
||||
* Require the module to be enabled
|
||||
* @returns void
|
||||
*/
|
||||
public function requireModuleEnabled(): void;
|
||||
|
||||
/**
|
||||
* Require the secret key to be set
|
||||
* @returns void
|
||||
*/
|
||||
public function requireValidSecretKey(): void;
|
||||
|
||||
/**
|
||||
* Require the publishable key to be set
|
||||
* @returns void
|
||||
*/
|
||||
public function requireValidPublishableKey(): void;
|
||||
|
||||
/**
|
||||
* Get the Stripe client
|
||||
* @returns StripeClient
|
||||
*/
|
||||
public function getClient(): StripeClient;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace stripe\config;
|
||||
|
||||
use Exception;
|
||||
use traits\module_config_variable;
|
||||
|
||||
class stripe_enabled_c
|
||||
{
|
||||
use module_config_variable;
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
self::setupConfigVariable(
|
||||
'Stripe',
|
||||
'enabled',
|
||||
'bool',
|
||||
true,
|
||||
null,
|
||||
'Whether Stripe is enabled',
|
||||
'1',
|
||||
false,
|
||||
'false'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace stripe\config;
|
||||
|
||||
use Exception;
|
||||
use traits\module_config_variable;
|
||||
|
||||
class stripe_publishable_key_c
|
||||
{
|
||||
use module_config_variable;
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
self::setupConfigVariable(
|
||||
'Stripe',
|
||||
'publishable_key',
|
||||
'string',
|
||||
true,
|
||||
null,
|
||||
'The publishable key for stripe',
|
||||
'1',
|
||||
false,
|
||||
''
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace stripe\config;
|
||||
|
||||
use Exception;
|
||||
use traits\module_config_variable;
|
||||
|
||||
class stripe_secret_key_c
|
||||
{
|
||||
use module_config_variable;
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
self::setupConfigVariable(
|
||||
'Stripe',
|
||||
'secret_key',
|
||||
'string',
|
||||
true,
|
||||
null,
|
||||
'The secret key for stripe',
|
||||
'1',
|
||||
true,
|
||||
''
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace stripe\endpoints;
|
||||
|
||||
use Exception;
|
||||
use Stripe\Collection;
|
||||
use Stripe\Customer;
|
||||
use Stripe\Exception\ApiErrorException;
|
||||
use traits\stripe_endpoint_t;
|
||||
|
||||
class stripe_endpoint_customers
|
||||
{
|
||||
use stripe_endpoint_t;
|
||||
|
||||
/**
|
||||
* Create a new customer
|
||||
* @param array $data
|
||||
* @return Customer
|
||||
* @throws ApiErrorException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function create(array $data): Customer
|
||||
{
|
||||
return self::getClient()->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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace stripe\endpoints;
|
||||
|
||||
use Exception;
|
||||
use objects\orders_o;
|
||||
use Stripe\Exception\ApiErrorException;
|
||||
use stripe\helpers\stripe_line_item;
|
||||
use stripe\helpers\stripe_line_items;
|
||||
use Stripe\PaymentLink;
|
||||
use traits\stripe_endpoint_t;
|
||||
|
||||
class stripe_endpoint_payment_link
|
||||
{
|
||||
use stripe_endpoint_t;
|
||||
|
||||
/**
|
||||
* Retrieve a payment link
|
||||
* @param string $id
|
||||
* @return PaymentLink
|
||||
* @throws ApiErrorException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function retrieve(string $id): PaymentLink
|
||||
{
|
||||
return self::getClient()->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
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace stripe\endpoints;
|
||||
|
||||
use Exception;
|
||||
use Stripe\Collection;
|
||||
use Stripe\Exception\ApiErrorException;
|
||||
use stripe\helpers\stripe_price;
|
||||
use traits\stripe_endpoint_t;
|
||||
|
||||
class stripe_endpoint_prices
|
||||
{
|
||||
use stripe_endpoint_t;
|
||||
|
||||
/**
|
||||
* Get all prices
|
||||
* @return Collection
|
||||
* @throws ApiErrorException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function list(): Collection
|
||||
{
|
||||
return self::getClient()->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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace stripe\endpoints;
|
||||
|
||||
use Exception;
|
||||
use Stripe\Collection;
|
||||
use Stripe\Exception\ApiErrorException;
|
||||
use stripe\helpers\stripe_product;
|
||||
use Stripe\Product;
|
||||
use traits\stripe_endpoint_t;
|
||||
|
||||
class stripe_endpoint_product
|
||||
{
|
||||
use stripe_endpoint_t;
|
||||
|
||||
/**
|
||||
* Get all products
|
||||
* @return Collection
|
||||
* @throws ApiErrorException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function list(): Collection
|
||||
{
|
||||
return self::getClient()->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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
namespace stripe\helpers;
|
||||
|
||||
use classes\stripe;
|
||||
use Exception;
|
||||
use Stripe\Exception\ApiErrorException;
|
||||
|
||||
class stripe_line_item
|
||||
{
|
||||
/**
|
||||
* @var int $product_id
|
||||
*/
|
||||
protected int $product_id;
|
||||
/**
|
||||
* Price (Unit amount)
|
||||
* @var int $price
|
||||
*/
|
||||
protected int $price;
|
||||
/**
|
||||
* @var int $quantity
|
||||
*/
|
||||
protected int $quantity;
|
||||
protected string $price_id;
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __construct(int $product_id, int $price, int $quantity = 1)
|
||||
{
|
||||
// Multiply the price by 100 to convert it to the smallest currency unit
|
||||
$price = $price * 100;
|
||||
// Check if the product exists
|
||||
if (!self::doesProductExist($product_id)) {
|
||||
// If the product does not exist, import it from the database
|
||||
self::createProduct($product_id);
|
||||
}
|
||||
// Create the price object (This seems redundant, but it is necessary for the Stripe API)
|
||||
self::createPrice($product_id, $price);
|
||||
$this->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,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace stripe\helpers;
|
||||
|
||||
class stripe_line_items
|
||||
{
|
||||
/**
|
||||
* @var array $line_items
|
||||
*/
|
||||
protected array $line_items = [];
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
// Return the line items as a JSON string
|
||||
return json_encode(self::get());
|
||||
}
|
||||
|
||||
public function get(): array
|
||||
{
|
||||
$line_items = [];
|
||||
/** @var stripe_line_item|array $line_item */
|
||||
foreach ( $this->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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace stripe\helpers;
|
||||
|
||||
class stripe_price
|
||||
{
|
||||
protected int $product_id;
|
||||
protected int $unit_amount;
|
||||
protected string $currency;
|
||||
protected string $id;
|
||||
|
||||
|
||||
public function __construct(int $product_id, int $unit_amount, string $currency = 'DKK')
|
||||
{
|
||||
$this->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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace stripe\helpers;
|
||||
|
||||
use Exception;
|
||||
use objects\products_o;
|
||||
|
||||
class stripe_product
|
||||
{
|
||||
/**
|
||||
* Product id
|
||||
* @var int $id
|
||||
*/
|
||||
protected int $id;
|
||||
/**
|
||||
* Product object
|
||||
* @var products_o $product
|
||||
*/
|
||||
protected products_o $product;
|
||||
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __construct(int $id)
|
||||
{
|
||||
// Get the product name from the database
|
||||
$products_o = new products_o();
|
||||
$product = $products_o->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,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace stripe;
|
||||
require_once WD . '/modules/stripe/config/stripe_enabled_c.php';
|
||||
require_once WD . '/modules/stripe/config/stripe_publishable_key_c.php';
|
||||
require_once WD . '/modules/stripe/config/stripe_secret_key_c.php';
|
||||
|
||||
use stripe\config\stripe_enabled_c;
|
||||
use stripe\config\stripe_publishable_key_c;
|
||||
use stripe\config\stripe_secret_key_c;
|
||||
use traits\module_config_t;
|
||||
|
||||
class stripe_c
|
||||
{
|
||||
use module_config_t;
|
||||
|
||||
/**
|
||||
* The status of reCAPTCHA, whether it is enabled or not
|
||||
* @var stripe_enabled_c
|
||||
*/
|
||||
public stripe_enabled_c $enabled;
|
||||
/**
|
||||
* The publishable key for stripe
|
||||
* @var stripe_publishable_key_c
|
||||
*/
|
||||
public stripe_publishable_key_c $publishable_key;
|
||||
/**
|
||||
* The secret key for stripe
|
||||
* @var stripe_secret_key_c
|
||||
*/
|
||||
public stripe_secret_key_c $secret_key;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->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();
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
namespace objects;
|
||||
|
||||
use classes\db;
|
||||
use classes\object_property;
|
||||
use classes\stripe;
|
||||
use Exception;
|
||||
use Stripe\Exception\ApiErrorException;
|
||||
use traits\db_object_t;
|
||||
|
||||
class stripe_module_orders_o extends db
|
||||
{
|
||||
use db_object_t;
|
||||
|
||||
public object_property $payment_link_id;
|
||||
public object_property $email;
|
||||
public object_property $email_sent;
|
||||
public object_property $url;
|
||||
|
||||
public object_property $created_at;
|
||||
|
||||
|
||||
public function structure(): void
|
||||
{
|
||||
$this->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());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
namespace routes;
|
||||
|
||||
use classes\authentication;
|
||||
use classes\response;
|
||||
use classes\router;
|
||||
use classes\stripe;
|
||||
use objects\logs_o;
|
||||
use objects\orders_o;
|
||||
use traits\route_t;
|
||||
|
||||
class moduleStripeRoute
|
||||
{
|
||||
use route_t;
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
global /** @var response $response */
|
||||
/** @var router $router */
|
||||
$router, $response;
|
||||
|
||||
|
||||
/** Modules > 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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace traits;
|
||||
|
||||
use classes\stripe;
|
||||
use Exception;
|
||||
use Stripe\StripeClient;
|
||||
|
||||
trait stripe_endpoint_t
|
||||
{
|
||||
/**
|
||||
* Stripe
|
||||
* @var stripe $stripe
|
||||
*/
|
||||
protected stripe $stripe;
|
||||
|
||||
/**
|
||||
* Get the Stripe client
|
||||
* @return StripeClient
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getClient(): StripeClient
|
||||
{
|
||||
return $this->Stripe()->getClient();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the stripe class
|
||||
* @return stripe
|
||||
*/
|
||||
public function Stripe(): stripe
|
||||
{
|
||||
if (!isset($this->stripe)) {
|
||||
$this->stripe = new stripe();
|
||||
}
|
||||
return $this->stripe;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user