Add basic gateways

This commit is contained in:
2023-12-13 16:02:06 +01:00
parent 53ff67d107
commit 9067cdc8e0
9 changed files with 157 additions and 3 deletions
+6
View File
@@ -14,6 +14,8 @@ services:
_instanceof:
App\Library\Economy\Currency\ExchangeInterface:
tags: ['app.lib.economy.currency.exchange']
App\Library\Economy\Payment\GatewayInterface:
tags: ['app.lib.economy.payment.gateway']
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
@@ -34,5 +36,9 @@ services:
arguments:
- !tagged 'app.lib.economy.currency.exchange'
App\Library\Economy\Payment\GatewayLocator:
arguments:
- !tagged 'app.lib.economy.payment.gateway'
# add more service definitions when explicit configuration is needed
# please note that last definitions always *replace* previous ones
+24
View File
@@ -0,0 +1,24 @@
<?php
namespace App\ApiResource;
use ApiPlatform\Metadata as API;
use App\Library\Economy\Payment\GatewayInterface;
use App\State\GatewayStateProvider;
/**
* Gateways represent external payment services
*/
#[API\GetCollection(provider: GatewayStateProvider::class)]
#[API\Get(provider: GatewayStateProvider::class)]
class Gateway
{
public function __construct(private readonly GatewayInterface $gateway) {
}
#[API\ApiProperty(identifier: true)]
public function getName(): string
{
return $this->gateway->getName();
}
}
-1
View File
@@ -15,7 +15,6 @@ use Symfony\Component\Validator\Constraints as Assert;
* When making relations between Transactions and Accountings you are effectively altering the platform's internal economy.
*/
#[ORM\Entity(repositoryClass: AccountingRepository::class)]
#[API\ApiResource()]
#[API\GetCollection()]
#[API\Get()]
#[API\Put()]
+4 -2
View File
@@ -11,8 +11,10 @@ use Symfony\Component\Validator\Constraints as Assert;
/**
* Transactions represent a movement of funds inside the platform.\
* When making relations between Transactions and Accountings you are effectively altering the platform's internal economy.\
* Transactions cannot be mutated after they are stored.
* When making relations between Transactions and Accountings you are effectively altering the platform's internal economy.
* \
* \
* Transactions cannot be mutated after they are stored.\
* If in need to reverse a Transaction generate a new Transaction reversing the to-be-cancelled one.
*/
#[ORM\Entity(repositoryClass: TransactionRepository::class)]
@@ -2,6 +2,8 @@
namespace App\Library\Economy;
use ApiPlatform\Metadata as API;
abstract class AbstractMonetizable
{
abstract public function getAmount(): int;
@@ -25,6 +27,7 @@ abstract class AbstractMonetizable
);
}
#[API\ApiProperty(readable: false)]
public function isZero(): bool
{
return $this->toBrickMoney()->isZero();
@@ -0,0 +1,11 @@
<?php
namespace App\Library\Economy\Payment;
interface GatewayInterface
{
/**
* @return string A short, unique, descriptive string of your gateway
*/
public function getName(): string;
}
@@ -0,0 +1,49 @@
<?php
namespace App\Library\Economy\Payment;
class GatewayLocator
{
/** @var GatewayInterface[] */
private array $gateways;
public function __construct(iterable $gateways)
{
/** @var GatewayInterface[] */
$gateways = \iterator_to_array($gateways);
foreach ($gateways as $gateway) {
$this->gateways[$gateway->getName()] = $gateway;
}
}
/**
* @return array<string> List of the available Gateway names
*/
public function getNames(): array
{
return \array_keys($this->gateways);
}
/**
* @return GatewayInterface[]
*/
public function getGateways(): array
{
return $this->gateways;
}
/**
* @param string $name Name of the Gateway interface implementation
* @return GatewayInterface
* @throws \Exception When the $name does not match to that of an implemented Gateway
*/
public function getGateway(string $name): GatewayInterface
{
if (!\array_key_exists($name, $this->gateways)) {
throw new \Exception("No such Gateway with the name $name");
}
return $this->gateways[$name];
}
}
@@ -0,0 +1,11 @@
<?php
namespace App\Library\Economy\Payment;
class StripeGateway implements GatewayInterface
{
public function getName(): string
{
return 'stripe';
}
}
+49
View File
@@ -0,0 +1,49 @@
<?php
namespace App\State;
use ApiPlatform\Metadata as API;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProviderInterface;
use App\ApiResource\Gateway;
use App\Library\Economy\Payment\GatewayLocator;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class GatewayStateProvider implements ProviderInterface
{
public function __construct(
private GatewayLocator $gateways
) {
}
private function getGateways(): array
{
$gateways = [];
foreach ($this->gateways->getGateways() as $gateway) {
$gateways[] = new Gateway($gateway);
}
return $gateways;
}
private function getGateway(string $name): Gateway
{
try {
$gateway = $this->gateways->getGateway($name);
return new Gateway($gateway);
} catch (\Exception $e) {
throw new NotFoundHttpException("Not Found");
}
}
public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
{
switch ($operation::class) {
case API\GetCollection::class:
return $this->getGateways();
case API\Get::class:
return $this->getGateway($uriVariables['name']);
}
}
}