PageRenderTime 45ms CodeModel.GetById 14ms 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

Large files files are truncated, but you can click here to view the full file

  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. $newTransa

Large files files are truncated, but you can click here to view the full file