759 lines
25 KiB
PHP
759 lines
25 KiB
PHP
<?php
|
||
|
||
namespace App\Lib\Mercanet;
|
||
|
||
use BadMethodCallException;
|
||
use Illuminate\Support\Facades\Log;
|
||
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);
|
||
}
|
||
|
||
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;
|
||
// }
|
||
// phpcs:ignore PSR12.ControlStructures.ControlStructureSpacing.FirstExpressionLine
|
||
if (in_array($this->parameters['responseCode'], [
|
||
'00', // Paiement accepté
|
||
'02', // Demande d’autorisation par téléphone à la banque à cause d’un dépassement du plafond d’autorisation sur la carte, si vous êtes autorisé à forcer les transactions
|
||
'03', // Contrat commerçant invalide
|
||
'05', // Autorisation refusée Refus 3D Secure, Refus bancaire acquéreur, Repli VADS, Fraude
|
||
'11', // Utilisé dans le cas d'un contrôle différé. Le PAN est en opposition
|
||
'12', // Transaction invalide, vérifier les paramètres transférés dans la requête
|
||
'14', // Coordonnées du moyen de paiement invalides (ex: n° de carte ou cryptogramme visuel de la carte) ou vérification AVS échouée
|
||
'17', // Annulation de l’acheteur
|
||
'30', // Erreur de format
|
||
'34', // Suspicion de fraude (seal erroné), Refus fraude acquéreur
|
||
'54', // Date de validité du moyen de paiement dépassée
|
||
'60', // ???
|
||
'75', // Nombre de tentatives de saisie des coordonnées du moyen de paiement sous Sips Paypage dépassé
|
||
'90', // Service temporairement indisponible
|
||
'94', // Transaction dupliquée : le transactionReference de la transaction est déjà utilisé
|
||
'97', // Délai expiré, transaction refusée
|
||
'97', // Délai expiré, transaction refusée
|
||
'99' // Problème temporaire du serveur de paiement.
|
||
])
|
||
) {
|
||
$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
|
||
$count = count($outArray);
|
||
for ($i = 0; $i < $count; $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);
|
||
$info = curl_getinfo($ch);
|
||
|
||
if (!$result) {
|
||
dd('toto', $this->parameters['transactionReference']);
|
||
Log::critical("MERCANET [$this->parameters['transactionReference']] : curl error: " . curl_error($ch));
|
||
curl_close($ch);
|
||
return (object)['status' => 'KO', 'code' => 500];
|
||
}
|
||
|
||
if ($info['http_code'] != 200) {
|
||
Log::critical(sprintf(
|
||
"MERCANET [%s] : service error: %s - Return : %s",
|
||
$this->parameters['transactionReference'],
|
||
$info['http_code'],
|
||
$result
|
||
));
|
||
curl_close($ch);
|
||
return (object)['status' => 'KO', 'code' => 500];
|
||
}
|
||
curl_close($ch);
|
||
|
||
if (strlen($result) == 0) {
|
||
Log::critical(sprintf(
|
||
"MERCANET [%s] : service did not sent back data",
|
||
$this->parameters['transactionReference']
|
||
));
|
||
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,
|
||
'seal' => $result_array->seal
|
||
];
|
||
}
|
||
} else {
|
||
Log::critical(sprintf(
|
||
"MERCANET [%s] : redirectionStatusCode missing",
|
||
$this->parameters['transactionReference']
|
||
));
|
||
return (object)['status' => 'KO', 'code' => 500];
|
||
}
|
||
}
|
||
|
||
public function quickPayment($amount, $ref)
|
||
{
|
||
// Required fields
|
||
$this->setInterfaceVersion(Mercanet::INTERFACE_VERSION);
|
||
$this->setKeyVersion('2');
|
||
$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();
|
||
}
|
||
}
|