Mercanet files integration

This commit is contained in:
Jérémy Munsch 2021-03-02 15:42:54 +01:00
parent b887bec932
commit 0f901fa7aa
6 changed files with 894 additions and 0 deletions

View file

@ -44,3 +44,7 @@ PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
MERCANET_SECRET=
MERCANET_MERCHAND_ID=
MERCANET_ENV=TEST

View file

@ -0,0 +1,55 @@
<?php
namespace App\Enums\Mercanet;
use Kwaadpepper\Enum\BaseEnum;
/**
* @method static self ok()
* Situation normale suivie du processus normal d'affichage des pages de paiement.
* @method static self invalidIds()
* L’identifiant commerçant ou le contrat acquéreur sont invalides.
* @method static self invalidParameters()
* Les paramètres de la transaction sont invalides. Vérifiez les paramètres de la requête.
* @method static self invalidRequestFormat()
* Le format de la requête est invalide.
* @method static self securityIssue()
* Problème de sécurité, par ex. le sceau calculé est incorrect.
* @method static self transactionAlreadyExists()
* La transaction existe déjà.
* @method static self unreachableService()
* Service temporairement indisponible
* @method static self internalIssue()
* (interne à la classe) = Pb appel cUrl
*/
final class PaymentResponse extends BaseEnum
{
protected static function values(): array
{
return [
'ok' => '00',
'invalidIds' => '03',
'invalidParameters' => '12',
'invalidRequestFormat' => '30',
'securityIssue' => '34',
'transactionAlreadyExists' => '94',
'unreachableService' => '99',
'internalIssue' => '500'
];
}
protected static function labels(): array
{
return [
'ok' => 'Situation normale suivie du processus normal d\'affichage des pages de paiement.',
'invalidIds' => 'L’identifiant commerçant ou le contrat acquéreur sont invalides.',
'invalidParameters' => 'Les paramètres de la transaction sont invalides. ' .
'Vérifiez les paramètres de la requête.',
'invalidRequestFormat' => 'Le format de la requête est invalide.',
'securityIssue' => 'Problème de sécurité, par ex. le sceau calculé est incorrect.',
'transactionAlreadyExists' => 'La transaction existe déjà.',
'unreachableService' => 'Service temporairement indisponible',
'internalIssue' => 'Erreur interne, eg: probleme appel CURL'
];
}
}

View file

@ -0,0 +1,53 @@
<?php
namespace App\Enums\Mercanet;
use Kwaadpepper\Enum\BaseEnum;
/**
* @method static self redirect()
* Ce cas doit être suivi de la redirection de l’utilisateur vers la page de paiement.
*
* @method static self requestError03()
* @method static self requestError12()
* @method static self requestError30()
* @method static self requestError34()
* Ces codes d’erreur indiquent que la requête comporte un problème qui doit être résolu.
* Le processus de paiement doit alors être interrompu.
*
* @method static self referenceAlreadyUsed()
* La référence de transaction a déjà été utilisée.
* Le commerçant doit réessayer avec une autre référence de transaction.
*
* @method static self serviceDisponibiltyIssue()
* Problème de disponibilité du service de paiement. Le commerçant doit essayer de renvoyer la requête.
* Il convient d’utiliser une nouvelle référence de transaction pour éviter un code de réponse 94.
*/
final class RedirectionStatusCode extends BaseEnum
{
protected static function values(): array
{
return [
'redirect' => '00',
'requestError03' => '03',
'requestError12' => '12',
'requestError30' => '30',
'requestError34' => '34',
'referenceAlreadyUsed' => '94',
'serviceDisponibiltyIssue' => '99',
];
}
protected static function labels(): array
{
return [
'redirect' => 'Redirection Acceptée',
'requestError03' => 'Problème de request code 03',
'requestError12' => 'Problème de request code 12',
'requestError30' => 'Problème de request code 30',
'requestError34' => 'Problème de request code 34',
'referenceAlreadyUsed' => 'La référence de transaction à déja été utilisée',
'serviceDisponibiltyIssue' => 'Problème de disponibilité du service de paiement',
];
}
}

View file

@ -0,0 +1,42 @@
<?php
namespace App\Enums\Mercanet;
use Kwaadpepper\Enum\BaseEnum;
/**
* @method static self accepted()
* Paiement accepté
* @method static self refused()
* Paiement refusé
* @method static self fraud()
* Paiement refusé pour fraude
* @method static self maxReached()
* Paiement refusé pour nombre max essais atteint
* @method static self technicalIssue()
* Paiement refusé pour problème technique
*/
final class TransactionResponse extends BaseEnum
{
protected static function values(): array
{
return [
'accepted' => '00',
'refused' => '05',
'fraud' => '34',
'maxReached' => '75',
'technicalIssue' => '90'
];
}
protected static function labels(): array
{
return [
'accepted' => 'Paiement accepté',
'refused' => 'Paiement refusé',
'fraud' => 'Paiement refusé pour fraude',
'maxReached' => 'Paiement refusé pour nombre max essais atteint',
'technicalIssue' => 'Paiement refusé pour problème technique'
];
}
}

View file

@ -0,0 +1,732 @@
<?php
namespace App\Lib\Mercanet;
use BadMethodCallException;
use InvalidArgumentException;
use Normalizer;
class Mercanet
{
public const TEST = "https://payment-webinit-mercanet.test.sips-atos.com/rs-services/v2/paymentInit";
public const SIMULATION = "https://payment-webinit.simu.mercanet.bnpparibas.net/rs-services/v2/paymentInit";
public const PRODUCTION = "https://payment-webinit.mercanet.bnpparibas.net/rs-services/v2/paymentInit";
public const INTERFACE_VERSION = "IR_WS_2.20";
public const INSTALMENT = "INSTALMENT";
// BYPASS3DS
public const BYPASS3DS_ALL = "ALL";
public const BYPASS3DS_MERCHANTWALLET = "MERCHANTWALLET";
private $brandsmap = array(
'ACCEPTGIRO' => 'CREDIT_TRANSFER',
'AMEX' => 'CARD',
'BCMC' => 'CARD',
'BUYSTER' => 'CARD',
'BANK CARD' => 'CARD',
'CB' => 'CARD',
'IDEAL' => 'CREDIT_TRANSFER',
'INCASSO' => 'DIRECT_DEBIT',
'MAESTRO' => 'CARD',
'MASTERCARD' => 'CARD',
'MASTERPASS' => 'CARD',
'MINITIX' => 'OTHER',
'NETBANKING' => 'CREDIT_TRANSFER',
'PAYPAL' => 'CARD',
'PAYLIB' => 'CARD',
'REFUND' => 'OTHER',
'SDD' => 'DIRECT_DEBIT',
'SOFORT' => 'CREDIT_TRANSFER',
'VISA' => 'CARD',
'VPAY' => 'CARD',
'VISA ELECTRON' => 'CARD',
'CBCONLINE' => 'CREDIT_TRANSFER',
'KBCONLINE' => 'CREDIT_TRANSFER'
);
/** @var ShaComposer */
private $secretKey;
private $env;
private $returnUrl;
private $automaticUrl = false;
private $pspURL = self::TEST;
private $responseData;
private $parameters = array();
private $pspFields = array(
'amount', 'cardExpiryDate', 'cardNumber', 'cardCSCValue',
'currencyCode', 'merchantId', 'interfaceVersion', 'sealAlgorithm',
'transactionReference', 'keyVersion', 'paymentMeanBrand', 'customerLanguage',
'billingAddress.city', 'billingAddress.company', 'billingAddress.country',
'billingAddress', 'billingAddress.postBox', 'billingAddress.state',
'billingAddress.street', 'billingAddress.streetNumber', 'billingAddress.zipCode',
'billingContact.email', 'billingContact.firstname', 'billingContact.gender',
'billingContact.lastname', 'billingContact.mobile', 'billingContact.phone',
'customerAddress', 'customerAddress.city', 'customerAddress.company',
'customerAddress.country', 'customerAddress.postBox', 'customerAddress.state',
'customerAddress.street', 'customerAddress.streetNumber', 'customerAddress.zipCode',
'customerEmail', 'customerContact', 'customerContact.email', 'customerContact.firstname',
'customerContact.gender', 'customerContact.lastname', 'customerContact.mobile',
'customerContact.phone', 'customerContact.title', 'expirationDate', 'automaticResponseUrl',
'templateName', 'paymentMeanBrandList', 'instalmentData.number', 'instalmentData.datesList',
'instalmentData.transactionReferencesList', 'instalmentData.amountsList', 'paymentPattern',
'captureDay', 'captureMode', 'merchantTransactionDateTime', 'fraudData.bypass3DS', 'seal',
'orderChannel', 'orderId', 'returnContext', 'transactionOrigin', 'merchantWalletId', 'paymentMeanId'
);
private $requiredFields = array(
'amount', 'currencyCode', 'interfaceVersion', 'keyVersion', 'merchantId', 'normalReturnUrl', 'orderChannel',
'transactionReference'
);
public $allowedlanguages = array(
'nl', 'fr', 'de', 'it', 'es', 'cy', 'en'
);
private static $currencies = array(
'EUR' => '978', 'USD' => '840', 'CHF' => '756', 'GBP' => '826',
'CAD' => '124', 'JPY' => '392', 'MXP' => '484', 'TRY' => '949',
'AUD' => '036', 'NZD' => '554', 'NOK' => '578', 'BRC' => '986',
'ARP' => '032', 'KHR' => '116', 'TWD' => '901', 'SEK' => '752',
'DKK' => '208', 'KRW' => '410', 'SGD' => '702', 'XPF' => '953',
'XOF' => '952'
);
public static function convertCurrencyToCurrencyCode($currency)
{
if (!in_array($currency, array_keys(self::$currencies))) {
throw new InvalidArgumentException("Unknown currencyCode $currency.");
}
return self::$currencies[$currency];
}
public static function convertCurrencyCodeToCurrency($code)
{
if (!in_array($code, array_values(self::$currencies))) {
throw new InvalidArgumentException("Unknown Code $code.");
}
return array_search($code, self::$currencies);
}
public static function getCurrencies()
{
return self::$currencies;
}
public function __construct($secret, $MerchantId, $env, $returnUrl, $automaticUrl = false)
{
$this->secretKey = $secret;
$this->parameters['merchantId'] = $MerchantId;
$this->env = $env;
$this->returnUrl = $returnUrl;
if ($automaticUrl !== false) {
$this->automaticUrl = $automaticUrl;
}
switch ($this->env) {
case 'TEST':
$this->setUrl(Mercanet::TEST);
break;
case 'SIMULATION':
$this->setUrl(Mercanet::SIMULATION);
break;
case 'PRODUCTION':
$this->setUrl(Mercanet::PRODUCTION);
break;
}
}
public function shaCompose(array $parameters)
{
$shaString = '';
foreach ($parameters as $key => $value) {
if ($key != 'keyVersion') {
if (is_array($value)) {
$shaString .= implode('', $value);
} else {
$shaString .= $value;
}
}
}
return $shaString;
}
/** @return string */
public function getShaSign()
{
$this->validate();
return hash_hmac('sha256', utf8_encode($this->shaCompose($this->toArray())), $this->secretKey);
}
/** @return string */
public function getUrl()
{
return $this->pspURL;
}
public function setUrl($pspUrl)
{
$this->validateUri($pspUrl);
$this->pspURL = $pspUrl;
}
public function setNormalReturnUrl($url)
{
$this->validateUri($url);
$this->parameters['normalReturnUrl'] = $url;
}
public function setAutomaticResponseUrl($url)
{
$this->validateUri($url);
$this->parameters['automaticResponseUrl'] = $url;
}
public function setTransactionReference($transactionReference)
{
if (preg_match('/[^a-zA-Z0-9_-]/', $transactionReference)) {
throw new \InvalidArgumentException("TransactionReference cannot contain special characters");
}
$this->parameters['transactionReference'] = $transactionReference;
}
/**
* Set amount in cents, eg EUR 12.34 is written as 1234
*/
public function setAmount($amount)
{
if (!is_int($amount)) {
throw new InvalidArgumentException("Integer expected. Amount is always in cents");
}
if ($amount <= 0) {
throw new InvalidArgumentException("Amount must be a positive number");
}
$this->parameters['amount'] = "$amount";
}
public function setCurrency($currency)
{
if (!array_key_exists(strtoupper($currency), self::getCurrencies())) {
throw new InvalidArgumentException("Unknown currency");
}
$this->parameters['currencyCode'] = self::convertCurrencyToCurrencyCode($currency);
}
public function setLanguage($language)
{
if (!in_array($language, $this->allowedlanguages)) {
throw new InvalidArgumentException("Invalid language locale");
}
$this->parameters['customerLanguage'] = $language;
}
public function setCustomerEmail($email)
{
$this->parameters['customerEmail'] = $email;
}
public function setPaymentBrands($brands)
{
$this->parameters['paymentMeanBrandList'] = '';
foreach ($brands as $brand) {
if (!array_key_exists(strtoupper($brand), $this->brandsmap)) {
throw new InvalidArgumentException("Unknown Brand [$brand].");
}
}
$this->parameters['paymentMeanBrandList'] = $brands;
}
public function setBillingContactEmail($email)
{
if (strlen($email) > 50) {
throw new InvalidArgumentException("Email is too long");
}
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new InvalidArgumentException("Email is invalid");
}
$this->parameters['billingContact.email'] = $email;
}
public function setBillingAddressStreet($street)
{
if (strlen($street) > 35) {
throw new InvalidArgumentException("street is too long");
}
$this->parameters['billingAddress.street'] = Normalizer::normalize($street);
}
public function setBillingAddressStreetNumber($nr)
{
if (strlen($nr) > 10) {
throw new InvalidArgumentException("streetNumber is too long");
}
$this->parameters['billingAddress.streetNumber'] = Normalizer::normalize($nr);
}
public function setBillingAddressZipCode($zipCode)
{
if (strlen($zipCode) > 10) {
throw new InvalidArgumentException("zipCode is too long");
}
$this->parameters['billingAddress.zipCode'] = Normalizer::normalize($zipCode);
}
public function setBillingAddressCity($city)
{
if (strlen($city) > 25) {
throw new InvalidArgumentException("city is too long");
}
$this->parameters['billingAddress.city'] = Normalizer::normalize($city);
}
public function setBillingContactPhone($phone)
{
if (strlen($phone) > 30) {
throw new InvalidArgumentException("phone is too long");
}
$this->parameters['billingContact.phone'] = $phone;
}
public function setBillingContactFirstname($firstname)
{
// replace quotes
$this->parameters['billingContact.firstname'] = str_replace(
array("'", '"'),
'',
Normalizer::normalize($firstname)
);
}
public function setBillingContactLastname($lastname)
{
// replace quotes
$this->parameters['billingContact.lastname'] = str_replace(
array("'", '"'),
'',
Normalizer::normalize($lastname)
);
}
public function setCaptureDay($number)
{
if (strlen($number) > 2) {
throw new InvalidArgumentException("captureDay is too long");
}
$this->parameters['captureDay'] = $number;
}
public function setCaptureMode($value)
{
if (strlen($value) > 20) {
throw new InvalidArgumentException("captureMode is too long");
}
$this->parameters['captureMode'] = $value;
}
public function setMerchantTransactionDateTime($value)
{
if (strlen($value) > 25) {
throw new InvalidArgumentException("merchantTransactionDateTime is too long");
}
$this->parameters['merchantTransactionDateTime'] = $value;
}
public function setInterfaceVersion($value)
{
$this->parameters['interfaceVersion'] = $value;
}
public function setSealAlgorithm($value)
{
$this->parameters['sealAlgorithm'] = $value;
}
public function setOrderChannel($value)
{
if (strlen($value) > 20) {
throw new InvalidArgumentException("orderChannel is too long");
}
$this->parameters['orderChannel'] = $value;
}
public function setOrderId($value)
{
if (strlen($value) > 32) {
throw new InvalidArgumentException("orderId is too long");
}
$this->parameters['orderId'] = $value;
}
public function setReturnContext($value)
{
if (strlen($value) > 255) {
throw new InvalidArgumentException("returnContext is too long");
}
$this->parameters['returnContext'] = $value;
}
public function setTransactionOrigin($value)
{
if (strlen($value) > 20) {
throw new InvalidArgumentException("transactionOrigin is too long");
}
$this->parameters['transactionOrigin'] = $value;
}
// Methodes liees a la carte
public function setCardNumber($number)
{
if (strlen($number) > 19) {
throw new InvalidArgumentException("cardNumber is too long");
}
if (strlen($number) < 12) {
throw new InvalidArgumentException("cardNumber is too short");
}
$this->parameters['cardNumber'] = $number;
}
public function setCardExpiryDate($date)
{
if (strlen($date) != 6) {
throw new InvalidArgumentException("cardExpiryDate value is invalid");
}
$this->parameters['cardExpiryDate'] = $date;
}
public function setCardCSCValue($value)
{
if (strlen($value) > 4) {
throw new InvalidArgumentException("cardCSCValue value is invalid");
}
$this->parameters['cardCSCValue'] = $value;
}
// Methodes liees a la lutte contre la fraude
public function setFraudDataBypass3DS($value)
{
if (strlen($value) > 128) {
throw new InvalidArgumentException("fraudData.bypass3DS is too long");
}
$this->parameters['fraudData.bypass3DS'] = $value;
}
// Methodes liees au paiement one-click
public function setMerchantWalletId($wallet)
{
if (strlen($wallet) > 21) {
throw new InvalidArgumentException("merchantWalletId is too long");
}
$this->parameters['merchantWalletId'] = $wallet;
}
public function setPaymentMeanId($value)
{
if (strlen($value) > 6) {
throw new InvalidArgumentException("paymentMeanId is too long");
}
$this->parameters['paymentMeanId'] = $value;
}
// Methodes liees au paiement en n-fois
public function setInstalmentDataNumber($number)
{
if (strlen($number) > 2) {
throw new InvalidArgumentException("instalmentData.number is too long");
}
if (($number < 2) || ($number > 50)) {
throw new InvalidArgumentException(
"instalmentData.number invalid value : value must be set between 2 and 50"
);
}
$this->parameters['instalmentData.number'] = $number;
}
public function setInstalmentDatesList($datesList)
{
$this->parameters['instalmentData.datesList'] = $datesList;
}
public function setInstalmentDataTransactionReferencesList($transactionReferencesList)
{
$this->parameters['instalmentData.transactionReferencesList'] = $transactionReferencesList;
}
public function setInstalmentDataAmountsList($amountsList)
{
$this->parameters['instalmentData.amountsList'] = $amountsList;
}
public function setPaymentPattern($paymentPattern)
{
$this->parameters['paymentPattern'] = $paymentPattern;
}
public function __call($method, $args)
{
if (substr($method, 0, 3) == 'set') {
$field = lcfirst(substr($method, 3));
if (in_array($field, $this->pspFields)) {
$this->parameters[$field] = $args[0];
return;
}
}
if (substr($method, 0, 3) == 'get') {
$field = lcfirst(substr($method, 3));
if (array_key_exists($field, $this->parameters)) {
return $this->parameters[$field];
}
}
throw new BadMethodCallException("Unknown method $method");
}
public function toArray()
{
ksort($this->parameters);
return $this->parameters;
}
public function toParameterString()
{
ksort($this->parameters);
$seal = $this->getShaSign();
$tmp = array_merge($this->parameters, ['seal' => $seal]);
return json_encode($tmp, JSON_UNESCAPED_SLASHES);
}
/*
if (substr($val, 0, 1) == "[")
$chaine .= '"'.$key.'":'.$val;
else
$chaine .= '"'.$key.'":"'.$val.'"'; */
/** @return PaymentRequest */
/* public static function createFromArray(ShaComposer $shaComposer, array $parameters)
{
$instance = new static($shaComposer);
foreach ($parameters as $key => $value) {
$instance->{"set$key"}($value);
}
return $instance;
} */
public function validate()
{
foreach ($this->requiredFields as $field) {
if (empty($this->parameters[$field])) {
throw new \RuntimeException($field . " can not be empty");
}
}
}
protected function validateUri($uri)
{
if (!filter_var($uri, FILTER_VALIDATE_URL)) {
throw new InvalidArgumentException("Uri is not valid");
}
if (strlen($uri) > 200) {
throw new InvalidArgumentException("Uri is too long");
}
}
// Traitement des reponses de Mercanet
// -----------------------------------
/** @var string */
public const SHASIGN_FIELD = "SEAL";
/** @var string */
public const DATA_FIELD = "DATA";
public function setResponse(array $httpRequest)
{
// use lowercase internally
$httpRequest = array_change_key_case($httpRequest, CASE_UPPER);
// set sha sign
$this->shaSign = $this->extractShaSign($httpRequest);
// filter request for Sips parameters
$this->parameters = $this->filterRequestParameters($httpRequest);
}
/**
* @var string
*/
private $shaSign;
private $dataString;
private $responseRequest;
private $responseStatus;
private $parameterArray;
/**
* Filter http request parameters
* @param array $requestParameters
*/
private function filterRequestParameters(array $httpRequest)
{
//filter request for Sips parameters
if (!array_key_exists(self::DATA_FIELD, $httpRequest) || $httpRequest[self::DATA_FIELD] == '') {
throw new InvalidArgumentException('Data parameter not present in parameters.');
}
$parameters = array();
$this->responseData = $httpRequest[self::DATA_FIELD];
$dataString = $httpRequest[self::DATA_FIELD];
$this->dataString = $dataString;
$dataParams = explode('|', $dataString);
foreach ($dataParams as $dataParamString) {
$dataKeyValue = explode('=', $dataParamString, 2);
$parameters[$dataKeyValue[0]] = $dataKeyValue[1];
}
return $parameters;
}
public function getSeal()
{
return $this->shaSign;
}
private function extractShaSign(array $parameters)
{
if (!array_key_exists(self::SHASIGN_FIELD, $parameters) || $parameters[self::SHASIGN_FIELD] == '') {
throw new InvalidArgumentException('SHASIGN parameter not present in parameters.');
}
return $parameters[self::SHASIGN_FIELD];
}
/**
* Checks if the response is valid
* @return bool
*/
public function isValid()
{
$resultat = false;
$signature = $this->responseData;
$compute = hash('sha256', utf8_encode($signature . $this->secretKey));
if (strcmp($this->shaSign, $compute) == 0) {
// phpcs:ignore PSR2.ControlStructures.ControlStructureSpacing.SpacingAfterOpenBrace
if (
(strcmp($this->parameters['responseCode'], "00") == 0) ||
(strcmp($this->parameters['responseCode'], "60") == 0)
) {
$resultat = true;
}
}
return $resultat;
}
public function getXmlValueByTag($inXmlset, $needle)
{
$resource = xml_parser_create(); //Create an XML parser
xml_parse_into_struct($resource, $inXmlset, $outArray); // Parse XML data into an array structure
xml_parser_free($resource); //Free an XML parser
for ($i = 0; $i < count($outArray); $i++) {
if ($outArray[$i]['tag'] == strtoupper($needle)) {
$tagValue = $outArray[$i]['value'];
}
}
return $tagValue;
}
/**
* Retrieves a response parameter
* @param string $param
* @throws \InvalidArgumentException
*/
public function getParam($key)
{
return $this->parameterArray[$key];
}
public function getResponseRequest()
{
return $this->responseRequest;
}
public function executeRequest()
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->getUrl());
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->toParameterString());
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Accept:application/json'));
curl_setopt($ch, CURLOPT_PORT, 443);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$result = curl_exec($ch); // $this->responseRequest et $this->responseStatus = false;
$info = curl_getinfo($ch);
if (!$result) {
error_log(
"MERCANET [" . $this->parameters['transactionReference'] . "] : curl error: " . curl_error($ch)
);
curl_close($ch);
return (object)['status' => 'KO', 'code' => 500];
}
if ($info['http_code'] != 200) {
error_log(
"MERCANET [" . $this->parameters['transactionReference'] .
"] : service error: " . $info['http_code'] . " - Return : " . $result
);
curl_close($ch);
return (object)['status' => 'KO', 'code' => 500];
}
curl_close($ch);
if (strlen($result) == 0) {
error_log("MERCANET [" . $this->parameters['transactionReference'] . "] : service did not sent back data");
return (object)['status' => 'KO', 'code' => 500];
}
$result_array = json_decode($result);
if (isset($result_array->redirectionStatusCode)) {
if ($result_array->redirectionStatusCode === '00') {
return (object)[
'status' => 'OK', 'code' => $result_array->redirectionStatusCode,
'url' => $result_array->redirectionUrl, 'version' => $result_array->redirectionVersion,
'data' => $result_array->redirectionData
];
} else {
return (object)['status' => 'KO', 'code' => $result_array->redirectionStatusCode, 'message' => $result_array->redirectionStatusMessage];
}
} else {
error_log("MERCANET [" . $this->parameters['transactionReference'] . "] : redirectionStatusCode missing");
return (object)['status' => 'KO', 'code' => 500];
}
}
public function quickPayment($amount, $ref)
{
//$this->setUrl($this->env === 'production' ? Mercanet::PRODUCTION : Mercanet::TEST);
// Required fields
$this->setInterfaceVersion(Mercanet::INTERFACE_VERSION);
$this->setKeyVersion('1');
$this->setCurrency('EUR');
$this->setOrderChannel("INTERNET");
// Variables
$this->setAmount($amount);
$this->setTransactionReference($ref);
$this->setNormalReturnUrl($this->returnUrl);
if ($this->automaticUrl !== false) {
$this->setAutomaticResponseUrl($this->automaticUrl);
}
// Optional fields
$this->setPaymentBrands(['CB', 'VISA', 'MASTERCARD']);
$this->setCaptureMode('IMMEDIATE');
// Validate
$this->validate();
return $this->executeRequest();
}
}

8
config/mercanet.php Normal file
View file

@ -0,0 +1,8 @@
<?php
return [
'secret' => env('MERCANET_SECRET'),
'merchantId' => env('MERCANET_MERCHAND_ID'),
// eg: TEST, SIMULATION, PRODUCTION
'env' => env('MERCANET_ENV', 'TEST'),
];