Commit 54cc9f01 by Yvon Kerdoncuff

redirige vers une page de paiement déjà existante : use 10 minutes fixed payzen page timeout

parent e0cdca17
...@@ -5,6 +5,7 @@ namespace App\Controller; ...@@ -5,6 +5,7 @@ namespace App\Controller;
use App\Entity\GlobalParameter; use App\Entity\GlobalParameter;
use App\Entity\Payment; use App\Entity\Payment;
use App\Entity\User; use App\Entity\User;
use App\Repository\PaymentRepository;
use App\Security\LoginAuthenticator; use App\Security\LoginAuthenticator;
use App\Utils\PaymentUtils; use App\Utils\PaymentUtils;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
...@@ -53,6 +54,15 @@ class PaymentController extends AbstractController ...@@ -53,6 +54,15 @@ class PaymentController extends AbstractController
*/ */
public function preparePaymentAction(Form $form, $type, $extra_data = null) public function preparePaymentAction(Form $form, $type, $extra_data = null)
{ {
/* @var PaymentRepository $repo */
$repo = $this->em->getRepository(Payment::class);
//Redirect to starting payment page if a valid starting payment page exists
$url = $repo->findUrlOfValidStartingPayment($this->getUser()->getUsername());
$this->em->flush(); //save status updates when looking to valid starting payment page
if ($url) {
$this->redirect($url);
}
// Enregistre les données du Flux en json, pour l'enregistrer une fois le paiement validé // Enregistre les données du Flux en json, pour l'enregistrer une fois le paiement validé
$serializer = $this->container->get('serializer'); $serializer = $this->container->get('serializer');
$toSerialize = Payment::TYPE_ADHESION == $type ? $form->get('cotisation')->getData() : $form->getData(); $toSerialize = Payment::TYPE_ADHESION == $type ? $form->get('cotisation')->getData() : $form->getData();
...@@ -144,10 +154,16 @@ class PaymentController extends AbstractController ...@@ -144,10 +154,16 @@ class PaymentController extends AbstractController
$captureToken->setTargetUrl($targetUrl); $captureToken->setTargetUrl($targetUrl);
$captureToken->setAfterUrl($afterUrl); $captureToken->setAfterUrl($afterUrl);
$targetUrl = $captureToken->getTargetUrl();
/* @var Payment $payment */
if (!$payment->getPayzenStartingPaymentUrl()) {
$payment->setPayzenStartingPaymentUrl($targetUrl);
}
$this->em->persist($captureToken); $this->em->persist($captureToken);
$this->em->flush(); $this->em->flush();
return $this->redirect($captureToken->getTargetUrl()); return $this->redirect($targetUrl);
} }
/* COMMENT LES FLUX SONT-ILS CREES SUITE A LA CREATION D'UN PAIEMENT PAYZEN ? /* COMMENT LES FLUX SONT-ILS CREES SUITE A LA CREATION D'UN PAIEMENT PAYZEN ?
......
...@@ -21,6 +21,12 @@ class Payment extends BasePayment ...@@ -21,6 +21,12 @@ class Payment extends BasePayment
const TYPE_PAIEMENT_COTISATION_TAV = 'paiement_cotisation_tav'; const TYPE_PAIEMENT_COTISATION_TAV = 'paiement_cotisation_tav';
const TYPE_PAIEMENT_RECURRENT_COTISATION_TAV = 'paiement_recurrent_cotisation_tav'; const TYPE_PAIEMENT_RECURRENT_COTISATION_TAV = 'paiement_recurrent_cotisation_tav';
public function __construct()
{
parent::__construct();
$this->created_at = new \DateTime();
}
/** /**
* @var \Ramsey\Uuid\UuidInterface * @var \Ramsey\Uuid\UuidInterface
* *
...@@ -75,6 +81,28 @@ class Payment extends BasePayment ...@@ -75,6 +81,28 @@ class Payment extends BasePayment
private $recurrenceAmount; private $recurrenceAmount;
/** /**
* @var string|null
* Payzen payment page requested when payment starts
*
* @ORM\Column(type="text", nullable=true)
*/
protected $payzenStartingPaymentUrl;
/**
* @var string|null
*
* @ORM\Column(type="string", length=50, nullable=true)
*/
protected $startingPaymentAnalysisStatus;
/**
* Payment creation datetime.
*
* @ORM\Column(type="datetime", nullable=true)
*/
private $created_at;
/**
* @return string * @return string
*/ */
public function getStatus(): ?string public function getStatus(): ?string
...@@ -182,6 +210,41 @@ class Payment extends BasePayment ...@@ -182,6 +210,41 @@ class Payment extends BasePayment
return $this; return $this;
} }
public function getPayzenStartingPaymentUrl(): ?string
{
return $this->payzenStartingPaymentUrl;
}
public function setPayzenStartingPaymentUrl(?string $payzenStartingPaymentUrl): self
{
$this->payzenStartingPaymentUrl = $payzenStartingPaymentUrl;
}
/**
* @return string
*/
public function getStartingPaymentAnalysisStatus(): ?string
{
return $this->startingPaymentAnalysisStatus;
}
/**
* @param string $startingPaymentAnalysisStatus
*
* @return Payment
*/
public function setStartingPaymentAnalysisStatus(string $startingPaymentAnalysisStatus): self
{
$this->startingPaymentAnalysisStatus = $startingPaymentAnalysisStatus;
return $this;
}
public function getCreatedAt(): ?DateTime
{
return $this->created_at;
}
/** /**
* Return null in case of error * Return null in case of error
* Returns true if payment is already ended or CB expired * Returns true if payment is already ended or CB expired
......
<?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 Version20240930144459 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 payment ADD payzen_starting_payment_url LONGTEXT DEFAULT NULL, ADD starting_payment_analysis_status VARCHAR(50) DEFAULT NULL');
}
public function down(Schema $schema) : void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE payment DROP payzen_starting_payment_url, DROP starting_payment_analysis_status');
}
}
<?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 Version20241007081547 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 payment ADD created_at DATETIME DEFAULT NULL');
}
public function down(Schema $schema) : void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE payment DROP created_at');
}
}
...@@ -5,6 +5,7 @@ namespace App\Repository; ...@@ -5,6 +5,7 @@ namespace App\Repository;
use App\Entity\Payment; use App\Entity\Payment;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry; use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\HttpClient\HttpClient;
/** /**
* @method Siege|null find($id, $lockMode = null, $lockVersion = null) * @method Siege|null find($id, $lockMode = null, $lockVersion = null)
...@@ -39,4 +40,39 @@ class PaymentRepository extends ServiceEntityRepository ...@@ -39,4 +40,39 @@ class PaymentRepository extends ServiceEntityRepository
return $results[0]; return $results[0];
} }
} }
/*
* Everytime a user clicks on "Payer en CB" button on the kohinos side,
* a Payment entry is created, with status NULL.
* We want to prevent a user from starting several payments, which can
* lead to duplicates.
* If we find a valid starting Payment, we will return the payzen URL used to start the payment.
* We mark as unvalid Payment that are unvalid when we check them.
*/
public function findUrlOfValidStartingPayment($clientEmail)
{
$candidates = $this->findBy([
'clientEmail' => $clientEmail,
'status' => null,
'startingPaymentAnalysisStatus' => null,
]);
foreach ($candidates as $p) {
/* @var Payment $p */
$url = $p->getPayzenStartingPaymentUrl();
if (!$url) {
$p->setStartingPaymentAnalysisStatus('NO URL');
continue;
}
$createdAt = clone $p->getCreatedAt(); //don't modify original object
$timeout = $createdAt->add(\DateInterval::createFromDateString("10 minutes"));
if ($timeout < new \DateTime()) {
$p->setStartingPaymentAnalysisStatus('TIMEOUT');
} else {
return $url;
}
}
//no valid payment found
return '';
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment