PageRenderTime 53ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 1ms

/class.xmodmonetique.inc

https://github.com/jcplat/console-seolan
PHP | 1856 lines | 1015 code | 81 blank | 760 comment | 172 complexity | 36d94239298c177e1cd74d1b9f9ffabd MD5 | raw file
Possible License(s): LGPL-2.0, LGPL-2.1, GPL-3.0, Apache-2.0, BSD-3-Clause
  1. <?php
  2. /**
  3. * \file class.xmodmonetique.inc
  4. * \name XModMonetique
  5. * \author Vladimir Monari
  6. * \version 1.0
  7. * \date 1 Septembre 2013
  8. */
  9. /**
  10. * \brief Classe MTransaction.
  11. * Classe représentant une transaction.
  12. * \version 1.0
  13. * \note
  14. * - Pour Paybox et Atos une transaction en état WAITTING signifie que le serveur n'était pas disponible lors de l'appel.
  15. * - Pour SystemPay une transaction en état WAITTING signifie que le status en banque de la transaction ne permet pas cette action pour le moment. Elle devra donc être rejouée. Exemple:
  16. * - Un remboursement ne peut être éfféctué que si la transaction à été remisé. Si le remboursement est intégral, on peut annuler la transaction, sinon il faudra attendre.
  17. */
  18. /*************************************************************************
  19. * TEST MULTI WEB_PAYMENT :
  20. * - $order->options['nbDeadLine'] = 3;
  21. * - $order->options['frequencyDuplicate'] = 31;
  22. * - $order->options['captureDay'] = 10; ///< Spécifique à paybox (numéro du jour de prélèvement dans le mois)
  23. * - $order->options['captureDelay'] = 10;
  24. * - $order->options['noCapture'] = true; ///< Demande d'autorisation uniquement
  25. *
  26. * TEST D'ENROLLEMENT :
  27. * - $order->options['enrollement']= true;
  28. * - $order->options['refAbonnement'] = 'Atos Refus';
  29. ***************************************************************************/
  30. class MTransaction{
  31. public $oid = null; ///< Identifiant de la transaction.
  32. public $orderOid = null; ///< Identifiant oid de la commande.
  33. public $orderReference = null; ///< Référence de la commande.
  34. public $customerOid = null; ///< Identifiant oid du client.
  35. public $customerEmail = null; ///< Email du client.
  36. public $dateCreated = null; ///< Date de création de la transaction.
  37. public $responseCode = null; ///< Code reponse de la banque.
  38. public $amount = null; ///< Float $amount : Montant de la transaction en euros.
  39. /**
  40. * \brief Status de la transaction.
  41. * \details Peut-être valorisé à :
  42. * - XModMonetique::RUNNING.
  43. * - XModMonetique::WAITTING.
  44. * - XModMonetique::SUCCESS.
  45. * - XModMonetique::ERROR.
  46. * - XModMonetique::INVALID.
  47. */
  48. public $status = null;
  49. /**
  50. * \brief Type de la transaction.
  51. * \details Peut-être valorisé à :
  52. * - XModMonetique::DUPLICATE.
  53. * - XModMonetique::WEB_PAYMENT.
  54. * - XModMonetique::REFUND.
  55. */
  56. public $type = null;
  57. public $dateTimeOut = null; ///< Date et heure d'envoi en banque des paramètres de la transaction.
  58. public $dateTimeIn = null; ///< Date et heure du retour banque de la transaction.
  59. public $transOri = null; ///< Lien vers la transaction d'origine (oid de la transaction d'origine).
  60. public $shopMoid = null; ///< Identifiant du module de la boutique.
  61. public $shopClass = null;///< Classe de la boutique.
  62. public $shopName = null;///< Nom de la boutique.
  63. /**
  64. * \brief Mode de la notification boutique.
  65. * \details Peut-être valorisé à :
  66. * - \link XModMonetique::ASYNC_RESPONSE \endlink
  67. * - \link XModMonetique::SYNC_RESPONSE \endlink
  68. * - \link XModMonetique::RESPONSE_NONE \endlink
  69. */
  70. public $autoResponseMode = null;
  71. public $shopCallBack = null; ///< Fonction de la boutique permettant le traitement de la réponse.
  72. public $statusComplement = null; ///< Complément de statut de la transaction. Donne des informations complémentaire sur l'état de la transaction.
  73. public $callParms = null; ///< Paramètres bruts transmis lors de l'appel en banque.
  74. public $responseParms = null; ///< Réponse brute retournée par la banque.
  75. public $refAbonneBoutique = null; ///< Référence d'abonné attribué à un client lors d'une commande définissant un enrollement.
  76. public $monetiqueMoid = null; ///< Identifiant du module de gestion des transaction utilisé pour celle-ci.
  77. public $nbReturn = null; ///< Nombre de retour banque (Utile à Paybox uniquement, maximum 3 trois retour pour un paiement web).
  78. /**
  79. * \brief Statut de la notification boutique.
  80. * \details Peut-être valorisé à :
  81. * - XModMonetique::RESPONSE_STATUS_SENT \endlink
  82. * - XModMonetique::RESPONSE_STATUS_TO_SEND \endlink
  83. * - XModMonetique::RESPONSE_STATUS_NOT_TO_SEND \endlink
  84. */
  85. public $responseStatus = null;
  86. public $transId = null; ///< Identifiant en bancaire de la transaction.
  87. public $modeTest = True; ///< Mode test par defaut.
  88. public $captureDelay = '0'; ///< Capture immédiate par défaut.
  89. /**
  90. *\brief Capture par défaut, sinon simple demande d'autorisation.
  91. * \details Peut-être valorisé à :
  92. * - \link XModMonetique::AUTHORIZATION_ONLY \endlink
  93. * - \link XModMonetique::CATCH_PAYMENT \endlink
  94. */
  95. public $captureMode = null;
  96. public $frequencyDuplicate = null; ///< Capture immédiate par défaut.
  97. public $enrollement = False; ///< Pas d'enrollement par défaut
  98. public $nbDeadLine = 1; ///< Nombre d'échéances par défaut
  99. }
  100. /**
  101. * \brief Classe MOrderInfos.
  102. * Classe représentant une commande.
  103. * \version 1.0
  104. */
  105. class MOrderInfos{
  106. public $oid = null; ///< Identifiant oid de la commande.
  107. public $reference = null; ///< Référence de la commande.
  108. public $amount = null; ///< Montant de la commande.
  109. /**
  110. * \brief Contient les options éventuelles de la commande.
  111. * \details Doit être valorisé à :
  112. * - Pour un enrollement :
  113. * - $order->options['enrollement']= true;
  114. * - $order->options['refAbonnement'] = '<Référence de l'abonné>';
  115. * - Pour un paiement multiple :
  116. * - $order->options['nbDeadLine'] = 3;
  117. * - Facultatif:
  118. * - $order->options['frequencyDuplicate'] = 31; Fréquence de prélevement en jours. Par défaut 30.
  119. * - $order->options['captureDay'] = 10; Spécifique à paybox : Numéro du jour de prelevement dans le mois. Par défaut le 1.
  120. * - Pour modifier le délai de la capture :
  121. * - $order->options['captureDelay'] = 10; Délais de capture réelle de la transaction en jours. Par défaut 0.
  122. * - Pour une demande d'autorisation seule :
  123. * - $order->options['noCapture'] = true; ///< Demande d'autorisation uniquement
  124. */
  125. public $options = array();
  126. public $cardsType = array();
  127. }
  128. /**
  129. * \brief Classe MCustomerInfos.
  130. * Classe représentant un client.
  131. * \version 1.0
  132. */
  133. class MCustomerInfos{
  134. public $oid = null; ///< Identifiant oid du client.
  135. public $email = null; ///< Email du client.
  136. }
  137. /**
  138. * \brief Classe MShopInfos.
  139. * Classe contenant les paramètres de la boutique.
  140. * \version 1.0
  141. */
  142. class MShopInfos{
  143. public $moid = null; ///< Identifiant du module de la boutique.
  144. public $class = null;///< Classe de la boutique.
  145. public $name = null;///< Nom de la boutique.
  146. public $autoResponseMode = null;///< Mode de reponse.
  147. public $autoResponseCallBack = null;///< Fonction de la boutique permettant le traitement de la réponse.
  148. public $cardsType =null; ///< Tableau des cartes voulue par la boutique
  149. }
  150. /**
  151. * \brief Classe abstraite, base des modules "monetique/VAD".
  152. * \details Cette classe permet d'unifier les appels et retours des différents modules de paiements en ligne (ATOS/SIPS, SystemPay et Paybox).
  153. */
  154. abstract class XModMonetique extends XModtable{
  155. // Options communes à tout (ou presque) les modules de paiements
  156. const CATCH_PAYMENT = 'capture';
  157. const AUTHORIZATION_ONLY = 'autorisation';
  158. // Constantes correspondant au type de transaction.
  159. const DUPLICATE = 'subscdebit'; ///< Prelèvement 'manuel' sur un abonné / enrollé.
  160. const WEB_PAYMENT = 'webpayment'; ///< Paiement de base par internet.
  161. const REFUND = 'refund'; ///< Remboursement.
  162. // Constantes pour la gestion du retour vers la boutique.
  163. const ASYNC_RESPONSE = 'async'; ///< Notifier la boutique en arrière plan.
  164. const SYNC_RESPONSE = 'sync'; ///< Notifier la boutique dès le retour.
  165. const RESPONSE_NONE = 'none'; ///< Ne pas notifier la boutique.
  166. // Status de notification de la réponse vers la boutique.
  167. const RESPONSE_STATUS_SENT = 'sent'; ///< Boutique notifiée.
  168. const RESPONSE_STATUS_TO_SEND = 'tosend'; ///< Boutique à notifier.
  169. const RESPONSE_STATUS_NOT_TO_SEND = 'nottosend'; ///< Boutique à notifier.
  170. // Constantes correspondant à l'état d'une transaction
  171. const RUNNING = 'running'; ///< En cours de traitement (on attend le retour banque, qui ne viendra peut être jamais, si le client n'arrive pas au bout de la transaction).
  172. const WAITTING = 'waitting'; ///< Opération en attente (Soit le serveur ATOS n'est pas disponible, soit il faut attendre que la transaction est un status permettant l'opération en attente pour SystemPay.
  173. const SUCCESS = 'success'; ///< Opération réalisée avec succés, que ce soit un paiement web, un remboursement ou une duplication.
  174. const ERROR = 'error'; ///< Opération échoué, motifs exacte dans compelement de status (statusComplement) \link MTransaction::$statusComplement \endlink
  175. const INVALID = 'invalid'; ///< Correspond à une erreur de vérification de signature.
  176. /**
  177. * \brief Type de carte géré par le module XmodMonetique.
  178. * \details Ce tableau est utilisable UNIQUEMENT avec SystemPay. Les autres modules de gestion, ne permette de préciser qu'un seul type de carte.
  179. * Pour utiliser ce tableau, il faut que la boutique est le même tableau avec les cartes qu'elle autorise à 'true'.
  180. */
  181. public $cardsType = array(
  182. 'AMEX' => false,
  183. 'AURORE' => false,
  184. 'BUYSTER' => false,
  185. 'CB' => false,
  186. 'COFINOGA' => false,
  187. 'MASTERCARD' => false,
  188. 'JCB' => false,
  189. 'VISA' => false,
  190. 'FINAREF' => false,
  191. 'FNAC' => false,
  192. 'CYRILLUS' => false,
  193. 'PRINTEMPS' => false,
  194. 'KANGOUROU' => false,
  195. 'SURCOUF' => false,
  196. 'POCKETCARD' => false,
  197. 'CONFORAMA' => false,
  198. 'NUITEA' => false,
  199. 'PASS' => false,
  200. 'PASS2' => false,
  201. 'PASS3FOIS' => false,
  202. 'CBPASS' => false,
  203. 'PEUGEOT' => false,
  204. 'ACCORD' => false,
  205. 'FRANFINANCE' => false,
  206. '1EUROCOM' => false,
  207. '4ETOILES' => false,
  208. 'COFIDIS_3X' => false,
  209. 'PROFILPLUS' => false,
  210. 'LIBRAVOU' => false,
  211. 'DINERS' => false,
  212. 'SOLO' => false,
  213. 'SWITCH' => false,
  214. 'DELTA' => false,
  215. 'BANCONTACTMISTERCASH' => false,
  216. 'VISA_ELECTRON' => false,
  217. 'COF3XCB' => false,
  218. 'COF3XCB_SB' => false,
  219. 'MAESTRO' => false,
  220. 'E-CARTEBLEUE' => false,
  221. 'ONEY' => false,
  222. 'ONEY_SANDBOX' => false,
  223. 'PAYPAL' => false,
  224. 'PAYPAL_SB' => false,
  225. 'PAYSAFECARD' => false,
  226. 'SOFINCO' => false,
  227. 'AVANTAGES' => false,
  228. 'CDGP' => false,
  229. 'RIVE GAUCHE' => false,
  230. 'WEXPAY' => false,
  231. 'KADEOS' => false,
  232. 'SVS' => false,
  233. 'LASER' => false,
  234. 'KWIXO' => false,
  235. 'LEETCHI' => false,
  236. 'MAXICHEQUE' => false,
  237. 'PAYBUTTON ING' => false,
  238. 'iDEAL' => false
  239. );
  240. // Constante définissants le mode de capture
  241. public $siteId = null; ///< Identifiant du site marchand.
  242. public $urlPayed = null; ///< Url de redirection du client pour un paiement accepté.
  243. public $urlCancelled = null; ///< Url de redirection du client en cas d'annulation.
  244. public $urlRefused = null; ///< Url de redirection du client en cas d'erreur.
  245. public $urlAutoResponse = null; ///< Url de retour automatique serveur.
  246. public $lang = "fr"; ///< Langue par defaut.
  247. public $defaultForeignLang = "en"; ///< Langue par defaut si pas de traduction disponible.
  248. public $defaultCurrencyCode = "978"; ///< La devise par défaut en l'euro.
  249. protected $defaultTemplate = null; ///< Template par defaut.
  250. /// Constructeur standard d'un module console.
  251. function __construct($ar=NULL){
  252. parent::__construct($ar);
  253. }
  254. /* Fonctions de paiements boutique */
  255. /**
  256. * \brief Méthode de génération des données de paiement.
  257. * Cette fonction permet de générer les données d'un paiement et l'insert dans la table TRANSACMONETIQUE.
  258. * \param MOrderInfos $order : Objet des données issues de la commande.
  259. * \param MCustomerInfos $customer : Objet des données issues du client.
  260. * \param MShopInfos $shop : Objet comportant les paramètres de la boutique.
  261. * \note
  262. * - Gestion du paiement à multiple écheances. \link MOrderInfos::$options \endlink
  263. * - Mémorise le nombre de retour banque (Spécifique à Paybox, maximum 3).
  264. * - Gestion de l'enrollement. \link insertAbonne($donnees) \endlink, \link MOrderInfos::$options \endlink
  265. * \exception:
  266. * - Error : \link webPaymentHandling(MOrderInfos $order, MCustomerInfos $customer, MShopInfos $shop, $transactionOid) \endlink.
  267. * \return array :
  268. * - String ok/ko.
  269. * - Array $formulaireAppel : Contient le formulaire envoyé en banque
  270. * - String $template : Le template correspondant correspondant un module de traitement
  271. * - String $tplentry : L'entrée smarty du template.
  272. * - Sring $transaction->oid : L'oid de la transaction \link MTransaction::$oid \endlink
  273. * \note
  274. * - Vérifie que toutes les infos nécésaires sont bien présentes
  275. * - Paramètres la transaction, l'insère en base et récupère son oid.
  276. * - Délègue au module approprié la création du formaulaire.
  277. * - Mémorise les données brutes d'appel et le status.
  278. */
  279. public function paymentCall(MOrderInfos $order, MCustomerInfos $customer, MShopInfos $shop){
  280. // Vérifie que toutes les infos nécésaires sont bien présentes.
  281. $this->checkPaymentData($order, $customer, $shop);
  282. $transaction = new MTransaction();
  283. if(isset($shop->cardsType)){
  284. $transaction->cardsType = $shop->cardsType;
  285. }
  286. // Définition des paramètres de la transaction
  287. if($this->testMode(true)){
  288. $transaction->testMode = True;
  289. }else{
  290. $transaction->testMode = False;
  291. }
  292. $transaction->status = self::RUNNING;
  293. $transaction->type = self::WEB_PAYMENT;
  294. /* Vérification des paramètres de la commande */
  295. $transaction->orderOid = $order->oid;
  296. $transaction->orderReference = $order->reference;
  297. $transaction->amount = $order->amount;
  298. // Préparation des paiement à multiples échéances
  299. if (isset($order->options['nbDeadLine']) && $order->options['nbDeadLine']>1) {
  300. $transaction->nbDeadLine = $order->options['nbDeadLine'];
  301. // Définition de la fréquence de prélèvement en jours
  302. if(empty($order->options['frequencyDuplicate'])){
  303. $transaction->frequencyDuplicate = '30';
  304. }else{
  305. $transaction->frequencyDuplicate = $order->options['frequencyDuplicate'];
  306. }
  307. // Par défaut le jour de prélèvement est la date courante
  308. if(!empty($order->options['captureDay'])){
  309. $transaction->captureDay = $order->options['captureDay'];
  310. }
  311. else{
  312. $transaction->captureDay = date('d');
  313. }
  314. } else {
  315. // Paiement à une seule échéances par défaut
  316. $transaction->nbDeadLine = '1';
  317. }
  318. // Si la commande indique que la capture doit être différé
  319. if(isset($order->options['captureDelay'])){
  320. $transaction->captureDelay = $order->options['captureDelay'];
  321. }else{
  322. $transaction->captureDelay = '0';
  323. }
  324. // Gestion du mode de capture (Capture par défaut, sinon autorisation seulement)
  325. if( $order->options['noCapture'] == true){
  326. $transaction->captureMode = self::AUTHORIZATION_ONLY;
  327. }
  328. else{
  329. $transaction->captureMode = self::CATCH_PAYMENT;
  330. }
  331. // Vérification de l'option enrollement
  332. if (isset($order->options['refAbonnement']) && $order->options['enrollement'] == true) {
  333. $transaction->enrollement = true;
  334. $transaction->refAbonneBoutique = $order->options['refAbonnement'];
  335. }
  336. $transaction->customerOid = $customer->oid;
  337. if(isset($customer->email)){
  338. $transaction->customerEmail = $customer->email;
  339. }
  340. if(isset($shop->class)){
  341. $transaction->shopClass = $shop->class;
  342. }
  343. // Paramètres de traitement de la réponse.
  344. $transaction->autoResponseMode = $shop->autoResponseMode;
  345. $transaction->shopCallBack = $shop->autoResponseCallBack;
  346. $transaction->shopName = $shop->name;
  347. $transaction->shopMoid = $shop->moid;
  348. $transaction->dateCreated = date('Y-m-d H:i:s');
  349. // champs plus spécifiques (pas communs à strictement toutes les vads)
  350. if (isset($order->options['specificsfields'])){
  351. if (isset($order->options['specificsfields']['transId'])){
  352. $transaction->transId = $order->options['specificsfields']['transId'];
  353. }
  354. }
  355. // Créer la transaction en base et récupère son oid pour les paramètres d'appel.
  356. $transaction->oid = $this->insertWebPayment($transaction);
  357. // Tentative de crétion du formulaire.
  358. try{
  359. // Appel au module concerné
  360. list($transaction, $formulaireAppel, $template, $tplentry) = $this->webPaymentHandling($transaction);
  361. $returnValue = array('ok', $formulaireAppel, $template, $tplentry, $transaction->oid);
  362. } catch(Exception $e){
  363. $transaction->status = self::ERROR;
  364. $transaction->statusComplement = $e->getMessage().' '.$e->getCode();
  365. XLogs::critical(get_class($this).' ::paymentCall ',XLabels::getSysLabel('xmodmonetique','exceptionPaymentCall').$transaction->statusComplement);
  366. $transactionParams = (array) $transaction;
  367. $transactionParams['_options'] = array('local'=>1);
  368. $transactionParams['options'] = array('callParms'=>array('raw'=>true,'toxml'=>true));
  369. $this->xset->procEdit($transactionParams);
  370. throw new Exception(get_class($this).' ::paymentCall : '.$transaction->statusComplement);
  371. }
  372. // Mémorisation de la date d'émission
  373. $transaction->dateTimeOut = date('Y-m-d H:i:s');
  374. // Gestion de l'enrollement.
  375. if (isset($order->options['refAbonnement']) && $order->options['enrollement'] == true) {
  376. $transaction->refAbonnement = $order->options['refAbonnement'];
  377. $this->insertAbonne($transaction);
  378. }
  379. // Enregistrement des paramètres d'appel
  380. $transactionParams = (array) $transaction;
  381. $transactionParams['_options'] = array('local'=>1);
  382. $transactionParams['options'] = array('callParms'=>array('raw'=>true,'toxml'=>true));
  383. $this->xset->procEdit($transactionParams);
  384. return $returnValue;
  385. }
  386. /**
  387. * \brief Fonction de traitement du retour banque automatique.
  388. * Cette fonction permet de faire le traitement du retour banque en passant par le module approprié.
  389. * \exception:
  390. * - Transaction introuvable.
  391. * - Montant d'appel et de réponse incohérents.
  392. * - Nombre de retour Paybox supérieur à 3.
  393. * - Trop grand nombre de retour pour une transaction.
  394. * \todo
  395. * - Exception si une transaction d'un module différent de paybox possède un statut différent de running. Ce cas se présente quand :
  396. * - Une réponse à déjà été reçue.
  397. * \return boolean : True (Pour un succès) ou False ( Error : \link webPaymentUnFoldReponse() \endlink )
  398. * \note
  399. * - Traite la réponse avec le module approprié. \link webPaymentUnFoldReponse() \endlink.
  400. * - Si l'oid de la transaction est introuvable, elle crée une nouvelle transaction pour mémoriser le paramètres reçus et lève une exception.
  401. * - Récupère les informations de la transaction d'origine. \link getTransaction($transactionOid) \endlink
  402. * - Lève une exception si une transaction d'un module différent de paybox possède un statut différent de running.
  403. * - Lève une exception si il y a une incohérence du montant, entre les paramètres d'appel et de réponse du serveur bancaire.
  404. * - Mémorise le retour.
  405. * - Gestion de l'enrollement. \link editAbonne($transaction) \endlink.
  406. * - Recupère tous les champs de la transaction non renseigné dans la reponse.
  407. * - Si la signature est vérifié, gestion de la notification boutique.
  408. * \todo Voir l'équivalent de instanceof pour voir si une classe appartient à une classe mère (pour Paybox).
  409. */
  410. public function autoresponse() {
  411. // Tentative de traitement de la réponse par le module approprié
  412. try{
  413. $transaction = $this->webPaymentUnFoldReponse();
  414. $ret = array(true, $transaction->oid);
  415. }catch(Exception $e){
  416. // Erreur de traitement de la réponse
  417. $transaction->status = self::ERROR;
  418. $transaction->statusComplement = 'Message : '.$e->getMessage().' Code : '.$e->getCode();
  419. $transactionParams = (array) $transaction;
  420. $transactionParams['_options'] = array('local'=>1);
  421. $transactionParams['options'] = array('callParms'=>array('raw'=>true,'toxml'=>true));
  422. $this->xset->procEdit($transactionParams);
  423. XLogs::critical(get_class($this).' ::autoresponse ' , $transaction->statusComplement);
  424. return false;
  425. }
  426. XLogs::critical(get_class($this).' ::autoresponse ', print_r($transaction, true));
  427. // Vérification de la réponse de la banque
  428. if($transaction->responseCode == '00'){
  429. $transaction->status = self::SUCCESS;
  430. }
  431. else{
  432. $transaction->status = self::ERROR;
  433. }
  434. // Si l'oid de la transaction n'a pas été trouvé par le module approprié, on crée une nouvelle transaction pour mémoriser le paramètres reçus.
  435. if ($transaction->oid == null){
  436. $transaction->statusComplement .= XLabels::getSysLabel('xmodmonetique','exceptionUnknowTransaction');
  437. $paramToMemorize = (array) $transaction;
  438. $paramToMemorize['options'] = array('responseParms'=>array('raw'=>true,'toxml'=>true));
  439. $r = $this->xset->procInput( (array) $paramToMemorize);
  440. XLogs::critical(get_class($this).' ::autoresponse '. XLabels::getSysLabel('xmodmonetique','exceptionUnknowTransaction'), print_r($transaction, true));
  441. // En cas de problème d'insertion de cette réponse, on log les paramètres reçus
  442. if (empty($r)) {
  443. XLogs::critical(get_class($this).' ::autoresponse : Problème d\'insertion de la transaction : ', print_r($transaction, true));
  444. }
  445. throw new Exception(get_class($this).' ::autoresponse :'.XLabels::getSysLabel('xmodmonetique','exceptionUnknowTransaction'));
  446. }
  447. // Si la transaction à été trouvée, on récupère les informations de la transaction d'origine
  448. $paramsOri = $this->getTransaction($transaction->oid);
  449. // Incrémentation du nombre de retour (3 maximum pour un paiement Web)
  450. if(empty($paramsOri->nbReturn)){
  451. $transaction->nbReturn = 1; ///< Premier retour
  452. }else{
  453. $transaction->nbReturn++; ///< Retours suivants
  454. }
  455. // Si le nombres de retour Paybox est supérieur à 3 on lève une exception
  456. if ( (($transaction->nbReturn > 3) && ($transaction->nbDeadLine == 1) || ($transaction->nbReturn > $transaction->nbDeadLine+2 ) ) && ((get_class($this)=='XModPaybox') || ($this instanceof XModPaybox == 1)) ){
  457. XLogs::update('update', $transaction->oid, $this->array2html($transaction->responseParms, true));
  458. XLogs::critical(get_class($this)."::autoresponse ".XLabels::getSysLabel('xmodmonetique','overmuchResponse'), print_r($transaction, true));
  459. throw new Exception(get_class($this).' ::autoresponse '.XLabels::getSysLabel('xmodmonetique','overmuchResponse').$transaction->oid);
  460. }
  461. // Si une transaction d'un module différent de paybox possède un statut différent de running (C'est qu'une réponse à déjà été reçu, ou qu'elle comportait une erreur de paramètre), donc on lève une execption
  462. if ( ( ($paramsOri->status != self::RUNNING) && ($paramsOri->nbDeadLine < $transaction->nbReturn)) && ((get_class($this)!='XModPaybox') && ($this instanceof XModPaybox != 1)) ) {
  463. $transaction->autoResponseMode = self::RESPONSE_NONE;
  464. $transaction->statusComplement = 'Erreur, trop de retour pour cette transaction on déjà été traité : '.$transaction->status.'/'.$transaction->statusComplement;
  465. // on garde la "reponse" dans les log de la transaction
  466. XLogs::update('update', $transaction->oid, print_r($transaction->responseParms, true));
  467. XLogs::critical(get_class($this).' ::autoresponse '.$transaction->statusComplement, print_r($transaction, true));
  468. throw new Exception('::autoresponse '.$transaction->statusComplement);
  469. }
  470. XLogs::critical(get_class($this).' ::autoresponse->transaction(initialiser par unfold) ', print_r($transaction, true));
  471. XLogs::critical(get_class($this).' ::autoresponse params ori', print_r($paramsOri, true));
  472. // Paypal ne fournisant pas le montant total pour un paiement multiple, il faut recalculer le montant de l'échéance
  473. if($paramsOri->nbDeadLine > 1){
  474. if((get_class($this)=='XModPaypal') || ($this instanceof XModPaypal == 1)){
  475. $montant = $paramsOri->amount / $paramsOri->nbDeadLine;
  476. $montant = round($montant , 2);
  477. // Calcule de la différence du aux arrondis
  478. $diff= $paramsOri->amount - ($montant* $paramsOri->nbDeadLine);
  479. if( !empty($transaction->responseParms['mc_amount1']) && ($transaction->responseParms['mc_amount1']==$montant+$diff) && ($transaction->responseParms['mc_amount1']==$montant) ){
  480. $transaction->amount= $paramsOri->amount;
  481. XLogs::critical(get_class($this).' ::autoresponse ', 'Montants OK');
  482. }else{
  483. list($firstDeadLine,$otherDeadLine) = $this->getAmountDeadLine($transaction->oid);
  484. if( $transaction->amount==$firstDeadLine || $transaction->amount==$otherDeadLine){
  485. $transaction->amount= $paramsOri->amount;
  486. }
  487. }
  488. }
  489. }
  490. // Vérification de la cohérence du montant, entre les paramètres d'appel et de réponse du serveur bancaire
  491. if (!$this->checkResponseAmount($transaction->amount, $paramsOri->amount)){
  492. $amountCall = XLabels::getSysLabel('xmodmonetique','amountCall').$paramsOri->amount;
  493. $amountResponse =XLabels::getSysLabel('xmodmonetique','amountResp').$transaction->amount ;
  494. $transaction->statusComplement = XLabels::getSysLabel('xmodmonetique','errorAmount').$amountCall.' : '.$amountResponse;
  495. $this->xset->procEdit(array('_options'=>array('local'=>1),
  496. 'oid'=> $transaction->oid,
  497. 'responseParms'=>$transaction->responseParms,
  498. 'status'=>self::ERROR,
  499. 'dateTimeIn'=>date('Y-m-d H:i:s'),
  500. 'statusComplement'=>$transaction->statusComplement,
  501. 'nbReturn'=>$transaction->nbReturn,
  502. 'responseStatus'=>'NA'
  503. ));
  504. XLogs::critical(get_class($this)."::autoresponse ", $transaction->statusComplement);
  505. throw new Exception(get_class($this).' ::autoresponse '.$transaction->statusComplement);
  506. }
  507. // Affectation du libellé du code erreur dans le statusComplement si il est vide
  508. if(empty( $transaction->statusComplement)){
  509. $transaction->statusComplement = $this->getErrorCode($transaction->responseCode);
  510. }
  511. // Mémorisation de la réponse
  512. $transaction->dateTimeIn = date('Y-m-d H:i:s');
  513. $infosToMemorize = (array) $transaction;
  514. $infosToMemorize['_options'] = array('local'=>1);
  515. $infosToMemorize['options'] = array('responseParms'=>array('raw'=>true,'toxml'=>true));
  516. $this->xset->procEdit($infosToMemorize);
  517. // Récupération des informations d'origine afin de traiter l'enrollement s'il y a lieu
  518. foreach ($paramsOri as $key => $value){
  519. // On vérifie que le champs est vide afin de ne pas écraser d'informations.
  520. if(empty($transaction->$key)){
  521. $transaction->$key = $value;
  522. }
  523. }
  524. // Si la transaction d'origine indique qu'il faut mettre à jour la table des enrollements
  525. if (!empty($transaction->refAbonneBoutique)){
  526. // Si la transaction est un echec on le mémorise également dans la table des enrollements
  527. if($transaction->status != self::SUCCESS){
  528. $transaction->porteur= XLabels::getSysLabel('xmodmonetique','enrollementError');
  529. $transaction->dateVal = XLabels::getSysLabel('xmodmonetique','enrollementError');
  530. $transaction->cvv = XLabels::getSysLabel('xmodmonetique','enrollementError');
  531. $transaction->numCarte = XLabels::getSysLabel('xmodmonetique','enrollementError');
  532. }
  533. // Mise à jour de l'enrollement
  534. $this->editAbonne($transaction);
  535. }
  536. // Si nécessaire on notifie le retour à la boutique
  537. if ($transaction->autoResponseMode === self::SYNC_RESPONSE){
  538. $this->notifyShop($transaction);
  539. }
  540. // Sinon on valorise le statut de réponse à : RESPONSE_STATUS_TO_SEND, afin qu'il soit traité de manière asynchrone
  541. elseif($transaction->autoResponseMode === self::ASYNC_RESPONSE){
  542. $this->xset->procEdit(array('_options'=>array('local'=>true), 'oid'=>$transaction->oid, 'responseStatus'=>self::RESPONSE_STATUS_TO_SEND));
  543. }
  544. $GLOBALS['XSHELL']->response = (object)array('complete' => true, 'content' => '');
  545. return true;
  546. }
  547. /**
  548. * \brief Fonction d'insertion d'une transaction en base.
  549. * Cette fonction permet d'inserer une transaction avant l'appel en banque.
  550. * \param MTransaction $transaction : La transaction paramètré par paymentCall.
  551. * \return String Oid de la transaction associée à ce paiement.
  552. */
  553. protected function insertWebPayment(MTransaction $transaction){
  554. $transaction->monetiqueMoid = $this->_moid;
  555. $transaction->responseStatus = self::RESPONSE_NONE;
  556. $r = $this->xset->procInput( (array) $transaction);
  557. if (empty($r)) {
  558. XLogs::critical(get_class($this).XLabels::getSysLabel('xmodmonetique','errorInsertWebPayment'), print_r($transactionParams, true));
  559. ;
  560. }
  561. return $r['oid'];
  562. }
  563. /**
  564. * \brief Fonction de création d'un abonné.
  565. * Cette fonction permet d'inserer un nouvel abonné avant l'appel en banque.
  566. * \param MTransaction $transaction : La transaction contenant les paramètres d'enrollement :
  567. * - $transaction->customerOid. \link MTransaction::$customerOid \endlink
  568. * - $transaction->refAbonneBoutique. \link MTransaction::$refAbonneBoutique \endlink
  569. * - $transaction->oid']. \link MTransaction::$oid \endlink
  570. * \note
  571. * - Récupère la table des abonnés.
  572. * - Prépare les paramètres à mémoriser.
  573. * - Insère les informations.
  574. * \return String Oid du nouvel enrollement.
  575. */
  576. protected function insertAbonne($transaction) {
  577. // Récupération de la table des abonnés
  578. $tableAbonne = XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.'ENROMONETIQUE');
  579. // Préparation des paramètres à mémoriser
  580. $infosAbonne = array(
  581. 'customerOid' => $transaction->customerOid,
  582. 'refAbonne'=> $transaction->refAbonneBoutique,
  583. 'transOri' => $transaction->oid
  584. );
  585. // Insertion des informations
  586. $r = $tableAbonne->procInput($infosAbonne);
  587. if (empty($r)) {
  588. XLogs::critical(get_class($this).XLabels::getSysLabel('xmodmonetique','errorInsertAbonne'), print_r($infosAbonne), true);
  589. }
  590. return $r['oid'];
  591. }
  592. /**
  593. * \brief Fonction de mise à jour d'un abonné.
  594. * Cette fonction permet de mettre à jour un abonné à la suite d'un retour banque.
  595. * \param MTransaction $transaction : La transaction donné par le retour banque.
  596. * - Doit contenir:
  597. * - $transaction->customerOid. \link MTransaction::$customerOid \endlink
  598. * - $transaction->refAbonneBoutique. \link MTransaction::$refAbonneBoutique \endlink
  599. * \note
  600. * - Récupère la table des abonnés.
  601. * - Vérifie que l'enrollement à été créé avant l'appel en banque.
  602. * - Prépare les paramètres à mémoriser
  603. * - Insère les informations.
  604. * \return String Oid du nouvel enrollement.
  605. */
  606. protected function editAbonne($transaction) {
  607. // Récupération de la table des abonnés
  608. $tableAbonne = XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.'ENROMONETIQUE');
  609. // On vérifie que l'enrollement à été créé avant l'appel bancaire
  610. $custEnro = $this->getEnrollement($transaction->customerOid,$transaction->refAbonneBoutique);
  611. if(!empty($custEnro)){
  612. // Préparation des paramètres à mémoriser
  613. $lar = array('_options'=>array('local'=>1),
  614. 'oid'=>$custEnro->KOID,
  615. 'refAbonne'=>$transaction->refAbonneBoutique,
  616. 'customerOid'=> $transaction->customerOid,
  617. 'porteur'=>$transaction->porteur,
  618. 'dateVal'=>$transaction->dateVal,
  619. 'cvv'=>$transaction->cvv,
  620. 'numCarte'=>$transaction->numCarte,
  621. );
  622. // Insertion des informations
  623. $r = $tableAbonne->procEdit($lar);
  624. if (empty($r)) {
  625. XLogs::critical(get_class($this).' ::editAbonne : '.XLabels::getSysLabel('xmodmonetique','errorUpdateAbonne'), print_r($lar), true);
  626. }
  627. }
  628. else{
  629. XLogs::critical(get_class($this).XLabels::getSysLabel('xmodmonetique','errorUnknowAbonne'), print_r($transaction), true);
  630. }
  631. return $r['oid'];
  632. }
  633. /**********************************************************
  634. *************** Fonctions de remboursement ***************
  635. *********************************************************/
  636. /**
  637. * \brief Fonction création d'un remboursement.
  638. * Cette fonction permet de mettre à jour un abonné à la suite d'un retour banque.
  639. * \param String $transactionOriginOid : Identifiant de la transaction d'origine. \link MTransaction::$oid \endlink
  640. * \param MOrderInfos $order : Commande à l'origine du remboursement, avec le montant du remboursement.
  641. * - $order->amount est obligatoire.\link MOrderInfos::$amount \endlink
  642. * \param MShopInfos $shop : Comporte les paramètres de la boutique (autoResponseCallBack, autoResponseMode, ...).\link MShopInfos \endlink
  643. * \return Array :
  644. * - String ok/ko.
  645. * - String oid de la nouvelle transaction. \link MTransaction::$oid \endlink
  646. * \exception:
  647. * - Error : \link refundHandling(& $transaction) \endlink.
  648. * - Impossible de trouver la transaction d'origine.
  649. * - Si $order->amount n'est pas initialisé. \link MOrderInfos::$amount \endlink
  650. * - Si la signature est invalide, levée par \link refundHandling(& $transaction) \endlink
  651. * \note
  652. * - Si $transactionOriginOid (\link MTransaction::$oid \endlink) est null, cherche la transaction à partir de l'order->reference (\link MTransaction::$reference \endlink).
  653. * - Vérification que le montant à rembourser à été saisi.
  654. * - Initialise les paramètres de base de la nouvelle transaction.
  655. * - Copie les informations manquantes à partir de la transaction d'origine.
  656. * - Crée la transaction en base. \link insertRefund ($transaction, $shop) \endlink.
  657. * - Formate le montant passé en paramètres. \link formatOrderAmount($amount); \endlink
  658. * - Met à jour les attributs de $newTransaction. \link refundHandling(& $transaction) \endlink.
  659. * - Mémorise les données brutes de reponse et le status.
  660. * - Si la signature est vérifié, gestion de la notification boutique.
  661. * \see
  662. * - getIdTransactionWithOrderRef($orderReference);
  663. * - getTransaction ($transactionOid);
  664. * - refundHandling(& $transaction);
  665. * \todo Factoriser le contrôle du montant dans monétique
  666. */
  667. public function refundCall($transactionOriginOid, $order, $shop){
  668. // Recherche la transaction d'origine
  669. // Si l'on ne possède que l'order->reference, on cherche la transaction à partir de celui-ci
  670. if(!empty($order->reference) && empty($transactionOriginOid)){
  671. // Récupération de l'oid de la transaction d'origine
  672. $transactionOriginOid = $this->getIdTransactionWithOrderRef($order->reference);
  673. // Récupération de toutres les infos relatives à cette transaction
  674. $transactionOrigin = $this->getTransaction($transactionOriginOid);
  675. // Mémorisation de l'oid d'origine
  676. $transactionOrigin->oid = $transactionOriginOid;
  677. }
  678. // Sinon on cherche la transaction à partir de son oid
  679. else if(!empty($transactionOriginOid)){
  680. // Récupération de toutres les infos relatives à cette transaction
  681. $transactionOrigin = $this->getTransaction($transactionOriginOid);
  682. // Mémorisation de l'oid d'origine
  683. $transactionOrigin->oid = $transactionOriginOid;
  684. }
  685. // Problème de paramètres, impossible de trouver la transaction d'origine
  686. if(empty($transactionOrigin->oid)){
  687. throw new Exception(get_class($this).' ::refundCall '.XLabels::getSysLabel('xmodmonetique','exceptionUnknowTransaction').' Order reference : '.$order->reference.' Transaction oid : '.$transactionOriginOid);
  688. }
  689. // Vérification que le montant à rembourser à été saisi
  690. if(empty($order->amount)){
  691. throw new Exception(get_class($this).' ::refundCall :'.XLabels::getSysLabel('xmodmonetique','noAmount'));
  692. }
  693. /* Initialisation des paramètres de base de la nouvelle transaction */
  694. // Mémorisation de la transaction d'origine
  695. $newTransaction->transOri = $transactionOrigin->oid;
  696. // Affectation de la date de création du remboursement
  697. $newTransaction->dateCreated = date('Y-m-d H:i:s');
  698. // Affectation du montant à rembourser
  699. $newTransaction->amount = $order->amount;
  700. // Récupération de l'oid de la commande à remboursée
  701. $newTransaction->orderOid = $transactionOrigin->orderOid;
  702. // Génération de la référence de la commande de remboursement
  703. $newTransaction->orderReference = 'N/A'; //$this->genOrderRef('Y%m%d%H%i%s');
  704. // Le remboursement est immédiat
  705. $newTransaction->captureMode = self::CATCH_PAYMENT;
  706. // Le traitement est en cours
  707. $newTransaction->status = self::RUNNING;
  708. // Le type de transaction est un remboursement
  709. $newTransaction->type = self::REFUND;
  710. // Il n'y a pas de dalai, si c'est faisable, on le fait
  711. $newTransaction->captureDelay = 0;
  712. // Récupération de l'oid du client à remboursée
  713. $newTransaction->customerOid = $transactionOrigin->customerOid;
  714. // On regarde s'il y a des infos supplémentaires au sujet du client
  715. if(isset($transactionOrigin->refAbonneBoutique)){
  716. $newTransaction->refAbonneBoutique = $transactionOrigin->refAbonneBoutique;
  717. }
  718. if(isset($transactionOrigin->customerEmail)){
  719. $newTransaction->customerEmail = $transactionOrigin->customerEmail;
  720. }
  721. /* Paramètres de la boutique */
  722. // On mémorise dans la transaction le mode de réponse attendu par la boutique.
  723. $newTransaction->autoResponseMode = $shop->autoResponseMode;
  724. // On mémorise dans la transaction la fonction de traitement de la reponse attendu par la boutique.
  725. $newTransaction->shopCallBack = $shop->autoResponseCallBack;
  726. $newTransaction->monetiqueMoid = $this->_moid;
  727. $newTransaction->shopMoid = $shop->moid;
  728. $newTransaction->shopName = $shop->name;
  729. $newTransaction->shopClass = $shop->class;
  730. // Tant qu'on n'a pas de réponse on ne cherche pas à notifier la boutique
  731. $newTransaction->responseStatus = self::RESPONSE_NONE;
  732. // Créer la transaction en base. On a besoin de son oid pour les paramètres d'appel
  733. $newTransaction->oid = $this->insertRefund($newTransaction, $shop);
  734. // Traiter la requête
  735. try{
  736. // Cette méthode retourne la transaction après l'appel en banque
  737. $transaction = $this->refundHandling($newTransaction);
  738. $returnValue = array('ok', $newTransaction->oid);
  739. }
  740. catch(Exception $e){
  741. XLogs::critical(get_class($this).'::refundCall ',print_r($newTransaction,true) );
  742. $newTransaction->status = self::ERROR;
  743. XLogs::critical(get_class($this), '::refundCall -> ::refundHandling '.$e->getMessage().' Code '.$e->getCode());
  744. $newTransaction->statusComplement = $e->getMessage();
  745. // Mémorise les données brutes de reponse et le status
  746. $this->xset->procEdit(array('_options'=>array('local'=>1),
  747. 'oid'=>$newTransaction->oid,
  748. 'responseParms'=>$newTransaction->responseParms,
  749. 'status'=> $newTransaction->status,
  750. 'dateTimeIn'=>date('Y-m-d H:i:s'),
  751. 'statusComplement'=> $newTransaction->statusComplement,
  752. 'responseCode'=>$newTransaction->responseCode,
  753. 'options'=>array('responseParms'=>array('raw'=>true,'toxml'=>true))
  754. ));
  755. $returnValue = array('ko', $newTransaction->oid);
  756. throw new Exception(get_class($this).' ::refundCall : '.$newTransaction->statusComplement);
  757. }
  758. XLogs::critical(get_class($this).' ::refundCall', print_r($transaction,true));
  759. // Mémorise les données brutes de reponse et le status
  760. $this->xset->procEdit(array('_options'=>array('local'=>1),
  761. 'oid'=>$transaction->oid,
  762. 'responseParms'=>$transaction->responseParms,
  763. 'status'=> $transaction->status,
  764. 'dateTimeIn'=>date('Y-m-d H:i:s'),
  765. 'statusComplement'=> $transaction->statusComplement,
  766. 'responseCode'=>$transaction->responseCode,
  767. 'options'=>array('responseParms'=>array('raw'=>true,'toxml'=>true))
  768. ));
  769. // si nécessaire notifier le retour à la boutique
  770. if ($newTransaction->autoResponseMode === self::SYNC_RESPONSE){
  771. $this->notifyShop($newTransaction);
  772. }
  773. // Sinon mise à jour pour traitement asynchrone
  774. elseif($newTransaction->autoResponseMode === self::ASYNC_RESPONSE){
  775. $this->xset->procEdit(array('_options'=>array('local'=>true),
  776. 'oid'=>$newTransaction->oid,
  777. 'responseStatus'=>self::RESPONSE_STATUS_TO_SEND
  778. ));
  779. }
  780. return $returnValue;
  781. }
  782. /**
  783. * \brief Fonction d'insertion d'un remboursement en base.
  784. * Cette fonction permet d'inserer une transaction avant l'appel en banque.
  785. * \param MTransaction $transaction : Contient les informations relatives au remboursement. \link MTransaction \endlink
  786. * \return String Oid de la transaction associée à ce remboursement. \link MTransaction::$oid \endlink
  787. */
  788. protected function insertRefund($transaction, $shop){
  789. $r = $this->xset->procInput( (array) $transaction);
  790. if (empty($r)) {
  791. XLogs::critical(get_class($this).' ::insertRefund :'.XLabels::getSysLabel('xmodmonetique','noAmount'), print_r($infosToMemorize), true);
  792. }
  793. return $r['oid'];
  794. }
  795. /**
  796. * \brief Fonction de ré-émission des remboursements ayant le status waitting.
  797. * Cette fonction permet de rejouer les remboursement en attente.
  798. * \return Array :
  799. * - Int $nbTotal : Nombre total de transactions rejouée.
  800. * - Int $nbSucces : Nombre total de succès.
  801. * - Array $error : Le details des erreurs (statusComplement de chaque transaction échouée).
  802. * \throws:
  803. * - Error : \link refundHandling(& $transaction) \endlink.
  804. * - Impossible de trouver la transaction d'origine.
  805. * \note
  806. * - Séléctionne des transaction à rejouer.
  807. * - Pour chaque transaction :
  808. * - Formate le montant de la transaction en centimes.
  809. * - Transforme les paramètres d'appels mémorisés en XML en tableau associatif.
  810. * - Appel à la fonction refundReplay spécifique au module de la transaction.
  811. * - Mémorise la réponse et les paramètres de la transaction.
  812. * - Si la signature est vérifié, gestion de la notification boutique.
  813. * \see
  814. * - XModMonetique::refundReplay(& $transaction);
  815. */
  816. public function refundAsyncHandling(){
  817. // Séléction des transaction à rejouer
  818. $rs = selectQuery('select * from '.$this->xset->getTable().' where status = "'.self::WAITTING.'" and type = "'.self::REFUND.'" and monetiqueMoid = "'.$this->_moid.'" ');
  819. // Initialisation des variables locales
  820. $nbTotal = $rs->rowcount();
  821. $nbSucces = '0';
  822. $error = array();
  823. // Tant qu'il y a des transactions à rejouer
  824. while($ors = $rs->fetch()){
  825. foreach ($ors as $key => $value){
  826. // Si c'est le montant on le formate en centimes et on le mémorise dans la transaction
  827. $transaction->$key = $value;
  828. }
  829. // On transforme les paramètres d'appels mémorisés en XML en tableau associatif
  830. $transaction->callParms = XSystem::xml2array($transaction->callParms);
  831. // Appel à la fonction refundReplay spécifique au module de la transaction
  832. $transaction = $this->refundReplay($transaction);
  833. // Mémorise la réponse et les paramètres de la transaction
  834. $this->xset->procEdit(array(
  835. '_options'=>array('local'=>1),
  836. 'oid'=>$transaction->KOID,
  837. 'responseParms'=>$transaction->responseParms,
  838. 'statusComplement'=> $transaction->statusComplement,
  839. 'status'=>$transaction->status,
  840. 'options'=>array('responseParms'=>array('raw'=>true,'toxml'=>true))
  841. ));
  842. if($transaction->status == self::SUCCESS){
  843. $nbSucces++;
  844. }else{
  845. $error[$ors['KOID']][$transaction->status] = $transaction->statusComplement;
  846. }
  847. // si nécessaire notifier le retour à la boutique
  848. if ($ors->autoResponseMode === self::SYNC_RESPONSE){
  849. $this->notifyShop($ors->oid);
  850. }
  851. elseif($ors->autoResponseMode === self::ASYNC_RESPONSE){
  852. $this->xset->procEdit(array('_options'=>array('local'=>true), 'oid'=>$ors->oid, 'responseStatus'=>self::RESPONSE_STATUS_TO_SEND));
  853. }
  854. }
  855. return array($nbTotal, $nbSucces, $error);
  856. }
  857. /* Fonctions de débit forcé d'un abonné */
  858. /**
  859. * \brief Fonction de génération des données de prelevement.
  860. * Cette fonction permet de dupliquer un paiement à partir d'un paiement web ayant généré un enrollement.
  861. * \param MOrderInfos $order : Commande relative à la duplication, avec le montant de la duplication.
  862. * - $order->amount est obligatoire.
  863. * \param MCustomerInfos $customer : Le client qui va être débité.
  864. * - $customer->oid et $customer->refAbonne sont obligatoire.
  865. * \param MShopInfos $shop : Comporte les paramètres de la boutique (autoResponseCallBack, autoResponseMode, ...).
  866. * \return MTransaction $transaction : La transaction après l'appel banque avec tous ses paramètres renseignés.
  867. * \exception:
  868. * - Error : \link refundHandling(& $transaction) \endlink
  869. * - Si $order->amount n'est pas initialisé.
  870. * - Si \link XModMonetique::getEnrollement($customerOid,$refAbonne) \endlink retourne null.
  871. * - Impossible de trouver la transaction d'origine.
  872. * \note
  873. * - Vérifie que le montant est saisi.
  874. * - Récupère les informations concernant l'abonné. \link getEnrollement($customerOid,$refAbonne); \endlink
  875. * - Initialise les paramètres de base de la nouvelle transaction.
  876. * - Formate le montant passé en paramètres. \link formatOrderAmount($amount); \endlink
  877. * - Récupère les informations de la transaction d'origine. \link getTransaction($transactionOid) \endlink
  878. * - Crée la transaction en base, avant l'appel en banque. \link insertDuplicate($transaction); \endlink
  879. * - L'appel à \link marshallRemboursement(& $newTransaction); \endlink permet de laissé le traitement de la duplication au module concerné. Cette appel renseigne le retour dans $newTransaction.
  880. * - Mémorise les données brutes de reponse et le status.
  881. * - Si la signature est vérifié, gestion de la notification boutique.
  882. * \see
  883. * - getEnrollement($customerOid,$refAbonne);
  884. * - formatOrderAmount($amount);
  885. * - getTransaction ($transactionOid);
  886. * - refundHandling($transaction);
  887. */
  888. public function duplicateCall(MOrderInfos $order, MCustomerInfos $customer, MShopInfos $shop){
  889. // Vérification que le montant est saisi
  890. if(empty($order->amount)){
  891. throw new Exception(get_class($this).' ::duplicateCall :'.XLabels::getSysLabel('xmodmonetique','noAmount'));
  892. }
  893. // Récupération des informations concernant l'abonné
  894. $customerEnrollment = $this->getEnrollement($customer->oid, $customer->refAbonne);
  895. // Si l'abonné existe dans ENROMONETIQUE
  896. if (!empty($customerEnrollment)){
  897. $newTransaction = new MTransaction();
  898. // Préparation des paiement à multiples échéances
  899. if (isset($order->options['nbDeadLine'])) {
  900. $newTransaction->nbDeadLine = $order->options['nbDeadLine'];
  901. // Définition de la fréquence de prélèvement en jours
  902. if(empty($order->options['frequencyDuplicate'])){
  903. $newTransaction->frequencyDuplicate = '30';
  904. }else{
  905. $newTransaction->frequencyDuplicate = $order->options['frequencyDuplicate'];
  906. }
  907. // Par défaut le jour de prélévement est la date courante
  908. if(!empty($order->options['captureDay'])){
  909. $newTransaction->captureDay = $order->options['captureDay'];
  910. }
  911. else{
  912. $newTransaction->captureDay = date('d');
  913. }
  914. }
  915. // Paiement à une seule échéances par défaut
  916. else {
  917. $newTransaction->nbDeadLine = '1';
  918. }
  919. // Si la commande indique que la capture doit être différé
  920. if(isset($order->options['captureDelay'])){
  921. $newTransaction->captureDelay = $order->options['captureDelay'];
  922. }else{
  923. $newTransaction->captureDelay = '0';
  924. }
  925. // Gestion du mode de capture (Capture par défaut, sinon autorisation seulement)
  926. if( $order->options['noCapture'] == true){
  927. $newTransaction->captureMode = self::AUTHORIZATION_ONLY;
  928. }
  929. else{
  930. $newTransaction->captureMode = self::CATCH_PAYMENT;
  931. }
  932. // Affectation du type de transaction : DEBIT
  933. $newTransaction->type = self::DUPLICATE;
  934. // Mémorisation de la transaction d'origine
  935. $newTransaction->transOri =$customerEnrollment->transOri;
  936. // Mémorisation de la référence abonné
  937. $newTransaction->refAbonneBoutique =$customerEnrollment->refAbonne;
  938. // Mémorisation du cvv
  939. $newTransaction->cvv =$customerEnrollment->cvv;
  940. // Mémorisation du porteur
  941. $newTransaction->porteur =$customerEnrollment->porteur;
  942. // Mémorisation de la date de validitée de la carte
  943. $newTransaction->dateVal =$customerEnrollment->dateVal;
  944. // Affectation du montant à rembourser
  945. $newTransaction->amount =$order->amount;
  946. // Définition du status
  947. $newTransaction->status = self::RUNNING;
  948. // Pas de notification tant qu'il n'y a pas de reponse
  949. $newTransaction->responseStatus = self::RESPONSE_NONE;
  950. // Récupération de la référence
  951. $newTransaction->orderReference = $order->reference;
  952. // Récupération de l'oid de la commande
  953. $newTransaction->orderOid = $order->oid;
  954. // Si la boutique fournis le mode de réponse attendu. Sinon on utilisera le même mode que la transaction d'origine.
  955. if(isset($shop->autoResponseMode)){
  956. $newTransaction->autoResponseMode = $shop->autoResponseMode;
  957. }
  958. // Si la boutique fournis la fonction de traitement de la reponse. Sinon on utilisera la même fonction que la transaction d'origine.
  959. if(isset($shop->autoResponseCallBack)){
  960. $newTransaction->shopCallBack = $shop->autoResponseCallBack;
  961. }
  962. $newTransaction->monetiqueMoid = $this->_moid;
  963. $newTransaction->shopMoid = $shop->moid;
  964. $newTransaction->shopName = $shop->name;
  965. $newTransaction->shopClass = $shop->class;
  966. $newTransaction->dateCreated = date('Y-m-d H:i:s');
  967. // Récupération de la transaction d'origine
  968. $transactionOrigin = $this->getTransaction($customerEnrollment->transOri);
  969. // Si la transaction d'origine à n'a pas été trouvée, on lève une exception.
  970. if(empty($transactionOrigin)){
  971. XLogs::critical(get_class($this).' ::duplicateCall '.XLabels::getSysLabel('xmodmonetique','exceptionUnknowTransaction'), print_r($customerEnrollment, true)) ;
  972. throw new Exception(get_class($this).' ::duplicateCall '.XLabels::getSysLabel('xmodmonetique','exceptionUnknowTransaction'));
  973. }
  974. // Récupération des informations concernant le client
  975. if(isset($transactionOrigin->customerOid)){
  976. $newTransaction->customerOid = $transactionOrigin->customerOid;
  977. }
  978. if(isset($transactionOrigin->customerEmail)){
  979. $newTransaction->customerEmail = $transactionOrigin->customerEmail;
  980. }
  981. // Créer la transaction en base. On a besoin de son oid pour les paramètres d'appel
  982. $newTransaction->oid = $this->insertDuplicate($newTransaction);
  983. // Traiter la requète
  984. try{
  985. // Cette méthode retoutne la transaction après l'appel banque.
  986. $transaction = $this->duplicateHandling($newTransaction);
  987. $returnValue = $transaction;
  988. } catch(Exception $e){
  989. $newTransaction->statusComplement = $e->getMessage().' '.$e->getCode();
  990. $newTransaction->status = self::ERROR;
  991. XLogs::critical(get_class($this).' ::duplicateCall : '.XLabels::getSysLabel('xmodmonetique','exceptionDuplicateCall'), print_r($newTransaction, true));
  992. throw new Exception('::duplicateCall :'.XLabels::getSysLabel('xmodmonetique','exceptionDuplicateCall').$newTransaction->statusComplement);
  993. }
  994. // On mémorise les données brutes et le status
  995. $this->xset->procEdit(array(
  996. '_options'=>array('local'=>1),
  997. 'oid'=>$transaction->oid,
  998. 'responseParms'=>$transaction->responseParms,
  999. 'status'=> $transaction->status,
  1000. 'dateTimeIn'=>date('Y-m-d H:i:s'),
  1001. 'statusComplement'=> $transaction->statusComplement,
  1002. 'responseCode'=>$transaction->responseCode,
  1003. 'options'=>array('responseParms'=>array('raw'=>true,'toxml'=>true))
  1004. ));
  1005. // si nécessaire notifier le retour à la boutique
  1006. if ($newTransaction->autoResponseMode === self::SYNC_RESPONSE){
  1007. $this->notifyShop($newTransaction);
  1008. } elseif($newTransaction->autoResponseMode === self::ASYNC_RESPONSE){
  1009. $this->xset->procEdit(array('_options'=>array('local'=>true), 'oid'=>$transaction->oid, 'responseStatus'=>self::RESPONSE_STATUS_TO_SEND));
  1010. }
  1011. return $returnValue;
  1012. }
  1013. // Si l'enrollement est introuvable
  1014. else{
  1015. XLogs::critical(get_class($this), '::duplicateCall erreur : Customer enrollemnt introuvable.');
  1016. throw new Exception('::duplicateCall erreur : Customer enrollemnt introuvable.');
  1017. }
  1018. }
  1019. /**
  1020. * \brief Fonction d'insertion d'une duplication en base.
  1021. * Cette fonction permet d'inserer une duplication avant l'appel en banque.
  1022. * \param MTransaction $transaction : Contient les informations relatives au remboursement.
  1023. * \return String Oid de la transaction associée à cette duplication.
  1024. */
  1025. protected function insertDuplicate($transaction){
  1026. $r = $this->xset->procInput((array) $transaction);
  1027. if (empty($r)) {
  1028. XLogs::critical(get_class($this), 'Problème d\'insertion de la transaction');
  1029. XLogs::critical(get_class($this), print_r($lar), true);
  1030. }
  1031. return $r['oid'];
  1032. }
  1033. /**
  1034. * \brief Fonction de ré-émission des duplications ayant le status waitting.
  1035. * Cette fonction permet de rejouer les duplications en attente.
  1036. * \return Array :
  1037. * - Int $nbTotal : Nombre total de transactions rejouée.
  1038. * - Int $nbSucces : Nombre total de succès.
  1039. * - Array $error : Le details des erreurs (statusComplement de chaque transaction échouée).
  1040. * \exception:
  1041. * - Error : \link refundHandling(& $transaction) \endlink.
  1042. * - Impossible de trouver la transaction d'origine.
  1043. * \note
  1044. * - Séléctionne des transaction à rejouer.
  1045. * - Pour chaque transaction :
  1046. * - Formate le montant de la transaction en centimes.
  1047. * - Transforme les paramètres d'appels mémorisés en XML en tableau associatif.
  1048. * - Appel à la fonction refundReplay spécifique au module de la transaction.
  1049. * - Mémorise la réponse et les paramètres de la transaction.
  1050. * - Si la signature est vérifié, gestion de la notification boutique.
  1051. * \see
  1052. * - duplicateReplay(& $transaction);
  1053. */
  1054. public function duplicateAsyncHandling(){
  1055. $rs = selectQuery('select * from '.$this->xset->getTable().' where status = "'.self::WAITTING.'" and type = "'.self::DUPLICATE.'"');
  1056. $nbTotal = $rs->rowcount();
  1057. $nbSucces = 0;
  1058. $error = array();
  1059. while ($ors = $rs->fetch()) {
  1060. foreach ($ors as $key => $value){
  1061. $transaction->$key = $value;
  1062. }
  1063. // On transforme les paramètres d'appels mémorisés en XML en tableau associatif
  1064. $transaction->callParms = XSystem::xml2array($transaction->callParms);
  1065. // Appel à la fonction duplicateReplay spécifique au module de la transaction
  1066. $transaction = $this->duplicateReplay($transaction);
  1067. // On mémorise le retour
  1068. $this->xset->procEdit(array(
  1069. '_options'=>array('local'=>1),
  1070. 'oid'=>$transaction->KOID,
  1071. 'responseParms'=>$transaction->responseParms,
  1072. 'statusComplement'=> $transaction->statusComplement,
  1073. 'status'=>$transaction->status,
  1074. 'options'=>array('responseParms'=>array('raw'=>true,'toxml'=>true))
  1075. ));
  1076. if($transaction->status == self::SUCCESS){
  1077. $nbSucces++;
  1078. }
  1079. else{
  1080. $error[$ors['KOID']][$transaction->status] = $transaction->statusComplement;
  1081. }
  1082. // On vérifie s'il faut notifier la boutique
  1083. if ($ors->autoResponseMode === self::SYNC_RESPONSE){
  1084. $this->notifyShop($ors->oid);
  1085. }
  1086. elseif($ors->autoResponseMode === self::ASYNC_RESPONSE){
  1087. $this->xset->procEdit(array('_options'=>array('local'=>true), 'oid'=>$ors->oid, 'responseStatus'=>self::RESPONSE_STATUS_TO_SEND));
  1088. }
  1089. }
  1090. return array($nbTotal, $nbSucces, $error);
  1091. }
  1092. /* Fonctions de notifications boutique */
  1093. /**
  1094. * \brief Fonction de notification de la boutique.
  1095. * Cette fonction permet de notifier la boutique au sujet du paiement d'une commande.
  1096. * \param MTransaction $transaction : Transaction à partir de laquelle la boutique sera notifiée.
  1097. * Il faut au minimum :
  1098. * - $transaction->shopMoid ou $transaction->shopClass. \link MTransaction::$shopMoid \endlink \link MTransaction::$shopClass \endlink
  1099. * - $transaction->orderOid. \link MTransaction::$orderOid \endlink
  1100. * - $transaction->shopCallBack. \link MTransaction::$shopCallBack \endlink
  1101. * - $transaction->oid. \link MTransaction::$oid \endlink
  1102. * \note
  1103. * - Vérifie que la transaction est initialisée.
  1104. * - Si la transaction connait le moid de la boutique, cette fonction pourra la notifier.
  1105. */
  1106. protected function notifyShop($transaction){
  1107. // On vérifie que la transaction est initialisée
  1108. if ($transaction == null){
  1109. Xlogs::critical(get_class($this), '::notifyShop notif module : transaction null');
  1110. }
  1111. // Si la transaction connait le moid de la boutique elle pourra la notifier
  1112. if (!empty($transaction->shopMoid)){
  1113. Xlogs::notice(get_class($this), '::notifyShop notif module : '.$transaction->shopMoid.'function '.$transaction->shopCallBack.', order '.$transaction->orderOid);
  1114. $mod = XModule::objectFactory(array('moid'=>$transaction->shopMoid, 'interactive'=>0, 'tplentry'=>TZR_RETURN_DATA));
  1115. $f = $transaction->shopCallBack;
  1116. $mod->$f($transaction->orderOid, $transaction);
  1117. } elseif (!empty($transaction->shopClass)){
  1118. Xlogs::notice(get_class($this), '::notifyShop notif classe : '.$transaction->shopClass.'function '.$transaction->shopCallBack.', order '.$transaction->orderOid);
  1119. $c = new $transaction->shopClass();
  1120. $f = $transaction->shopCallBack;
  1121. $c->$f($transaction->orderOid, $transaction);
  1122. }
  1123. // Mise à jour du status de reponse à la boutique
  1124. $this->xset->procEdit(array('_options'=>array('local'=>true), 'oid'=>$transaction->oid, 'responseStatus'=>self::RESPONSE_STATUS_SENT));
  1125. }
  1126. /**
  1127. * \brief Fonction de notification en asynchone des retours de paiement.
  1128. * Cette fonction permet de notifier la boutique de manière asynchrone au sujet du paiement d'une commande.
  1129. * \note
  1130. * - Séléctionne toute les transaction ayant un status différent de ( \link XModMonetique::ERROR \endlink ou \link XModMonetique::INVALID \endlink) et un autoResponseMode = \link XModMonetique::ASYNC_RESPONSE \endlink et un responseStatus = \link XModMonetique::RESPONSE_STATUS_TO_SEND \endlink .
  1131. * - Pour chaque transaction :
  1132. * - Appel à \link notifyShop($transaction) \endlink
  1133. */
  1134. public function notifyShopAsync(){
  1135. $rs = selectQuery('select KOID from '.$this->xset->getTable().' where (status != "'.self::ERROR.'" or status != "'.self::INVALID.'" ) and autoResponseMode="'.self::ASYNC_RESPONSE.'" and responseStatus="'.self::RESPONSE_STATUS_TO_SEND.'"');
  1136. while($ors = $rs->fetch()){
  1137. $transaction = $this->getTransaction($ors['KOID']);
  1138. $transaction->oid = $ors['KOID'];
  1139. $this->notifyShop($transaction);
  1140. }
  1141. }
  1142. /* Fonctions utilitaires */
  1143. /**
  1144. * \brief Fonction de controle des paramètres attendus pour le paiement d'une commande.
  1145. * Cette fonction permet de controler :
  1146. * - $order->oid : L'oid de la commande correspondant à la transaction. \link MOrderInfos::oid \endlink
  1147. * - $order->amount : Le montant de la commande. \link MOrderInfos::amount \endlink
  1148. * - $shop->moid ou $shop->class : La boutique à l'origine de la commande. \link MShopInfos::moid \endlink \link MShopInfos::class \endlink
  1149. * - $order->reference : La référence de la commande. \link MOrderInfos::reference \endlink
  1150. * - $shop->autoResponseMode : Le mode de reponse doit être cohérent avec les paramètres attendus. \link MShopInfos::autoResponseMode \endlink
  1151. * \exception:
  1152. * - Si l'un de tous ces champs n'est pas correctement initialisé.
  1153. */
  1154. protected function checkPaymentData(MOrderInfos $order, MCustomerInfos $customer, MShopInfos $shop){
  1155. if (empty($order->oid)){
  1156. throw new Exception('order oid is not set',01);
  1157. }
  1158. if (empty($order->amount)){
  1159. throw new Exception('order amount is not set',02);
  1160. }
  1161. if (empty($shop->moid) && empty($shop->class)){
  1162. throw new Exception('must provide shopMoid or shop class',03);
  1163. }
  1164. if (empty($order->reference)){
  1165. throw new Exception('must provide order reference',04);
  1166. }
  1167. if (!in_array($shop->autoResponseMode, array(self::RESPONSE_NONE, self::ASYNC_RESPONSE, self::SYNC_RESPONSE))){
  1168. throw new Exception('must provide options auo response (none|async|live)',05);
  1169. }
  1170. }
  1171. /**
  1172. * \brief Fonction de chargement d'une transaction depuis la table grace à son KOID.
  1173. * Cette fonction permet de récupérer tous les paramètres d'une transaction depuis la table.
  1174. * \param String $transactionOid : L'identifiant d'une transaction. \link MTransaction::$oid \endlink
  1175. * \return MTransaction $transaction.
  1176. * \see
  1177. * MTransaction.
  1178. */
  1179. protected function getTransaction($transactionOid){
  1180. if ($ors == NULL){
  1181. $rs = selectQuery('select * from '.$this->xset->getTable().' where KOID="'.$transactionOid.'"');
  1182. }
  1183. if ($rs->rowcount() == 1){
  1184. $ors = $rs->fetch();
  1185. $transaction = new MTransaction();
  1186. foreach($ors as $k=>$v){
  1187. $transaction->{$k} = $v;
  1188. }
  1189. } else {
  1190. $transaction = null;
  1191. XLogs::critical(get_class($this), 'Impossible de trouver la transaction ayant pour KOID : '.$transactionOid);
  1192. }
  1193. return $transaction;
  1194. }
  1195. /**
  1196. * \brief Fonction de recherche du KOID d'une transaction depuis la table grâce à la référence commande.
  1197. * Cette fonction permet de récupérer le KOID d'une transaction depuis la table du module.
  1198. * \param String $orderReference : La référence d'une commande. \link MTransaction::$orderReference \endlink
  1199. * \return String $transactionOid : \link MTransaction::$oid \endlink
  1200. * \see
  1201. * MTransaction.
  1202. */
  1203. protected function getIdTransactionWithOrderRef($orderReference){
  1204. $rs = selectQuery('select KOID from '.$this->xset->getTable().' where `orderReference`="'.$orderReference.'"');
  1205. $transactionOid = null;
  1206. if($rs->rowCount()==1){
  1207. $transactionOid = $rs->fetch(PDO::FETCH_COLUMN);
  1208. }
  1209. else{
  1210. XLogs::critical(get_class($this), 'Transaction de la commande '.$orderReference.' non trouvé!');
  1211. }
  1212. return $transactionOid;
  1213. }
  1214. /**
  1215. * \brief Fonction de recherche du type de capture d'une transaction.
  1216. * Cette fonction permet de récupérer le captureMode d'une transaction depuis la table du module.
  1217. * \param MTransaction $transaction : La transaction pour laquelle on veut connaitre le captureMode. \link MTransaction::$captureMode \endlink
  1218. * \return String $captureMode.
  1219. * \see
  1220. * MTransaction.
  1221. */
  1222. protected function getCaptureMode($transaction){
  1223. $rs = selectQuery('select captureMode from '.$this->xset->getTable().' where `KOID`="'.$transaction->oid.'"');
  1224. $res = null;
  1225. if($rs->rowCount()==1){
  1226. $res = $rs->fetch(PDO::FETCH_COLUMN);
  1227. }
  1228. else{
  1229. XLogs::critical(get_class($this), 'Transaction ayant pour KOID '.$transaction->oid.' non trouvé!');
  1230. }
  1231. return $res;
  1232. }
  1233. /**
  1234. * \brief Fonction de recherche du nombre d'échéances d'une transaction.
  1235. * Cette fonction permet de récupérer le nombre d'échéances d'une transaction depuis la table du module.
  1236. * \param MTransaction $transaction : La transaction pour laquelle on veut connaitre le nombre d'échéances. \link MTransaction::$nbDeadLine \endlink
  1237. * \return Int $nbDeadLine.
  1238. * \see
  1239. * MTransaction.
  1240. */
  1241. protected function getNbDeadLine($transaction){
  1242. $rs = selectQuery('select nbDeadLine from '.$this->xset->getTable().' where `KOID`="'.$transaction->oid.'"');
  1243. $res = null;
  1244. if($rs->rowCount()==1){
  1245. $res = $rs->fetch(PDO::FETCH_COLUMN);
  1246. }
  1247. else{
  1248. XLogs::critical(get_class($this), 'Transaction ayant pour KOID '.$transaction->oid.' non trouvé!');
  1249. }
  1250. return $res;
  1251. }
  1252. /**
  1253. * \brief Fonction de chargement d'une transaction depuis la table grace à la référence commande.
  1254. * Cette fonction permet de récupérer tous les paramètres d'une transaction depuis la table.
  1255. * \param String $orderReference : La référence d'une commande. \link MTransaction::$orderReference \endlink
  1256. * \return MTransaction $transaction.
  1257. * \see
  1258. * MTransaction.
  1259. */
  1260. protected function getTransactionWithOrderRef($orderReference){
  1261. $rs = selectQuery('select * from '.$this->xset->getTable().' where `orderReference`="'.$orderReference.'"');
  1262. $transactionOid = null;
  1263. if($rs->rowCount()==1){
  1264. $transaction = $rs->fetch();
  1265. }
  1266. else{
  1267. XLogs::critical(get_class($this), 'Transaction de la commande '.$orderReference.' non trouvé!');
  1268. }
  1269. return $transaction;
  1270. }
  1271. /**
  1272. * \brief Fonction de recherche d'un enrollement dans la table ENROMONETIQUE.
  1273. * Cette fonction permet de récupérer tous les paramètres d'un enrollement.
  1274. * \param String $customerOid : L'identifiant d'un client. \link MCustomerInfos::$oid \endlink
  1275. * \param String $refAbonne : La référence abonné d'un client. \link MCustomerInfos::$refAbonne \endlink
  1276. * \return $customerEnrollement : Les paramètres nécéssaires au remboursement ou à la duplication d'une transaction.
  1277. */
  1278. protected function getEnrollement($customerOid,$refAbonne){
  1279. $rs = selectQuery('select * from ENROMONETIQUE where `customerOid`="'.$customerOid.'" and `refAbonne`="'.$refAbonne.'"' );
  1280. if($rs->rowCount()==1){
  1281. $ors = $rs->fetch();
  1282. foreach($ors as $k=>$v){
  1283. $customerEnrollement->{$k} = $v;
  1284. }
  1285. } else {
  1286. $customerEnrollement = null;
  1287. XLogs::critical(get_class($this), 'Impossible de trouver l\'enrollement ayant pour customerOid :'.$customerOid);
  1288. }
  1289. return $customerEnrollement;
  1290. }
  1291. public function genOrderRef($format, $vars = null){
  1292. $ressource = 'refCommande';
  1293. while(!getLock($ressource, 10)){
  1294. XLogs::notice(get_class($this), 'waiting for lock '.$ressource);
  1295. }
  1296. $key = 'xmodmonetique::hourlychrono';
  1297. $hour = date('H');
  1298. $date = date('Y-m-d');
  1299. $vchrono=XDbIni::get($key, 'val');
  1300. if($vchrono == NULL){
  1301. $init = true;
  1302. }
  1303. list($ldate, $lhour, $chrono) = explode(',', $vchrono);
  1304. if ($lhour != $hour || $ldate != $date){
  1305. $init = true;
  1306. }
  1307. if ($init){
  1308. $day = date('d');
  1309. $year = date('Y');
  1310. $month = date('m');
  1311. $ors = selectQueryGetAll('select ifnull(max(substring(orderReference, -4)), 0) as lchrono from TRANSACMONETIQUE where year(dateCreated)='.$year.' and month(dateCreated)='.$month.' and day(dateCreated)='.$day.' and hour(dateCreated)='.$hour);
  1312. if (!$ors || !is_array($ors)){
  1313. XLogs::critical(get_class($this), '::genOrderRef erreur lecture dernier chrono');
  1314. $chrono = 0;
  1315. } else {
  1316. $chrono = $ors[0]['lchrono'];
  1317. }
  1318. }
  1319. $chrono += 1;
  1320. XDBIni::set($key, $date.','.$hour.','.$chrono);
  1321. $refbase = strftime($format, strtotime(date('Y-m-d H:i:s')));
  1322. if (!empty($vars)){
  1323. $refbase = str_replace($vars[0], $vars[1], $refbase);
  1324. }
  1325. releaseLock($ressource);
  1326. return $refbase.sprintf('%04d', $chrono);
  1327. }
  1328. /**
  1329. * \brief Fonction de génération d'un idantifiant de transaction unique pour la journée.
  1330. * Cette fonction utilise \b checkPidFiles() pour assurer un accès unique à la ressource.
  1331. * \return String $newTransId : l'identifiant une d'une transaction (6 charactères).
  1332. */
  1333. protected function genTransId(){
  1334. $ressource = TZR_VAR2_DIR.'/transId';
  1335. // Fonction limitant l'accès à une personne en même temps, et n'accordant qu'une tentative
  1336. $r = checkPidFiles($ressource, 1, 1) ;
  1337. // Si une commande est en cours de traitement, on génère un id maximal
  1338. if($r == 'unavailable'){
  1339. $newTransId = $this->getMaxDayTransId();
  1340. }
  1341. // Sinon on génère un id habituel
  1342. else{
  1343. $newTransId = date('His');
  1344. }
  1345. return $newTransId;
  1346. }
  1347. /**
  1348. * \brief Fonction qui retourne le nouvel identifiant de transaction la plus haut du jour courant pour une transaction en collision (2 commandes en même temps).
  1349. * Cette fonction recherche dans la table des transactions, l'identifiant de transaction le plus haut (avec une heure supérieur à 24), ce cas ce produit quand deux génération d'identifiant de transaction s'execute au même moment. La première aura comme identifiant le vrai jour et la seconde 24. Si ce cas se reproduit la même journée, la seconde sera incrémentee à partir de la plus haute, soit 24 et aura donc 25 comme value pour l'heure.
  1350. * \return String $newTransId : Le nouvel identifiant de transaction déjà incrémenté.
  1351. */
  1352. protected function getMaxDayTransId(){
  1353. // Récupère la date courante
  1354. $date = date('Ymd');
  1355. // Selectionne la transaction (ayant subis une collision) et ayant la référence la plus haute
  1356. $rs = selectQuery('select transId from '.$this->xset->getTable().' where `transId` >= "'.$date.'500000" order by orderReference desc limit 1')->fetch();
  1357. // Si ce n'est pas la première collision de la journée
  1358. if(!empty($rs)){
  1359. // On extrait la value remplaçant le jour par sa value incrémentée
  1360. $incremente = substr($rs['transId'], 8,2);
  1361. $incremente++;
  1362. // On retourne la nouvelle référence
  1363. return $newTransId = $incremente.date('is');
  1364. }
  1365. // Si c'est la première collision de la journée
  1366. else{
  1367. $newTransId = '24'.date('is');
  1368. }
  1369. return $newTransId;
  1370. }
  1371. /**
  1372. * \brief Fonction retourne un motant en euros passé en paramètre, en centimes.
  1373. * \param Float $amount : Un montant en euros.
  1374. * \return Int $amount*100 : Le montant en centimes.
  1375. */
  1376. protected function formatOrderAmount($amount){
  1377. return $amount*100;
  1378. }
  1379. /**
  1380. * \brief Fonction retourne un motant en euros passé en paramètre, en centimes.
  1381. * \param String $amount: Un montant en centimes.
  1382. * \param MTransaction $transaction: Une transaction dont $transaction->amount est en euros.
  1383. * \return Bool $test : Renvoi True si le montant est le même, False sinon.
  1384. */
  1385. protected function checkResponseAmount($amountResponse, $amountOri){
  1386. return ($amountResponse == $amountOri);
  1387. }
  1388. /**
  1389. * \brief Fonction retourne un motant en euros passé en paramètre, en centimes.
  1390. * \param String $amount: Un montant en centimes.
  1391. * \param MTransaction $transaction: Une transaction dont $transaction->amount est en euros.
  1392. * \return Bool $test : Renvoi True si le montant est le même, False sinon.
  1393. */
  1394. protected function checkNbDeadLine($nbDeadLineResponse, $nbDeadLineOri){
  1395. return ($nbDeadLineResponse == $nbDeadLineOri);
  1396. }
  1397. /*
  1398. * codification des langues pour l'interface de banque
  1399. * par defaut = celle reçue en option
  1400. *
  1401. * \brief Fonction retourne un motant en euros passé en paramètre, en centimes.
  1402. * \param String $amount: Un montant en centimes.
  1403. * \param MTransaction $transaction: Une transaction dont $transaction->amount est en euros.
  1404. * \return Bool $test : Renvoi True si le montant est le même, False sinon.
  1405. *
  1406. protected function getLanguageCode($lang){
  1407. if (empty($lang)){
  1408. $lang = $this->defaultLang;
  1409. }
  1410. return $lang;
  1411. }*/
  1412. /**
  1413. * \brief Fonction qui permet de choisir le fomat d'une référence.
  1414. * \param String $format : Le format de la référence désiré. Ex :'%Y%m%d%H%i%s%$myVar'
  1415. * \return Array:
  1416. * - String $formatDate : La manière dont on souhaite représenter la date.
  1417. * - String $refSpe : Le key de la variable à concatener à la référence.
  1418. * - Bool $refAfterDate : Renvoi true si la variable que l'on souhaite concatener, se place après la date.
  1419. */
  1420. protected function formatOrderRef($format){
  1421. // Sépare les paramètres grâce au caractère d'échapement '%'
  1422. $params = explode('%', $format);
  1423. $formatDate = $refSpe = null;
  1424. $i = 0;
  1425. // Pour tous les paramètres
  1426. foreach($params as $val){
  1427. // S'il font partis de la date ou d'un caractère d'échappement
  1428. if (($val == 'Y') || ($val == 'y') || ($val == 'm') || ($val == 'd')
  1429. || ($val == 'D') || ($val == 'H') || ($val == 'h')
  1430. || ($val == 'i') || ($val == 's') || ($val == ':') || ($val == ' ') || ($val == '-') ) {
  1431. $i++;
  1432. // On concatène le nouveau paramètre au format requis pour la date
  1433. $formatDate = $formatDate.$val;
  1434. }else{
  1435. // si c'est une variable
  1436. if($val[0] == '$'){
  1437. $refSpe = $val;
  1438. // Mémorise si la date va avant ou apres la variable personalisée
  1439. if($i > 0){
  1440. $refAfterDate = true;
  1441. }else{
  1442. $refAfterDate = false;
  1443. }
  1444. }
  1445. }
  1446. }
  1447. return array($formatDate,$refSpe, $refAfterDate);
  1448. }
  1449. public function secGroups($function, $group=NULL) {
  1450. $g=array();
  1451. $g['autoresponse'] = array('none');
  1452. if(isset($g[$function])) {
  1453. return $g[$function];
  1454. }
  1455. if(isset($g[$function])) {
  1456. if(!empty($group)){
  1457. return in_array($group, $g[$function]);
  1458. }
  1459. return $g[$function];
  1460. }
  1461. return parent::secGroups($function,$group);
  1462. }
  1463. /**
  1464. * \brief Fonction qui retourne le libellé d'une erreur à partir de son code.
  1465. * \param Int $errorCode : Le code erreur retourné par la banque pour une transaction.
  1466. * \return String $errorLabel : Le libellé de l'erreur ou 'Code erreur non documenté'
  1467. */
  1468. protected function getErrorCode ($errorCode) {
  1469. $errorTab= array( '00' => 'Paiement autorisé.',
  1470. '02' => 'Contacter l’émetteur de carte.',
  1471. '03' => 'Accepteur invalide.',
  1472. '04' => 'Conserver la carte.',
  1473. '05' => 'Ne pas honorer.',
  1474. '07' => 'Conserver la carte, conditions spéciales.',
  1475. '08' => 'Approuver après identification.',
  1476. '12' => 'Transaction invalide.',
  1477. '13' => 'Montant invalide.',
  1478. '14' => 'Numéro de porteur invalide.',
  1479. '17' => 'Annulation du client.',
  1480. '24' => 'Opération impossible. L\'opération que vous souhaitez réaliser n\'est pas compatible avec l\'état de la transaction.',
  1481. '30' => 'Error de format.',
  1482. '31' => 'Identifiant de l\'organisme acquéreur inconnu.',
  1483. '33' => 'Date de validité de la carte dépassée.',
  1484. '34' => 'Suspicion de fraude.',
  1485. '41' => 'Carte perdue.',
  1486. '43' => 'Carte volée.',
  1487. '51' => 'Provision insuffisante ou crédit dépassé.',
  1488. '54' => 'Date de validité de la carte dépassée.',
  1489. '56' => 'Carte absente du fichier.',
  1490. '57' => 'Transaction non permise à ce porteur.',
  1491. '58' => 'Transaction interdite au terminal.',
  1492. '59' => 'Suspicion de fraude.',
  1493. '60' => 'L\'accepteur de carte doit contacter l’acquéreur.',
  1494. '61' => 'Montant de retrait hors limite.',
  1495. '63' => 'Règles de sécurité non respectées.',
  1496. '68' => 'Réponse non parvenue ou reçue trop tard.',
  1497. '75' => 'Nombre de tentatives de saisie du numéro de carte dépassé.',
  1498. '90' => 'Arret momentané du système.',
  1499. '91' => 'Emetteur de cartes inaccessible.',
  1500. '94' => 'Transaction dupliquée.',
  1501. '96' => 'Mauvais fonctionnement du système.',
  1502. '97' => 'Echéance de la temporisation de surveillance globale.',
  1503. '98' => 'Serveur indisponible routage réseau demandé à nouveau.',
  1504. '99' => 'Incident domaine initiateur.');
  1505. // Si le code erreur existe dans le tableau
  1506. if(array_key_exists($errorCode,$errorTab)){
  1507. $errorLabel = $errorTab[$errorCode];
  1508. return $errorLabel;
  1509. }
  1510. // Si le ccode erreur n'est pas répertorié.
  1511. else{
  1512. return 'Code erreur non documenté';
  1513. }
  1514. }
  1515. /**
  1516. * Translate a result array into a HTML table
  1517. *
  1518. * @author Aidan Lister <aidan@php.net>
  1519. * @version 1.3.2
  1520. * @link http://aidanlister.com/repos/v/function.array2table.php
  1521. * @param array $array The result (numericaly keyed, associative inner) array.
  1522. * @param bool $recursive Recursively generate tables for multi-dimensional arrays
  1523. * @param string $null String to output for blank cells
  1524. */
  1525. function array2html($array, $recursive = false, $null = '&nbsp;') {
  1526. // Sanity check
  1527. if (empty($array) || !is_array($array)) {
  1528. return false;
  1529. }
  1530. if (!isset($array[0]) || !is_array($array[0])) {
  1531. $array = array($array);
  1532. }
  1533. // Start the table
  1534. $table = "<table>\n";
  1535. // The header
  1536. $table .= "\t<tr>";
  1537. // Take the keys from the first row as the headings
  1538. foreach (array_keys($array[0]) as $heading) {
  1539. $table .= '<th>' . $heading . '</th>';
  1540. }
  1541. $table .= "</tr>\n";
  1542. // The body
  1543. foreach ($array as $row) {
  1544. $table .= "\t<tr>" ;
  1545. foreach ($row as $cell) {
  1546. $table .= '<td>';
  1547. // Cast objects
  1548. if (is_object($cell)) {
  1549. $cell = (array) $cell;
  1550. }
  1551. if ($recursive === true && is_array($cell) && !empty($cell)) {
  1552. // Recursive mode
  1553. $table .= "\n" . array2table($cell, true, true) . "\n";
  1554. } else {
  1555. $table .= (strlen($cell) > 0) ?
  1556. htmlspecialchars((string) $cell) :
  1557. $null;
  1558. }
  1559. $table .= '</td>';
  1560. }
  1561. $table .= "</tr>\n";
  1562. }
  1563. $table .= '</table>';
  1564. return $table;
  1565. }
  1566. /**
  1567. * \brief Fonction d'initialisation des options communes à tout les sytèmes de paiement (permet d'ajouter dans champs dans les proprètés du module).
  1568. * Permet d'initialiser les options communes aux trois modules (Paybox, SystemPay et Atos).
  1569. * \note
  1570. * Crée les champs:
  1571. * - siteId \link XModMonetique::$siteId \endlink
  1572. * - urlPayed \link XModMonetique::$urlPayed \endlink
  1573. * - urlCancelled \link XModMonetique::$urlCancelled \endlink
  1574. * - urlAutoResponse \link XModMonetique::$urlAutoResponse \endlink
  1575. */
  1576. public function initOptions() {
  1577. parent::initOptions();
  1578. $alabel = XLabels::getSysLabel('xmodmonetique.modulename');
  1579. $this->_options->setOpt(XLabels::getSysLabel('xmodmonetique','siteid'), 'siteId','text',NULL,NULL,$alabel);
  1580. $this->_options->setOpt(XLabels::getSysLabel('xmodmonetique','urlPayed'), 'urlPayed','text',NULL,NULL,$alabel);
  1581. $this->_options->setOpt(XLabels::getSysLabel('xmodmonetique','urlCancelled'), 'urlCancelled','text',NULL,NULL,$alabel);
  1582. $this->_options->setOpt(XLabels::getSysLabel('xmodmonetique','urlAutoResponse'),'urlAutoResponse','text',NULL,NULL,$alabel);
  1583. }
  1584. /**
  1585. * \brief Méthode de vérification de la présence du fichier de retour automatique.
  1586. * Permet d'afficher une erreur dans les propriètés du module si le fichier de retour automatique n'est pas présent.
  1587. */
  1588. public function editProperties($ar) {
  1589. parent::editProperties($ar);
  1590. if (!preg_match('@^(?:https?://)?[^/]+/([^?]*)(\?[^?]*)?$@', $this->urlAutoResponse, $matches))
  1591. setSessionVar('message', 'Url de retour automatique incorrecte : '.$this->urlAutoResponse);
  1592. // Si le fichier n'exite pas, affiche l'erreur
  1593. elseif(!file_exists(TZR_WWW_DIR.$matches[1]) ){
  1594. setSessionVar('message', 'Fichier de retour automatique non présent à l\'adresse : '.TZR_WWW_DIR.$matches[1]);
  1595. }
  1596. }
  1597. /**
  1598. * \brief Fonction abstraite de preparation des paramètres d'appel en banque spécifique à chaques module.
  1599. * \param MOrderInfos $order : La commande à l'origine de la transaction.
  1600. * \param MCustomerInfos $customer : Le client à l'origine de la commande.
  1601. * \param MShopInfos $shop : La boutique demandant la création de la transaction.
  1602. * \param MTransaction $transaction : La transaction en cours de préparation.
  1603. * @return Array :
  1604. * - MTransaction $transaction : La transaction avec ses paramètres.
  1605. * - Array $payboxForm : Le formulaire à soumettre à la banque.
  1606. * - String $template : Le template à utilisé pour afficher le formulaire avant l'envoi en banque.
  1607. * - String $tplEntry : L'entrée smarty du template.
  1608. * \see
  1609. * - XModPaybox::webPaymentHandling(MOrderInfos $order, MCustomerInfos $customer, MShopInfos $shop, $transaction);
  1610. * - XModSystemPay::webPaymentHandling(MOrderInfos $order, MCustomerInfos $customer, MShopInfos $shop, $transaction);
  1611. * - XModAtos::webPaymentHandling(MOrderInfos $order, MCustomerInfos $customer, MShopInfos $shop, $transaction);
  1612. */
  1613. abstract protected function webPaymentHandling(MTransaction $transaction);
  1614. /**
  1615. * \brief Fonction abstraite de traitement automatique d'un retour banque spécifique à chaques module.
  1616. * @return
  1617. * MTransaction $transaction : La transaction avec ses paramètres concernée par le retour.
  1618. * \see
  1619. * - XModPaybox::webPaymentUnFoldReponse();
  1620. * - XModSystemPay::webPaymentUnFoldReponse();
  1621. * - XModAtos::webPaymentUnFoldReponse();
  1622. */
  1623. abstract protected function webPaymentUnFoldReponse();
  1624. /**
  1625. * \brief Fonction abstraite de création d'un remboursement.
  1626. * Cette fonction permet à chaque module héritant de cette classe, de créer un remboursement avec les paramètres attendus par la banque.
  1627. * \param MTransaction &$newTransaction : Transaction relative au remboursement.
  1628. * \return MTransaction $newTransaction : La transaction passé en paramètre, contenant les paramètres d'appel et la réponse.
  1629. * \see
  1630. * - XModPaybox::refundHandling(& $transaction);
  1631. * - XModAtos::refundHandling(& $transaction);
  1632. * - XModSystemPay::refundHandling(& $transaction);
  1633. */
  1634. abstract protected function refundHandling($newTransaction);
  1635. /**
  1636. * \brief Fonction abstraite de réémission d'un remboursement.
  1637. * Cette fonction permet à chaque module héritant de cette classe, de rejouer un remboursement avec les même paramètres.
  1638. * \param MTransaction &$newTransaction : Transaction relative au remboursement.
  1639. * \return MTransaction $newTransaction : La transaction contenant les paramètres d'appel et la réponse.
  1640. * \see
  1641. * - XModPaybox::refundReplay(& $transaction);
  1642. * - XModAtos::refundReplay(& $transaction);
  1643. * - XModSystemPay::refundReplay(& $transaction);
  1644. */
  1645. abstract protected function refundReplay($newTransaction);
  1646. /**
  1647. * \brief Fonction abstraite de création d'une duplication.
  1648. * Cette fonction permet à chaque module héritant de cette classe, de créer une duplication avec les paramètres attendus par la banque.
  1649. * \param MTransaction &$newTransaction : Transaction relative à la duplication.
  1650. * \return MTransaction $newTransaction : La transaction passé en paramètre mis à jour.
  1651. * \see
  1652. * - XModPaybox::duplicateHandling(& $transaction);
  1653. * - XModAtos::duplicateHandling(& $transaction);
  1654. * - XModSystemPay::duplicateHandling(& $transaction);
  1655. */
  1656. abstract protected function duplicateHandling($newTransaction);
  1657. /**
  1658. * \brief Fonction abstraite de réémission d'une duplication.
  1659. * Cette fonction permet à chaque module héritant de cette classe, de rejouer une duplication avec les même paramètres.
  1660. * \param MTransaction &$newTransaction : Transaction relative à la duplication.
  1661. * \return MTransaction $newTransaction : La transaction passé en paramètre mis à jour.
  1662. * \see
  1663. * - XModPaybox::duplicateReplay(& $transaction);
  1664. * - XModAtos::duplicateReplay(& $transaction);
  1665. * - XModSystemPay::duplicateReplay(& $transaction);
  1666. */
  1667. abstract protected function duplicateReplay($newTransaction);
  1668. }
  1669. class Mutex
  1670. {
  1671. private $lock_ = null;
  1672. // create a mutex with with a given id. This ID must be system unique.
  1673. // [string] id - a unique id
  1674. // return - true on success
  1675. public function Initialize($id)
  1676. {
  1677. $this->lock_ = fopen($id, 'a');
  1678. return is_resource($this->lock_);
  1679. }
  1680. // destroy the mutex
  1681. public function Destroy()
  1682. {
  1683. $result = false;
  1684. if (is_resource($this->lock_));
  1685. {
  1686. $result = flock($this->lock_, LOCK_UN);
  1687. $result &= fclose($this->lock_);
  1688. $this->lock_ = null;
  1689. }
  1690. return $result;
  1691. }
  1692. // exclusively lock the resource
  1693. // return - true on success
  1694. public function Lock()
  1695. {
  1696. if (is_resource($this->lock_)){
  1697. XLogs::notice(get_class($this), 'waiting for lock on boucle '.$this->lock_);
  1698. return flock($this->lock_, LOCK_EX);
  1699. }
  1700. return false;
  1701. }
  1702. // release the locked resource
  1703. // return - true on success
  1704. public function Release()
  1705. {
  1706. if (is_resource($this->lock_))
  1707. return flock($this->lock_, LOCK_UN);
  1708. return false;
  1709. }
  1710. }
  1711. /******************* NOTIFICATION BOUTIQUE REFUND: **************************
  1712. *
  1713. * // Si la transaction correspond à un remboursement
  1714. * if( ($transaction->type == XModMonetique::REFUND) ){
  1715. * // Si la transaction retourne une erreur
  1716. * if ($transaction->status == XModMonetique::ERROR){
  1717. * $transaction->etat = XModMonetique::REFUNDERROR;
  1718. * $transaction->newAmount = $order->CURRENTAMOUNT;
  1719. * XLogs::critical(get_class($this).'::monetiqueRetourAutoBanque', "Error de montant de remboursement.");
  1720. * XLogs::critical(get_class($this).'::monetiqueRetourAutoBanque', print_r($order, true));
  1721. * XLogs::critical(get_class($this).'::monetiqueRetourAutoBanque', print_r($transaction, true));
  1722. * }
  1723. * // Si il n'y a pas eu d'erreur sur la transaction
  1724. * else{
  1725. * // On récupère la commande
  1726. * $order = $this->getOrder($orderoid);
  1727. * // On calcule le nouveau montant
  1728. * $transaction->newAmount = sprintf("%.2f",$order->CURRENTAMOUNT - sprintf("%.2f",$transaction->amount/100));
  1729. * // Si c'est un remboursement partiel
  1730. * if($transaction->newAmount > 0){
  1731. * // Si la transaction est en attente de traitement
  1732. * if($transaction->status == XModMonetique::WAITTING){
  1733. * $transaction->etat = XModMonetique::PARTIALREFUNDWAITTING;
  1734. * }
  1735. * // Si la transaction s'est déroulé intégralement
  1736. * else if($transaction->status == XModMonetique::SUCCESS){
  1737. * $transaction->etat = XModMonetique::PARTIALREFUND; ///< On affecte l'etat de la transaction par rapport à la commande
  1738. * }
  1739. * }
  1740. * // Si c'est un remboursement integral
  1741. * else if($transaction->newAmount == 0){
  1742. * // Si la transaction est en attente de traitement
  1743. * if($transaction->status == XModMonetique::WAITTING){
  1744. * $transaction->etat = XModMonetique::REFUNDCOMPLETEWAITTING;
  1745. * }
  1746. * // Si la transaction s'est déroulé intégralement
  1747. * else if($transaction->status == XModMonetique::SUCCESS){
  1748. * $transaction->etat = XModMonetique::REFUNDCOMPLETE; ///< On affecte l'etat de la transaction par rapport à la commande
  1749. * }
  1750. * }
  1751. * // Si on à rembourser plus que le montant initial (Ou qu'un tel remboursement est en attente
  1752. * else{
  1753. * // Si la transaction est en attente de traitement
  1754. * if($transaction->status == XModMonetique::WAITTING){
  1755. * $transaction->etat = XModMonetique::REFUNDERRORWAIT; ///< On affecte l'etat de la transaction par rapport à la commande
  1756. * }
  1757. * // Si la transaction s'est déroulé intégralement
  1758. * else if($transaction->status == XModMonetique::SUCCESS){
  1759. * $transaction->etat = XModMonetique::REFUNDERROR; ///< On affecte l'etat de la transaction par rapport à la commande
  1760. * }
  1761. * // On log l'erreur
  1762. * XLogs::critical(get_class($this).'::monetiqueRetourAutoBanque', "Error de montant de remboursement, à vérifier d'urgence.");
  1763. * XLogs::critical(get_class($this).'::monetiqueRetourAutoBanque', print_r($order, true));
  1764. * XLogs::critical(get_class($this).'::monetiqueRetourAutoBanque', print_r($transaction, true));
  1765. * }
  1766. * // Dans tous les cas on mémorise le retour
  1767. * $this->dsorder->procEdit(array('_options'=>array('local'=>true),
  1768. * 'oid'=>$orderoid,
  1769. * 'ETATFABRICATION'=>$transaction->etat,
  1770. * 'CURRENTAMOUNT'=>$transaction->newAmount
  1771. * ));
  1772. * }
  1773. * }
  1774. ************************************************************************************************/
  1775. ?>