Commit 7d6d9e20 by Damien Moulard

Removed git submodule: payum-payzen is just a local lib

parent da9125f9
payum-payzen @ 17c280ea
Subproject commit 17c280ea86308a430cc355578264a1c1f0800edd
<?php
namespace Ekyna\Component\Payum\Payzen\Action\Api;
use Ekyna\Component\Payum\Payzen\Api\Api;
use Payum\Core\Action\ActionInterface;
use Payum\Core\ApiAwareInterface;
use Payum\Core\Exception\UnsupportedApiException;
use Payum\Core\GatewayAwareInterface;
use Payum\Core\GatewayAwareTrait;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerInterface;
/**
* Class AbstractApiAction
* @package Ekyna\Component\Payum\Payzen\Action\Api
* @author Etienne Dauvergne <contact@ekyna.com>
*/
abstract class AbstractApiAction implements ActionInterface, GatewayAwareInterface, ApiAwareInterface, LoggerAwareInterface
{
use GatewayAwareTrait;
/**
* @var Api
*/
protected $api;
/**
* @var LoggerInterface
*/
private $logger;
/**
* @inheritDoc
*/
public function setApi($api)
{
if (false == $api instanceof Api) {
throw new UnsupportedApiException('Not supported.');
}
$this->api = $api;
}
/**
* {@inheritDoc}
*/
public function setLogger(LoggerInterface $logger)
{
$this->logger = $logger;
}
/**
* Logs the given message.
*
* @param string $message
*/
protected function log($message)
{
if (!$this->logger) {
return;
}
$this->logger->debug($message);
}
/**
* Logs the given message and data.
*
* @param string $message
* @param array $data
* @param array $filterKeys
*/
protected function logData($message, array $data, array $filterKeys = [])
{
if (!$this->logger) {
return;
}
if (!empty($filterKeys)) {
$data = array_intersect_key($data, array_flip($filterKeys));
}
$data = array_map(function($key, $value) {
return "$key: $value";
}, array_keys($data), $data);
$this->logger->debug($message . ': ' . implode(', ', $data));
}
}
<?php
namespace Ekyna\Component\Payum\Payzen\Action\Api;
use Ekyna\Component\Payum\Payzen\Request\Request;
use Payum\Core\Bridge\Spl\ArrayObject;
use Payum\Core\Exception\RequestNotSupportedException;
use Payum\Core\Reply\HttpRedirect;
/**
* Class RequestAction
* @package Ekyna\Component\Payum\Payzen\Action\Api
* @author Etienne Dauvergne <contact@ekyna.com>
*/
class ApiRequestAction extends AbstractApiAction
{
/**
* @inheritdoc
*
* @throws \Payum\Core\Reply\HttpRedirect
*/
public function execute($request)
{
/** @var Request $request */
RequestNotSupportedException::assertSupports($this, $request);
$model = ArrayObject::ensureArrayObject($request->getModel());
if ($model['vads_trans_id']) {
return;
}
$model['vads_trans_id'] = $this->api->getTransactionId();
// Current UTC date time
$model['vads_trans_date'] = (new \DateTime('now', new \DateTimeZone('UTC')))->format('YmdHis');
$data = $model->getArrayCopy();
$this->logRequestData($data);
$url = $this->api->createRequestUrl($data);
throw new HttpRedirect($url);
}
/**
* Logs the request data.
*
* @param array $data
*/
private function logRequestData(array $data)
{
$this->logData("[Payzen] Request", $data, [
'vads_order_id',
'vads_amount',
'vads_ctx_mode',
'vads_currency',
'vads_payment_config',
'vads_site_id',
'vads_trans_date',
'vads_trans_id',
'vads_version',
]);
}
/**
* @inheritdoc
*/
public function supports($request)
{
return $request instanceof Request
&& $request->getModel() instanceof \ArrayAccess;
}
}
<?php
namespace Ekyna\Component\Payum\Payzen\Action\Api;
use Ekyna\Component\Payum\Payzen\Request\Response;
use Payum\Core\Bridge\Spl\ArrayObject;
use Payum\Core\Exception\RequestNotSupportedException;
use Payum\Core\Request\GetHttpRequest;
/**
* Class ResponseAction
* @package Ekyna\Component\Payum\Payzen\Action\Api
* @author Etienne Dauvergne <contact@ekyna.com>
*/
class ApiResponseAction extends AbstractApiAction
{
/**
* @inheritdoc
*/
public function execute($request)
{
/** @var Response $request */
RequestNotSupportedException::assertSupports($this, $request);
$model = ArrayObject::ensureArrayObject($request->getModel());
$this->gateway->execute($httpRequest = new GetHttpRequest());
if (isset($httpRequest->request['vads_result'])) {
$data = $httpRequest->request;
} elseif (isset($httpRequest->query['vads_result'])) {
$data = $httpRequest->query;
} else {
return;
}
$this->logResponseData($data);
// Check amount
if ($model['vads_amount'] != $data['vads_amount']) {
return;
}
// Check the response signature
if ($this->api->checkResponseIntegrity($data)) {
// Update the payment details
$model->replace($data);
$request->setModel($model);
}
}
/**
* Logs the response data.
*
* @param array $data
*/
private function logResponseData(array $data)
{
$this->logData("[Payzen] Response", $data, [
'vads_order_id',
'vads_trans_id',
'vads_amount',
'vads_auth_result',
'vads_auth_mode',
'vads_auth_number',
'vads_validation_mode',
'vads_result',
'vads_extra_result',
'vads_warranty_result',
]);
}
/**
* @inheritdec
*/
public function supports($request)
{
return $request instanceof Response
&& $request->getModel() instanceof \ArrayAccess;
}
}
<?php
namespace Ekyna\Component\Payum\Payzen\Action;
use Ekyna\Component\Commerce\Bridge\Payum\Request\GetHumanStatus;
use Payum\Core\Action\ActionInterface;
use Payum\Core\Bridge\Spl\ArrayObject;
use Payum\Core\Exception\RequestNotSupportedException;
use Payum\Core\GatewayAwareInterface;
use Payum\Core\GatewayAwareTrait;
use Payum\Core\Request\Cancel;
/**
* Class CancelAction
* @package Ekyna\Component\Payum\Payzen\Action
* @author Etienne Dauvergne <contact@ekyna.com>
*/
class CancelAction implements ActionInterface, GatewayAwareInterface
{
use GatewayAwareTrait;
/**
* {@inheritdoc}
*
* @param Cancel $request
*/
public function execute($request)
{
RequestNotSupportedException::assertSupports($this, $request);
$model = ArrayObject::ensureArrayObject($request->getModel());
$this->gateway->execute($status = new GetHumanStatus($model));
if ($status->isNew()) {
$model['state_override'] = 'canceled';
}
}
/**
* {@inheritdoc}
*/
public function supports($request)
{
return $request instanceof Cancel
&& $request->getModel() instanceof \ArrayAccess;
}
}
<?php
namespace Ekyna\Component\Payum\Payzen\Action;
use Ekyna\Component\Payum\Payzen\Request\Request;
use Payum\Core\Action\ActionInterface;
use Payum\Core\Bridge\Spl\ArrayObject;
use Payum\Core\Exception\RequestNotSupportedException;
use Payum\Core\GatewayAwareInterface;
use Payum\Core\GatewayAwareTrait;
use Payum\Core\Request\Capture;
use Payum\Core\Request\Sync;
use Payum\Core\Security\GenericTokenFactoryAwareInterface;
use Payum\Core\Security\GenericTokenFactoryAwareTrait;
/**
* Class CaptureAction
* @package Ekyna\Component\Payum\Payzen\Action
* @author Etienne Dauvergne <contact@ekyna.com>
*/
class CaptureAction implements ActionInterface, GatewayAwareInterface, GenericTokenFactoryAwareInterface
{
use GatewayAwareTrait;
use GenericTokenFactoryAwareTrait;
/**
* {@inheritdoc}
*
* @param Capture $request
*/
public function execute($request)
{
RequestNotSupportedException::assertSupports($this, $request);
$model = ArrayObject::ensureArrayObject($request->getModel());
if ($request->getToken()) {
// Done redirections
$targetUrl = $request->getToken()->getTargetUrl();
$doneUrlFields = [
'vads_url_cancel', // Annuler et retourner à la boutique
'vads_url_error', // Erreur de traitement interne
'vads_url_referral', // 02 contacter l'émetteur de la carte
'vads_url_refused', // Refus autre que 02
'vads_url_success', // 00 Success
'vads_url_return', // Retour à la boutique
];
foreach ($doneUrlFields as $field) {
if (false == $model[$field]) {
$model[$field] = $targetUrl;
}
}
// Notify url
if (empty($model['vads_url_check']) && $this->tokenFactory) {
// Custom action
$model['vads_url_check'] = $request->getToken()->getAfterUrl();
}
}
if (false == $model['vads_trans_id']) {
$this->gateway->execute(new Request($model));
}
$this->gateway->execute(new Sync($model));
}
/**
* {@inheritdoc}
*/
public function supports($request)
{
return $request instanceof Capture
&& $request->getModel() instanceof \ArrayAccess;
}
}
<?php
namespace Ekyna\Component\Payum\Payzen\Action;
use Payum\Core\Action\ActionInterface;
use Payum\Core\Bridge\Spl\ArrayObject;
use Payum\Core\Exception\RequestNotSupportedException;
use Payum\Core\Exception\RuntimeException;
use Payum\Core\GatewayAwareInterface;
use Payum\Core\GatewayAwareTrait;
use Payum\Core\Model\PaymentInterface;
use Payum\Core\Request\Convert;
use Payum\Core\Request\GetCurrency;
/**
* Class ConvertPaymentAction
* @package Ekyna\Component\Payum\Payzen\Action
* @author Etienne Dauvergne <contact@ekyna.com>
*/
class ConvertPaymentAction implements ActionInterface, GatewayAwareInterface
{
use GatewayAwareTrait;
/**
* {@inheritDoc}
*
* @param Convert $request
*/
public function execute($request)
{
RequestNotSupportedException::assertSupports($this, $request);
/** @var PaymentInterface $payment */
$payment = $request->getSource();
$model = ArrayObject::ensureArrayObject($payment->getDetails());
if (false == $model['vads_amount']) {
$this->gateway->execute($currency = new GetCurrency($payment->getCurrencyCode()));
if (2 < $currency->exp) {
throw new RuntimeException('Unexpected currency exp.');
}
$divisor = pow(10, 2 - $currency->exp);
$model['vads_currency'] = (string)$currency->numeric;
$model['vads_amount'] = (string)abs($payment->getTotalAmount() / $divisor);
}
if (false == $model['vads_order_id']) {
$model['vads_order_id'] = $payment->getNumber();
}
if (false == $model['vads_cust_id']) {
$model['vads_cust_id'] = $payment->getClientId();
}
if (false == $model['vads_cust_email']) {
$model['vads_cust_email'] = $payment->getClientEmail();
}
$request->setResult((array)$model);
}
/**
* {@inheritDoc}
*/
public function supports($request)
{
return $request instanceof Convert
&& $request->getSource() instanceof PaymentInterface
&& $request->getTo() == 'array';
}
}
<?php
namespace Ekyna\Component\Payum\Payzen\Action;
use Payum\Core\Action\ActionInterface;
use Payum\Core\Bridge\Spl\ArrayObject;
use Payum\Core\Exception\RequestNotSupportedException;
use Payum\Core\GatewayAwareInterface;
use Payum\Core\GatewayAwareTrait;
use Payum\Core\Request\Notify;
use Payum\Core\Request\Sync;
/**
* Class NotifyAction
* @package Ekyna\Component\Payum\Payzen\Action
* @author Etienne Dauvergne <contact@ekyna.com>
*/
class NotifyAction implements ActionInterface, GatewayAwareInterface
{
use GatewayAwareTrait;
/**
* {@inheritDoc}
*
* @param Notify $request
*/
public function execute($request)
{
RequestNotSupportedException::assertSupports($this, $request);
$details = ArrayObject::ensureArrayObject($request->getModel());
$this->gateway->execute(new Sync($details));
}
/**
* {@inheritDoc}
*/
public function supports($request)
{
return $request instanceof Notify
&& $request->getModel() instanceof \ArrayAccess;
}
}
<?php
namespace Ekyna\Component\Payum\Payzen\Action;
use Ekyna\Component\Commerce\Bridge\Payum\Request\GetHumanStatus;
use Payum\Core\Action\ActionInterface;
use Payum\Core\Bridge\Spl\ArrayObject;
use Payum\Core\Exception\RequestNotSupportedException;
use Payum\Core\GatewayAwareInterface;
use Payum\Core\GatewayAwareTrait;
use Payum\Core\Request\Refund;
/**
* Class CaptureAction
* @package Ekyna\Component\Payum\Payzen\Action
* @author Etienne Dauvergne <contact@ekyna.com>
*/
class RefundAction implements ActionInterface, GatewayAwareInterface
{
use GatewayAwareTrait;
/**
* {@inheritdoc}
*
* @param Refund $request
*/
public function execute($request)
{
RequestNotSupportedException::assertSupports($this, $request);
$model = ArrayObject::ensureArrayObject($request->getModel());
$this->gateway->execute($status = new GetHumanStatus($model));
if ($status->isCaptured()) {
$model['state_override'] = 'refunded';
}
}
/**
* {@inheritdoc}
*/
public function supports($request)
{
return $request instanceof Refund
&& $request->getModel() instanceof \ArrayAccess;
}
}
<?php
namespace Ekyna\Component\Payum\Payzen\Action;
use Payum\Core\Action\ActionInterface;
use Payum\Core\Bridge\Spl\ArrayObject;
use Payum\Core\Exception\RequestNotSupportedException;
use Payum\Core\Request\GetStatusInterface;
/**
* Class StatusAction
* @package Ekyna\Component\Payum\Payzen\Action
* @author Etienne Dauvergne <contact@ekyna.com>
*/
class StatusAction implements ActionInterface
{
/**
* {@inheritdoc}
*
* @param GetStatusInterface $request
*/
public function execute($request)
{
RequestNotSupportedException::assertSupports($this, $request);
/** @var GetStatusInterface $request */
$model = ArrayObject::ensureArrayObject($request->getModel());
if (false == $model['vads_trans_id']) {
$request->markNew();
return;
}
if (false != $code = $model['vads_result']) {
switch ($code) {
case "00" : // transaction approuvée ou traitée avec succès
$request->markCaptured();
break;
case "02" : // contacter l’émetteur de carte
$request->markPending(); // TODO is that the good status ?
break;
case "17" : // Annulation client.
$request->markCanceled();
break;
case "03" : // accepteur invalide
case "04" : // conserver la carte
case "05" : // ne pas honorer
case "07" : // conserver la carte, conditions spéciales
case "08" : // approuver après identification
case "12" : // transaction invalide
case "13" : // montant invalide
case "14" : // numéro de porteur invalide
case "30" : // erreur de format
case "31" : // identifiant de l’organisme acquéreur inconnu
case "33" : // date de validité de la carte dépassée
case "34" : // suspicion de fraude
case "41" : // carte perdue
case "43" : // carte volée
case "51" : // provision insuffisante ou crédit dépassé
case "54" : // date de validité de la carte dépassée
case "56" : // carte absente du fichier
case "57" : // transaction non permise à ce porteur
case "58" : // transaction interdite au terminal
case "59" : // suspicion de fraude
case "60" : // l’accepteur de carte doit contacter l’acquéreur
case "61" : // montant de retrait hors limite
case "63" : // règles de sécurité non respectées
case "68" : // réponse non parvenue ou reçue trop tard
case "90" : // arrêt momentané du système
case "91" : // émetteur de cartes inaccessible
case "96" : // mauvais fonctionnement du système
case "94" : // transaction dupliquée
case "97" : // échéance de la temporisation de surveillance globale
case "98" : // serveur indisponible routage réseau demandé à nouveau
case "99" : // incident domaine initiateur
$request->markFailed();
break;
default :
$request->markUnknown();
}
if ($request->isCaptured() && false != $code = $model['state_override']) {
if ($code == 'refunded') {
$request->markRefunded();
}
}
return;
}
if (false != $code = $model['state_override']) {
if ($code == 'canceled') {
$request->markCanceled();
return;
}
}
$request->markNew();
}
/**
* {@inheritdoc}
*/
public function supports($request)
{
return $request instanceof GetStatusInterface
&& $request->getModel() instanceof \ArrayAccess;
}
}
<?php
namespace Ekyna\Component\Payum\Payzen\Action;
use Ekyna\Component\Payum\Payzen\Request\Response;
use Payum\Core\Action\ActionInterface;
use Payum\Core\Bridge\Spl\ArrayObject;
use Payum\Core\Exception\RequestNotSupportedException;
use Payum\Core\GatewayAwareInterface;
use Payum\Core\GatewayAwareTrait;
use Payum\Core\Request\Sync;
/**
* Class SyncAction
* @package Ekyna\Component\Payum\Payzen\Action
* @author Etienne Dauvergne <contact@ekyna.com>
*/
class SyncAction implements ActionInterface, GatewayAwareInterface
{
use GatewayAwareTrait;
/**
* {@inheritdoc}
*
* @param Sync $request
*/
public function execute($request)
{
RequestNotSupportedException::assertSupports($this, $request);
$model = ArrayObject::ensureArrayObject($request->getModel());
$this->gateway->execute(new Response($model));
}
/**
* {@inheritdoc}
*/
public function supports($request)
{
return $request instanceof Sync
&& $request->getModel() instanceof \ArrayAccess;
}
}
Copyright (c) 2017 Etienne Dauvergne
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
<?php
namespace Ekyna\Component\Payum\Payzen;
use Payum\Core\Bridge\Spl\ArrayObject;
use Payum\Core\GatewayFactory;
use Payum\Core\GatewayFactoryInterface;
/**
* Class PayzenGatewayFactory
* @package Ekyna\Component\Payum\Payzen
* @author Etienne Dauvergne <contact@ekyna.com>
*/
class PayzenGatewayFactory extends GatewayFactory
{
/**
* Builds a new factory.
*
* @param array $defaultConfig
* @param GatewayFactoryInterface $coreGatewayFactory
*
* @return PayzenGatewayFactory
*/
public static function build(array $defaultConfig, GatewayFactoryInterface $coreGatewayFactory = null)
{
return new static($defaultConfig, $coreGatewayFactory);
}
/**
* @inheritDoc
*/
protected function populateConfig(ArrayObject $config)
{
$config->defaults([
'payum.factory_name' => 'payzen',
'payum.factory_title' => 'Payzen',
'payum.action.capture' => new Action\CaptureAction(),
'payum.action.convert_payment' => new Action\ConvertPaymentAction(),
'payum.action.sync' => new Action\SyncAction(),
'payum.action.cancel' => new Action\CancelAction(),
'payum.action.refund' => new Action\RefundAction(),
'payum.action.status' => new Action\StatusAction(),
'payum.action.notify' => new Action\NotifyAction(),
'payum.action.api.request' => new Action\Api\ApiRequestAction(),
'payum.action.api.response' => new Action\Api\ApiResponseAction(),
]);
if (false == $config['payum.api']) {
$config['payum.default_options'] = [
'site_id' => null,
'certificate' => null,
'ctx_mode' => null,
'directory' => null,
'endpoint' => null,
'debug' => false,
];
$config->defaults($config['payum.default_options']);
$config['payum.required_options'] = ['site_id', 'certificate', 'ctx_mode', 'directory'];
$config['payum.api'] = function (ArrayObject $config) {
$config->validateNotEmpty($config['payum.required_options']);
$payzenConfig = [
'endpoint' => $config['endpoint'],
'site_id' => $config['site_id'],
'certificate' => $config['certificate'],
'ctx_mode' => $config['ctx_mode'],
'directory' => $config['directory'],
'debug' => $config['debug'],
];
$api = new Api\Api();
$api->setConfig($payzenConfig);
return $api;
};
}
}
}
PayumPayzen
===========
PayZen Payum Gateway
## Installation / Configuration
TODO
<?php
namespace Ekyna\Component\Payum\Payzen\Request;
use Payum\Core\Request\Generic;
/**
* Class Request
* @package Ekyna\Component\Payum\Payzen\Request
* @author Etienne Dauvergne <contact@ekyna.com>
*/
class Request extends Generic
{
}
<?php
namespace Ekyna\Component\Payum\Payzen\Request;
use Payum\Core\Request\Generic;
/**
* Class Response
* @package Ekyna\Component\Payum\Payzen\Request
* @author Etienne Dauvergne <contact@ekyna.com>
*/
class Response extends Generic
{
}
{
"name": "ekyna/payum-payzen",
"description": "PayZen Payum gateway",
"type": "component",
"authors": [
{
"name": "Etienne Dauvergne",
"homepage": "http://ekyna.com"
}
],
"keywords": [
"payum",
"payzen"
],
"homepage": "https://github.com/ekyna/PayumPayzen",
"license": [
"MIT"
],
"require": {
"php": "^7.0",
"payum/core": "^1.5",
"php-http/guzzle6-adapter": "^2.0",
"symfony/process": "4.4.*",
"psr/log": "~1.0"
},
"autoload": {
"psr-4": {
"Ekyna\\Component\\Payum\\Payzen\\": ""
}
}
}
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