feat(WalletController): Ajoute la création de paiement de wallet

Cette commit ajoute une route pour créer des paiements de wallet via l'API, incluant la validation des headers et la création de l'historique.
This commit is contained in:
Serreau Jovann
2025-11-11 15:29:40 +01:00
parent 50063dfadc
commit ceef8b7a44
5 changed files with 159 additions and 8 deletions

View File

@@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20251111141753 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE customer_wallet_history ADD is_completed BOOLEAN NOT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE SCHEMA public');
$this->addSql('ALTER TABLE customer_wallet_history DROP is_completed');
}
}

View File

@@ -2,10 +2,13 @@
namespace App\Controller\Api\Private\EsyWeb;
use App\Entity\CustomerWalletHistory;
use App\Entity\EsyWeb\WebsiteDns;
use App\Entity\EsyWeb\WebsiteKey;
use App\Repository\EsyWeb\WebsiteDnsRepository;
use App\Repository\EsyWeb\WebsiteKeyRepository;
use App\Service\Stancer\Client;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
@@ -74,13 +77,15 @@ class WalletController extends AbstractController
$historys = [];
foreach ($wallet->getCustomerWalletHistories() as $history) {
$historys[] = [
'ammount' => $history->getAmmount(),
'paymentId' => $history->getPaimentId(),
'entryAt' => $history->getEntryAt()->format('d/m/Y H:i:s'),
'operation' => $history->getOperation(),
'linkFac' => ($history->getPaimentId() != null)?"/":null
];
if($history->isCompleted()) {
$historys[] = [
'ammount' => $history->getAmmount(),
'paymentId' => $history->getPaimentId(),
'entryAt' => $history->getEntryAt()->format('d/m/Y H:i:s'),
'operation' => $history->getOperation(),
'linkFac' => ($history->getPaimentId() != null) ? "/" : null
];
}
}
// 5. Success response
return $this->json([
@@ -88,4 +93,86 @@ class WalletController extends AbstractController
'history' => $historys
]);
}
#[Route('/api/private/esyweb/wallet', name: 'api_private_esyweb_wallet_process', methods: ['POST'])]
public function walletCreatePayment(
Request $request,
WebsiteDnsRepository $websiteDnsRepository,
WebsiteKeyRepository $websiteKeyRepository,
EntityManagerInterface $entityManager,
Client $client,
): JsonResponse {
// Helper function to return a standardized 'unkown' error response
$errorResponse = function (): JsonResponse {
return $this->json(['wallet' => 0,'history'=>[]], Response::HTTP_BAD_REQUEST);
};
// 1. Get and validate required headers
$dns = $request->headers->get('EsyWebDns');
$apiKey = $request->headers->get('EsyWebApiKey');
if (!$dns || !$apiKey) {
// Note: The ApiSubscriber should ideally handle the *missing* headers.
// This handles the case where the headers might be present but empty strings.
return $errorResponse();
}
// 2. Find WebsiteDns
/** @var WebsiteDns|null $websiteDns */
$websiteDns = $websiteDnsRepository->findOneBy(['dns' => $dns]);
if (!$websiteDns) {
return $errorResponse();
}
// 3. Find WebsiteKey (checking against the constant for type)
/** @var WebsiteKey|null $websiteApiKey */
$websiteApiKey = $websiteKeyRepository->findOneBy([
'apiKey' => $apiKey,
'type' => self::API_KEY_TYPE
]);
if (!$websiteApiKey) {
return $errorResponse();
}
// 4. Cross-reference the Website objects
$websiteFromDns = $websiteDns->getWebsite();
$websiteFromKey = $websiteApiKey->getWebsitre();
if (!$websiteFromDns || !$websiteFromKey || $websiteFromDns->getId() !== $websiteFromKey->getId()) {
// This check ensures both the DNS and API Key belong to the same website
return $errorResponse();
}
$content = json_decode($request->getContent());
if(!isset($content->amount)) {
return $errorResponse();
}
if($content->amount < 0) {
return $errorResponse();
}
$wallet = $websiteFromDns->getCustomer()->getCustomerWallet();
$ch = new CustomerWalletHistory();
$ch->setWallet($wallet);
$ch->setOperation("credit");
$ch->setDescrition("");
$ch->setEntryAt(new \DateTimeImmutable());
$ch->setIsCompleted(false);
$ch->setAmmount($content->amount);
$ch->setAuthor($websiteFromDns->getCustomer()->getRaisonSocial());
$paymentId = $client->createPayementWallet($ch);
$ch->setPaimentId($paymentId->getId());
$entityManager->persist($ch);
$entityManager->flush();
return $this->json([
'link' => $paymentId->getPaymentPageUrl()
]);
}
}

View File

@@ -700,6 +700,7 @@ class CustomerController extends AbstractController
if($formWallet->isSubmitted() && $formWallet->isValid()) {
$wallet = $customer->getCustomerWallet();
$ch->setIsCompleted(true);
if($ch->getOperation() == "credit")
$wallet->setAmmount($wallet->getAmmount()+floatval($ch->getAmmount()));
else

View File

@@ -34,6 +34,9 @@ class CustomerWalletHistory
#[ORM\Column(length: 255, nullable: true)]
private ?string $paimentId = null;
#[ORM\Column]
private ?bool $isCompleted = null;
public function getId(): ?int
{
return $this->id;
@@ -122,4 +125,16 @@ class CustomerWalletHistory
return $this;
}
public function isCompleted(): ?bool
{
return $this->isCompleted;
}
public function setIsCompleted(bool $isCompleted): static
{
$this->isCompleted = $isCompleted;
return $this;
}
}

View File

@@ -6,13 +6,16 @@ use App\Entity\Customer as AppCustomer;
use Doctrine\ORM\EntityManagerInterface;
use Stancer\Config;
use Stancer\Customer;
use Stancer\Payment;
use Stancer\Sepa;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class Client
{
private Config $client;
public function __construct(private readonly EntityManagerInterface $entityManager)
public function __construct(private readonly RequestStack $requestStack,private readonly UrlGeneratorInterface $urlGenerator, private readonly EntityManagerInterface $entityManager)
{
$publicKey = $_ENV['STANCER_PUBLIC_KEY'] ?? '';
$privateKey = $_ENV['STANCER_PRIVATE_KEY'] ?? '';
@@ -58,4 +61,17 @@ class Client
$sepa->setName($param['titulaire_compte']);
return$sepa->send();
}
public function createPayementWallet(\App\Entity\CustomerWalletHistory $ch)
{
$customer = $ch->getWallet()->getCustomer();
$payment = new Payment();
$payment->setCustomer(Customer::retrieve($customer->getStancerId()));
$payment->setCurrency('eur');
$url = ($_ENV['APP_ENV'] == "dev")?$_ENV['DEV_URL']:$this->requestStack->getCurrentRequest()->getSchemeAndHttpHost();
$payment->setReturnUrl($url.$this->urlGenerator->generate('app_logout'));
$payment->setAmount($ch->getAmmount()*100);
return $payment->send();
}
}