diff --git a/.version b/.version
new file mode 100644
index 0000000..238d6e8
--- /dev/null
+++ b/.version
@@ -0,0 +1 @@
+1.0.7
diff --git a/LICENSE-2.0.txt b/LICENSE-2.0.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/LICENSE-2.0.txt
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/modules/payxpert/config.xml b/modules/payxpert/config.xml
new file mode 100644
index 0000000..f11969b
--- /dev/null
+++ b/modules/payxpert/config.xml
@@ -0,0 +1,13 @@
+
+
+ payxpert
+
+
+
+
+
+
+ 1
+ 1
+
+
\ No newline at end of file
diff --git a/modules/payxpert/controllers/front/index.php b/modules/payxpert/controllers/front/index.php
new file mode 100644
index 0000000..54b3024
--- /dev/null
+++ b/modules/payxpert/controllers/front/index.php
@@ -0,0 +1,36 @@
+
+* @copyright 2007-2013 PrestaShop SA
+
+* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
+* International Registered Trademark & Property of PrestaShop SA
+*/
+
+header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
+header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
+
+header('Cache-Control: no-store, no-cache, must-revalidate');
+header('Cache-Control: post-check=0, pre-check=0', false);
+header('Pragma: no-cache');
+
+header('Location: ../../../../');
+exit;
\ No newline at end of file
diff --git a/modules/payxpert/controllers/front/payment.php b/modules/payxpert/controllers/front/payment.php
new file mode 100644
index 0000000..e2ab92e
--- /dev/null
+++ b/modules/payxpert/controllers/front/payment.php
@@ -0,0 +1,101 @@
+context->cart;
+
+ // Default value for Prestashop < 1.7
+ $template = 'payment_execution.tpl';
+
+ $params = array();
+
+ // These should be filled only with Prestashop >= 1.7
+ $paymentType = Tools::getValue('payment_type', null);
+ $paymentProvider = Tools::getValue('payment_provider', null);
+
+ if (version_compare(_PS_VERSION_, '1.7', '>=')) {
+ if ($paymentType !== null && PayXpert\Connect2Pay\C2PValidate::isPayment($paymentType)) {
+ $params['payment_type'] = $paymentType;
+
+ if ($paymentProvider !== null && PayXpert\Connect2Pay\C2PValidate::isProvider($paymentProvider)) {
+ $params['payment_provider'] = $paymentProvider;
+ }
+
+ switch ($paymentType) {
+ case PayXpert\Connect2Pay\Connect2PayClient::_PAYMENT_TYPE_BANKTRANSFER:
+ $template = 'module:' . $this->module->name . '/views/templates/front/payment_execution_bank_transfer.tpl';
+
+ if (isset($params['payment_provider'])) {
+ switch ($params['payment_provider']) {
+ case PayXpert\Connect2Pay\Connect2PayClient::_PAYMENT_PROVIDER_SOFORT:
+ $paymentLogo = 'sofort';
+ break;
+ case PayXpert\Connect2Pay\Connect2PayClient::_PAYMENT_PROVIDER_PRZELEWY24:
+ $paymentLogo = 'przelewy24';
+ break;
+ case PayXpert\Connect2Pay\Connect2PayClient::_PAYMENT_PROVIDER_IDEALKP:
+ $paymentLogo = 'ideal';
+ break;
+ }
+ }
+ break;
+ default:
+ // Default is Credit Card
+ $template = 'module:' . $this->module->name . '/views/templates/front/payment_execution_credit_card.tpl';
+ $paymentLogo = 'creditcard';
+ break;
+ }
+
+ $this->context->smarty->assign("payment_logo", $paymentLogo);
+ }
+ }
+
+ $this->context->smarty->assign(
+ array(/* */
+ 'nbProducts' => $cart->nbProducts(), /* */
+ 'cust_currency' => intval($cart->id_currency), /* */
+ 'total' => $cart->getOrderTotal(true, Cart::BOTH), /* */
+ 'isoCode' => $this->context->language->iso_code, /* */
+ 'this_path' => $this->module->getPathUri(), /* */
+ 'this_link' => $this->module->getModuleLinkCompat('payxpert', 'redirect', $params), /* */
+ 'this_link_back' => $this->module->getPageLinkCompat('order', true, NULL, "step=3") /* */
+ ) /* */
+ );
+
+ $this->setTemplate($template);
+ }
+}
\ No newline at end of file
diff --git a/modules/payxpert/controllers/front/redirect.php b/modules/payxpert/controllers/front/redirect.php
new file mode 100644
index 0000000..acf0e7f
--- /dev/null
+++ b/modules/payxpert/controllers/front/redirect.php
@@ -0,0 +1,67 @@
+context->cart)) {
+ $this->context->cart = new Cart();
+ }
+
+ $cart = $this->context->cart;
+
+ // These should be filled only with Prestashop >= 1.7
+ $paymentType = Tools::getValue('payment_type', null);
+ $paymentProvider = Tools::getValue('payment_provider', null);
+
+ $errorMessage = $this->module->redirect($cart, $paymentType, $paymentProvider);
+
+ $this->display_column_left = false;
+ parent::initContent();
+
+ $this->context->smarty->assign(
+ array(/* */
+ 'errorMessage' => $errorMessage, /* */
+ 'this_path' => $this->module->getPathUri(), /* */
+ 'this_path_ssl' => Configuration::get('PS_SSL_ENABLED') ? 'https' : 'http' . '://' . $_SERVER['HTTP_HOST'] . __PS_BASE_URI__ .
+ 'modules/payxpert/', /* */
+ 'this_link_back' => $this->module->getPageLinkCompat('order', true, NULL, "step=3") /* */
+ ) /* */
+ );
+
+ if (version_compare(_PS_VERSION_, '1.7', '>=')) {
+ $this->setTemplate('module:' . $this->module->name . '/views/templates/front/payment_error17.tpl');
+ } else {
+ $this->setTemplate('payment_error.tpl');
+ }
+ }
+}
diff --git a/modules/payxpert/controllers/front/validation.php b/modules/payxpert/controllers/front/validation.php
new file mode 100644
index 0000000..956f67c
--- /dev/null
+++ b/modules/payxpert/controllers/front/validation.php
@@ -0,0 +1,131 @@
+display_header = false;
+ $this->display_footer = false;
+ }
+
+ /**
+ *
+ * @see FrontController::initContent()
+ */
+ public function initContent() {
+ // $cart = $this->context->cart;
+ require_once dirname(__FILE__) . '/../../lib/Connect2PayClient.php';
+
+ // init api
+ $c2pClient = new PayXpert\Connect2Pay\Connect2PayClient($this->module->getPayXpertUrl(), Configuration::get('PAYXPERT_ORIGINATOR'),
+ html_entity_decode(Configuration::get('PAYXPERT_PASSWORD')));
+
+ if ($c2pClient->handleCallbackStatus()) {
+ $responseStatus = "KO";
+ $responseMessage = "Callback validation failed";
+
+ $status = $c2pClient->getStatus();
+
+ // get the Error code
+ $errorCode = $status->getErrorCode();
+ $errorMessage = $status->getErrorMessage();
+
+ $transaction = $status->getLastTransactionAttempt();
+
+ if ($transaction !== null) {
+ $transactionId = $transaction->getTransactionID();
+
+ $orderId = $status->getOrderID();
+ $amount = number_format($transaction->getAmount() / 100, 2, '.', '');
+ $callbackData = $status->getCtrlCustomData();
+
+ $severity = 1;
+
+ $message = "PayXpert payment module: ";
+ $message .= "Received a new transaction status callback from " . $_SERVER["REMOTE_ADDR"] . ". ";
+ $message .= "Error code: " . $errorCode . " ";
+ $message .= "Error message: " . $errorMessage . " ";
+ $message .= "Transaction ID: " . $transactionId . " ";
+ $message .= "Order ID: " . $orderId . " ";
+
+ $customer = null;
+ if (version_compare(_PS_VERSION_, '1.5', '>=')) {
+ Context::getContext()->cart = new Cart((int) $orderId);
+ $customer = new Customer((int) (Context::getContext()->cart->id_customer));
+ }
+
+ // For Prestashop >= 1.7, multi payment types is possible
+ switch ($transaction->getPaymentType()) {
+ case PayXpert\Connect2Pay\Connect2PayClient::_PAYMENT_TYPE_BANKTRANSFER:
+ $paymentMean = $this->module->l('Bank Transfer');
+ break;
+ default:
+ $paymentMean = $this->module->l('Credit Card');
+ break;
+ }
+ $paymentMean .= ' (PayXpert)';
+
+ if (!$customer) {
+ $message .= "Customer not found for order " . $orderId;
+ error_log($message);
+ $severity = 3;
+ } else {
+ if (!PayXpert::checkCallbackAuthenticityData($callbackData, Context::getContext()->cart->id, $customer->secure_key)) {
+ $message .= "Invalid callback received for order " . $orderId . ". Validation failed.";
+ error_log($message);
+ $severity = 3;
+ } else {
+ switch ($errorCode) {
+ case "000":
+ // Payment OK
+ $this->module->validateOrder((int) $orderId, Configuration::get('PS_OS_PAYMENT'), $amount, $paymentMean, $errorMessage,
+ array(), NULL, false);
+ break;
+ default:
+ $this->module->validateOrder((int) $orderId, Configuration::get('PS_OS_ERROR'), $amount, $paymentMean, $errorMessage,
+ array(), NULL, false);
+ $severity = 2;
+ break;
+ }
+ $responseStatus = "OK";
+ $responseMessage = "Payment status recorded";
+ }
+ }
+ }
+
+ $this->module->addLog($message, $severity, $errorCode);
+
+ // Send a response to mark this transaction as notified
+ $response = array("status" => $responseStatus, "message" => $responseMessage);
+ header("Content-type: application/json");
+ echo json_encode($response);
+ exit();
+ } else {
+ $this->module->addLog("PayXpert payment module:\n Callback received an incorrect status from " . $_SERVER["REMOTE_ADDR"], 2);
+ }
+ }
+}
diff --git a/modules/payxpert/controllers/index.php b/modules/payxpert/controllers/index.php
new file mode 100644
index 0000000..3f4b16e
--- /dev/null
+++ b/modules/payxpert/controllers/index.php
@@ -0,0 +1,35 @@
+
+* @copyright 2007-2013 PrestaShop SA
+* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
+* International Registered Trademark & Property of PrestaShop SA
+*/
+
+header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
+header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
+
+header('Cache-Control: no-store, no-cache, must-revalidate');
+header('Cache-Control: post-check=0, pre-check=0', false);
+header('Pragma: no-cache');
+
+header('Location: ../../../../');
+exit;
\ No newline at end of file
diff --git a/modules/payxpert/css/index.php b/modules/payxpert/css/index.php
new file mode 100644
index 0000000..a230e5a
--- /dev/null
+++ b/modules/payxpert/css/index.php
@@ -0,0 +1,35 @@
+
+* @copyright 2007-2013 PrestaShop SA
+* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
+* International Registered Trademark & Property of PrestaShop SA
+*/
+
+header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
+header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
+
+header("Cache-Control: no-store, no-cache, must-revalidate");
+header("Cache-Control: post-check=0, pre-check=0", false);
+header("Pragma: no-cache");
+
+header("Location: ../");
+exit;
\ No newline at end of file
diff --git a/modules/payxpert/css/payxpert.css b/modules/payxpert/css/payxpert.css
new file mode 100644
index 0000000..aa3867e
--- /dev/null
+++ b/modules/payxpert/css/payxpert.css
@@ -0,0 +1,17 @@
+p.payment_module a.creditcard::after{
+ display: block;
+ content: "\f054";
+ position: absolute;
+ right: 15px;
+ margin-top: -11px;
+ top: 50%;
+ font-family: "FontAwesome";
+ font-size: 25px;
+ height: 22px;
+ width: 14px;
+ color: #777;
+}
+
+p.payment_module a.creditcard {
+ background: url(../images/payment-types/creditcard_icon.png) 15px 12px no-repeat #fbfbfb;
+}
\ No newline at end of file
diff --git a/modules/payxpert/en.php b/modules/payxpert/en.php
new file mode 100644
index 0000000..601358d
--- /dev/null
+++ b/modules/payxpert/en.php
@@ -0,0 +1,4 @@
+payxpert_cbe0a99684b145e77f3e14174ac212e3'] = 'Voulez-vous vraiment effacer ces données ?';
+$_MODULE['<{payxpert}prestashop>payxpert_a02758d758e8bec77a33d7f392eb3f8a'] = 'Aucune devise n\'a été configurée pour ce module.';
+$_MODULE['<{payxpert}prestashop>payxpert_a91fb0f9c94dc572c0db5aac09d4d443'] = 'Installation du module PayXpert : l\'installation a échoué';
+$_MODULE['<{payxpert}prestashop>payxpert_d79c0cec2cf84da7893298a7043bf275'] = 'Installation du module PayXpert : l\'installation des hooks a échoué';
+$_MODULE['<{payxpert}prestashop>payxpert_c6276fca84020c9022b21c27884ef91d'] = 'Installation du module PayXpert : la configuration a échoué';
+$_MODULE['<{payxpert}prestashop>payxpert_782a0d30f7df22256fc7c7d62aa83ebc'] = 'Installation du module PayXpert : l\'installation est réussie';
+$_MODULE['<{payxpert}prestashop>payxpert_e77bb171c7ae55bba8b2ed869fadfb19'] = 'Payer par carte bancaire';
+$_MODULE['<{payxpert}prestashop>payxpert_a282d97ef76eaba7b74335c441c6e9e4'] = 'Payer par virement bancaire via Sofort';
+$_MODULE['<{payxpert}prestashop>payxpert_3876948a17b228eb6664b7c1bf3fc169'] = 'Payer par virement bancaire via Przelewy24';
+$_MODULE['<{payxpert}prestashop>payxpert_5fd8f493f6299e6934e2342514fdbb14'] = 'Payer par virement bancaire via iDeal';
+$_MODULE['<{payxpert}prestashop>payxpert_abbbd19bce9246d4a53a252efe4a8ef8'] = 'Facture:';
+$_MODULE['<{payxpert}prestashop>payxpert_f4f70727dc34561dfde1a3c529b6205c'] = 'Paramètres';
+$_MODULE['<{payxpert}prestashop>payxpert_2ea3b0f6afbc5d22bca6c482c0bf54ca'] = 'Identifiant initiateur';
+$_MODULE['<{payxpert}prestashop>payxpert_1e0e47cb9fb5d70cfdee039faa4df351'] = 'L\'identifiant de votre initiateur';
+$_MODULE['<{payxpert}prestashop>payxpert_bd5d0eb5e80dabb222588e51b128a952'] = 'Mot de passe initiateur';
+$_MODULE['<{payxpert}prestashop>payxpert_b33897812550f490e39369ab16b494fe'] = 'Le mot de passe de votre initiateur (laissez vide pour conserver l\'actuel)';
+$_MODULE['<{payxpert}prestashop>payxpert_f234bf4aa382bcdf69c1f46dd045f280'] = 'Laissez vide pour conserver l\'actuel)';
+$_MODULE['<{payxpert}prestashop>payxpert_f70e151f4edf5e2dd4bb00a69a2e8aa7'] = 'Adresse de la page de paiement';
+$_MODULE['<{payxpert}prestashop>payxpert_2ac8cc53c7de4e6b529440632ab049d2'] = 'Laissez ce champ vide sauf si on vous a fourni une URL';
+$_MODULE['<{payxpert}prestashop>payxpert_6f974bbda9064a9c0836370dbf5a6076'] = 'Notifications marchand';
+$_MODULE['<{payxpert}prestashop>payxpert_b3151328e1f2e8eed187ecee1d0b078a'] = 'Envoyer ou non une notification par email au marchand pour chaque paiement';
+$_MODULE['<{payxpert}prestashop>payxpert_00d23a76e43b46dae9ec7aa9dcbebb32'] = 'Activées';
+$_MODULE['<{payxpert}prestashop>payxpert_b9f5c797ebbf55adccdd8539a65a0241'] = 'De';
+$_MODULE['<{payxpert}prestashop>payxpert_6ae25f49f9b8ff8dd9d77931f13cd7ce'] = 'Destinataire des notifications marchand';
+$_MODULE['<{payxpert}prestashop>payxpert_712cfbc42564d7b5b0f29cf3114f1b39'] = 'Adresse email du destinataire des notifications marchand';
+$_MODULE['<{payxpert}prestashop>payxpert_c200e98fc7b00b24a16affd294c5a856'] = 'Langue des notifications marchand';
+$_MODULE['<{payxpert}prestashop>payxpert_14f2d2487d30e069719bcbab2a9c9141'] = 'Langue à utiliser lors de l\'envoi des notifications marchand';
+$_MODULE['<{payxpert}prestashop>payxpert_78463a384a5aa4fad5fa73e2f506ecfc'] = 'Anglais';
+$_MODULE['<{payxpert}prestashop>payxpert_ad225f707802ba118c22987186dd38e8'] = 'Français';
+$_MODULE['<{payxpert}prestashop>payxpert_cb5480c32e71778852b08ae1e8712775'] = 'Espagnol';
+$_MODULE['<{payxpert}prestashop>payxpert_4be8e06d27bca7e1828f2fa9a49ca985'] = 'Italien';
+$_MODULE['<{payxpert}prestashop>payxpert_b17f3f4dcf653a5776792498a9b44d6a'] = 'Modifier la configuration';
+$_MODULE['<{payxpert}prestashop>payxpert_73a61696f100b3858511e212a3feea6b'] = 'Carte bancaire';
+$_MODULE['<{payxpert}prestashop>payxpert_104497b6ea18dff7f445ef5497d8a89a'] = 'Activer le moyen de paiement : carte bancaire';
+$_MODULE['<{payxpert}prestashop>payxpert_e66aa0693ced02e8d97af3c83d364757'] = 'Virement bancaire via Sofort';
+$_MODULE['<{payxpert}prestashop>payxpert_17613c57686611bcdb8f7dd684918f1a'] = 'Activer le moyen de paiement : virement bancaire via Sofort';
+$_MODULE['<{payxpert}prestashop>payxpert_1e25d70eb7c29b3396ff55c1bbd595b9'] = 'Virement bancaire via Przelewy24';
+$_MODULE['<{payxpert}prestashop>payxpert_820cdf51304d3b3dad0ac77a5c4c3a9a'] = 'Activer le moyen de paiement : virement bancaire via Przelewy24';
+$_MODULE['<{payxpert}prestashop>payxpert_133199f93d165a81bc21cdbcc42a1743'] = 'Virement bancaire via iDeal';
+$_MODULE['<{payxpert}prestashop>payxpert_4b554beb5ba2d91db0a6d06393a2dbee'] = 'Activer le moyen de paiement : virement bancaire via iDeal';
+$_MODULE['<{payxpert}prestashop>payxpert_a7ec39e91b86c1f5af031d85fc2eaba1'] = 'L\'identifiant de l\'initiateur est requis.';
+$_MODULE['<{payxpert}prestashop>payxpert_20aedd1e6de4dcf8d115b5a7424c58d7'] = 'Le mot de passe est requis.';
+$_MODULE['<{payxpert}prestashop>payxpert_02a2b395b673a990d4a164126510966f'] = 'L\'adresse du destinataire des notifications marchand est requise.';
+$_MODULE['<{payxpert}prestashop>payxpert_a6aab07cbf3e97724a9ea7fbda5e9d7a'] = 'L\'adresse email du destinataire des notifications marchand doit être une adresse email valide.';
+$_MODULE['<{payxpert}prestashop>payxpert_edec9b6255aa33c5dfa1ecb4cbf53634'] = 'La langue des notifications marchand n\'est pas valide.';
+$_MODULE['<{payxpert}prestashop>payxpert_20015706a8cbd457cbb6ea3e7d5dc9b3'] = 'Configuration mise à jour';
+$_MODULE['<{payxpert}prestashop>validation_73a61696f100b3858511e212a3feea6b'] = 'Carte bancaire';
+$_MODULE['<{payxpert}prestashop>validation_3726d2bc671a53445f9f57095bf9d76b'] = 'Virement bancaire';
+$_MODULE['<{payxpert}prestashop>config_f4f70727dc34561dfde1a3c529b6205c'] = 'Paramètres';
+$_MODULE['<{payxpert}prestashop>config_2ea3b0f6afbc5d22bca6c482c0bf54ca'] = 'Identifiant initiateur';
+$_MODULE['<{payxpert}prestashop>config_1e0e47cb9fb5d70cfdee039faa4df351'] = 'L\'identifiant de votre initiateur';
+$_MODULE['<{payxpert}prestashop>config_bd5d0eb5e80dabb222588e51b128a952'] = 'Mot de passe initiateur';
+$_MODULE['<{payxpert}prestashop>config_b33897812550f490e39369ab16b494fe'] = 'Le mot de passe de votre initiateur (laissez vide pour conserver l\'actuel)';
+$_MODULE['<{payxpert}prestashop>config_40b25dd0e73aec4884f398823590e65e'] = 'URL de la page de paiement';
+$_MODULE['<{payxpert}prestashop>config_f20ec5655452017530ce687f6fcea5cb'] = 'Laisser vide sauf si on vous a communiqué une adresse spécifique';
+$_MODULE['<{payxpert}prestashop>config_6f974bbda9064a9c0836370dbf5a6076'] = 'Notifications marchand';
+$_MODULE['<{payxpert}prestashop>config_b3151328e1f2e8eed187ecee1d0b078a'] = 'Envoyer ou non une notification par email au marchand pour chaque paiement';
+$_MODULE['<{payxpert}prestashop>config_6ae25f49f9b8ff8dd9d77931f13cd7ce'] = 'Destinataire des notifications marchand';
+$_MODULE['<{payxpert}prestashop>config_712cfbc42564d7b5b0f29cf3114f1b39'] = 'Adresse email du destinataire des notifications marchand';
+$_MODULE['<{payxpert}prestashop>config_c200e98fc7b00b24a16affd294c5a856'] = 'Langue des notifications marchand';
+$_MODULE['<{payxpert}prestashop>config_78463a384a5aa4fad5fa73e2f506ecfc'] = 'Anglais';
+$_MODULE['<{payxpert}prestashop>config_ad225f707802ba118c22987186dd38e8'] = 'Français';
+$_MODULE['<{payxpert}prestashop>config_cb5480c32e71778852b08ae1e8712775'] = 'Espagnol';
+$_MODULE['<{payxpert}prestashop>config_4be8e06d27bca7e1828f2fa9a49ca985'] = 'Italien';
+$_MODULE['<{payxpert}prestashop>config_14f2d2487d30e069719bcbab2a9c9141'] = 'Langue à utiliser lors de l\'envoi des notifications marchand';
+$_MODULE['<{payxpert}prestashop>config_b17f3f4dcf653a5776792498a9b44d6a'] = 'Modifier la configuration';
+$_MODULE['<{payxpert}prestashop>infos_aa2e442679e64b770ad11c1ac5d7d7d0'] = 'Ce module permet d\'accepter des paiements sécurisés.';
+$_MODULE['<{payxpert}prestashop>payment_error_5fdd505123089ad1f093d5467e6e0fa5'] = 'Paiement par carte bancaire';
+$_MODULE['<{payxpert}prestashop>payment_error_f1d3b424cd68795ecaa552883759aceb'] = 'Récapitulatif de commande';
+$_MODULE['<{payxpert}prestashop>payment_error_569fd05bdafa1712c4f6be5b153b8418'] = 'Autres moyens de paiement';
+$_MODULE['<{payxpert}prestashop>payment_execution_5fdd505123089ad1f093d5467e6e0fa5'] = 'Paiement par carte bancaire';
+$_MODULE['<{payxpert}prestashop>payment_execution_f1d3b424cd68795ecaa552883759aceb'] = 'Récapitulatif de commande';
+$_MODULE['<{payxpert}prestashop>payment_execution_879f6b8877752685a966564d072f498f'] = 'Votre panier est vide.';
+$_MODULE['<{payxpert}prestashop>payment_execution_73a61696f100b3858511e212a3feea6b'] = 'Carte bancaire';
+$_MODULE['<{payxpert}prestashop>payment_execution_38e5d5a82e049662d1d60d31ea2fd300'] = 'Vous avez choisi de régler par carte bancaire.';
+$_MODULE['<{payxpert}prestashop>payment_execution_c884ed19483d45970c5bf23a681e2dd2'] = 'Voici un bref récapitulatif de votre commande :';
+$_MODULE['<{payxpert}prestashop>payment_execution_e2867a925cba382f1436d1834bb52a1c'] = 'Le montant total de votre commande s\'élève à';
+$_MODULE['<{payxpert}prestashop>payment_execution_1f87346a16cf80c372065de3c54c86d9'] = 'TTC';
+$_MODULE['<{payxpert}prestashop>payment_execution_2c915fa837f3213915eea3e1dc6286ec'] = 'Vos informations de paiement vous serons demandées sur la prochaine page sécurisée';
+$_MODULE['<{payxpert}prestashop>payment_execution_93c1f9dffc8c38b2c108d449a9181d92'] = 'Merci de confirmer votre commande en cliquant sur \"Je confirme ma commande\"';
+$_MODULE['<{payxpert}prestashop>payment_execution_baa62374832554652160fe5a827b2741'] = 'Je confirme ma commande';
+$_MODULE['<{payxpert}prestashop>payment_execution_569fd05bdafa1712c4f6be5b153b8418'] = 'Autres moyens de paiement';
+$_MODULE['<{payxpert}prestashop>payment_execution_bank_transfer_fb077ecba55e5552916bde26d8b9e794'] = 'Confirmation de commande';
+$_MODULE['<{payxpert}prestashop>payment_execution_bank_transfer_879f6b8877752685a966564d072f498f'] = 'Votre panier est vide.';
+$_MODULE['<{payxpert}prestashop>payment_execution_bank_transfer_3726d2bc671a53445f9f57095bf9d76b'] = 'Virement bancaire';
+$_MODULE['<{payxpert}prestashop>payment_execution_bank_transfer_7932ecf622ec454c25bfbe87a6dca3a6'] = 'Vous avez choisi de payer par virement bancaire.';
+$_MODULE['<{payxpert}prestashop>payment_execution_bank_transfer_9afb6a88186a8c57ef9562b66e928135'] = 'Le montant total de votre commande est de %s.';
+$_MODULE['<{payxpert}prestashop>payment_execution_bank_transfer_5958921b7d034715d2f2ec04a3eaaf87'] = 'Vous serez en mesure de payer en fournissant les coordonnées de votre compte bancaire au moyen d\'un formulaire sécurisé sur les pages suivantes.';
+$_MODULE['<{payxpert}prestashop>payment_execution_bank_transfer_c624426fb64f742a7e113f3381f47b52'] = 'Veuillez confirmer votre commande en utilisant le bouton « Payer ma commande » ci dessous.';
+$_MODULE['<{payxpert}prestashop>payment_execution_bank_transfer_512bb802df28ada6f304c32398bb40d0'] = 'Payer ma commande';
+$_MODULE['<{payxpert}prestashop>payment_execution_bank_transfer_569fd05bdafa1712c4f6be5b153b8418'] = 'Autres moyens de paiement';
+$_MODULE['<{payxpert}prestashop>payment_execution_credit_card_fb077ecba55e5552916bde26d8b9e794'] = 'Récapitulatif de commande';
+$_MODULE['<{payxpert}prestashop>payment_execution_credit_card_879f6b8877752685a966564d072f498f'] = 'Votre panier est vide.';
+$_MODULE['<{payxpert}prestashop>payment_execution_credit_card_73a61696f100b3858511e212a3feea6b'] = 'Carte bancaire';
+$_MODULE['<{payxpert}prestashop>payment_execution_credit_card_38e5d5a82e049662d1d60d31ea2fd300'] = 'Vous avez choisi de régler par carte bancaire.';
+$_MODULE['<{payxpert}prestashop>payment_execution_credit_card_9afb6a88186a8c57ef9562b66e928135'] = 'Le montant total de votre commande s\'élève à %s.';
+$_MODULE['<{payxpert}prestashop>payment_execution_credit_card_aea960762718b5dfebc2731749d2b963'] = 'Vous serez en mesure de payer en fournissant les informations de votre carte bancaire au moyen d\'un formulaire sécurisé sur les pages suivantes.';
+$_MODULE['<{payxpert}prestashop>payment_execution_credit_card_c624426fb64f742a7e113f3381f47b52'] = 'Veuillez confirmer votre commande en utilisant le bouton « Payer ma commande » ci dessous.';
+$_MODULE['<{payxpert}prestashop>payment_execution_credit_card_512bb802df28ada6f304c32398bb40d0'] = 'Payer ma commande';
+$_MODULE['<{payxpert}prestashop>payment_execution_credit_card_569fd05bdafa1712c4f6be5b153b8418'] = 'Autres moyens de paiement';
+$_MODULE['<{payxpert}prestashop>payment_infos_bank_transfer_ideal_c3e6e1fb2780181e710c3b5b8df98568'] = 'Régler votre commande en utilisant vos informations de compte bancaire avec le fournisseur iDeal';
+$_MODULE['<{payxpert}prestashop>payment_infos_bank_transfer_przelewy24_a5c4c63be0923c45042b9c6544272db9'] = 'Régler votre commande en utilisant vos informations de compte bancaire avec le fournisseur Przelewy24';
+$_MODULE['<{payxpert}prestashop>payment_infos_bank_transfer_sofort_64c4d630033101176b2c183d95d4b077'] = 'Régler votre commande en utilisant vos informations de compte bancaire avec le fournisseur Sofort';
+$_MODULE['<{payxpert}prestashop>payment_infos_credit_card_7358d61686326706aedac475364bdb81'] = 'Régler votre commande en utilisant vos informations de carte bancaire';
+$_MODULE['<{payxpert}prestashop>orderconfirmation_1167e46c7a94af11bd9bef3805ef4e73'] = 'Le paiement de votre commande a été effectué.';
+$_MODULE['<{payxpert}prestashop>orderconfirmation_9bfbb6e7dd3a9356d9338c53dd5809c9'] = 'Elle sera validée ou expédiée au plus vite.';
+$_MODULE['<{payxpert}prestashop>orderconfirmation_0db71da7150c27142eef9d22b843b4a9'] = 'Pour toute question ou information complémentaire merci de contacter notre';
+$_MODULE['<{payxpert}prestashop>orderconfirmation_64430ad2835be8ad60c59e7d44e4b0b1'] = 'support client';
+$_MODULE['<{payxpert}prestashop>orderconfirmation_8591f5ec4ceb388620dc7617565f73ad'] = 'Votre commande est encore en attente.';
+$_MODULE['<{payxpert}prestashop>orderconfirmation_0750d4a213576f483f679fa8200145eb'] = 'Votre commande sera expédiée dès réception de votre paiement.';
+$_MODULE['<{payxpert}prestashop>orderconfirmation_8de637e24570c1edb0357826a2ad5aea'] = 'Nous avons rencontré un problème avec votre commande. Merci de prendre contact avec notre';
+$_MODULE['<{payxpert}prestashop>payment_e77bb171c7ae55bba8b2ed869fadfb19'] = 'Paiement par carte bancaire';
diff --git a/modules/payxpert/images/baian.png b/modules/payxpert/images/baian.png
new file mode 100644
index 0000000..3c0a418
Binary files /dev/null and b/modules/payxpert/images/baian.png differ
diff --git a/modules/payxpert/images/fullpass.png b/modules/payxpert/images/fullpass.png
new file mode 100644
index 0000000..63f8ed0
Binary files /dev/null and b/modules/payxpert/images/fullpass.png differ
diff --git a/modules/payxpert/images/index.php b/modules/payxpert/images/index.php
new file mode 100644
index 0000000..3f6561f
--- /dev/null
+++ b/modules/payxpert/images/index.php
@@ -0,0 +1,35 @@
+
+* @copyright 2007-2013 PrestaShop SA
+* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
+* International Registered Trademark & Property of PrestaShop SA
+*/
+
+header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
+header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
+
+header("Cache-Control: no-store, no-cache, must-revalidate");
+header("Cache-Control: post-check=0, pre-check=0", false);
+header("Pragma: no-cache");
+
+header("Location: ../");
+exit;
\ No newline at end of file
diff --git a/modules/payxpert/images/logo-baian.gif b/modules/payxpert/images/logo-baian.gif
new file mode 100644
index 0000000..4db7f98
Binary files /dev/null and b/modules/payxpert/images/logo-baian.gif differ
diff --git a/modules/payxpert/images/logo-baian.png b/modules/payxpert/images/logo-baian.png
new file mode 100644
index 0000000..2a3cfc4
Binary files /dev/null and b/modules/payxpert/images/logo-baian.png differ
diff --git a/modules/payxpert/images/logo-fullpass.gif b/modules/payxpert/images/logo-fullpass.gif
new file mode 100644
index 0000000..1e38410
Binary files /dev/null and b/modules/payxpert/images/logo-fullpass.gif differ
diff --git a/modules/payxpert/images/logo-fullpass.png b/modules/payxpert/images/logo-fullpass.png
new file mode 100644
index 0000000..910ccb9
Binary files /dev/null and b/modules/payxpert/images/logo-fullpass.png differ
diff --git a/modules/payxpert/images/logo-payxpert.gif b/modules/payxpert/images/logo-payxpert.gif
new file mode 100644
index 0000000..5c46c52
Binary files /dev/null and b/modules/payxpert/images/logo-payxpert.gif differ
diff --git a/modules/payxpert/images/logo-payxpert.png b/modules/payxpert/images/logo-payxpert.png
new file mode 100644
index 0000000..93955e3
Binary files /dev/null and b/modules/payxpert/images/logo-payxpert.png differ
diff --git a/modules/payxpert/images/logo-payzone.gif b/modules/payxpert/images/logo-payzone.gif
new file mode 100644
index 0000000..09ce9ce
Binary files /dev/null and b/modules/payxpert/images/logo-payzone.gif differ
diff --git a/modules/payxpert/images/logo-payzone.png b/modules/payxpert/images/logo-payzone.png
new file mode 100644
index 0000000..5646ae5
Binary files /dev/null and b/modules/payxpert/images/logo-payzone.png differ
diff --git a/modules/payxpert/images/payment-types/creditcard.png b/modules/payxpert/images/payment-types/creditcard.png
new file mode 100644
index 0000000..217c692
Binary files /dev/null and b/modules/payxpert/images/payment-types/creditcard.png differ
diff --git a/modules/payxpert/images/payment-types/creditcard_icon.png b/modules/payxpert/images/payment-types/creditcard_icon.png
new file mode 100644
index 0000000..fddb498
Binary files /dev/null and b/modules/payxpert/images/payment-types/creditcard_icon.png differ
diff --git a/modules/payxpert/images/payment-types/ideal.png b/modules/payxpert/images/payment-types/ideal.png
new file mode 100644
index 0000000..2e3fe59
Binary files /dev/null and b/modules/payxpert/images/payment-types/ideal.png differ
diff --git a/modules/payxpert/images/payment-types/przelewy24.png b/modules/payxpert/images/payment-types/przelewy24.png
new file mode 100644
index 0000000..a257c72
Binary files /dev/null and b/modules/payxpert/images/payment-types/przelewy24.png differ
diff --git a/modules/payxpert/images/payment-types/sofort.png b/modules/payxpert/images/payment-types/sofort.png
new file mode 100644
index 0000000..4e2c2a4
Binary files /dev/null and b/modules/payxpert/images/payment-types/sofort.png differ
diff --git a/modules/payxpert/images/payxpert.png b/modules/payxpert/images/payxpert.png
new file mode 100644
index 0000000..ac1f5a3
Binary files /dev/null and b/modules/payxpert/images/payxpert.png differ
diff --git a/modules/payxpert/images/payzone.png b/modules/payxpert/images/payzone.png
new file mode 100644
index 0000000..503d1e9
Binary files /dev/null and b/modules/payxpert/images/payzone.png differ
diff --git a/modules/payxpert/index.php b/modules/payxpert/index.php
new file mode 100644
index 0000000..3f6561f
--- /dev/null
+++ b/modules/payxpert/index.php
@@ -0,0 +1,35 @@
+
+* @copyright 2007-2013 PrestaShop SA
+* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
+* International Registered Trademark & Property of PrestaShop SA
+*/
+
+header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
+header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
+
+header("Cache-Control: no-store, no-cache, must-revalidate");
+header("Cache-Control: post-check=0, pre-check=0", false);
+header("Pragma: no-cache");
+
+header("Location: ../");
+exit;
\ No newline at end of file
diff --git a/modules/payxpert/lib/Connect2PayClient.php b/modules/payxpert/lib/Connect2PayClient.php
new file mode 100644
index 0000000..04d24ce
--- /dev/null
+++ b/modules/payxpert/lib/Connect2PayClient.php
@@ -0,0 +1,3454 @@
+= 5.3.0
+ * PHP CURL module
+ * PHP Mcrypt module
+ *
+ * @version 2.6.0
+ * @copyright 2011-2017 PayXpert
+ *
+ */
+class Connect2PayClient {
+ /**
+ * Payment types constants
+ */
+ const _PAYMENT_TYPE_CREDITCARD = 'CreditCard';
+ const _PAYMENT_TYPE_TODITOCASH = 'ToditoCash';
+ const _PAYMENT_TYPE_BANKTRANSFER = 'BankTransfer';
+
+ /**
+ * Payment providers constants
+ */
+ const _PAYMENT_PROVIDER_SOFORT = 'Sofort';
+ const _PAYMENT_PROVIDER_PRZELEWY24 = 'Przelewy24';
+ const _PAYMENT_PROVIDER_IDEALKP = 'IDealKP';
+
+ /**
+ * Operation types constants
+ */
+ const _OPERATION_TYPE_SALE = 'sale';
+ const _OPERATION_TYPE_AUTHORIZE = 'authorize';
+
+ /**
+ * Payment modes constants
+ */
+ const _PAYMENT_MODE_SINGLE = 'Single';
+ const _PAYMENT_MODE_ONSHIPPING = 'OnShipping';
+ const _PAYMENT_MODE_RECURRENT = 'Recurrent';
+ const _PAYMENT_MODE_INSTALMENTS = 'InstalmentsPayments';
+
+ /**
+ * Shipping types constants
+ */
+ const _SHIPPING_TYPE_PHYSICAL = 'Physical';
+ const _SHIPPING_TYPE_ACCESS = 'Access';
+ const _SHIPPING_TYPE_VIRTUAL = 'Virtual';
+
+ /**
+ * Subscription types constants
+ */
+ const _SUBSCRIPTION_TYPE_NORMAL = 'normal';
+ const _SUBSCRIPTION_TYPE_LIFETIME = 'lifetime';
+ const _SUBSCRIPTION_TYPE_ONETIME = 'onetime';
+ const _SUBSCRIPTION_TYPE_INFINITE = 'infinite';
+
+ /**
+ * Lang constants
+ */
+ const _LANG_EN = 'en';
+ const _LANG_FR = 'fr';
+ const _LANG_ES = 'es';
+ const _LANG_IT = 'it';
+
+ /**
+ * ~~~~
+ * Subscription cancel reasons
+ * ~~~~
+ */
+ /**
+ * Bank denial
+ */
+ const _SUBSCRIPTION_CANCEL_BANK_DENIAL = 1000;
+ /**
+ * Canceled due to refund
+ */
+ const _SUBSCRIPTION_CANCEL_REFUNDED = 1001;
+ /**
+ * Canceled due to retrieval request
+ */
+ const _SUBSCRIPTION_CANCEL_RETRIEVAL = 1002;
+ /**
+ * Cancellation letter sent by bank
+ */
+ const _SUBSCRIPTION_CANCEL_BANK_LETTER = 1003;
+ /**
+ * Chargeback
+ */
+ const _SUBSCRIPTION_CANCEL_CHARGEBACK = 1004;
+ /**
+ * Company account closed
+ */
+ const _SUBSCRIPTION_CANCEL_COMPANY_ACCOUNT_CLOSED = 1005;
+ /**
+ * Site account closed
+ */
+ const _SUBSCRIPTION_CANCEL_WEBSITE_ACCOUNT_CLOSED = 1006;
+ /**
+ * Didn't like the site
+ */
+ const _SUBSCRIPTION_CANCEL_DID_NOT_LIKE = 1007;
+ /**
+ * Disagree ('Did not do it' or 'Do not recognize the transaction')
+ */
+ const _SUBSCRIPTION_CANCEL_DISAGREE = 1008;
+ /**
+ * Fraud from webmaster
+ */
+ const _SUBSCRIPTION_CANCEL_WEBMASTER_FRAUD = 1009;
+ /**
+ * I could not get in to the site
+ */
+ const _SUBSCRIPTION_CANCEL_COULD_NOT_GET_INTO = 1010;
+ /**
+ * No problem, just moving on
+ */
+ const _SUBSCRIPTION_CANCEL_NO_PROBLEM = 1011;
+ /**
+ * Not enough updates
+ */
+ const _SUBSCRIPTION_CANCEL_NOT_UPDATED = 1012;
+ /**
+ * Problems with the movies/videos
+ */
+ const _SUBSCRIPTION_CANCEL_TECH_PROBLEM = 1013;
+ /**
+ * Site was too slow
+ */
+ const _SUBSCRIPTION_CANCEL_TOO_SLOW = 1014;
+ /**
+ * The site did not work
+ */
+ const _SUBSCRIPTION_CANCEL_DID_NOT_WORK = 1015;
+ /**
+ * Too expensive
+ */
+ const _SUBSCRIPTION_CANCEL_TOO_EXPENSIVE = 1016;
+ /**
+ * Un-authorized signup by family member
+ */
+ const _SUBSCRIPTION_CANCEL_UNAUTH_FAMILLY = 1017;
+ /**
+ * Undetermined reasons
+ */
+ const _SUBSCRIPTION_CANCEL_UNDETERMINED = 1018;
+ /**
+ * Webmaster requested to cancel
+ */
+ const _SUBSCRIPTION_CANCEL_WEBMASTER_REQUESTED = 1019;
+ /**
+ * I haven't received my item
+ */
+ const _SUBSCRIPTION_CANCEL_NOTHING_RECEIVED = 1020;
+ /**
+ * The item was damaged or defective
+ */
+ const _SUBSCRIPTION_CANCEL_DAMAGED = 1021;
+ /**
+ * The box was empty
+ */
+ const _SUBSCRIPTION_CANCEL_EMPTY_BOX = 1022;
+ /**
+ * The order was incomplete
+ */
+ const _SUBSCRIPTION_CANCEL_INCOMPLETE_ORDER = 1023;
+
+ /**
+ * Field content constant
+ */
+ const _UNAVAILABLE = 'NA';
+ const _UNAVAILABLE_COUNTRY = 'ZZ';
+
+ /*
+ * API calls routes
+ */
+ private static $API_ROUTES = array(/* */
+ 'TRANS_PREPARE' => '/payment/prepare', /* */
+ 'PAYMENT_STATUS' => '/payment/:merchantToken/status', /* */
+ 'TRANS_REFUND' => '/transaction/:transactionID/refund', /* */
+ 'TRANS_DOPAY' => '/payment/:customerToken', /* */
+ 'SUB_CANCEL' => '/subscription/:subscriptionID/cancel');
+
+ /*
+ * Fields required for payment creation
+ */
+ protected $fieldsRequired = array('orderID', 'currency', 'amount', 'shippingType', 'paymentMode');
+
+ /*
+ * Fields maximum size
+ */
+ protected $fieldsSize = array(/* */
+ 'shopperID' => 32, /* */
+ 'shopperEmail' => 100, /* */
+ 'shipToCountryCode' => 2, /* */
+ 'shopperCountryCode' => 2, /* */
+ 'orderID' => 100, /* */
+ 'orderDescription' => 500, /* */
+ 'currency' => 3, /* */
+ 'orderFOLanguage' => 50, /* */
+ 'shippingType' => 50, /* */
+ 'shippingName' => 50, /* */
+ 'paymentType' => 32, /* */
+ 'operation' => 32, /* */
+ 'paymentMode' => 30, /* */
+ 'subscriptionType' => 32, /* */
+ 'trialPeriod' => 10, /* */
+ 'rebillPeriod' => 10, /* */
+ 'ctrlRedirectURL' => 2048, /* */
+ 'ctrlCallbackURL' => 2048, /* */
+ 'timeOut' => 10, /* */
+ 'merchantNotificationTo' => 100, /* */
+ 'merchantNotificationLang' => 2, /* */
+ 'ctrlCustomData' => 2048 /* */
+ );
+
+ /*
+ * Fields validation constraints
+ */
+ protected $fieldsValidate = array(/* */
+ 'shopperID' => 'isString', /* */
+ 'shopperEmail' => 'isEmail', /* */
+ 'shipToCountryCode' => 'isCountryName', /* */
+ 'shopperCountryCode' => 'isCountryName', /* */
+ 'orderID' => 'isString', /* */
+ 'orderDescription' => 'isString', /* */
+ 'currency' => 'isString', /* */
+ 'amount' => 'isInt', /* */
+ 'orderTotalWithoutShipping' => 'isInt', /* */
+ 'orderShippingPrice' => 'isInt', /* */
+ 'orderDiscount' => 'isInt', /* */
+ 'orderFOLanguage' => 'isString', /* */
+ 'shippingType' => 'isShippingType', /* */
+ 'shippingName' => 'isString', /* */
+ 'paymentType' => 'isPayment', /* */
+ 'provider' => 'isProvider', /* */
+ 'operation' => 'isOperation', /* */
+ 'paymentMode' => 'isPaymentMode', /* */
+ 'offerID' => 'isInt', /* */
+ 'subscriptionType' => 'isSubscriptionType', /* */
+ 'trialPeriod' => 'isString', /* */
+ 'rebillAmount' => 'isInt', /* */
+ 'rebillPeriod' => 'isString', /* */
+ 'rebillMaxIteration' => 'isInt', /* */
+ 'ctrlRedirectURL' => 'isAbsoluteUrl', /* */
+ 'ctrlCallbackURL' => 'isAbsoluteUrl', /* */
+ 'timeOut' => 'isString', /* */
+ 'merchantNotification' => 'isBool', /* */
+ 'merchantNotificationTo' => 'isEmail', /* */
+ 'merchantNotificationLang' => 'isString', /* */
+ 'themeID' => 'isInt' /* */
+ );
+
+ /*
+ * Fields to be included in JSON
+ */
+ protected $fieldsJSON = array(/* */
+ 'apiVersion', /* */
+ 'shopperID', /* */
+ 'shopperEmail', /* */
+ 'shipToFirstName', /* */
+ 'shipToLastName', /* */
+ 'shipToCompany', /* */
+ 'shipToPhone', /* */
+ 'shipToAddress', /* */
+ 'shipToState', /* */
+ 'shipToZipcode', /* */
+ 'shipToCity', /* */
+ 'shipToCountryCode', /* */
+ 'shopperFirstName', /* */
+ 'shopperLastName', /* */
+ 'shopperPhone', /* */
+ 'shopperAddress', /* */
+ 'shopperState', /* */
+ 'shopperZipcode', /* */
+ 'shopperCity', /* */
+ 'shopperCountryCode', /* */
+ 'shopperBirthDate', /* */
+ 'shopperIDNumber', /* */
+ 'shopperCompany', /* */
+ 'shopperLoyaltyProgram', /* */
+ 'orderID', /* */
+ 'orderDescription', /* */
+ 'currency', /* */
+ 'amount', /* */
+ 'orderTotalWithoutShipping', /* */
+ 'orderShippingPrice', /* */
+ 'orderDiscount', /* */
+ 'orderFOLanguage', /* */
+ 'orderCartContent', /* */
+ 'shippingType', /* */
+ 'shippingName', /* */
+ 'paymentType', /* */
+ 'provider', /* */
+ 'operation', /* */
+ 'paymentMode', /* */
+ 'secure3d', /* */
+ 'offerID', /* */
+ 'subscriptionType', /* */
+ 'trialPeriod', /* */
+ 'rebillAmount', /* */
+ 'rebillPeriod', /* */
+ 'rebillMaxIteration', /* */
+ 'ctrlCustomData', /* */
+ 'ctrlRedirectURL', /* */
+ 'ctrlCallbackURL', /* */
+ 'timeOut', /* */
+ 'merchantNotification', /* */
+ 'merchantNotificationTo', /* */
+ 'merchantNotificationLang', /* */
+ 'themeID' /* */
+ );
+
+ /*
+ * API version implemented by this library
+ */
+ private $apiVersion = '002.50';
+
+ /**
+ * URL of the connect2pay application
+ *
+ * @var string
+ */
+ private $url;
+
+ /**
+ * Login for the connect2pay application
+ *
+ * @var string
+ */
+ private $merchant;
+
+ /**
+ * Password for the connect2pay application
+ *
+ * @var string
+ */
+ private $password;
+
+ // ~~~~
+ // Transaction related data
+ // ~~~~
+
+ /**
+ * Force the transaction to use Secure 3D
+ *
+ * @var Boolean
+ */
+ private $secure3d;
+
+ // Customer fields
+ /**
+ * Merchant unique customer numeric id
+ *
+ * @var string
+ */
+ private $shopperID;
+ /**
+ * Customer email address
+ *
+ * @var string
+ */
+ private $shopperEmail;
+ /**
+ * Customer first name for shipping
+ *
+ * @var string
+ */
+ private $shipToFirstName;
+ /**
+ * Customer last name for shipping
+ *
+ * @var string
+ */
+ private $shipToLastName;
+ /**
+ * Customer company name for shipping
+ *
+ * @var string
+ */
+ private $shipToCompany;
+ /**
+ * Customer phone for shipping ; if many, separate by ";"
+ *
+ * @var string
+ */
+ private $shipToPhone;
+ /**
+ * Customer address for shipping
+ *
+ * @var string
+ */
+ private $shipToAddress;
+ /**
+ * Customer state for shipping
+ *
+ * @var string
+ */
+ private $shipToState;
+ /**
+ * Customer ZIP Code for shipping
+ *
+ * @var string
+ */
+ private $shipToZipcode;
+ /**
+ * Customer city for shipping
+ *
+ * @var string
+ */
+ private $shipToCity;
+ /**
+ * Customer country for shipping
+ *
+ * @var string
+ */
+ private $shipToCountryCode;
+ /**
+ * Customer first name for invoicing
+ *
+ * @var string
+ */
+ private $shopperFirstName;
+ /**
+ * Customer last name for invoicing
+ *
+ * @var string
+ */
+ private $shopperLastName;
+ /**
+ * Customer phone for invoicing ; if many, separate by ";"
+ *
+ * @var string
+ */
+ private $shopperPhone;
+ /**
+ * Customer address for invoicing
+ *
+ * @var string
+ */
+ private $shopperAddress;
+ /**
+ * Customer state for invoicing
+ *
+ * @var string
+ */
+ private $shopperState;
+ /**
+ * Customer ZIP Code for invoicing
+ *
+ * @var string
+ */
+ private $shopperZipcode;
+ /**
+ * Customer city for invoicing
+ *
+ * @var string
+ */
+ private $shopperCity;
+ /**
+ * Customer country for invoicing
+ *
+ * @var string
+ */
+ private $shopperCountryCode;
+ /**
+ * Customer birth date YYYYMMDD
+ *
+ * @var string
+ */
+ private $shopperBirthDate;
+ /**
+ * Customer ID number (identity card, passport...)
+ *
+ * @var string
+ */
+ private $shopperIDNumber;
+ /**
+ * Customer company name for invoicing
+ *
+ * @var string
+ */
+ private $shopperCompany;
+ /**
+ * Customer Loyalty Program name
+ *
+ * @var string
+ */
+ private $shopperLoyaltyProgram;
+
+ // Order Fields
+ /**
+ * Merchant internal unique order ID
+ *
+ * @var string
+ */
+ private $orderID;
+ /**
+ * Sum up of the order to display on the payment page
+ *
+ * @var string
+ */
+ private $orderDescription;
+ /**
+ * Currency for the current order
+ *
+ * @var string
+ */
+ private $currency;
+ /**
+ * The transaction amount in cents (for 1€ => 100)
+ *
+ * @var integer
+ */
+ private $amount;
+ /**
+ * The transaction amount in cents, without shipping fee
+ *
+ * @var integer
+ */
+ private $orderTotalWithoutShipping;
+ /**
+ * The shipping amount in cents (for 1€ => 100)
+ *
+ * @var integer
+ */
+ private $orderShippingPrice;
+ /**
+ * The discount amount in cents (for 1€ => 100)
+ *
+ * @var integer
+ */
+ private $orderDiscount;
+ /**
+ * Language of the Front Office used to validate the order
+ *
+ * @var string
+ */
+ private $orderFOLanguage;
+ /**
+ * Product or service bought - see details below
+ *
+ * @var array[](integer CartProductId, string CartProductName, float
+ * CartProductUnitPrice,
+ * integer CartProductQuantity, string CartProductBrand, string
+ * CartProductMPN,
+ * string CartProductCategoryName, integer CartProductCategoryID)
+ */
+ private $orderCartContent;
+
+ // Shipping Fields
+ /**
+ * Type can be either : Physical (for physical goods), Virtual (for
+ * dematerialized goods), Access (for protected content)
+ *
+ * @var string
+ */
+ private $shippingType;
+ /**
+ * In case of Physical shipping type, name of the shipping company
+ *
+ * @var string
+ */
+ private $shippingName;
+
+ // Payment Detail Fields
+ /**
+ * Can be CreditCard, ToditoCash, BankTransfer or empty.
+ * This will change the type of the payment page displayed.
+ * If empty, a selection page will be displayed to the customer with payment
+ * types available for the account.
+ *
+ * @var string
+ */
+ private $paymentType;
+
+ /**
+ * The technical payment provider to use for the payment.
+ * This can be needed for payment types other than credit card where everal
+ * provider are available and can not be all used in every countries.
+ *
+ * @var string
+ */
+ private $provider;
+
+ /**
+ * Can be authorize or sale (default value is according to what is configured
+ * for the account).
+ * This will change the operation done for the payment page.
+ * Only relevant for Credit Card payment type.
+ *
+ * @var string
+ */
+ private $operation;
+
+ /**
+ * Can be either : Single, OnShipping, Recurrent, InstalmentsPayments
+ *
+ * @var string
+ */
+ private $paymentMode;
+
+ /**
+ * Predefined price point with initial and rebill period (for Recurrent,
+ * InstalmentsPayments payment types)
+ *
+ * @var integer
+ */
+ private $offerID;
+
+ /**
+ * Type of subscription.
+ *
+ * @var string
+ */
+ private $subscriptionType;
+
+ /**
+ * Number of days in the initial period (for Recurrent, InstalmentsPayments
+ * payment types)
+ *
+ * @var integer
+ */
+ private $trialPeriod;
+
+ /**
+ * Number in minor unit, amount to be rebilled after the initial period (for
+ * Recurrent, InstalmentsPayments payment types)
+ *
+ * @var integer
+ */
+ private $rebillAmount;
+
+ /**
+ * Number of days next re-billing transaction will be settled in (for
+ * Recurrent, InstalmentsPayments payment types)
+ *
+ * @var integer
+ */
+ private $rebillPeriod;
+
+ /**
+ * Number of re-billing transactions that will be settled (for Recurrent,
+ * InstalmentsPayments payment types)
+ *
+ * @var integer
+ */
+ private $rebillMaxIteration;
+
+ // Template and Control Fields
+ /**
+ * The URL where to redirect the customer after the transaction processing
+ *
+ * @var string
+ */
+ private $ctrlRedirectURL;
+
+ /**
+ * A URL that will be notified of the status of the transaction
+ *
+ * @var string
+ */
+ private $ctrlCallbackURL;
+
+ /**
+ * Custom data that will be returned back with the status of the transaction
+ *
+ * @var string
+ */
+ private $ctrlCustomData;
+
+ /**
+ * Validity for the payment link in ISO 8601 duration format.
+ * See http://en.wikipedia.org/wiki/ISO_8601.
+ * For example: 2 days => P2D, 1 month => P1M
+ *
+ * @var string
+ */
+ private $timeOut;
+
+ /**
+ * Whether or not to send notification to the merchant after payment
+ * processing
+ *
+ * @var boolean
+ */
+ private $merchantNotification;
+
+ /**
+ * Mail address to send merchant notification to
+ *
+ * @var string
+ */
+ private $merchantNotificationTo;
+
+ /**
+ * Lang to use in merchant notification (defaults to the customer lang)
+ *
+ * @var string
+ */
+ private $merchantNotificationLang;
+
+ /**
+ * Select a predefined payment page template
+ *
+ * @var integer
+ */
+ private $themeID;
+
+ // Data returned from prepare call
+ private $returnCode;
+ private $returnMessage;
+ private $merchantToken;
+ private $customerToken;
+
+ // Data returned from status call
+ private $status;
+
+ // Internal data
+ private $clientErrorMessage;
+
+ // HTTP Proxy data
+ private $proxy_host = null;
+ private $proxy_port = null;
+ private $proxy_username = null;
+ private $proxy_password = null;
+
+ // Internal Currency Helper
+ private $currencyHelper = null;
+
+ // Extra CURL options that can be set by the caller
+ private $extraCurlOptions = array();
+
+ /**
+ * Instantiate a new payment page client
+ *
+ * @param string $url
+ * The URL of the payment page application
+ * @param string $merchant
+ * The login of the merchant on the payment page
+ * @param string $password
+ * The password of the merchant on the payment page
+ * @param array $data
+ * Data for the transaction to create (optional)
+ */
+ public function __construct($url, $merchant, $password, $data = null) {
+ $this->url = preg_replace('/\/*$/', '', $url);
+ $this->merchant = $merchant;
+ $this->password = $password;
+
+ if ($data != null && is_array($data)) {
+ foreach ($data as $var => $value) {
+ if (property_exists($this, $var)) {
+ $this->$var = $value;
+ }
+ }
+ }
+ }
+
+ /**
+ * Set the parameter in the case of the use of an outgoing proxy
+ *
+ * @param string $host
+ * The proxy host.
+ * @param int $port
+ * The proxy port.
+ * @param string $username
+ * The proxy username.
+ * @param string $password
+ * The proxy password.
+ */
+ public function useProxy($host, $port, $username = null, $password = null) {
+ $this->proxy_host = $host;
+ $this->proxy_port = $port;
+ $this->proxy_username = $username;
+ $this->proxy_password = $password;
+ }
+
+ /**
+ * Force the validation of the Connect2Pay SSL certificate.
+ *
+ * @param string $certFilePath
+ * The path to the PEM file containing the certification chain.
+ * If not set, defaults to
+ * "_current-dir_/ssl/connect2pay-signing-ca-cert.pem"
+ * @deprecated Has no effect anymore
+ */
+ public function forceSSLValidation($certFilePath = null) {
+ Utils::deprecation_error('Custom certificate file path is deprecated. Will use the system CA.');
+ }
+
+ /**
+ * Add extra curl options
+ */
+ public function setExtraCurlOption($name, $value) {
+ $this->extraCurlOptions[$name] = $value;
+ }
+
+ /**
+ *
+ * @deprecated Use preparePayment() instead.
+ */
+ public function prepareTransaction() {
+ Utils::deprecation_error('Method prepareTransaction() is deprecated, use preparePayment() instead');
+ return $this->preparePayment();
+ }
+
+ /**
+ * Prepare a new payment on the payment page application.
+ * This method will validate the payment data and call
+ * the payment page application to create a new payment.
+ * The fields returnCode, returnMessage, merchantToken and
+ * customerToken will be populated according to the call result.
+ *
+ * @return boolean true if creation is successful, false otherwise
+ */
+ public function preparePayment() {
+ if ($this->validate()) {
+ $trans = array();
+
+ foreach ($this->fieldsJSON as $fieldName) {
+ if (is_array($this->{$fieldName}) || !C2PValidate::isEmpty($this->{$fieldName})) {
+ $trans[$fieldName] = $this->{"get" . ucfirst($fieldName)}();
+ }
+ }
+
+ // Only PHP >= 5.4 has JSON_UNESCAPED_SLASHES option
+ $post_data = str_replace('\\/', '/', json_encode($trans));
+ $url = $this->url . Connect2PayClient::$API_ROUTES['TRANS_PREPARE'];
+
+ $result = $this->doPost($url, $post_data);
+
+ if ($result != null && is_array($result)) {
+ $this->returnCode = $result['code'];
+ $this->returnMessage = $result['message'];
+
+ if ($this->returnCode == "200") {
+ $this->merchantToken = $result['merchantToken'];
+ $this->customerToken = $result['customerToken'];
+ return true;
+ } else {
+ $this->clientErrorMessage = $this->returnMessage;
+ }
+ }
+ } else {
+ $this->clientErrorMessage = 'The transaction is not valid.';
+ }
+
+ return false;
+ }
+
+ /**
+ *
+ * @deprecated Use getPaymentStatus($merchantToken) instead.
+ *
+ * @param string $merchantToken
+ */
+ public function getTransactionStatus($merchantToken) {
+ Utils::deprecation_error('getTransactionStatus is deprecated, use getPaymentStatus instead');
+ return $this->getPaymentStatus($merchantToken);
+ }
+
+ /**
+ * Do a transaction status request on the payment page application.
+ *
+ * @param string $merchantToken
+ * The merchant token related to this payment
+ * @return The PaymentStatus object of the payment or null on error
+ */
+ public function getPaymentStatus($merchantToken) {
+ if ($merchantToken != null && strlen(trim($merchantToken)) > 0) {
+ $url = $this->url . str_replace(":merchantToken", $merchantToken, Connect2PayClient::$API_ROUTES['PAYMENT_STATUS']);
+
+ $result = $this->doGet($url, array(), false);
+
+ if ($result !== null && is_object($result)) {
+ $this->initStatus($result);
+ if (isset($this->status)) {
+ return $this->status;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Refund a transaction.
+ *
+ * @param string $transactionID
+ * Identifier of the transaction to refund
+ * @param int $amount
+ * The amount to refund
+ * @return The RefundStatus filled with values returned from the operation or
+ * null on failure (in that case call getClientErrorMessage())
+ */
+ public function refundTransaction($transactionID, $amount) {
+ if ($transactionID !== null && $amount !== null && (is_int($amount) || ctype_digit($amount))) {
+ $url = $this->url . str_replace(":transactionID", $transactionID, Connect2PayClient::$API_ROUTES['TRANS_REFUND']);
+ $trans = array();
+ $trans['apiVersion'] = $this->apiVersion;
+ $trans['amount'] = intval($amount);
+
+ $result = $this->doPost($url, json_encode($trans));
+
+ $this->status = null;
+ if ($result != null && is_array($result)) {
+ $this->status = new RefundStatus();
+ if (isset($result['code'])) {
+ $this->status->setCode($result['code']);
+ }
+ if (isset($result['message'])) {
+ $this->status->setMessage($result['message']);
+ }
+ if (isset($result['transactionID'])) {
+ $this->status->setTransactionID($result['transactionID']);
+ }
+
+ return $this->status;
+ } else {
+ $this->clientErrorMessage = 'No result received from refund call';
+ }
+ } else {
+ $this->clientErrorMessage = '"transactionID" must not be null, "amount" must be a positive integer';
+ }
+
+ return null;
+ }
+
+ /**
+ * Do a subscription cancellation.
+ *
+ * @param int $subscriptionID
+ * Identifier of the subscription to cancel
+ * @param int $cancelReason
+ * Identifier of the cancelReason (see _SUBSCRIPTION_CANCEL_*
+ * constants)
+ * @return The result code of the operation (200 for success) or null on
+ * failure
+ */
+ public function cancelSubscription($subscriptionID, $cancelReason) {
+ if ($subscriptionID != null && is_numeric($subscriptionID) && isset($cancelReason) && is_numeric($cancelReason)) {
+ $url = $this->url . str_replace(":subscriptionID", $subscriptionID, Connect2PayClient::$API_ROUTES['SUB_CANCEL']);
+ $trans = array();
+ $trans['apiVersion'] = $this->apiVersion;
+ $trans['cancelReason'] = intval($cancelReason);
+
+ $result = $this->doPost($url, json_encode($trans));
+
+ if ($result != null && is_array($result)) {
+ $this->clientErrorMessage = $result['message'];
+ return $result['code'];
+ }
+ } else {
+ $this->clientErrorMessage = 'subscriptionID and cancelReason must be not null and numeric';
+ }
+
+ return null;
+ }
+
+ /**
+ * Handle the callback done by the payment page application after
+ * a transaction processing.
+ * This will populate the status field that can be retrieved by calling
+ * getStatus().
+ *
+ * @return true on succes or false on error
+ */
+ public function handleCallbackStatus() {
+ // Read the body of the request
+ $body = @file_get_contents('php://input');
+
+ if ($body != null && strlen(trim($body)) > 0) {
+ $status = json_decode(trim($body), false);
+
+ if ($status != null && is_object($status)) {
+ $this->initStatus($status);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Handle the data received by the POST done when payment page redirects
+ * the customer to the merchant website.
+ * This will populate the status field that can be retrieved by calling
+ * getStatus().
+ *
+ * @param string $encryptedData
+ * The content of the 'data' field posted
+ * @param string $merchantToken
+ * The merchant token related to this transaction
+ * @return boolean True on success or false on error
+ */
+ public function handleRedirectStatus($encryptedData, $merchantToken) {
+ $key = $this->urlsafe_base64_decode($merchantToken);
+ $binData = $this->urlsafe_base64_decode($encryptedData);
+
+ // Decrypting
+ $json = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $binData, MCRYPT_MODE_ECB);
+
+ if ($json) {
+ // Remove PKCS#5 padding
+ $json = $this->pkcs5_unpad($json);
+ $status = json_decode($json, false);
+
+ if ($status != null && is_object($status)) {
+ $this->initStatus($status);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns the URL to redirect the customer to after a transaction
+ * creation.
+ *
+ * @return string The URL to redirect the customer to.
+ */
+ public function getCustomerRedirectURL() {
+ return $this->url . str_replace(":customerToken", $this->customerToken, Connect2PayClient::$API_ROUTES['TRANS_DOPAY']);
+ }
+
+ /**
+ * Validate the current transaction data.
+ *
+ * @return boolean True if transaction data are valid, false otherwise
+ */
+ public function validate() {
+ $arrErrors = array();
+
+ $arrErrors = $this->validateFields();
+
+ if (sizeof($arrErrors) > 0) {
+ foreach ($arrErrors as $error) {
+ $this->clientErrorMessage .= $error . " * ";
+ }
+ return false;
+ }
+
+ return true;
+ }
+
+ private function doGet($url, $params, $assoc = true) {
+ return $this->doHTTPRequest("GET", $url, $params, $assoc);
+ }
+
+ private function doPost($url, $data, $assoc = true) {
+ return $this->doHTTPRequest("POST", $url, $data, $assoc);
+ }
+
+ private function doHTTPRequest($type, $url, $data, $assoc = true) {
+ $curl = curl_init();
+
+ if ($type === "GET") {
+ // In that case, $data is the array of params to add in the URL
+ if (is_array($data) && count($data) > 0) {
+ $urlParams = array();
+ foreach ($data as $param => $value) {
+ $urlParams[] = urlencode($param) . "=" . urlencode($value);
+ }
+ if (count($urlParams) > 0) {
+ $url .= "?" . implode("&", $urlParams);
+ }
+ }
+ } elseif ($type === "POST") {
+ // In that case, $data is the body of the request
+ curl_setopt($curl, CURLOPT_POST, true);
+ curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
+ curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
+ } else {
+ $this->clientErrorMessage = "Bad HTTP method specified.";
+ return null;
+ }
+
+ curl_setopt($curl, CURLOPT_URL, $url);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
+ curl_setopt($curl, CURLOPT_USERPWD, $this->merchant . ":" . $this->password);
+
+ if ($this->proxy_host != null && $this->proxy_port != null) {
+ curl_setopt($curl, CURLOPT_PROXY, $this->proxy_host);
+ curl_setopt($curl, CURLOPT_PROXYPORT, $this->proxy_port);
+
+ if ($this->proxy_username != null && $this->proxy_password != null) {
+ curl_setopt($curl, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
+ curl_setopt($curl, CURLOPT_PROXYUSERPWD, $this->proxy_username . ":" . $this->proxy_password);
+ }
+ }
+
+ // Extra Curl Options
+ foreach ($this->extraCurlOptions as $name => $value) {
+ curl_setopt($curl, $name, $value);
+ }
+
+ $json = curl_exec($curl);
+ $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
+ curl_close($curl);
+
+ if ($httpCode != 200) {
+ $this->clientErrorMessage = "Received HTTP code " . $httpCode . " from payment page.";
+ } else {
+ if ($json !== false) {
+ $result = json_decode($json, $assoc);
+
+ if ($result != null) {
+ return $result;
+ } else {
+ $this->clientErrorMessage = 'JSON decoding error.';
+ }
+ } else {
+ $this->clientErrorMessage = 'Error requesting ' . $connect2pay;
+ }
+ }
+
+ return null;
+ }
+
+ private function initStatus($status) {
+ if ($status != null && is_object($status)) {
+ // Root element, PaymentStatus
+ $this->status = new PaymentStatus();
+ $reflector = new \ReflectionClass('PayXpert\Connect2Pay\PaymentStatus');
+ $this->copyScalarProperties($reflector->getProperties(), $status, $this->status);
+
+ // Transaction attempts
+ if (isset($status->transactions) && is_array($status->transactions)) {
+ $transactionAttempts = array();
+ foreach ($status->transactions as $transaction) {
+ $transAttempt = new TransactionAttempt();
+
+ $reflector = new \ReflectionClass('PayXpert\Connect2Pay\TransactionAttempt');
+ $this->copyScalarProperties($reflector->getProperties(), $transaction, $transAttempt);
+
+ // Set the shopper
+ if (isset($transaction->shopper) && is_object($transaction->shopper)) {
+ $shopper = new Shopper();
+ $reflector = new \ReflectionClass('PayXpert\Connect2Pay\Shopper');
+ $this->copyScalarProperties($reflector->getProperties(), $transaction->shopper, $shopper);
+ $transAttempt->setShopper($shopper);
+ }
+
+ // Payment Mean Info
+ if (isset($transaction->paymentType) && isset($transaction->paymentMeanInfo) && is_object($transaction->paymentMeanInfo)) {
+ $paymentMeanInfo = null;
+ switch ($transaction->paymentType) {
+ case self::_PAYMENT_TYPE_CREDITCARD:
+ $paymentMeanInfo = $this->extractCreditCardPaymentMeanInfo($transaction->paymentMeanInfo);
+ break;
+ case self::_PAYMENT_TYPE_TODITOCASH:
+ $paymentMeanInfo = $this->extractToditoCashPaymentMeanInfo($transaction->paymentMeanInfo);
+ break;
+ case self::_PAYMENT_TYPE_BANKTRANSFER:
+ $paymentMeanInfo = $this->extractBankTransferPaymentMeanInfo($transaction->paymentMeanInfo);
+ break;
+ }
+
+ if ($paymentMeanInfo !== null) {
+ $transAttempt->setPaymentMeanInfo($paymentMeanInfo);
+ }
+ }
+
+ $transactionAttempts[] = $transAttempt;
+ }
+
+ $this->status->setTransactions($transactionAttempts);
+ }
+ }
+ }
+
+ private function extractCreditCardPaymentMeanInfo($paymentMeanInfo) {
+ $ccInfo = new CreditCardPaymentMeanInfo();
+ $reflector = new \ReflectionClass('PayXpert\Connect2Pay\CreditCardPaymentMeanInfo');
+ $this->copyScalarProperties($reflector->getProperties(), $paymentMeanInfo, $ccInfo);
+
+ return $ccInfo;
+ }
+
+ private function extractToditoCashPaymentMeanInfo($paymentMeanInfo) {
+ $tcInfo = new ToditoCashPaymentMeanInfo();
+ $reflector = new \ReflectionClass('PayXpert\Connect2Pay\ToditoCashPaymentMeanInfo');
+ $this->copyScalarProperties($reflector->getProperties(), $paymentMeanInfo, $tcInfo);
+
+ return $tcInfo;
+ }
+
+ private function extractBankTransferPaymentMeanInfo($paymentMeanInfo) {
+ $btInfo = new BankTransferPaymentMeanInfo();
+ $reflector = new \ReflectionClass('PayXpert\Connect2Pay\BankAccount');
+
+ if (is_object($paymentMeanInfo->sender)) {
+ $sender = new BankAccount();
+ $this->copyScalarProperties($reflector->getProperties(), $paymentMeanInfo->sender, $sender);
+ $btInfo->setSender($sender);
+ }
+
+ if (is_object($paymentMeanInfo->recipient)) {
+ $recipient = new BankAccount();
+ $this->copyScalarProperties($reflector->getProperties(), $paymentMeanInfo->recipient, $recipient);
+ $btInfo->setRecipient($recipient);
+ }
+
+ return $btInfo;
+ }
+
+ private function copyScalarProperties($properties, $src, &$dest) {
+ if ($properties !== null && is_object($src) && is_object($dest)) {
+ foreach ($properties as $property) {
+ if (isset($src->{$property->getName()}) && is_scalar($src->{$property->getName()})) {
+ $dest->{"set" . ucfirst($property->getName())}($src->{$property->getName()});
+ }
+ }
+ }
+ }
+
+ private function urlsafe_base64_decode($string) {
+ return base64_decode(strtr($string, '-_', '+/'));
+ }
+
+ private function pkcs5_unpad($text) {
+ $pad = ord($text{strlen($text) - 1});
+ if ($pad > strlen($text)) {
+ // The initial text was empty
+ return "";
+ }
+
+ if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) {
+ // The length of the padding sequence is incorrect
+ return false;
+ }
+
+ return substr($text, 0, -1 * $pad);
+ }
+
+ public function getApiVersion() {
+ return $this->apiVersion;
+ }
+
+ public function getURL() {
+ return $this->url;
+ }
+
+ public function setURL($url) {
+ $this->url = $url;
+ return ($this);
+ }
+
+ public function getMerchant() {
+ return $this->merchant;
+ }
+
+ public function setMerchant($merchant) {
+ $this->merchant = $merchant;
+ return ($this);
+ }
+
+ public function getPassword() {
+ return $this->password;
+ }
+
+ public function setPassword($password) {
+ $this->password = $password;
+ return ($this);
+ }
+
+ public function getAfClientId() {
+ Utils::deprecation_error('The field afClientId does not exist any more');
+ return null;
+ }
+
+ public function setAfClientId($afClientId) {
+ Utils::deprecation_error('The field afClientId does not exist any more');
+ return ($this);
+ }
+
+ public function getAfPassword() {
+ Utils::deprecation_error('The field afPassword does not exist any more');
+ return null;
+ }
+
+ public function setAfPassword($afPassword) {
+ Utils::deprecation_error('The field afPassword does not exist any more');
+ return ($this);
+ }
+
+ public function getSecure3d() {
+ return $this->secure3d;
+ }
+
+ public function setSecure3d($secure3d) {
+ $this->secure3d = $secure3d;
+ return ($this);
+ }
+
+ public function getShopperID() {
+ return $this->shopperID;
+ }
+
+ public function setShopperID($shopperID) {
+ $this->shopperID = (strlen($shopperID) > 32) ? substr((string) $shopperID, 0, 32) : (string) $shopperID;
+ return ($this);
+ }
+
+ public function getShopperEmail() {
+ return $this->shopperEmail;
+ }
+
+ public function setShopperEmail($shopperEmail) {
+ $this->shopperEmail = (strlen($shopperEmail) > 100) ? substr((string) $shopperEmail, 0, 100) : (string) $shopperEmail;
+ return ($this);
+ }
+
+ public function getShipToFirstName() {
+ return $this->shipToFirstName;
+ }
+
+ public function setShipToFirstName($shipToFirstName) {
+ $this->shipToFirstName = (strlen($shipToFirstName) > 35) ? substr((string) $shipToFirstName, 0, 35) : (string) $shipToFirstName;
+ return ($this);
+ }
+
+ public function getShipToLastName() {
+ return $this->shipToLastName;
+ }
+
+ public function setShipToLastName($shipToLastName) {
+ $this->shipToLastName = (strlen($shipToLastName) > 35) ? substr((string) $shipToLastName, 0, 35) : (string) $shipToLastName;
+ return ($this);
+ }
+
+ public function getShipToCompany() {
+ return $this->shipToCompany;
+ }
+
+ public function setShipToCompany($shipToCompany) {
+ $this->shipToCompany = (strlen($shipToCompany) > 128) ? substr((string) $shipToCompany, 0, 128) : (string) $shipToCompany;
+ return ($this);
+ }
+
+ public function getShipToPhone() {
+ return $this->shipToPhone;
+ }
+
+ public function setShipToPhone($shipToPhone) {
+ $this->shipToPhone = (strlen($shipToPhone) > 20) ? substr((string) $shipToPhone, 0, 20) : (string) $shipToPhone;
+ return ($this);
+ }
+
+ public function getShipToAddress() {
+ return $this->shipToAddress;
+ }
+
+ public function setShipToAddress($shipToAddress) {
+ $this->shipToAddress = (strlen($shipToAddress) > 255) ? substr((string) $shipToAddress, 0, 255) : (string) $shipToAddress;
+ return ($this);
+ }
+
+ public function getShipToState() {
+ return $this->shipToState;
+ }
+
+ public function setShipToState($shipToState) {
+ $this->shipToState = (strlen($shipToState) > 30) ? substr((string) $shipToState, 0, 30) : (string) $shipToState;
+ return ($this);
+ }
+
+ public function getShipToZipcode() {
+ return $this->shipToZipcode;
+ }
+
+ public function setShipToZipcode($shipToZipcode) {
+ $this->shipToZipcode = (strlen($shipToZipcode) > 10) ? substr((string) $shipToZipcode, 0, 10) : (string) $shipToZipcode;
+ return ($this);
+ }
+
+ public function getShipToCity() {
+ return $this->shipToCity;
+ }
+
+ public function setShipToCity($shipToCity) {
+ $this->shipToCity = (strlen($shipToCity) > 50) ? substr((string) $shipToCity, 0, 50) : (string) $shipToCity;
+ return ($this);
+ }
+
+ public function getShipToCountryCode() {
+ return $this->shipToCountryCode;
+ }
+
+ public function setShipToCountryCode($shipToCountryCode) {
+ $this->shipToCountryCode = (strlen($shipToCountryCode) > 2) ? substr((string) $shipToCountryCode, 0, 2) : (string) $shipToCountryCode;
+ return ($this);
+ }
+
+ public function getShopperFirstName() {
+ return $this->shopperFirstName;
+ }
+
+ public function setShopperFirstName($shopperFirstName) {
+ $this->shopperFirstName = (strlen($shopperFirstName) > 35) ? substr((string) $shopperFirstName, 0, 35) : (string) $shopperFirstName;
+ return ($this);
+ }
+
+ public function getShopperLastName() {
+ return (!C2PValidate::isEmpty($this->shopperLastName)) ? $this->shopperLastName : Connect2PayClient::_UNAVAILABLE;
+ }
+
+ public function setShopperLastName($shopperLastName) {
+ $this->shopperLastName = (strlen($shopperLastName) > 35) ? substr((string) $shopperLastName, 0, 35) : (string) $shopperLastName;
+ return ($this);
+ }
+
+ public function getShopperPhone() {
+ return (!C2PValidate::isEmpty($this->shopperPhone)) ? $this->shopperPhone : Connect2PayClient::_UNAVAILABLE;
+ }
+
+ public function setShopperPhone($shopperPhone) {
+ $this->shopperPhone = (strlen($shopperPhone) > 20) ? substr((string) $shopperPhone, 0, 20) : (string) $shopperPhone;
+ return ($this);
+ }
+
+ public function getShopperAddress() {
+ return (!C2PValidate::isEmpty($this->shopperAddress)) ? $this->shopperAddress : Connect2PayClient::_UNAVAILABLE;
+ }
+
+ public function setShopperAddress($shopperAddress) {
+ $this->shopperAddress = (strlen($shopperAddress) > 255) ? substr((string) $shopperAddress, 0, 255) : (string) $shopperAddress;
+ return ($this);
+ }
+
+ public function getShopperState() {
+ return (!C2PValidate::isEmpty($this->shopperState)) ? $this->shopperState : Connect2PayClient::_UNAVAILABLE;
+ }
+
+ public function setShopperState($shopperState) {
+ $this->shopperState = (strlen($shopperState) > 30) ? substr((string) $shopperState, 0, 30) : (string) $shopperState;
+ return ($this);
+ }
+
+ public function getShopperZipcode() {
+ return (!C2PValidate::isEmpty($this->shopperZipcode)) ? $this->shopperZipcode : Connect2PayClient::_UNAVAILABLE;
+ }
+
+ public function setShopperZipcode($shopperZipcode) {
+ $this->shopperZipcode = (strlen($shopperZipcode) > 10) ? substr((string) $shopperZipcode, 0, 10) : (string) $shopperZipcode;
+ return ($this);
+ }
+
+ public function getShopperCity() {
+ return (!C2PValidate::isEmpty($this->shopperCity)) ? $this->shopperCity : Connect2PayClient::_UNAVAILABLE;
+ }
+
+ public function setShopperCity($shopperCity) {
+ $this->shopperCity = (strlen($shopperCity) > 50) ? substr((string) $shopperCity, 0, 50) : (string) $shopperCity;
+ return ($this);
+ }
+
+ public function getShopperCountryCode() {
+ return (!C2PValidate::isEmpty($this->shopperCountryCode)) ? $this->shopperCountryCode : Connect2PayClient::_UNAVAILABLE_COUNTRY;
+ }
+
+ public function setShopperCountryCode($shopperCountryCode) {
+ $this->shopperCountryCode = (strlen($shopperCountryCode) > 2) ? substr((string) $shopperCountryCode, 0, 2) : (string) $shopperCountryCode;
+ return ($this);
+ }
+
+ public function getShopperBirthDate() {
+ return $this->shopperBirthDate;
+ }
+
+ public function setShopperBirthDate($shopperBirthDate) {
+ $this->shopperBirthDate = (strlen($shopperBirthDate) > 8) ? substr((string) $shopperBirthDate, 0, 8) : (string) $shopperBirthDate;
+ return ($this);
+ }
+
+ public function getShopperIDNumber() {
+ return $this->shopperIDNumber;
+ }
+
+ public function setShopperIDNumber($shopperIDNumber) {
+ $this->shopperIDNumber = (strlen($shopperIDNumber) > 32) ? substr((string) $shopperIDNumber, 0, 32) : (string) $shopperIDNumber;
+ return ($this);
+ }
+
+ public function getShopperCompany() {
+ return $this->shopperCompany;
+ }
+
+ public function setShopperCompany($shopperCompany) {
+ $this->shopperCompany = (strlen($shopperCompany) > 128) ? substr((string) $shopperCompany, 0, 128) : (string) $shopperCompany;
+ return ($this);
+ }
+
+ public function getShopperLoyaltyProgram() {
+ return $this->shopperLoyaltyProgram;
+ }
+
+ public function setShopperLoyaltyProgram($shopperLoyaltyProgram) {
+ $this->shopperLoyaltyProgram = (string) $shopperLoyaltyProgram;
+ return ($this);
+ }
+
+ public function getOrderID() {
+ return $this->orderID;
+ }
+
+ public function setOrderID($orderID) {
+ $this->orderID = (string) $orderID;
+ return ($this);
+ }
+
+ public function getOrderDescription() {
+ return $this->orderDescription;
+ }
+
+ public function setOrderDescription($orderDescription) {
+ $this->orderDescription = (strlen($orderDescription) > 500) ? substr((string) $orderDescription, 0, 500) : (string) $orderDescription;
+ return ($this);
+ }
+
+ public function getCurrency() {
+ return $this->currency;
+ }
+
+ public function setCurrency($currency) {
+ $this->currency = (string) $currency;
+ return ($this);
+ }
+
+ public function getAmount() {
+ return $this->amount;
+ }
+
+ public function setAmount($amount) {
+ $this->amount = (int) $amount;
+ return ($this);
+ }
+
+ public function getOrderTotalWithoutShipping() {
+ return $this->orderTotalWithoutShipping;
+ }
+
+ public function setOrderTotalWithoutShipping($orderTotalWithoutShipping) {
+ $this->orderTotalWithoutShipping = (int) $orderTotalWithoutShipping;
+ return ($this);
+ }
+
+ public function getOrderShippingPrice() {
+ return $this->orderShippingPrice;
+ }
+
+ public function setOrderShippingPrice($orderShippingPrice) {
+ $this->orderShippingPrice = (int) $orderShippingPrice;
+ return ($this);
+ }
+
+ public function getOrderDiscount() {
+ return $this->orderDiscount;
+ }
+
+ public function setOrderDiscount($orderDiscount) {
+ $this->orderDiscount = (int) $orderDiscount;
+ return ($this);
+ }
+
+ /**
+ *
+ * @deprecated This field is not present anymore in the API, the value is
+ * obtained from the connected user
+ */
+ public function getCustomerIP() {
+ return null;
+ }
+
+ /**
+ *
+ * @deprecated This field is not present anymore in the API, the value is
+ * obtained from the connected user
+ */
+ public function setCustomerIP($customerIP) {
+ return ($this);
+ }
+
+ public function getOrderFOLanguage() {
+ return $this->orderFOLanguage;
+ }
+
+ public function setOrderFOLanguage($orderFOLanguage) {
+ $this->orderFOLanguage = (string) $orderFOLanguage;
+ return ($this);
+ }
+
+ public function getOrderCartContent() {
+ return $this->orderCartContent;
+ }
+
+ public function setOrderCartContent($orderCartContent) {
+ $this->orderCartContent = $orderCartContent;
+ return ($this);
+ }
+
+ /**
+ * Add a CartProduct in the orderCartContent.
+ *
+ * @param CartProduct $cartProduct
+ * The product to add to the cart
+ * @return Connect2PayClient
+ */
+ public function addCartProduct($cartProduct) {
+ if ($this->orderCartContent == null || !is_array($this->orderCartContent)) {
+ $this->orderCartContent = array();
+ }
+
+ if ($cartProduct instanceof CartProduct) {
+ $this->orderCartContent[] = $cartProduct;
+ }
+
+ return $this;
+ }
+
+ public function getShippingType() {
+ return $this->shippingType;
+ }
+
+ public function setShippingType($shippingType) {
+ $this->shippingType = (string) $shippingType;
+ return ($this);
+ }
+
+ public function getShippingName() {
+ return $this->shippingName;
+ }
+
+ public function setShippingName($shippingName) {
+ $this->shippingName = (string) $shippingName;
+ return ($this);
+ }
+
+ public function getPaymentType() {
+ return (!C2PValidate::isEmpty($this->paymentType)) ? $this->paymentType : Connect2PayClient::_PAYMENT_TYPE_CREDITCARD;
+ }
+
+ public function setPaymentType($paymentType) {
+ $this->paymentType = (string) $paymentType;
+ return ($this);
+ }
+
+ public function getProvider() {
+ return $this->provider;
+ }
+
+ public function setProvider($provider) {
+ $this->provider = $provider;
+ return $this;
+ }
+
+ public function getOperation() {
+ return $this->operation;
+ }
+
+ public function setOperation($operation) {
+ $this->operation = (string) $operation;
+ return ($this);
+ }
+
+ public function getPaymentMode() {
+ return $this->paymentMode;
+ }
+
+ public function setPaymentMode($paymentMode) {
+ $this->paymentMode = (string) $paymentMode;
+ return ($this);
+ }
+
+ public function getOfferID() {
+ return $this->offerID;
+ }
+
+ public function setOfferID($offerID) {
+ $this->offerID = (int) $offerID;
+ return ($this);
+ }
+
+ public function getSubscriptionType() {
+ return $this->subscriptionType;
+ }
+
+ public function setSubscriptionType($subscriptionType) {
+ $this->subscriptionType = $subscriptionType;
+ return ($this);
+ }
+
+ public function getTrialPeriod() {
+ return $this->trialPeriod;
+ }
+
+ public function setTrialPeriod($trialPeriod) {
+ $this->trialPeriod = $trialPeriod;
+ return ($this);
+ }
+
+ public function getRebillAmount() {
+ return $this->rebillAmount;
+ }
+
+ public function setRebillAmount($rebillAmount) {
+ $this->rebillAmount = (int) $rebillAmount;
+ return ($this);
+ }
+
+ public function getRebillPeriod() {
+ return $this->rebillPeriod;
+ }
+
+ public function setRebillPeriod($rebillPeriod) {
+ $this->rebillPeriod = $rebillPeriod;
+ return ($this);
+ }
+
+ public function getRebillMaxIteration() {
+ return $this->rebillMaxIteration;
+ }
+
+ public function setRebillMaxIteration($rebillMaxIteration) {
+ $this->rebillMaxIteration = (int) $rebillMaxIteration;
+ return ($this);
+ }
+
+ public function getCtrlRedirectURL() {
+ return $this->ctrlRedirectURL;
+ }
+
+ public function setCtrlRedirectURL($ctrlRedirectURL) {
+ $this->ctrlRedirectURL = (string) $ctrlRedirectURL;
+ return ($this);
+ }
+
+ public function getCtrlCallbackURL() {
+ return $this->ctrlCallbackURL;
+ }
+
+ public function setCtrlCallbackURL($ctrlCallbackURL) {
+ $this->ctrlCallbackURL = (string) $ctrlCallbackURL;
+ return ($this);
+ }
+
+ public function getCtrlCustomData() {
+ return $this->ctrlCustomData;
+ }
+
+ public function setCtrlCustomData($ctrlCustomData) {
+ $this->ctrlCustomData = (string) $ctrlCustomData;
+ return ($this);
+ }
+
+ public function getTimeOut() {
+ return $this->timeOut;
+ }
+
+ public function setTimeOut($timeOut) {
+ $this->timeOut = (string) $timeOut;
+ return ($this);
+ }
+
+ public function getMerchantNotification() {
+ return $this->merchantNotification;
+ }
+
+ public function setMerchantNotification($merchantNotification) {
+ $this->merchantNotification = $merchantNotification;
+ return ($this);
+ }
+
+ public function getMerchantNotificationTo() {
+ return $this->merchantNotificationTo;
+ }
+
+ public function setMerchantNotificationTo($merchantNotificationTo) {
+ $this->merchantNotificationTo = $merchantNotificationTo;
+ return ($this);
+ }
+
+ public function getMerchantNotificationLang() {
+ return $this->merchantNotificationLang;
+ }
+
+ public function setMerchantNotificationLang($merchantNotificationLang) {
+ $this->merchantNotificationLang = $merchantNotificationLang;
+ return ($this);
+ }
+
+ public function getThemeID() {
+ return $this->themeID;
+ }
+
+ public function setThemeID($themeID) {
+ $this->themeID = (int) $themeID;
+ return ($this);
+ }
+
+ public function getReturnCode() {
+ return $this->returnCode;
+ }
+
+ public function getReturnMessage() {
+ return $this->returnMessage;
+ }
+
+ public function getMerchantToken() {
+ return $this->merchantToken;
+ }
+
+ public function getCustomerToken() {
+ return $this->customerToken;
+ }
+
+ public function getStatus() {
+ return $this->status;
+ }
+
+ public function getClientErrorMessage() {
+ return $this->clientErrorMessage;
+ }
+
+ public function getCurrencyHelper() {
+ if ($this->currencyHelper == null) {
+ $this->currencyHelper = new Connect2PayCurrencyHelper();
+
+ $this->currencyHelper->useProxy($this->proxy_host, $this->proxy_port, $this->proxy_password, $this->proxy_username);
+ }
+
+ return $this->currencyHelper;
+ }
+
+ /**
+ * Set a default cart content, to be used when anti fraud system is enabled
+ * and no real cart is known
+ */
+ public function setDefaultOrderCartContent() {
+ $this->orderCartContent = array();
+ $product = new CartProduct();
+ $product->setCartProductId(0)->setCartProductName("NA");
+ $product->setCartProductUnitPrice(0)->setCartProductQuantity(1);
+ $product->setCartProductBrand("NA")->setCartProductMPN("NA");
+ $product->setCartProductCategoryName("NA")->setCartProductCategoryID(0);
+
+ $this->orderCartContent[] = $product;
+ }
+
+ /**
+ * Check for fields validity
+ *
+ * @return array empty if everything is OK or as many elements as errors
+ * matched
+ */
+ private function validateFields() {
+ $fieldsRequired = $this->fieldsRequired;
+ $returnError = array();
+
+ foreach ($fieldsRequired as $field) {
+ if (C2PValidate::isEmpty($this->{$field}) && (!is_numeric($this->{$field})))
+ $returnError[] = $field . ' is empty';
+ }
+
+ foreach ($this->fieldsSize as $field => $size) {
+ if (isset($this->{$field}) && C2PValidate::strlen($this->{$field}) > $size)
+ $returnError[] = $field . ' Length ' . $size;
+ }
+
+ foreach ($this->fieldsValidate as $field => $method) {
+ if (!C2PValidate::isEmpty($this->{$field}) && !call_user_func(array('PayXpert\Connect2Pay\C2PValidate', $method), $this->{$field}))
+ $returnError[] = $field . ' = ' . $this->{$field};
+ }
+
+ return $returnError;
+ }
+}
+
+/**
+ * Represent the status of a payment returned by the payment page
+ */
+class PaymentStatus {
+ /**
+ * Status of the payment: "Authorized", "Not authorized", "Expired", "Call
+ * failed", "Pending" or "Not processed"
+ *
+ * @var String
+ */
+ private $status;
+
+ /**
+ * The merchant token of this payment
+ *
+ * @var String
+ */
+ private $merchantToken;
+
+ /**
+ * Type of operation for the last transaction done for this payment: Can be
+ * sale or authorize.
+ *
+ * @var String
+ */
+ private $operation;
+
+ /**
+ * Result code of the last transaction done for this payment
+ *
+ * @var Int
+ */
+ private $errorCode;
+
+ /**
+ * Error message of the last transaction done for this payment
+ *
+ * @var String
+ */
+ private $errorMessage;
+
+ /**
+ * The order ID of the payment
+ *
+ * @var String
+ */
+ private $orderID;
+
+ /**
+ * Currency for the payment
+ *
+ * @var String
+ */
+ private $currency;
+
+ /**
+ * Amount of the payment in cents (1.00€ => 100)
+ *
+ * @var Int
+ */
+ private $amount;
+
+ /**
+ * Custom data provided by merchant at payment creation.
+ *
+ * @var String
+ */
+ private $ctrlCustomData;
+
+ /**
+ * The list of transactions done to complete this payment
+ *
+ * @var array
+ */
+ private $transactions;
+
+ public function getStatus() {
+ return $this->status;
+ }
+
+ public function setStatus($status) {
+ $this->status = $status;
+ return $this;
+ }
+
+ public function getMerchantToken() {
+ return $this->merchantToken;
+ }
+
+ public function setMerchantToken($merchantToken) {
+ $this->merchantToken = $merchantToken;
+ return $this;
+ }
+
+ public function getOperation() {
+ return $this->operation;
+ }
+
+ public function setOperation($operation) {
+ $this->operation = $operation;
+ return $this;
+ }
+
+ public function getErrorCode() {
+ return $this->errorCode;
+ }
+
+ public function setErrorCode($errorCode) {
+ $this->errorCode = $errorCode;
+ return $this;
+ }
+
+ public function getErrorMessage() {
+ return $this->errorMessage;
+ }
+
+ public function setErrorMessage($errorMessage) {
+ $this->errorMessage = $errorMessage;
+ return $this;
+ }
+
+ public function getOrderID() {
+ return $this->orderID;
+ }
+
+ public function setOrderID($orderID) {
+ $this->orderID = $orderID;
+ return $this;
+ }
+
+ public function getCurrency() {
+ return $this->currency;
+ }
+
+ public function setCurrency($currency) {
+ $this->currency = $currency;
+ return $this;
+ }
+
+ public function getAmount() {
+ return $this->amount;
+ }
+
+ public function setAmount($amount) {
+ $this->amount = $amount;
+ return $this;
+ }
+
+ public function getCtrlCustomData() {
+ return $this->ctrlCustomData;
+ }
+
+ public function setCtrlCustomData($ctrlCustomData) {
+ $this->ctrlCustomData = $ctrlCustomData;
+ return $this;
+ }
+
+ public function getTransactions() {
+ return $this->transactions;
+ }
+
+ public function setTransactions($transactions) {
+ $this->transactions = $transactions;
+ return $this;
+ }
+
+ /**
+ * Return the last transaction attempt done for this payment
+ *
+ * @return TransactionAttempt The last transaction attempt done for this
+ * payment
+ */
+ public function getLastTransactionAttempt() {
+ $lastAttempt = null;
+
+ if (isset($this->transactions) && is_array($this->transactions) && count($this->transactions) > 0) {
+ // Return the entry with the highest timestamp with type sale or authorize
+ foreach ($this->transactions as $transaction) {
+ if (in_array($transaction->getOperation(), array("sale", "authorize"))) {
+ if ($lastAttempt == null || $lastAttempt->getDate() < $transaction->getDate()) {
+ $lastAttempt = $transaction;
+ }
+ }
+ }
+ }
+
+ return $lastAttempt;
+ }
+}
+
+class TransactionAttempt {
+ /**
+ * Type of payment for this transaction attempt: CreditCard, BankTransfer or
+ * ToditoCash
+ *
+ * @var String
+ */
+ private $paymentType;
+
+ /**
+ * Type of operation for that transaction: Can be sale or authorize.
+ *
+ * @var String
+ */
+ private $operation;
+
+ /**
+ * Date of the transaction
+ *
+ * @var timestamp
+ */
+ private $date;
+
+ /**
+ * Amount of the transaction
+ *
+ * @var integer
+ */
+ private $amount;
+
+ /**
+ * The result code for this transaction
+ *
+ * @var String
+ */
+ private $resultCode;
+
+ /**
+ * The result message for this transaction
+ *
+ * @var String
+ */
+ private $resultMessage;
+
+ /**
+ * Status of the transaction: "Authorized", "Not authorized", "Expired", "Call
+ * failed", "Pending" or "Not processed"
+ *
+ * @var String
+ */
+ private $status;
+
+ /**
+ * Shopper information for this transaction
+ *
+ * @var Shopper
+ */
+ private $shopper;
+
+ /**
+ * Transaction identifier of this transaction.
+ *
+ * @var String
+ */
+ private $transactionID;
+
+ /**
+ * Identifier of the subscription this transaction is part of (if any).
+ *
+ * @var Int
+ */
+ private $subscriptionID;
+
+ /**
+ * Details of the payment mean used to process the transaction
+ *
+ * @var Depends on the paymentType
+ */
+ private $paymentMeanInfo;
+
+ public function getPaymentType() {
+ return $this->paymentType;
+ }
+
+ public function setPaymentType($paymentType) {
+ $this->paymentType = $paymentType;
+ return $this;
+ }
+
+ public function getOperation() {
+ return $this->operation;
+ }
+
+ public function setOperation($operation) {
+ $this->operation = $operation;
+ return $this;
+ }
+
+ public function getDate() {
+ return $this->date;
+ }
+
+ public function getDateAsDateTime() {
+ if ($this->date != null) {
+ // API returns date as timestamp in milliseconds
+ $timestamp = intval($this->date / 1000);
+ return new \DateTime("@" . $timestamp);
+ }
+
+ return null;
+ }
+
+ public function setDate($date) {
+ $this->date = $date;
+ return $this;
+ }
+
+ public function getAmount() {
+ return $this->amount;
+ }
+
+ public function setAmount($amount) {
+ $this->amount = $amount;
+ return $this;
+ }
+
+ public function getResultCode() {
+ return $this->resultCode;
+ }
+
+ public function setResultCode($resultCode) {
+ $this->resultCode = $resultCode;
+ return $this;
+ }
+
+ public function getResultMessage() {
+ return $this->resultMessage;
+ }
+
+ public function setResultMessage($resultMessage) {
+ $this->resultMessage = $resultMessage;
+ return $this;
+ }
+
+ public function getStatus() {
+ return $this->status;
+ }
+
+ public function setStatus($status) {
+ $this->status = $status;
+ return $this;
+ }
+
+ public function getShopper() {
+ return $this->shopper;
+ }
+
+ public function setShopper($shopper) {
+ $this->shopper = $shopper;
+ return $this;
+ }
+
+ public function getTransactionID() {
+ return $this->transactionID;
+ }
+
+ public function setTransactionID($transactionID) {
+ $this->transactionID = $transactionID;
+ return $this;
+ }
+
+ public function getSubscriptionID() {
+ return $this->subscriptionID;
+ }
+
+ public function setSubscriptionID($subscriptionID) {
+ $this->subscriptionID = $subscriptionID;
+ return $this;
+ }
+
+ public function getPaymentMeanInfo() {
+ return $this->paymentMeanInfo;
+ }
+
+ public function setPaymentMeanInfo($paymentMeanInfo) {
+ $this->paymentMeanInfo = $paymentMeanInfo;
+ return $this;
+ }
+}
+
+class Shopper {
+ /**
+ * Name provided by the shopper
+ *
+ * @var String
+ */
+ private $name;
+
+ /**
+ * Address provided by the shopper
+ *
+ * @var String
+ */
+ private $address;
+
+ /**
+ * Zipcode provided by the shopper.
+ *
+ * @var String
+ */
+ private $zipcode;
+
+ /**
+ * City provided by the shopper.
+ *
+ * @var String
+ */
+ private $city;
+
+ /**
+ * State provided by the shopper
+ *
+ * @var String
+ */
+ private $state;
+
+ /**
+ * Country provided by the shopper.
+ *
+ * @var String
+ */
+ private $countryCode;
+
+ /**
+ * Phone provided by the shopper
+ *
+ * @var String
+ */
+ private $phone;
+
+ /**
+ * Email address provided by the shopper.
+ *
+ * @var String
+ */
+ private $email;
+
+ /**
+ * Birth date provided by the shopper (YYYYMMDD)
+ *
+ * @var string
+ */
+ private $birthDate;
+
+ /**
+ * ID number provided by the shopper (identity card, passport...)
+ *
+ * @var string
+ */
+ private $idNumber;
+
+ /**
+ * IP address of the shopper
+ *
+ * @var String
+ */
+ private $ipAddress;
+
+ public function getname() {
+ return $this->name;
+ }
+
+ public function setName($name) {
+ $this->name = $name;
+ return $this;
+ }
+
+ public function getAddress() {
+ return $this->address;
+ }
+
+ public function setAddress($address) {
+ $this->address = $address;
+ return $this;
+ }
+
+ public function getZipcode() {
+ return $this->zipcode;
+ }
+
+ public function setZipcode($zipcode) {
+ $this->zipcode = $zipcode;
+ return $this;
+ }
+
+ public function getCity() {
+ return $this->city;
+ }
+
+ public function setCity($city) {
+ $this->city = $city;
+ return $this;
+ }
+
+ public function getState() {
+ return $this->state;
+ }
+
+ public function setState($state) {
+ $this->state = $state;
+ return $this;
+ }
+
+ public function getCountryCode() {
+ return $this->countryCode;
+ }
+
+ public function setCountryCode($countryCode) {
+ $this->countryCode = $countryCode;
+ return $this;
+ }
+
+ public function getPhone() {
+ return $this->phone;
+ }
+
+ public function setPhone($phone) {
+ $this->phone = $phone;
+ return $this;
+ }
+
+ public function getEmail() {
+ return $this->email;
+ }
+
+ public function setEmail($email) {
+ $this->email = $email;
+ return $this;
+ }
+
+ public function getBirthDate() {
+ return $this->birthDate;
+ }
+
+ public function setBirthDate($birthDate) {
+ $this->birthDate = $birthDate;
+ return $this;
+ }
+
+ public function getIdNumber() {
+ return $this->idNumber;
+ }
+
+ public function setIdNumber($idNumber) {
+ $this->idNumber = $idNumber;
+ return $this;
+ }
+
+ public function getIpAddress() {
+ return $this->ipAddress;
+ }
+
+ public function setIpAddress($ipAddress) {
+ $this->ipAddress = $ipAddress;
+ return $this;
+ }
+}
+
+class CreditCardPaymentMeanInfo {
+ /**
+ * The truncated card number used for this transaction
+ *
+ * @var string
+ */
+ private $cardNumber;
+
+ /**
+ * The card expiration year
+ *
+ * @var string
+ */
+ private $cardExpireYear;
+
+ /**
+ * The card expire month
+ *
+ * @var string
+ */
+ private $cardExpireMonth;
+
+ /**
+ * The name of the holder of the card
+ *
+ * @var string
+ */
+ private $cardHolderName;
+
+ /**
+ * Brand of the card (Visa, Mcrd...)
+ *
+ * @var string
+ */
+ private $cardBrand;
+
+ /**
+ * Level of the card.
+ * Special permission needed
+ *
+ * @var string
+ */
+ private $cardLevel;
+
+ /**
+ * Sub type of the card.
+ * Special permission needed.
+ *
+ * @var string
+ */
+ private $cardSubType;
+
+ /**
+ * ISO2 country code of the issuer of the card.
+ * Special permission needed.
+ *
+ * @var string
+ */
+ private $iinCountry;
+
+ /**
+ * Card Issuer Bank Name.
+ * Special permission needed.
+ *
+ * @var string
+ */
+ private $iinBankName;
+
+ /**
+ * The liability shift for 3D Secure.
+ * Can be true or false
+ *
+ * @var boolean
+ */
+ private $is3DSecure;
+
+ /**
+ * Credit Card Descriptor for this transaction
+ *
+ * @var String
+ */
+ private $statementDescriptor;
+
+ public function getCardNumber() {
+ return $this->cardNumber;
+ }
+
+ public function setCardNumber($cardNumber) {
+ $this->cardNumber = $cardNumber;
+ return $this;
+ }
+
+ public function getCardExpireYear() {
+ return $this->cardExpireYear;
+ }
+
+ public function setCardExpireYear($cardExpireYear) {
+ $this->cardExpireYear = $cardExpireYear;
+ return $this;
+ }
+
+ public function getCardExpireMonth() {
+ return $this->cardExpireMonth;
+ }
+
+ public function setCardExpireMonth($cardExpireMonth) {
+ $this->cardExpireMonth = $cardExpireMonth;
+ return $this;
+ }
+
+ public function getCardHolderName() {
+ return $this->cardHolderName;
+ }
+
+ public function setCardHolderName($cardHolderName) {
+ $this->cardHolderName = $cardHolderName;
+ return $this;
+ }
+
+ public function getCardBrand() {
+ return $this->cardBrand;
+ }
+
+ public function setCardBrand($cardBrand) {
+ $this->cardBrand = $cardBrand;
+ return $this;
+ }
+
+ public function getCardLevel() {
+ return $this->cardLevel;
+ }
+
+ public function setCardLevel($cardLevel) {
+ $this->cardLevel = $cardLevel;
+ return $this;
+ }
+
+ public function getCardSubType() {
+ return $this->cardSubType;
+ }
+
+ public function setCardSubType($cardSubType) {
+ $this->cardSubType = $cardSubType;
+ return $this;
+ }
+
+ public function getIinCountry() {
+ return $this->iinCountry;
+ }
+
+ public function setIinCountry($iinCountry) {
+ $this->iinCountry = $iinCountry;
+ return $this;
+ }
+
+ public function getIinBankName() {
+ return $this->iinBankName;
+ }
+
+ public function setIinBankName($iinBankName) {
+ $this->iinBankName = $iinBankName;
+ return $this;
+ }
+
+ public function getIs3DSecure() {
+ return $this->is3DSecure;
+ }
+
+ public function setIs3DSecure($is3DSecure) {
+ $this->is3DSecure = $is3DSecure;
+ return $this;
+ }
+
+ public function getStatementDescriptor() {
+ return $this->statementDescriptor;
+ }
+
+ public function setStatementDescriptor($statementDescriptor) {
+ $this->statementDescriptor = $statementDescriptor;
+ return $this;
+ }
+}
+
+class ToditoCashPaymentMeanInfo {
+ /**
+ * The truncated Todito card number used for this transaction
+ *
+ * @var string
+ */
+ private $cardNumber;
+
+ public function getCardNumber() {
+ return $this->cardNumber;
+ }
+
+ public function setCardNumber($cardNumber) {
+ $this->cardNumber = $cardNumber;
+ return $this;
+ }
+}
+
+class BankTransferPaymentMeanInfo {
+ /**
+ * Sender account
+ *
+ * @var BankAccount
+ */
+ private $sender;
+
+ /**
+ * Recipient account
+ *
+ * @var BankAccount
+ */
+ private $recipient;
+
+ public function getSender() {
+ return $this->sender;
+ }
+
+ public function setSender($sender) {
+ $this->sender = $sender;
+ return $this;
+ }
+
+ public function getRecipient() {
+ return $this->recipient;
+ }
+
+ public function setRecipient($recipient) {
+ $this->recipient = $recipient;
+ return $this;
+ }
+}
+
+class BankAccount {
+ /**
+ * The account holder name
+ *
+ * @var string
+ */
+ private $holderName;
+
+ /**
+ * Name of the bank of the account
+ *
+ * @var string
+ */
+ private $bankName;
+
+ /**
+ * IBAN number of the account (truncated)
+ *
+ * @var string
+ */
+ private $iban;
+
+ /**
+ * BIC number of the account
+ *
+ * @var string
+ */
+ private $bic;
+
+ /**
+ * ISO2 country code of the account
+ *
+ * @var string
+ */
+ private $countryCode;
+
+ public function getHolderName() {
+ return $this->holderName;
+ }
+
+ public function setHolderName($holderName) {
+ $this->holderName = $holderName;
+ return $this;
+ }
+
+ public function getBankName() {
+ return $this->bankName;
+ }
+
+ public function setBankName($bankName) {
+ $this->bankName = $bankName;
+ return $this;
+ }
+
+ public function getIban() {
+ return $this->iban;
+ }
+
+ public function setIban($iban) {
+ $this->iban = $iban;
+ return $this;
+ }
+
+ public function getBic() {
+ return $this->bic;
+ }
+
+ public function setBic($bic) {
+ $this->bic = $bic;
+ return $this;
+ }
+
+ public function getCountryCode() {
+ return $this->countryCode;
+ }
+
+ public function setCountryCode($countryCode) {
+ $this->countryCode = $countryCode;
+ return $this;
+ }
+}
+
+class RefundStatus {
+ /**
+ * Result code of the refund call
+ *
+ * @var Int
+ */
+ private $code;
+
+ /**
+ * Error message of the refund call
+ *
+ * @var String
+ */
+ private $message;
+
+ /**
+ * Transaction identifier of refund transaction.
+ *
+ * @var String
+ */
+ private $transactionID;
+
+ public function getCode() {
+ return $this->code;
+ }
+
+ public function setCode($code) {
+ $this->code = $code;
+ return $this;
+ }
+
+ public function getMessage() {
+ return $this->message;
+ }
+
+ public function setMessage($message) {
+ $this->message = $message;
+ return $this;
+ }
+
+ public function getTransactionID() {
+ return $this->transactionID;
+ }
+
+ public function setTransactionID($transactionID) {
+ $this->transactionID = $transactionID;
+ return $this;
+ }
+}
+
+class CartProduct {
+ // Fields are public otherwise json_encode can't see them...
+ public $cartProductId;
+ public $cartProductName;
+ public $cartProductUnitPrice;
+ public $cartProductQuantity;
+ public $cartProductBrand;
+ public $cartProductMPN;
+ public $cartProductCategoryName;
+ public $cartProductCategoryID;
+
+ public function getCartProductId() {
+ return $this->cartProductId;
+ }
+
+ public function setCartProductId($cartProductId) {
+ $this->cartProductId = $cartProductId;
+ return $this;
+ }
+
+ public function getCartProductName() {
+ return $this->cartProductName;
+ }
+
+ public function setCartProductName($cartProductName) {
+ $this->cartProductName = $cartProductName;
+ return $this;
+ }
+
+ public function getCartProductUnitPrice() {
+ return $this->cartProductUnitPrice;
+ }
+
+ public function setCartProductUnitPrice($cartProductUnitPrice) {
+ $this->cartProductUnitPrice = $cartProductUnitPrice;
+ return $this;
+ }
+
+ public function getCartProductQuantity() {
+ return $this->cartProductQuantity;
+ }
+
+ public function setCartProductQuantity($cartProductQuantity) {
+ $this->cartProductQuantity = $cartProductQuantity;
+ return $this;
+ }
+
+ public function getCartProductBrand() {
+ return $this->cartProductBrand;
+ }
+
+ public function setCartProductBrand($cartProductBrand) {
+ $this->cartProductBrand = $cartProductBrand;
+ return $this;
+ }
+
+ public function getCartProductMPN() {
+ return $this->cartProductMPN;
+ }
+
+ public function setCartProductMPN($cartProductMPN) {
+ $this->cartProductMPN = $cartProductMPN;
+ return $this;
+ }
+
+ public function getCartProductCategoryName() {
+ return $this->cartProductCategoryName;
+ }
+
+ public function setCartProductCategoryName($cartProductCategoryName) {
+ $this->cartProductCategoryName = $cartProductCategoryName;
+ return $this;
+ }
+
+ public function getCartProductCategoryID() {
+ return $this->cartProductCategoryID;
+ }
+
+ public function setCartProductCategoryID($cartProductCategoryID) {
+ $this->cartProductCategoryID = $cartProductCategoryID;
+ return $this;
+ }
+}
+
+/**
+ * Helper to manipulate amount in different currencies.
+ * Permits to convert amount between different currencies
+ * and get rates in real time from Yahoo Web service.
+ */
+class Connect2PayCurrencyHelper {
+ // The base address to fetch currency rates
+ private static $YAHOO_SERVICE_URL = 'http://download.finance.yahoo.com/d/quotes.csv';
+
+ // Optional proxy to use for outgoing request
+ private static $proxy_host = null;
+ private static $proxy_port = null;
+ private static $proxy_username = null;
+ private static $proxy_password = null;
+ private static $currencies = array( /* */
+ "AUD" => array("currency" => "Australian Dollar", "code" => "036", "symbol" => "$"),
+ "CAD" => array("currency" => "Canadian Dollar", "code" => "124", "symbol" => "$"),
+ "CHF" => array("currency" => "Swiss Franc", "code" => "756", "symbol" => "CHF"),
+ "DKK" => array("currency" => "Danish Krone", "code" => "208", "symbol" => "kr"),
+ "EUR" => array("currency" => "Euro", "code" => "978", "symbol" => "€"),
+ "GBP" => array("currency" => "Pound Sterling", "code" => "826", "symbol" => "£"),
+ "HKD" => array("currency" => "Hong Kong Dollar", "code" => "344", "symbol" => "$"),
+ "JPY" => array("currency" => "Yen", "code" => "392", "symbol" => "¥"),
+ "MXN" => array("currency" => "Mexican Peso", "code" => "484", "symbol" => "$"),
+ "NOK" => array("currency" => "Norwegian Krone", "code" => "578", "symbol" => "kr"),
+ "SEK" => array("currency" => "Swedish Krona", "code" => "752", "symbol" => "kr"),
+ "USD" => array("currency" => "US Dollar", "code" => "840", "symbol" => "$") /* */
+ );
+
+ /**
+ * Set the parameter in the case of the use of an outgoing proxy
+ *
+ * @param string $host
+ * The proxy host.
+ * @param int $port
+ * The proxy port.
+ * @param string $username
+ * The proxy username.
+ * @param string $password
+ * The proxy password.
+ */
+ public static function useProxy($host, $port, $username = null, $password = null) {
+ Connect2PayCurrencyHelper::$proxy_host = $host;
+ Connect2PayCurrencyHelper::$proxy_port = $port;
+ Connect2PayCurrencyHelper::$proxy_username = $username;
+ Connect2PayCurrencyHelper::$proxy_password = $password;
+ }
+
+ /**
+ * Return the supported currencies array.
+ *
+ * @return Array of all the currencies supported.
+ */
+ public static function getCurrencies() {
+ return array_keys(Connect2PayCurrencyHelper::$currencies);
+ }
+
+ /**
+ * Get a currency alphabetic code according to its numeric code in ISO4217
+ *
+ * @param string $code
+ * The numeric code to look for
+ * @return The alphabetic code (like EUR or USD) or null if not found.
+ */
+ public static function getISO4217CurrencyFromCode($code) {
+ foreach (Connect2PayCurrencyHelper::$currencies as $currency => $data) {
+ if ($data["code"] == $code) {
+ return $currency;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Return the ISO4217 currency code.
+ *
+ * @param string $currency
+ * The currency to look for
+ * @return The ISO4217 code or null if not found
+ */
+ public static function getISO4217CurrencyCode($currency) {
+ return (array_key_exists($currency, Connect2PayCurrencyHelper::$currencies)) ? Connect2PayCurrencyHelper::$currencies[$currency]["code"] : null;
+ }
+
+ /**
+ * Return the currency symbol.
+ *
+ * @param string $currency
+ * The currency to look for
+ * @return The currency symbol or null if not found
+ */
+ public static function getCurrencySymbol($currency) {
+ return (array_key_exists($currency, Connect2PayCurrencyHelper::$currencies)) ? Connect2PayCurrencyHelper::$currencies[$currency]["symbol"] : null;
+ }
+
+ /**
+ * Return the currency name.
+ *
+ * @param string $currency
+ * The currency to look for
+ * @return The currency name or null if not found
+ */
+ public static function getCurrencyName($currency) {
+ return (array_key_exists($currency, Connect2PayCurrencyHelper::$currencies)) ? Connect2PayCurrencyHelper::$currencies[$currency]["currency"] : null;
+ }
+
+ /**
+ * Get a currency conversion rate from Yahoo webservice.
+ *
+ * @param string $from
+ * The source currency
+ * @param string $to
+ * The destination currency
+ */
+ public static function getRate($from, $to) {
+ // Check if currencies exists
+ if (!Connect2PayCurrencyHelper::currencyIsAvailable($from) || !Connect2PayCurrencyHelper::currencyIsAvailable($to)) {
+ return null;
+ }
+
+ // Build the request URL
+ $url = Connect2PayCurrencyHelper::$YAHOO_SERVICE_URL . "?s=" . $from . $to . "=X&f=l1&e=.csv";
+
+ // Do the request
+ $curl = curl_init($url);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+
+ if (Connect2PayCurrencyHelper::$proxy_host != null && Connect2PayCurrencyHelper::$proxy_port != null) {
+ curl_setopt($curl, CURLOPT_PROXY, Connect2PayCurrencyHelper::$proxy_host);
+ curl_setopt($curl, CURLOPT_PROXYPORT, Connect2PayCurrencyHelper::$proxy_port);
+
+ if (Connect2PayCurrencyHelper::$proxy_username != null && Connect2PayCurrencyHelper::$proxy_password != null) {
+ curl_setopt($curl, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
+ curl_setopt($curl, CURLOPT_PROXYUSERPWD,
+ Connect2PayCurrencyHelper::$proxy_username . ":" . Connect2PayCurrencyHelper::$proxy_password);
+ }
+ }
+
+ $csv = trim(curl_exec($curl));
+ $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
+ curl_close($curl);
+
+ // Parse the CSV, we should only have a number, check this
+ if ($httpCode == 200 && preg_match('/^[0-9.]+$/', $csv)) {
+ return $csv;
+ }
+
+ return null;
+ }
+
+ /**
+ * Convert an amount from one currency to another
+ *
+ * @param int $amount
+ * The amount to convert
+ * @param string $from
+ * The source currency
+ * @param string $to
+ * The destination currency
+ * @param boolean $cent
+ * Specifies if the amount is in cent (default true)
+ * @return The converted amount or null in case of error
+ */
+ public static function convert($amount, $from, $to, $cent = true) {
+ // Get the conversion rate
+ $rate = Connect2PayCurrencyHelper::getRate($from, $to);
+
+ if ($rate != null) {
+ $convert = $amount * $rate;
+
+ // If the amount was in cent, truncate the digit after the comma
+ // else round the result to 2 digits only
+ return ($cent) ? round($convert, 0) : round($convert, 2);
+ }
+
+ return null;
+ }
+
+ private static function currencyIsAvailable($currency) {
+ return array_key_exists($currency, Connect2PayCurrencyHelper::$currencies);
+ }
+}
+
+/**
+ * Validation class
+ */
+class C2PValidate {
+
+ /**
+ * Check for e-mail validity
+ *
+ * @param string $email
+ * e-mail address to validate
+ * @return boolean Validity is ok or not
+ */
+ static public function isEmail($email) {
+ return C2PValidate::isEmpty($email) or
+ preg_match('/^[a-z0-9!#$%&\'*+\/=?^`{}|~_-]+[.a-z0-9!#$%&\'*+\/=?^`{}|~_-]*@[a-z0-9]+[._a-z0-9-]*\.[a-z0-9]+$/ui', $email);
+ }
+
+ /**
+ * Check for IP validity
+ *
+ * @param string $ip
+ * IP address to validate
+ * @return boolean Validity is ok or not
+ */
+ static public function isIP($ip) {
+ return C2PValidate::isEmpty($ip) or preg_match('/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/', $ip);
+ }
+
+ /**
+ * Check for MD5 string validity
+ *
+ * @param string $md5
+ * MD5 string to validate
+ * @return boolean Validity is ok or not
+ */
+ static public function isMd5($md5) {
+ return preg_match('/^[a-f0-9A-F]{32}$/', $md5);
+ }
+
+ /**
+ * Check for SHA1 string validity
+ *
+ * @param string $sha1
+ * SHA1 string to validate
+ * @return boolean Validity is ok or not
+ */
+ static public function isSha1($sha1) {
+ return preg_match('/^[a-fA-F0-9]{40}$/', $sha1);
+ }
+
+ /**
+ * Check for a float number validity
+ *
+ * @param float $float
+ * Float number to validate
+ * @return boolean Validity is ok or not
+ */
+ static public function isFloat($float) {
+ return strval((float) ($float)) == strval($float);
+ }
+
+ static public function isUnsignedFloat($float) {
+ return strval((float) ($float)) == strval($float) and $float >= 0;
+ }
+
+ /**
+ * Check for name validity
+ *
+ * @param string $name
+ * Name to validate
+ * @return boolean Validity is ok or not
+ */
+ static public function isName($name) {
+ return preg_match('/^[^0-9!<>,;?=+()@#"°{}_$%:]*$/', stripslashes($name));
+ }
+
+ /**
+ * Check for a country name validity
+ *
+ * @param string $name
+ * Country name to validate
+ * @return boolean Validity is ok or not
+ */
+ static public function isCountryName($name) {
+ return preg_match('/^[a-zA-Z -]+$/', $name);
+ }
+
+ /**
+ * Check for a postal address validity
+ *
+ * @param string $address
+ * Address to validate
+ * @return boolean Validity is ok or not
+ */
+ static public function isAddress($address) {
+ return empty($address) or preg_match('/^[^!<>?=+@{}_$%]*$/', $address);
+ }
+
+ /**
+ * Check for city name validity
+ *
+ * @param string $city
+ * City name to validate
+ * @return boolean Validity is ok or not
+ */
+ static public function isCityName($city) {
+ return preg_match('/^[^!<>;?=+@#"°{}_$%]*$/', $city);
+ }
+
+ /**
+ * Check for date format
+ *
+ * @param string $date
+ * Date to validate
+ * @return boolean Validity is ok or not
+ */
+ static public function isDateFormat($date) {
+ return (bool) preg_match('/^([0-9]{4})-((0?[0-9])|(1[0-2]))-((0?[1-9])|([0-2][0-9])|(3[01]))( [0-9]{2}:[0-9]{2}:[0-9]{2})?$/', $date);
+ }
+
+ /**
+ * Check for date validity
+ *
+ * @param string $date
+ * Date to validate
+ * @return boolean Validity is ok or not
+ */
+ static public function isDate($date) {
+ if (!preg_match('/^([0-9]{4})-((0?[1-9])|(1[0-2]))-((0?[1-9])|([1-2][0-9])|(3[01]))( [0-9]{2}:[0-9]{2}:[0-9]{2})?$/', $date, $matches))
+ return false;
+ return checkdate((int) $matches[2], (int) $matches[5], (int) $matches[0]);
+ }
+
+ /**
+ * Check for boolean validity
+ *
+ * @param boolean $bool
+ * Boolean to validate
+ * @return boolean Validity is ok or not
+ */
+ static public function isBool($bool) {
+ return is_null($bool) or is_bool($bool) or preg_match('/^0|1$/', $bool);
+ }
+
+ /**
+ * Check for phone number validity
+ *
+ * @param string $phoneNumber
+ * Phone number to validate
+ * @return boolean Validity is ok or not
+ */
+ static public function isPhoneNumber($phoneNumber) {
+ return preg_match('/^[+0-9. ()-;]*$/', $phoneNumber);
+ }
+
+ /**
+ * Check for postal code validity
+ *
+ * @param string $postcode
+ * Postal code to validate
+ * @return boolean Validity is ok or not
+ */
+ static public function isPostCode($postcode) {
+ return empty($postcode) or preg_match('/^[a-zA-Z 0-9-]+$/', $postcode);
+ }
+
+ /**
+ * Check for zip code format validity
+ *
+ * @param string $zip_code
+ * zip code format to validate
+ * @return boolean Validity is ok or not
+ */
+ static public function isZipCodeFormat($zip_code) {
+ if (!empty($zip_code))
+ return preg_match('/^[NLCnlc -]+$/', $zip_code);
+ return true;
+ }
+
+ /**
+ * Check for an integer validity
+ *
+ * @param integer $id
+ * Integer to validate
+ * @return boolean Validity is ok or not
+ */
+ static public function isInt($value) {
+ return ((string) (int) $value === (string) $value or $value === false or empty($value));
+ }
+
+ /**
+ * Check for an integer validity (unsigned)
+ *
+ * @param integer $id
+ * Integer to validate
+ * @return boolean Validity is ok or not
+ */
+ static public function isUnsignedInt($value) {
+ return (preg_match('#^[0-9]+$#', (string) $value) and $value < 4294967296 and $value >= 0);
+ }
+
+ /**
+ * Check url valdity (disallowed empty string)
+ *
+ * @param string $url
+ * Url to validate
+ * @return boolean Validity is ok or not
+ */
+ static public function isUrl($url) {
+ return preg_match('/^[~:#%&_=\(\)\.\? \+\-@\/a-zA-Z0-9]+$/', $url);
+ }
+
+ /**
+ * Check object validity
+ *
+ * @param integer $object
+ * Object to validate
+ * @return boolean Validity is ok or not
+ */
+ static public function isAbsoluteUrl($url) {
+ if (!empty($url))
+ return preg_match('/^https?:\/\/[:#%&_=\(\)\.\? \+\-@\/a-zA-Z0-9]+$/', $url);
+ return true;
+ }
+
+ /**
+ * String validity (PHP one)
+ *
+ * @param string $data
+ * Data to validate
+ * @return boolean Validity is ok or not
+ */
+ static public function isString($data) {
+ return is_string($data);
+ }
+
+ /**
+ * Shipping Type validity
+ *
+ * @param string $shipping
+ * Shipping Type to validate
+ * @return boolean Validity is ok or not
+ */
+ static public function isShippingType($shipping) {
+ return ((string) $shipping == "Physical" || (string) $shipping == "Virtual" || (string) $shipping == "Access");
+ }
+
+ /**
+ * Payment Mean validity
+ *
+ * @param string $payment
+ * Payment Mean to validate
+ * @return boolean Validity is ok or not
+ */
+ static public function isPayment($payment) {
+ return ((string) $payment == Connect2PayClient::_PAYMENT_TYPE_CREDITCARD ||
+ (string) $payment == Connect2PayClient::_PAYMENT_TYPE_TODITOCASH ||
+ (string) $payment == Connect2PayClient::_PAYMENT_TYPE_BANKTRANSFER);
+ }
+
+ /**
+ * Provider validity
+ *
+ * @param string $provider
+ * Provider to validate
+ * @return boolean Validity is ok or not
+ */
+ static public function isProvider($provider) {
+ return ((string) $provider == Connect2PayClient::_PAYMENT_PROVIDER_SOFORT ||
+ (string) $provider == Connect2PayClient::_PAYMENT_PROVIDER_PRZELEWY24 ||
+ (string) $provider == Connect2PayClient::_PAYMENT_PROVIDER_IDEALKP);
+ }
+
+ /**
+ * Operation validity
+ *
+ * @param string $operation
+ * Operation to validate
+ * @return boolean Validity is ok or not
+ */
+ static public function isOperation($operation) {
+ return ((string) $operation == Connect2PayClient::_OPERATION_TYPE_SALE ||
+ (string) $operation == Connect2PayClient::_OPERATION_TYPE_AUTHORIZE);
+ }
+
+ /**
+ * Payment Type validity
+ *
+ * @param string $paymentMode
+ * Payment Mode to validate
+ * @return boolean Validity is ok or not
+ */
+ static public function isPaymentMode($paymentMode) {
+ return ((string) $paymentMode == Connect2PayClient::_PAYMENT_MODE_SINGLE ||
+ (string) $paymentMode == Connect2PayClient::_PAYMENT_MODE_ONSHIPPING ||
+ (string) $paymentMode == Connect2PayClient::_PAYMENT_MODE_RECURRENT ||
+ (string) $paymentMode == Connect2PayClient::_PAYMENT_MODE_INSTALMENTS);
+ }
+
+ /**
+ * Subscription Type validity
+ *
+ * @param string $subscriptionType
+ * Subscription Type to validate
+ * @return boolean Validity is ok or not
+ */
+ static public function isSubscriptionType($subscriptionType) {
+ return ((string) $subscriptionType == Connect2PayClient::_SUBSCRIPTION_TYPE_NORMAL ||
+ (string) $subscriptionType == Connect2PayClient::_SUBSCRIPTION_TYPE_INFINITE ||
+ (string) $subscriptionType == Connect2PayClient::_SUBSCRIPTION_TYPE_ONETIME ||
+ (string) $subscriptionType == Connect2PayClient::_SUBSCRIPTION_TYPE_LIFETIME);
+ }
+
+ /**
+ * Test if a variable is set
+ *
+ * @param mixed $field
+ * @return boolean field is set or not
+ */
+ public static function isEmpty($field) {
+ return ($field === '' or $field === NULL);
+ }
+
+ /**
+ * strlen overloaded function
+ *
+ * @param string $str
+ * @return int size of the string
+ */
+ public static function strlen($str) {
+ if (is_array($str))
+ return false;
+
+ if (function_exists('mb_strlen'))
+ return mb_strlen($str, 'UTF-8');
+
+ return strlen($str);
+ }
+}
+
+class Utils {
+
+ public static function deprecation_error($message) {
+ trigger_error($message, version_compare(phpversion(), '5.3.0', '<') ? E_USER_NOTICE : E_USER_DEPRECATED);
+ }
+}
diff --git a/modules/payxpert/logo.gif b/modules/payxpert/logo.gif
new file mode 100644
index 0000000..69a9bbb
Binary files /dev/null and b/modules/payxpert/logo.gif differ
diff --git a/modules/payxpert/logo.png b/modules/payxpert/logo.png
new file mode 100644
index 0000000..b56962e
Binary files /dev/null and b/modules/payxpert/logo.png differ
diff --git a/modules/payxpert/payment.php b/modules/payxpert/payment.php
new file mode 100644
index 0000000..8206a57
--- /dev/null
+++ b/modules/payxpert/payment.php
@@ -0,0 +1,37 @@
+isLogged()) {
+ Tools::redirect('authentication.php?back=order.php');
+}
+
+$payxpert = new PayXpert();
+echo $payxpert->execPayment($cart);
+
+require_once(dirname(__FILE__) . '/../../footer.php');
\ No newline at end of file
diff --git a/modules/payxpert/payxpert.php b/modules/payxpert/payxpert.php
new file mode 100644
index 0000000..8936968
--- /dev/null
+++ b/modules/payxpert/payxpert.php
@@ -0,0 +1,976 @@
+name = 'payxpert';
+ $this->version = '1.0.8';
+
+ $this->tab = 'payments_gateways';
+
+ $this->author = 'PayXpert';
+ $this->need_instance = 1;
+
+ $this->controllers = array('payment', 'validation');
+ $this->is_eu_compatible = 1;
+
+ if (version_compare(_PS_VERSION_, '1.5', '>=')) {
+ $this->ps_versions_compliancy = array('min' => '1.4.0.0', 'max' => _PS_VERSION_);
+ }
+
+ if (version_compare(_PS_VERSION_, '1.6', '>=')) {
+ $this->bootstrap = true;
+ }
+
+ parent::__construct();
+
+ $this->displayName = 'PayXpert Payment Solutions';
+ $this->description = $this->l("Accept payments today with PayXpert");
+ $this->confirmUninstall = $this->l('Are you sure about removing these details?');
+
+ if (!count(Currency::checkPaymentCurrencies($this->id))) {
+ $this->warning = $this->l('No currency has been set for this module.');
+ }
+
+ /* For 1.4.3 and less compatibility */
+ $updateConfig = array('PS_OS_CHEQUE' => 1, 'PS_OS_PAYMENT' => 2, 'PS_OS_PREPARATION' => 3, 'PS_OS_SHIPPING' => 4,
+ 'PS_OS_DELIVERED' => 5, 'PS_OS_CANCELED' => 6, 'PS_OS_REFUND' => 7, 'PS_OS_ERROR' => 8, 'PS_OS_OUTOFSTOCK' => 9,
+ 'PS_OS_BANKWIRE' => 10, 'PS_OS_PAYPAL' => 11, 'PS_OS_WS_PAYMENT' => 12);
+
+ foreach ($updateConfig as $u => $v) {
+ if (!Configuration::get($u) || (int) Configuration::get($u) < 1) {
+ if (defined('_' . $u . '_') && (int) constant('_' . $u . '_') > 0) {
+ Configuration::updateValue($u, constant('_' . $u . '_'));
+ } else {
+ Configuration::updateValue($u, $v);
+ }
+ }
+ }
+ }
+
+ /**
+ * Install method
+ */
+ public function install() {
+ // call parents
+ if (!parent::install()) {
+ $errorMessage = Tools::displayError($this->l('PayXpert installation : install failed.'));
+ $this->addLog($errorMessage, 3, '000002');
+ return false;
+ }
+
+ // Add hook methods
+ $hookResult = $this->registerHook('paymentReturn');
+ if (version_compare(_PS_VERSION_, '1.7', '<')) {
+ $hookResult = $hookResult && $this->registerHook('payment');
+ } else {
+ $hookResult = $hookResult && $this->registerHook('paymentOptions');
+ }
+
+ if (!$hookResult) {
+ $errorMessage = Tools::displayError($this->l('PayXpert installation : hooks failed.'));
+ $this->addLog($errorMessage, 3, '000002');
+
+ return false;
+ }
+
+ // Add configuration parameters
+ foreach ($this->getModuleParameters() as $parameter) {
+ if (!Configuration::updateValue($parameter, '')) {
+ $errorMessage = Tools::displayError($this->l('PayXpert installation : configuration failed.'));
+ $this->addLog($errorMessage, 3, '000002');
+
+ return false;
+ }
+ }
+
+ $this->addLog($this->l('PayXpert installation : installation successful'));
+
+ return true;
+ }
+
+ /**
+ * Uninstall the module
+ *
+ * @return boolean
+ */
+ public function uninstall() {
+ $result = parent::uninstall();
+
+ foreach ($this->getModuleParameters() as $parameter) {
+ $result = $result || Configuration::deleteByName($parameter);
+ }
+
+ return $result;
+ }
+
+ private function getModuleParameters() {
+ $moduleParameters = array( /* */
+ 'PAYXPERT_ORIGINATOR', /* */
+ 'PAYXPERT_PASSWORD', /* */
+ 'PAYXPERT_URL', /* */
+ 'PAYXPERT_MERCHANT_NOTIF', /* */
+ 'PAYXPERT_MERCHANT_NOTIF_TO', /* */
+ 'PAYXPERT_MERCHANT_NOTIF_LANG' /* */
+ );
+
+ if (version_compare(_PS_VERSION_, '1.7', '>=')) {
+ $moduleParameters[] = 'PAYXPERT_PAYMENT_TYPE_CREDIT_CARD';
+ $moduleParameters[] = 'PAYXPERT_PAYMENT_TYPE_BANK_TRANSFERT_SOFORT';
+ $moduleParameters[] = 'PAYXPERT_PAYMENT_TYPE_BANK_TRANSFERT_PRZELEWY24';
+ $moduleParameters[] = 'PAYXPERT_PAYMENT_TYPE_BANK_TRANSFERT_IDEAL';
+ }
+
+ return $moduleParameters;
+ }
+
+ public function checkPaymentOption($params) {
+ // if module disabled, can't go through
+ if (!$this->active) {
+ return false;
+ }
+
+ // Check if currency ok
+ if (!$this->checkCurrency($params['cart'])) {
+ return false;
+ }
+
+ // Check if module is configured
+ if (Configuration::get('PAYXPERT_ORIGINATOR') == "" && Configuration::get('PAYXPERT_PASSWORD') == "") {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Hook payment options
+ *
+ * @since Prestashop 1.7
+ * @param type $params
+ * @return type
+ */
+ public function hookPaymentOptions($params) {
+ if (!$this->checkPaymentOption($params)) {
+ return;
+ }
+
+ $this->smarty->assign($this->getTemplateVarInfos());
+
+ $payment_options = array();
+
+ $ccOption = $this->getCreditCardPaymentOption();
+ if ($ccOption != null) {
+ $payment_options[] = $ccOption;
+ }
+ $sofortOption = $this->getBankTransferViaSofortPaymentOption();
+ if ($sofortOption != null) {
+ $payment_options[] = $sofortOption;
+ }
+ $przelewy24Option = $this->getBankTransferViaPrzelewy24PaymentOption();
+ if ($przelewy24Option != null) {
+ $payment_options[] = $przelewy24Option;
+ }
+ $idealOption = $this->getBankTransferViaIDealPaymentOption();
+ if ($idealOption != null) {
+ $payment_options[] = $idealOption;
+ }
+
+ return $payment_options;
+ }
+
+ /**
+ *
+ * @since Prestashop 1.7
+ */
+ public function getCreditCardPaymentOption() {
+ if (Configuration::get('PAYXPERT_PAYMENT_TYPE_CREDIT_CARD') == "true") {
+ $option = new PrestaShop\PrestaShop\Core\Payment\PaymentOption();
+ $option->setCallToActionText($this->l('Pay by Credit Card'));
+ $option->setAction(
+ $this->context->link->getModuleLink($this->name, 'payment',
+ array('payment_type' => PayXpert\Connect2Pay\Connect2PayClient::_PAYMENT_TYPE_CREDITCARD), true));
+
+ $this->context->smarty->assign('pxpCCLogo',
+ Media::getMediaPath(_PS_MODULE_DIR_ . $this->name . '/images/payment-types/creditcard.png'));
+ $option->setAdditionalInformation(
+ $this->context->smarty->fetch('module:payxpert/views/templates/front/payment_infos_credit_card.tpl'));
+
+ return $option;
+ }
+
+ return null;
+ }
+
+ /**
+ *
+ * @since Prestashop 1.7
+ */
+ public function getBankTransferViaSofortPaymentOption() {
+ if (Configuration::get('PAYXPERT_PAYMENT_TYPE_BANK_TRANSFERT_SOFORT') == "true") {
+ $option = new PrestaShop\PrestaShop\Core\Payment\PaymentOption();
+ $option->setCallToActionText($this->l('Pay by Bank Transfer via Sofort'));
+ $option->setAction(
+ $this->context->link->getModuleLink($this->name, 'payment',
+ array('payment_type' => PayXpert\Connect2Pay\Connect2PayClient::_PAYMENT_TYPE_BANKTRANSFER,
+ 'payment_provider' => PayXpert\Connect2Pay\Connect2PayClient::_PAYMENT_PROVIDER_SOFORT), true));
+
+ $this->context->smarty->assign("pxpSofortLogo",
+ Media::getMediaPath(_PS_MODULE_DIR_ . $this->name . '/images/payment-types/sofort.png'));
+ $option->setAdditionalInformation(
+ $this->context->smarty->fetch('module:payxpert/views/templates/front/payment_infos_bank_transfer_sofort.tpl'));
+
+ return $option;
+ }
+
+ return null;
+ }
+
+ /**
+ *
+ * @since Prestashop 1.7
+ */
+ public function getBankTransferViaPrzelewy24PaymentOption() {
+ if (Configuration::get('PAYXPERT_PAYMENT_TYPE_BANK_TRANSFERT_PRZELEWY24') == "true") {
+ $option = new PrestaShop\PrestaShop\Core\Payment\PaymentOption();
+ $option->setCallToActionText($this->l('Pay by Bank Transfer via Przelewy24'));
+ $option->setAction(
+ $this->context->link->getModuleLink($this->name, 'payment',
+ array('payment_type' => PayXpert\Connect2Pay\Connect2PayClient::_PAYMENT_TYPE_BANKTRANSFER,
+ 'payment_provider' => PayXpert\Connect2Pay\Connect2PayClient::_PAYMENT_PROVIDER_PRZELEWY24), true));
+
+ $this->context->smarty->assign("pxpPrzelewy24Logo",
+ Media::getMediaPath(_PS_MODULE_DIR_ . $this->name . '/images/payment-types/przelewy24.png'));
+ $option->setAdditionalInformation(
+ $this->context->smarty->fetch('module:payxpert/views/templates/front/payment_infos_bank_transfer_przelewy24.tpl'));
+
+ return $option;
+ }
+
+ return null;
+ }
+
+ /**
+ *
+ * @since Prestashop 1.7
+ */
+ public function getBankTransferViaIDealPaymentOption() {
+ if (Configuration::get('PAYXPERT_PAYMENT_TYPE_BANK_TRANSFERT_IDEAL') == "true") {
+ $option = new PrestaShop\PrestaShop\Core\Payment\PaymentOption();
+ $option->setCallToActionText($this->l('Pay by Bank Transfer via iDeal'));
+ $option->setAction(
+ $this->context->link->getModuleLink($this->name, 'payment',
+ array('payment_type' => PayXpert\Connect2Pay\Connect2PayClient::_PAYMENT_TYPE_BANKTRANSFER,
+ 'payment_provider' => PayXpert\Connect2Pay\Connect2PayClient::_PAYMENT_PROVIDER_IDEALKP), true));
+
+ $this->context->smarty->assign("pxpIdealLogo", Media::getMediaPath(_PS_MODULE_DIR_ . $this->name . '/images/payment-types/ideal.png'));
+ $option->setAdditionalInformation(
+ $this->context->smarty->fetch('module:payxpert/views/templates/front/payment_infos_bank_transfer_ideal.tpl'));
+
+ return $option;
+ }
+
+ return null;
+ }
+
+ public function getTemplateVarInfos() {
+ $cart = $this->context->cart;
+
+ return array(/* */
+ 'nbProducts' => $cart->nbProducts(), /* */
+ 'cust_currency' => $cart->id_currency, /* */
+ 'total' => $cart->getOrderTotal(true, Cart::BOTH), /* */
+ 'isoCode' => $this->context->language->iso_code /* */
+ );
+ }
+
+ /**
+ * Hook payment for Prestashop < 1.7
+ *
+ * @param type $params
+ * @return type
+ */
+ public function hookPayment($params) {
+ if (!$this->checkPaymentOption($params)) {
+ return;
+ }
+
+ $this->assignSmartyVariable('this_path', $this->_path);
+ $this->assignSmartyVariable('this_path_ssl',
+ (Configuration::get('PS_SSL_ENABLED') ? 'https://' : 'http://') . htmlspecialchars($_SERVER['HTTP_HOST'], ENT_COMPAT, 'UTF-8') .
+ __PS_BASE_URI__ . 'modules/payxpert/');
+ $this->assignSmartyVariable('this_link', $this->getModuleLinkCompat('payxpert', 'payment'));
+
+ if (version_compare(_PS_VERSION_, '1.6.0', '>=') === true) {
+ $this->context->controller->addCSS($this->_path . 'css/payxpert.css');
+ }
+
+ return $this->display(__FILE__, 'views/templates/hook/payment.tpl');
+ }
+
+ /**
+ * Hook paymentReturn
+ *
+ * Displays order confirmation
+ *
+ * @param type $params
+ * @return type
+ */
+ public function hookPaymentReturn($params) {
+ if (!$this->active) {
+ return;
+ }
+
+ if (isset($params['objOrder'])) {
+ // For Prestashop < 1.7
+ $order = $params['objOrder'];
+ } else {
+ $order = $params['order'];
+ }
+
+ switch ($order->getCurrentState()) {
+ case _PS_OS_PAYMENT_:
+ case _PS_OS_OUTOFSTOCK_:
+ $this->assignSmartyVariable('status', 'ok');
+ break;
+
+ case _PS_OS_BANKWIRE_:
+ $this->assignSmartyVariable('status', 'pending');
+ break;
+
+ case _PS_OS_ERROR_:
+ default:
+ $this->assignSmartyVariable('status', 'failed');
+ break;
+ }
+
+ $this->assignSmartyVariable('this_link_contact', $this->getPageLinkCompat('contact', true));
+
+ return $this->display(__FILE__, 'views/templates/hook/orderconfirmation.tpl');
+ }
+
+ /**
+ * Init the payment
+ *
+ * In this method, we'll start to initialize the transaction
+ * And redirect the customer
+ *
+ * For Prestashop >= 1.5
+ *
+ * @global type $cookie
+ * @param Cart $cart
+ * @return type
+ */
+ public function redirect($cart, $paymentType = null, $paymentProvider = null) {
+ // if module disabled, can't go through
+ if (!$this->active) {
+ return "Module is not active";
+ }
+
+ // Check if currency ok
+ if (!$this->checkCurrency($cart)) {
+ return "Incorrect currency";
+ }
+
+ // Check if module is configured
+ if (Configuration::get('PAYXPERT_ORIGINATOR') == "" && Configuration::get('PAYXPERT_PASSWORD') == "") {
+ return "Module is not setup";
+ }
+
+ if ($paymentType == null || !PayXpert\Connect2Pay\C2PValidate::isPayment($paymentType)) {
+ $paymentType = PayXpert\Connect2Pay\Connect2PayClient::_PAYMENT_TYPE_CREDITCARD;
+ }
+
+ if (!$this->checkPaymentTypeAndProvider($paymentType, $paymentProvider)) {
+ return "Payment type or provider is not enabled";
+ }
+
+ // get all informations
+ $customer = new Customer((int) ($cart->id_customer));
+ $currency = new Currency((int) ($cart->id_currency));
+ $carrier = new Carrier((int) ($cart->id_carrier));
+ $addr_delivery = new Address((int) ($cart->id_address_delivery));
+ $addr_invoice = new Address((int) ($cart->id_address_invoice));
+
+ $invoice_state = new State((int) ($addr_invoice->id_state));
+ $invoice_country = new Country((int) ($addr_invoice->id_country));
+
+ $delivery_state = new State((int) ($addr_delivery->id_state));
+ $delivery_country = new Country((int) ($addr_delivery->id_country));
+
+ $invoice_phone = (!empty($addr_invoice->phone)) ? $addr_invoice->phone : $addr_invoice->phone_mobile;
+ $delivery_phone = (!empty($addr_delivery->phone)) ? $addr_delivery->phone : $addr_delivery->phone_mobile;
+
+ // init api
+ $c2pClient = new PayXpert\Connect2Pay\Connect2PayClient($this->getPayXpertUrl(), Configuration::get('PAYXPERT_ORIGINATOR'),
+ html_entity_decode(Configuration::get('PAYXPERT_PASSWORD')));
+
+ // customer informations
+ $c2pClient->setShopperID($cart->id_customer);
+ $c2pClient->setShopperEmail($customer->email);
+ $c2pClient->setShopperFirstName(substr($customer->firstname, 0, 35));
+ $c2pClient->setShopperLastName(substr($customer->lastname, 0, 35));
+ $c2pClient->setShopperCompany(substr($addr_invoice->company, 0, 128));
+ $c2pClient->setShopperAddress(substr(trim($addr_invoice->address1 . ' ' . $addr_invoice->address2), 0, 255));
+ $c2pClient->setShopperZipcode(substr($addr_invoice->postcode, 0, 10));
+ $c2pClient->setShopperCity(substr($addr_invoice->city, 0, 50));
+ $c2pClient->setShopperState(substr($invoice_state->name, 0, 30));
+ $c2pClient->setShopperCountryCode($invoice_country->iso_code);
+ $c2pClient->setShopperPhone(substr(trim($invoice_phone), 0, 20));
+
+ // Shipping information
+ $c2pClient->setShipToFirstName(substr($addr_delivery->firstname, 0, 35));
+ $c2pClient->setShipToLastName(substr($addr_delivery->lastname, 0, 35));
+ $c2pClient->setShipToCompany(substr($addr_delivery->company, 0, 128));
+ $c2pClient->setShipToPhone(substr(trim($delivery_phone), 0, 20));
+ $c2pClient->setShipToAddress(substr(trim($addr_delivery->address1 . " " . $addr_delivery->address2), 0, 255));
+ $c2pClient->setShipToZipcode(substr($addr_delivery->postcode, 0, 10));
+ $c2pClient->setShipToCity(substr($addr_delivery->city, 0, 50));
+ $c2pClient->setShipToState(substr($delivery_state->name, 0, 30));
+ $c2pClient->setShipToCountryCode($delivery_country->iso_code);
+ $c2pClient->setShippingName(substr($carrier->name, 0, 50));
+ $c2pClient->setShippingType(PayXpert\Connect2Pay\Connect2PayClient::_SHIPPING_TYPE_PHYSICAL);
+
+ // Order informations
+ $c2pClient->setOrderID(substr(pSQL($cart->id), 0, 100));
+ $c2pClient->setOrderDescription(substr($this->l('Invoice:') . pSQL($cart->id), 0, 255));
+ $c2pClient->setCustomerIP($_SERVER['REMOTE_ADDR']);
+ $c2pClient->setCurrency($currency->iso_code);
+
+ $total = number_format($cart->getOrderTotal(true, 3) * 100, 0, '.', '');
+
+ $c2pClient->setAmount($total);
+ $c2pClient->setOrderCartContent($this->getProductsApi($cart));
+ $c2pClient->setPaymentMode(PayXpert\Connect2Pay\Connect2PayClient::_PAYMENT_MODE_SINGLE);
+ $c2pClient->setPaymentType($paymentType);
+ if ($paymentProvider != null && PayXpert\Connect2Pay\C2PValidate::isProvider($paymentProvider)) {
+ $c2pClient->setProvider($paymentProvider);
+ }
+ $c2pClient->setCtrlCustomData(PayXpert::getCallbackAuthenticityData($c2pClient->getOrderID(), $customer->secure_key));
+
+ // Merchant notifications
+ if (Configuration::get('PAYXPERT_MERCHANT_NOTIF') === "true" && Configuration::get('PAYXPERT_MERCHANT_NOTIF_TO')) {
+ $c2pClient->setMerchantNotification(true);
+ $c2pClient->setMerchantNotificationTo(Configuration::get('PAYXPERT_MERCHANT_NOTIF_TO'));
+ if (Configuration::get('PAYXPERT_MERCHANT_NOTIF_LANG')) {
+ $c2pClient->setMerchantNotificationLang(Configuration::get('PAYXPERT_MERCHANT_NOTIF_LANG'));
+ }
+ }
+
+ $ctrlURLPrefix = Configuration::get('PS_SSL_ENABLED') ? 'https://' : 'http://';
+
+ if (version_compare(_PS_VERSION_, '1.5', '<')) {
+ $c2pClient->setCtrlCallbackURL($ctrlURLPrefix . $_SERVER['HTTP_HOST'] . __PS_BASE_URI__ . 'modules/payxpert/validation.php');
+ $c2pClient->setCtrlRedirectURL(
+ $ctrlURLPrefix . $_SERVER['HTTP_HOST'] . __PS_BASE_URI__ . 'order-confirmation.php?id_cart=' . (int) ($cart->id) . '&id_module=' .
+ (int) ($this->id) . '&key=' . $customer->secure_key);
+ } else {
+ $c2pClient->setCtrlCallbackURL($this->context->link->getModuleLink('payxpert', 'validation'));
+ $c2pClient->setCtrlRedirectURL(
+ $ctrlURLPrefix . $_SERVER['HTTP_HOST'] . __PS_BASE_URI__ . 'index.php?controller=order-confirmation&id_cart=' . (int) ($cart->id) .
+ '&id_module=' . (int) ($this->id) . '&key=' . $customer->secure_key);
+ }
+
+ // prepare API
+ if ($c2pClient->preparePayment() == false) {
+ $message = "PayXpert : can't prepare transaction - " . $c2pClient->getClientErrorMessage();
+ $this->addLog($message, 3);
+ return $message;
+ }
+
+ header('Location: ' . $c2pClient->getCustomerRedirectURL());
+ exit();
+ }
+
+ /**
+ * Return array of product to fill Api Product properties
+ *
+ * @param Cart $cart
+ * @return array
+ */
+ protected function getProductsApi($cart) {
+ $products = array();
+
+ foreach ($cart->getProducts() as $product) {
+ $obj = new Product((int) $product['id_product']);
+ $products[] = array( /* */
+ 'CartProductId' => $product['id_product'], /* */
+ 'CartProductName' => $product['name'], /* */
+ 'CartProductUnitPrice' => $product['price'], /* */
+ 'CartProductQuantity' => $product['quantity'], /* */
+ 'CartProductBrand' => $obj->manufacturer_name, /* */
+ 'CartProductMPN' => $product['ean13'], /* */
+ 'CartProductCategoryName' => $product['category'], /* */
+ 'CartProductCategoryID' => $product['id_category_default'] /* */
+ );
+ }
+
+ return $products;
+ }
+
+ public function getContent() {
+ if (Tools::isSubmit('btnSubmit')) {
+ $this->_postValidation();
+
+ if (!count($this->_postErrors)) {
+ $this->_postProcess();
+ } else {
+ foreach ($this->_postErrors as $err) {
+ $this->_html .= $this->displayError($err);
+ }
+ }
+ } else {
+ $this->_html .= '
';
+ }
+
+ $this->_html .= $this->display(__FILE__, '/views/templates/admin/infos.tpl');
+
+ if (version_compare(_PS_VERSION_, '1.6', '<')) {
+ /* Prestashop parameter names must not exceed 32 chars for v < 1.6 */
+ $this->assignSmartyVariable('PAYXPERT_ORIGINATOR',
+ Tools::safeOutput(Tools::getValue('PAYXPERT_ORIGINATOR', Configuration::get('PAYXPERT_ORIGINATOR'))));
+ $this->assignSmartyVariable('PAYXPERT_URL', Tools::safeOutput(Tools::getValue('PAYXPERT_URL', Configuration::get('PAYXPERT_URL'))));
+
+ $merchantNotifications = (Configuration::get('PAYXPERT_MERCHANT_NOTIF') == "true") ? "true" : "false";
+ if (Tools::getValue('PAYXPERT_MERCHANT_NOTIF')) {
+ $merchantNotifications = (in_array(Tools::getValue('PAYXPERT_MERCHANT_NOTIF'), array("true", "1", "on"))) ? "true" : "false";
+ }
+ $this->assignSmartyVariable('PAYXPERT_MERCHANT_NOTIF', $merchantNotifications);
+ $this->assignSmartyVariable('PAYXPERT_MERCHANT_NOTIF_TO',
+ Tools::safeOutput(Tools::getValue('PAYXPERT_MERCHANT_NOTIF_TO', Configuration::get('PAYXPERT_MERCHANT_NOTIF_TO'))));
+ $this->assignSmartyVariable('PAYXPERT_MERCHANT_NOTIF_LANG',
+ Tools::safeOutput(Tools::getValue('PAYXPERT_MERCHANT_NOTIF_LANG', Configuration::get('PAYXPERT_MERCHANT_NOTIF_LANG'))));
+
+ $this->_html .= $this->display(__FILE__, '/views/templates/admin/config.tpl');
+ } else {
+ $this->_html .= $this->renderForm();
+ }
+
+ return $this->_html;
+ }
+
+ public function getConfigFieldsValues() {
+ // Handle checkboxes
+ $merchantNotif = Tools::getValue('PAYXPERT_MERCHANT_NOTIF', Configuration::get('PAYXPERT_MERCHANT_NOTIF'));
+
+ $result = array( /* */
+ 'PAYXPERT_ORIGINATOR' => Tools::getValue('PAYXPERT_ORIGINATOR', Configuration::get('PAYXPERT_ORIGINATOR')), /* */
+ 'PAYXPERT_URL' => Tools::getValue('PAYXPERT_URL', Configuration::get('PAYXPERT_URL')), /* */
+ 'PAYXPERT_MERCHANT_NOTIF' => ($merchantNotif === "true" || $merchantNotif == 1) ? 1 : 0, /* */
+ 'PAYXPERT_MERCHANT_NOTIF_TO' => Tools::getValue('PAYXPERT_MERCHANT_NOTIF_TO', Configuration::get('PAYXPERT_MERCHANT_NOTIF_TO')), /* */
+ 'PAYXPERT_MERCHANT_NOTIF_LANG' => Tools::getValue('PAYXPERT_MERCHANT_NOTIF_LANG',
+ Configuration::get('PAYXPERT_MERCHANT_NOTIF_LANG')), /* */
+ );
+
+ if (version_compare(_PS_VERSION_, '1.7', '>=')) {
+ $creditCardPaymentType = Tools::getValue('PAYXPERT_PAYMENT_TYPE_CREDIT_CARD', Configuration::get('PAYXPERT_PAYMENT_TYPE_CREDIT_CARD'));
+ $sofortPaymentType = Tools::getValue('PAYXPERT_PAYMENT_TYPE_BANK_TRANSFERT_SOFORT',
+ Configuration::get('PAYXPERT_PAYMENT_TYPE_BANK_TRANSFERT_SOFORT'));
+ $przelewy24PaymentType = Tools::getValue('PAYXPERT_PAYMENT_TYPE_BANK_TRANSFERT_PRZELEWY24',
+ Configuration::get('PAYXPERT_PAYMENT_TYPE_BANK_TRANSFERT_PRZELEWY24'));
+ $idealPaymentType = Tools::getValue('PAYXPERT_PAYMENT_TYPE_BANK_TRANSFERT_IDEAL',
+ Configuration::get('PAYXPERT_PAYMENT_TYPE_BANK_TRANSFERT_IDEAL'));
+
+ $result['PAYXPERT_PAYMENT_TYPE_CREDIT_CARD'] = ($creditCardPaymentType === "true" || $creditCardPaymentType == 1) ? 1 : 0;
+ $result['PAYXPERT_PAYMENT_TYPE_BANK_TRANSFERT_SOFORT'] = ($sofortPaymentType === "true" || $sofortPaymentType == 1) ? 1 : 0;
+ $result['PAYXPERT_PAYMENT_TYPE_BANK_TRANSFERT_PRZELEWY24'] = ($przelewy24PaymentType === "true" || $przelewy24PaymentType == 1) ? 1 : 0;
+ $result['PAYXPERT_PAYMENT_TYPE_BANK_TRANSFERT_IDEAL'] = ($idealPaymentType === "true" || $idealPaymentType == 1) ? 1 : 0;
+ }
+
+ return $result;
+ }
+
+ public function renderForm() {
+ $fields_form = array(
+ 'form' => array( /* */
+ 'legend' => array( /* */
+ 'title' => $this->l('Settings'), /* */
+ 'icon' => 'icon-gears' /* */
+ ), /* */
+ 'input' => array( /* */
+ array( /* */
+ 'type' => 'text', /* */
+ 'name' => 'PAYXPERT_ORIGINATOR', /* */
+ 'label' => $this->l('Originator ID'), /* */
+ 'desc' => $this->l('The identifier of your Originator'), /* */
+ 'required' => true /* */
+ ),
+ array( /* */
+ 'type' => 'password', /* */
+ 'name' => 'PAYXPERT_PASSWORD', /* */
+ 'label' => $this->l('Originator password'), /* */
+ 'desc' => $this->l('The password associated with your Originator (leave empty to keep the current one)'), /* */
+ 'hint' => $this->l('Leave empty to keep the current one'), /* */
+ 'required' => false /* */
+ ),
+ array( /* */
+ 'type' => 'text', /* */
+ 'name' => 'PAYXPERT_URL', /* */
+ 'label' => $this->l('Payment Page URL'), /* */
+ 'desc' => $this->l('Leave this field empty unless you have been given an URL'), /* */
+ 'required' => false /* */
+ ),
+ array( /* */
+ 'type' => 'switch', /* */
+ 'name' => 'PAYXPERT_MERCHANT_NOTIF', /* */
+ 'label' => $this->l('Merchant notifications'), /* */
+ 'desc' => $this->l('Whether or not to send a notification to the merchant for each processed payment'), /* */
+ 'required' => false, /* */
+ 'is_bool' => true, /* */
+ 'values' => array( /* */
+ array('id' => 'notif_on', 'value' => 1, 'label' => $this->l('Enabled')), /* */
+ array('id' => 'notif_off', 'value' => 0, 'label' => $this->l('Disabled')) /* */
+ ) /* */
+ ), /* */
+ array( /* */
+ 'type' => 'text', /* */
+ 'name' => 'PAYXPERT_MERCHANT_NOTIF_TO', /* */
+ 'label' => $this->l('Merchant notifications recipient'), /* */
+ 'desc' => $this->l('Recipient email address for merchant notifications'), /* */
+ 'required' => false, /* */
+ 'size' => 100 /* */
+ ), /* */
+ array( /* */
+ 'type' => 'select', /* */
+ 'name' => 'PAYXPERT_MERCHANT_NOTIF_LANG', /* */
+ 'label' => $this->l('Merchant notifications lang'), /* */
+ 'desc' => $this->l('Language to use for merchant notifications'), /* */
+ 'required' => false, /* */
+ 'options' => array( /* */
+ 'query' => array( /* */
+ array('id_option' => 'en', 'name' => $this->l('English')), /* */
+ array('id_option' => 'fr', 'name' => $this->l('French')), /* */
+ array('id_option' => 'es', 'name' => $this->l('Spanish')), /* */
+ array('id_option' => 'it', 'name' => $this->l('Italian')) /* */
+ ), /* */
+ 'id' => 'id_option', /* */
+ 'name' => 'name' /* */
+ ) /* */
+ ) /* */
+ ), /* */
+ 'submit' => array('title' => $this->l('Update settings')) /* */
+ ) /* */
+ );
+
+ if (version_compare(_PS_VERSION_, '1.7', '>=')) {
+ $fields_form['form']['input'][] = array( /* */
+ 'type' => 'switch', /* */
+ 'name' => 'PAYXPERT_PAYMENT_TYPE_CREDIT_CARD', /* */
+ 'label' => $this->l('Credit Card'), /* */
+ 'desc' => $this->l('Enable payment type: Credit Card'), /* */
+ 'required' => false, /* */
+ 'is_bool' => true, /* */
+ 'values' => array(/* */
+ array('id' => 'cc_on', 'value' => 1, 'label' => $this->l('Enabled')), /* */
+ array('id' => 'cc_off', 'value' => 0, 'label' => $this->l('Disabled')) /* */
+ ) /* */
+ );
+ $fields_form['form']['input'][] = array( /* */
+ 'type' => 'switch', /* */
+ 'name' => 'PAYXPERT_PAYMENT_TYPE_BANK_TRANSFERT_SOFORT', /* */
+ 'label' => $this->l('Bank Transfert via Sofort'), /* */
+ 'desc' => $this->l('Enable payment type: Bank Transfer via Sofort'), /* */
+ 'required' => false, /* */
+ 'is_bool' => true, /* */
+ 'values' => array(/* */
+ array('id' => 'sofort_on', 'value' => 1, 'label' => $this->l('Enabled')), /* */
+ array('id' => 'sofort_off', 'value' => 0, 'label' => $this->l('Disabled')) /* */
+ ) /* */
+ );
+ $fields_form['form']['input'][] = array( /* */
+ 'type' => 'switch', /* */
+ 'name' => 'PAYXPERT_PAYMENT_TYPE_BANK_TRANSFERT_PRZELEWY24', /* */
+ 'label' => $this->l('Bank Transfert via Przelewy24'), /* */
+ 'desc' => $this->l('Enable payment type: Bank Transfer via Przelewy24'), /* */
+ 'required' => false, /* */
+ 'is_bool' => true, /* */
+ 'values' => array(/* */
+ array('id' => 'przelewy24_on', 'value' => 1, 'label' => $this->l('Enabled')), /* */
+ array('id' => 'przelewy24_off', 'value' => 0, 'label' => $this->l('Disabled')) /* */
+ ) /* */
+ );
+ $fields_form['form']['input'][] = array( /* */
+ 'type' => 'switch', /* */
+ 'name' => 'PAYXPERT_PAYMENT_TYPE_BANK_TRANSFERT_IDEAL', /* */
+ 'label' => $this->l('Bank Transfert via iDeal'), /* */
+ 'desc' => $this->l('Enable payment type: Bank Transfer via iDeal'), /* */
+ 'required' => false, /* */
+ 'is_bool' => true, /* */
+ 'values' => array(/* */
+ array('id' => 'ideal_on', 'value' => 1, 'label' => $this->l('Enabled')), /* */
+ array('id' => 'ideal_off', 'value' => 0, 'label' => $this->l('Disabled')) /* */
+ ) /* */
+ );
+ }
+
+ $helper = new HelperForm();
+ $helper->show_toolbar = false;
+ $helper->table = $this->table;
+ $lang = new Language((int) Configuration::get('PS_LANG_DEFAULT'));
+ $helper->default_form_language = $lang->id;
+ $helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') ? Configuration::get(
+ 'PS_BO_ALLOW_EMPLOYEE_FORM_LANG') : 0;
+ $this->fields_form = array();
+
+ $helper->identifier = $this->identifier;
+ $helper->submit_action = 'btnSubmit';
+ $helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false) . '&configure=' . $this->name . '&tab_module=' .
+ $this->tab . '&module_name=' . $this->name;
+ $helper->token = Tools::getAdminTokenLite('AdminModules');
+ $helper->tpl_vars = array( /* */
+ 'fields_value' => $this->getConfigFieldsValues(), /* */
+ 'languages' => $this->context->controller->getLanguages(), /* */
+ 'id_language' => $this->context->language->id /* */
+ );
+
+ return $helper->generateForm(array($fields_form));
+ }
+
+ private function _postValidation() {
+ if (Tools::isSubmit('btnSubmit')) {
+ if (!Tools::getValue('PAYXPERT_ORIGINATOR')) {
+ $this->_postErrors[] = $this->l('Originator is required.');
+ }
+
+ if (!Configuration::get('PAYXPERT_PASSWORD') && !Tools::getValue('PAYXPERT_PASSWORD')) {
+ $this->_postErrors[] = $this->l('Password is required.');
+ }
+
+ if (in_array(Tools::getValue('PAYXPERT_MERCHANT_NOTIF'), array("true", "1", "on")) && !Tools::getValue('PAYXPERT_MERCHANT_NOTIF_TO')) {
+ $this->_postErrors[] = $this->l('Merchant notifications recipient is required.');
+ }
+
+ if (Tools::getValue('PAYXPERT_MERCHANT_NOTIF_TO') && !Validate::isEmail(Tools::getValue('PAYXPERT_MERCHANT_NOTIF_TO'))) {
+ $this->_postErrors[] = $this->l('Merchant notifications recipient must be a valid email address.');
+ }
+
+ if (!in_array(Tools::getValue('PAYXPERT_MERCHANT_NOTIF_LANG'), array("en", "fr", "es", "it"))) {
+ $this->_postErrors[] = $this->l('Merchant notification lang is not valid.');
+ }
+ }
+ }
+
+ protected function _postProcess() {
+ if (Tools::isSubmit('btnSubmit')) {
+ Configuration::updateValue('PAYXPERT_ORIGINATOR', Tools::getValue('PAYXPERT_ORIGINATOR'));
+
+ if (Tools::getValue('PAYXPERT_PASSWORD')) {
+ // Manually handle HTML special chars to avoid losing them
+ Configuration::updateValue('PAYXPERT_PASSWORD', htmlentities(Tools::getValue('PAYXPERT_PASSWORD')));
+ }
+
+ Configuration::updateValue('PAYXPERT_URL', Tools::getValue('PAYXPERT_URL'));
+
+ Configuration::updateValue('PAYXPERT_MERCHANT_NOTIF_TO', Tools::getValue('PAYXPERT_MERCHANT_NOTIF_TO'));
+
+ if (in_array(Tools::getValue('PAYXPERT_MERCHANT_NOTIF_LANG'), array("en", "fr", "es", "it"))) {
+ Configuration::updateValue('PAYXPERT_MERCHANT_NOTIF_LANG', Tools::getValue('PAYXPERT_MERCHANT_NOTIF_LANG'));
+ }
+
+ // Handle checkboxes
+ $checkboxes = array( /* */
+ 'PAYXPERT_MERCHANT_NOTIF' /* */
+ );
+ if (version_compare(_PS_VERSION_, '1.7', '>=')) {
+ $checkboxes[] = 'PAYXPERT_PAYMENT_TYPE_CREDIT_CARD';
+ $checkboxes[] = 'PAYXPERT_PAYMENT_TYPE_BANK_TRANSFERT_SOFORT';
+ $checkboxes[] = 'PAYXPERT_PAYMENT_TYPE_BANK_TRANSFERT_PRZELEWY24';
+ $checkboxes[] = 'PAYXPERT_PAYMENT_TYPE_BANK_TRANSFERT_IDEAL';
+ }
+
+ foreach ($checkboxes as $checkbox) {
+ if (in_array(Tools::getValue($checkbox), array("true", "1", "on"))) {
+ Configuration::updateValue($checkbox, "true");
+ } else {
+ Configuration::updateValue($checkbox, "false");
+ }
+ }
+ }
+
+ if (version_compare(_PS_VERSION_, '1.6', '>=')) {
+ $this->_html .= $this->displayConfirmation($this->l('Configuration updated'));
+ } else {
+ $this->_html .= '
' . $this->l('Configuration updated') . '
';
+
+ return true;
+ }
+ }
+
+ private function checkPaymentTypeAndProvider($paymentType, $paymentProvider) {
+ // For Prestashop >=1.7, check that the payment type is enabled
+ if (version_compare(_PS_VERSION_, '1.7.0', '>=') === true) {
+ switch ($paymentType) {
+ case PayXpert\Connect2Pay\Connect2PayClient::_PAYMENT_TYPE_CREDITCARD:
+ return Configuration::get('PAYXPERT_PAYMENT_TYPE_CREDIT_CARD') === "true";
+ case PayXpert\Connect2Pay\Connect2PayClient::_PAYMENT_TYPE_BANKTRANSFER:
+ if ($paymentProvider !== null) {
+ switch ($paymentProvider) {
+ case PayXpert\Connect2Pay\Connect2PayClient::_PAYMENT_PROVIDER_SOFORT:
+ return Configuration::get('PAYXPERT_PAYMENT_TYPE_BANK_TRANSFERT_SOFORT') === "true";
+ case PayXpert\Connect2Pay\Connect2PayClient::_PAYMENT_PROVIDER_PRZELEWY24:
+ return Configuration::get('PAYXPERT_PAYMENT_TYPE_BANK_TRANSFERT_PRZELEWY24') === "true";
+ case PayXpert\Connect2Pay\Connect2PayClient::_PAYMENT_PROVIDER_IDEALKP:
+ return Configuration::get('PAYXPERT_PAYMENT_TYPE_BANK_TRANSFERT_IDEAL') === "true";
+ }
+ }
+ break;
+ }
+ } else {
+ return true;
+ }
+
+ return false;
+ }
+
+ private function checkCurrency($cart) {
+ $currency_order = new Currency((int) ($cart->id_currency));
+ $currencies_module = $this->getCurrency((int) $cart->id_currency);
+
+ if (is_array($currencies_module)) {
+ foreach ($currencies_module as $currency_module) {
+ if ($currency_order->id == $currency_module['id_currency']) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Get PayXpert Url depending of the env
+ *
+ * @return string Url
+ */
+ public function getPayXpertUrl() {
+ $url = Configuration::get('PAYXPERT_URL');
+
+ if (strlen(trim($url)) <= 0) {
+ $url = 'https://connect2.payxpert.com/';
+ }
+
+ return $url;
+ }
+
+ /* Theses functions are used to support all versions of Prestashop */
+ public function assignSmartyVariable($name, $value) {
+
+ // Check if context smarty variable is available
+ if (isset($this->context->smarty)) {
+ return $this->context->smarty->assign($name, $value);
+ } else {
+ // Use the global variable
+ global $smarty;
+
+ return $smarty->assign($name, $value);
+ }
+ }
+
+ public function getModuleLinkCompat($module, $controller = 'default', $params = null) {
+ if (class_exists('Context')) {
+ if (!$params) {
+ $params = array();
+ }
+
+ return Context::getContext()->link->getModuleLink($module, $controller, $params);
+ } else {
+ if ($controller == 'default') {
+ if ($params) {
+ $params = "?" . $params;
+ }
+
+ return Configuration::get('PS_SSL_ENABLED') ? 'https' : 'http' . '://' . $_SERVER['HTTP_HOST'] . __PS_BASE_URI__ . $module . '.php' .
+ $params;
+ } else {
+ return Configuration::get('PS_SSL_ENABLED') ? 'https' : 'http' . '://' . $_SERVER['HTTP_HOST'] . __PS_BASE_URI__ .
+ 'modules/payxpert/' . $controller . '.php';
+ }
+ }
+ }
+
+ public function getPageLinkCompat($controller, $ssl = null, $id_lang = null, $request = null, $request_url_encode = false, $id_shop = null) {
+ if (class_exists('Context')) {
+ return Context::getContext()->link->getPageLink($controller, $ssl, $id_lang, $request, $request_url_encode, $id_shop);
+ } else {
+ if ($controller == 'contact') {
+ return Configuration::get('PS_SSL_ENABLED') ? 'https' : 'http' . '://' . $_SERVER['HTTP_HOST'] . __PS_BASE_URI__ . 'contact-form.php';
+ } else {
+ $params = (isset($params)) ? "?" . $params : "";
+
+ return Configuration::get('PS_SSL_ENABLED') ? 'https' : 'http' . '://' . $_SERVER['HTTP_HOST'] . __PS_BASE_URI__ . $controller .
+ '.php' . $params;
+ }
+ }
+ }
+
+ public function addLog($message, $severity = 1, $errorCode = null, $objectType = null, $objectId = null, $allowDuplicate = true) {
+ if (class_exists('PrestaShopLogger')) {
+ PrestaShopLogger::addLog($message, $severity, $errorCode, $objectType, $objectId, $allowDuplicate);
+ } else if (class_exists('Logger')) {
+ Logger::addLog($message, $severity, $errorCode, $objectType, $objectId, $allowDuplicate);
+ } else {
+ error_log($message . "(" . $errorCode . ")");
+ }
+ }
+
+ /* Callback authenticity check methods */
+ public static function getCallbackAuthenticityData($orderId, $secure_key) {
+ return sha1($orderId . $secure_key . html_entity_decode(Configuration::get('PAYXPERT_PASSWORD')));
+ }
+
+ public static function checkCallbackAuthenticityData($callbackData, $orderId, $secure_key) {
+ return (strcasecmp($callbackData, PayXpert::getCallbackAuthenticityData($orderId, $secure_key)) === 0);
+ }
+
+ /* Theses functions are only used for Prestashop prior to version 1.5 */
+ public function execPayment($cart) {
+ global $cookie;
+
+ $this->assignSmartyVariable('nbProducts', $cart->nbProducts());
+ $this->assignSmartyVariable('cust_currency', $cart->id_currency);
+ $this->assignSmartyVariable('currencies', $this->getCurrency());
+ $this->assignSmartyVariable('total', $cart->getOrderTotal(true, 3));
+ $this->assignSmartyVariable('isoCode', Language::getIsoById(intval($cookie->id_lang)));
+ $this->assignSmartyVariable('this_path', $this->_path);
+ $this->assignSmartyVariable('this_link', $this->getModuleLinkCompat('payxpert', 'redirect'));
+ $this->assignSmartyVariable('this_link_back', $this->getPageLinkCompat('order', true, NULL, "step=3"));
+
+ return $this->display(__FILE__, '/views/templates/front/payment_execution.tpl');
+ }
+
+ public function displayErrorPage($message) {
+ $this->assignSmartyVariable('errorMessage', $message);
+ $this->assignSmartyVariable('this_link_back', $this->getPageLinkCompat('order', true, NULL, "step=3"));
+
+ return $this->display(__FILE__, '/views/templates/front/payment_error.tpl');
+ }
+}
\ No newline at end of file
diff --git a/modules/payxpert/redirect.php b/modules/payxpert/redirect.php
new file mode 100644
index 0000000..78a4f87
--- /dev/null
+++ b/modules/payxpert/redirect.php
@@ -0,0 +1,39 @@
+isLogged()) {
+ Tools::redirect('authentication.php?back=order.php');
+}
+
+$payxpert = new PayXpert();
+$message = $payxpert->redirect($cart);
+
+echo $payxpert->displayErrorPage($message);
+
+require_once(dirname(__FILE__) . '/../../footer.php');
diff --git a/modules/payxpert/validation.php b/modules/payxpert/validation.php
new file mode 100644
index 0000000..bd3e4c6
--- /dev/null
+++ b/modules/payxpert/validation.php
@@ -0,0 +1,107 @@
+getPayXpertUrl(), Configuration::get('PAYXPERT_ORIGINATOR'),
+ html_entity_decode(Configuration::get('PAYXPERT_PASSWORD')));
+
+if ($c2pClient->handleCallbackStatus()) {
+
+ $status = $c2pClient->getStatus();
+
+ // get the Error code
+ $errorCode = $status->getErrorCode();
+ $errorMessage = $status->getErrorMessage();
+
+ $transaction = $status->getLastTransactionAttempt();
+
+ if ($transaction !== null) {
+ $transactionId = $transaction->getTransactionID();
+
+ $orderId = $status->getOrderID();
+ $amount = number_format($status->getAmount() / 100, 2, '.', '');
+ $callbackData = $status->getCtrlCustomData();
+
+ $message = "PayXpert payment module: ";
+
+ // load the customer cart and perform some checks
+ $cart = new Cart((int) ($orderId));
+ if (!$cart->id) {
+ $message .= "Cart is empty: " . $orderId;
+ error_log($message);
+ }
+
+ $responseStatus = "KO";
+ $responseMessage = "Callback validation failed";
+ $customer = new Customer((int) ($cart->id_customer));
+
+ if (!$customer) {
+ $message .= "Customer is empty for order " . $orderId;
+ error_log($message);
+ } else {
+ if (!PayXpert::checkCallbackAuthenticityData($callbackData, $cart->id, $customer->secure_key)) {
+ $message .= "Invalid callback received for order " . $orderId . ". Validation failed.";
+ error_log($message);
+ } else {
+ $responseStatus = "OK";
+ $responseMessage = "Status recorded";
+
+ $message .= "Error code: " . $errorCode . "
";
+ $message .= "Error message: " . $errorMessage . "
";
+ $message .= "Transaction ID: " . $transactionId . "
";
+ $message .= "Order ID: " . $orderId . "
";
+
+ error_log(str_replace("
", " ", $message));
+
+ // To avoid issue with conversion rate get the amount from the order
+ $amount = $cart->getOrderTotal(true, 3);
+
+ $paymentMean = $payxpert->l('Credit Card') . ' (PayXpert)';
+
+ switch ($errorCode) {
+ case "000":
+ /* Payment OK */
+ $payxpert->validateOrder((int) $orderId, _PS_OS_PAYMENT_, $amount, $paymentMean, $message);
+ break;
+ default:
+ $payxpert->validateOrder((int) $orderId, _PS_OS_ERROR_, $amount, $paymentMean, $message);
+ break;
+ }
+ }
+ }
+ }
+
+ // Send a response to mark this transaction as notified
+ $response = array("status" => $responseStatus, "message" => $responseMessage);
+ header("Content-type: application/json");
+ echo json_encode($response);
+}
diff --git a/modules/payxpert/views/index.php b/modules/payxpert/views/index.php
new file mode 100644
index 0000000..69b76d9
--- /dev/null
+++ b/modules/payxpert/views/index.php
@@ -0,0 +1,36 @@
+
+* @copyright 2007-2013 PrestaShop SA
+
+* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
+* International Registered Trademark & Property of PrestaShop SA
+*/
+
+header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
+header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
+
+header('Cache-Control: no-store, no-cache, must-revalidate');
+header('Cache-Control: post-check=0, pre-check=0', false);
+header('Pragma: no-cache');
+
+header('Location: ../../../');
+exit;
\ No newline at end of file
diff --git a/modules/payxpert/views/templates/admin/config.tpl b/modules/payxpert/views/templates/admin/config.tpl
new file mode 100644
index 0000000..f3d99ea
--- /dev/null
+++ b/modules/payxpert/views/templates/admin/config.tpl
@@ -0,0 +1,78 @@
+{*
+* Copyright 2013-2017 PayXpert
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+* @author Regis Vidal
+*
+*}
+
+
diff --git a/modules/payxpert/views/templates/admin/index.php b/modules/payxpert/views/templates/admin/index.php
new file mode 100644
index 0000000..a230e5a
--- /dev/null
+++ b/modules/payxpert/views/templates/admin/index.php
@@ -0,0 +1,35 @@
+
+* @copyright 2007-2013 PrestaShop SA
+* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
+* International Registered Trademark & Property of PrestaShop SA
+*/
+
+header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
+header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
+
+header("Cache-Control: no-store, no-cache, must-revalidate");
+header("Cache-Control: post-check=0, pre-check=0", false);
+header("Pragma: no-cache");
+
+header("Location: ../");
+exit;
\ No newline at end of file
diff --git a/modules/payxpert/views/templates/admin/infos.tpl b/modules/payxpert/views/templates/admin/infos.tpl
new file mode 100644
index 0000000..417d1ad
--- /dev/null
+++ b/modules/payxpert/views/templates/admin/infos.tpl
@@ -0,0 +1,26 @@
+{*
+ Copyright 2013-2017 PayXpert
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ @author Alexandre Chatiron
+*}
+{if $smarty.const._PS_VERSION_ >= 1.6}
+
+{/if}
+
+
{l s='This module allows you to accept secure payments.' mod='payxpert'}
+
+{if $smarty.const._PS_VERSION_ >= 1.6}
+
+{/if}
\ No newline at end of file
diff --git a/modules/payxpert/views/templates/front/index.php b/modules/payxpert/views/templates/front/index.php
new file mode 100644
index 0000000..422fa9d
--- /dev/null
+++ b/modules/payxpert/views/templates/front/index.php
@@ -0,0 +1,36 @@
+
+* @copyright 2007-2013 PrestaShop SA
+
+* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
+* International Registered Trademark & Property of PrestaShop SA
+*/
+
+header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
+header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
+
+header('Cache-Control: no-store, no-cache, must-revalidate');
+header('Cache-Control: post-check=0, pre-check=0', false);
+header('Pragma: no-cache');
+
+header('Location: ../../../../../');
+exit;
\ No newline at end of file
diff --git a/modules/payxpert/views/templates/front/payment_error.tpl b/modules/payxpert/views/templates/front/payment_error.tpl
new file mode 100644
index 0000000..ce2df2e
--- /dev/null
+++ b/modules/payxpert/views/templates/front/payment_error.tpl
@@ -0,0 +1,53 @@
+{*
+* Copyright 2013-2017 PayXpert
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+* @author Regis Vidal
+*
+*}
+{capture name=path}{l s='Credit Card payment.' mod='payxpert'}{/capture}
+{if $smarty.const._PS_VERSION_ < 1.6}{include file="$tpl_dir./breadcrumb.tpl"}{/if}
+{l s='Order summary' mod='payxpert'}
+
+{assign var='current_step' value='payment'}
+{include file="$tpl_dir./order-steps.tpl"}
+
+{if $smarty.const._PS_VERSION_ >= 1.6}
+
+{/if}
\ No newline at end of file
diff --git a/modules/payxpert/views/templates/front/payment_error17.tpl b/modules/payxpert/views/templates/front/payment_error17.tpl
new file mode 100644
index 0000000..c786fa1
--- /dev/null
+++ b/modules/payxpert/views/templates/front/payment_error17.tpl
@@ -0,0 +1,47 @@
+{*
+* Copyright 2013-2017 PayXpert
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+* @author Regis Vidal
+*
+*}
+{capture name=path}{l s='Credit Card payment.' mod='payxpert'}{/capture}
+
+{extends file='page.tpl'}
+{l s='Order summary' mod='payxpert'}
+
+{assign var='current_step' value='payment'}
+
+{block name="content"}
+
+
+
+
+
Error
+
+ {$errorMessage}
+
+
+
+
+
+ {l s='Other payment methods' mod='payxpert'}
+
+
+
+{/block}
\ No newline at end of file
diff --git a/modules/payxpert/views/templates/front/payment_execution.tpl b/modules/payxpert/views/templates/front/payment_execution.tpl
new file mode 100644
index 0000000..75f85bd
--- /dev/null
+++ b/modules/payxpert/views/templates/front/payment_execution.tpl
@@ -0,0 +1,78 @@
+{*
+* Copyright 2013-2017 PayXpert
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+* @author Regis Vidal
+* @copyright 2013-2017 PayXpert
+* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0 (the "License")
+*}
+
+{capture name=path}{l s='Credit Card payment.' mod='payxpert'}{/capture}
+
+{if $smarty.const._PS_VERSION_ < 1.6}
+{include file="$tpl_dir./breadcrumb.tpl"}
+{/if}
+{l s='Order summary' mod='payxpert'}
+
+{assign var='current_step' value='payment'}
+{include file="$tpl_dir./order-steps.tpl"}
+
+{if $nbProducts <= 0}
+ {l s='Your shopping cart is empty.' mod='payxpert'}
+{else}
+ {if $smarty.const._PS_VERSION_ < 1.6}{l s='Credit Card payment.' mod='payxpert'}
{/if}
+
+{/if}
\ No newline at end of file
diff --git a/modules/payxpert/views/templates/front/payment_execution_bank_transfer.tpl b/modules/payxpert/views/templates/front/payment_execution_bank_transfer.tpl
new file mode 100644
index 0000000..c06f378
--- /dev/null
+++ b/modules/payxpert/views/templates/front/payment_execution_bank_transfer.tpl
@@ -0,0 +1,68 @@
+{*
+* Copyright 2013-2017 PayXpert
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+* @author Regis Vidal
+* @copyright 2013-2017 PayXpert
+* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0 (the "License")
+*}
+
+{extends file=$layout}
+
+{block name='content'}
+
+
+
{l s='Order confirmation' mod='payxpert'}
+
+ {if $nbProducts <= 0}
+
{l s='Your shopping cart is empty.' mod='payxpert'}
+ {else}
+
+ {assign var='current_step' value='payment'}
+
+
+
+
+
+ {l s='You have chosen to pay by Bank Transfer.' mod='payxpert'}
+
+
+ {capture name='amount'}{Tools::displayPrice($total, $cust_currency)}{/capture}
+ {assign var='order_amount' value=$smarty.capture.amount}
+ {l s='The total amount of your order is %s.' sprintf=[$order_amount|escape:'html':'UTF-8'] mod='payxpert'}
+
+ {l s='You will be able to pay by entering your bank account information on the next pages using a secured payment form.' mod='payxpert'}
+
+
+ {l s='Please confirm your order by clicking the "Pay my order" button below.' mod='payxpert'}
+
+
+
+
+ {/if}
+
+{/block}
\ No newline at end of file
diff --git a/modules/payxpert/views/templates/front/payment_execution_credit_card.tpl b/modules/payxpert/views/templates/front/payment_execution_credit_card.tpl
new file mode 100644
index 0000000..794eedb
--- /dev/null
+++ b/modules/payxpert/views/templates/front/payment_execution_credit_card.tpl
@@ -0,0 +1,68 @@
+{*
+* Copyright 2013-2017 PayXpert
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+* @author Regis Vidal
+* @copyright 2013-2017 PayXpert
+* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0 (the "License")
+*}
+
+{extends file=$layout}
+
+{block name='content'}
+
+
+
{l s='Order confirmation' mod='payxpert'}
+
+ {if $nbProducts <= 0}
+
{l s='Your shopping cart is empty.' mod='payxpert'}
+ {else}
+
+ {assign var='current_step' value='payment'}
+
+
+
+
+
+ {l s='You have chosen to pay by Credit Card.' mod='payxpert'}
+
+
+ {capture name='amount'}{Tools::displayPrice($total, $cust_currency)}{/capture}
+ {assign var='order_amount' value=$smarty.capture.amount}
+ {l s='The total amount of your order is %s.' sprintf=[$order_amount|escape:'html':'UTF-8'] mod='payxpert'}
+
+ {l s='You will be able to pay by entering your credit card information on the next page using a secured payment page.' mod='payxpert'}
+
+
+ {l s='Please confirm your order by clicking the "Pay my order" button below.' mod='payxpert'}
+
+
+
+
+ {/if}
+
+{/block}
\ No newline at end of file
diff --git a/modules/payxpert/views/templates/front/payment_infos_bank_transfer_ideal.tpl b/modules/payxpert/views/templates/front/payment_infos_bank_transfer_ideal.tpl
new file mode 100644
index 0000000..37f2f9c
--- /dev/null
+++ b/modules/payxpert/views/templates/front/payment_infos_bank_transfer_ideal.tpl
@@ -0,0 +1,3 @@
+
+ {l s='Use your bank account information with the iDeal provider to pay your order' mod='payxpert'}
+
\ No newline at end of file
diff --git a/modules/payxpert/views/templates/front/payment_infos_bank_transfer_przelewy24.tpl b/modules/payxpert/views/templates/front/payment_infos_bank_transfer_przelewy24.tpl
new file mode 100644
index 0000000..6539034
--- /dev/null
+++ b/modules/payxpert/views/templates/front/payment_infos_bank_transfer_przelewy24.tpl
@@ -0,0 +1,3 @@
+
+ {l s='Use your bank account information with the Przelewy24 provider to pay your order' mod='payxpert'}
+
\ No newline at end of file
diff --git a/modules/payxpert/views/templates/front/payment_infos_bank_transfer_sofort.tpl b/modules/payxpert/views/templates/front/payment_infos_bank_transfer_sofort.tpl
new file mode 100644
index 0000000..b07ab79
--- /dev/null
+++ b/modules/payxpert/views/templates/front/payment_infos_bank_transfer_sofort.tpl
@@ -0,0 +1,3 @@
+
+ {l s='Use your bank account information with the Sofort provider to pay your order' mod='payxpert'}
+
\ No newline at end of file
diff --git a/modules/payxpert/views/templates/front/payment_infos_credit_card.tpl b/modules/payxpert/views/templates/front/payment_infos_credit_card.tpl
new file mode 100644
index 0000000..b971ee3
--- /dev/null
+++ b/modules/payxpert/views/templates/front/payment_infos_credit_card.tpl
@@ -0,0 +1,3 @@
+
+ {l s='Use your credit card information in a secured form to pay your order' mod='payxpert'}
+
\ No newline at end of file
diff --git a/modules/payxpert/views/templates/hook/index.php b/modules/payxpert/views/templates/hook/index.php
new file mode 100644
index 0000000..422fa9d
--- /dev/null
+++ b/modules/payxpert/views/templates/hook/index.php
@@ -0,0 +1,36 @@
+
+* @copyright 2007-2013 PrestaShop SA
+
+* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
+* International Registered Trademark & Property of PrestaShop SA
+*/
+
+header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
+header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
+
+header('Cache-Control: no-store, no-cache, must-revalidate');
+header('Cache-Control: post-check=0, pre-check=0', false);
+header('Pragma: no-cache');
+
+header('Location: ../../../../../');
+exit;
\ No newline at end of file
diff --git a/modules/payxpert/views/templates/hook/orderconfirmation.tpl b/modules/payxpert/views/templates/hook/orderconfirmation.tpl
new file mode 100644
index 0000000..e6ae09b
--- /dev/null
+++ b/modules/payxpert/views/templates/hook/orderconfirmation.tpl
@@ -0,0 +1,37 @@
+{*
+* Copyright 2013-2017 PayXpert
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+* @author Regis Vidal
+* @copyright 2013-2017 PayXpert
+* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0 (the "License")
+*}
+{if $status == 'ok'}
+ {l s='Your order has been completed.' mod='payxpert'}
+
{l s='It will be shipped as soon as possible.' mod='payxpert'}
+
{l s='For any questions or for further information, please contact our' mod='payxpert'} {l s='customer support' mod='payxpert'}.
+
+{else}
+ {if $status == 'pending'}
+ {l s='Your order is still pending.' mod='payxpert'}
+
{l s='Your order will be shipped as soon as we receive your payment.' mod='payxpert'}
+
{l s='For any questions or for further information, please contact our' mod='payxpert'} {l s='customer support' mod='payxpert'}.
+
+ {else}
+
+ {l s='We noticed a problem with your order. If you think this is an error, you can contact our' mod='payxpert'}
+ {l s='customer support' mod='payxpert'}.
+
+ {/if}
+{/if}
\ No newline at end of file
diff --git a/modules/payxpert/views/templates/hook/payment.tpl b/modules/payxpert/views/templates/hook/payment.tpl
new file mode 100644
index 0000000..1d5e112
--- /dev/null
+++ b/modules/payxpert/views/templates/hook/payment.tpl
@@ -0,0 +1,36 @@
+{*
+* Copyright 2013-2014 PayXpert
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+* @author Regis Vidal
+* @copyright 2013-2017 PayXpert
+* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0 (the "License")
+*}
+
+{if $smarty.const._PS_VERSION_ >= 1.6}
+
+{/if}
\ No newline at end of file
diff --git a/modules/payxpert/views/templates/index.php b/modules/payxpert/views/templates/index.php
new file mode 100644
index 0000000..54b3024
--- /dev/null
+++ b/modules/payxpert/views/templates/index.php
@@ -0,0 +1,36 @@
+
+* @copyright 2007-2013 PrestaShop SA
+
+* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
+* International Registered Trademark & Property of PrestaShop SA
+*/
+
+header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
+header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
+
+header('Cache-Control: no-store, no-cache, must-revalidate');
+header('Cache-Control: post-check=0, pre-check=0', false);
+header('Pragma: no-cache');
+
+header('Location: ../../../../');
+exit;
\ No newline at end of file
diff --git a/readme.txt b/readme.txt
new file mode 100644
index 0000000..ca1612f
--- /dev/null
+++ b/readme.txt
@@ -0,0 +1,46 @@
+//-----------------------------------------------------------------
+// Prestashop PayXpert Payment Module
+// Version for Prestashop 1.4.X to 1.7.x
+//------------------------------------------------------------------
+
+This version works with all version of Prestashop
+
+The author of this plugin can NEVER be held responsible for this software.
+There is no warranty what so ever. You accept this by using this software.
+
+Changelog
+=========
+1.0.7 - Supports Prestashop 1.7
+1.0.1 - Improve Prestashop versions support
+1.0.0 - Initial Release
+
+Automatic Installation
+======================
+1. In Prestashop Admin panel, go to "Modules"
+
+2. Choose "Add a new module" or "Add a module from my computer" (according to your Prestashop version)
+
+3. Using the "Module file" form field, select the PayXpert module zip archive and click "Upload this module"
+
+4. Locate the PayXpert entry in the module list and select install
+
+5. According to your Prestashop version, either the configure page will be displayed or select Configure and setup your information
+
+6. Save your settings and you'll be ready to start using the module
+
+Manual Installation
+===================
+1. Unzip the module zip archive
+
+2. Upload the "payxpert" folder to your Prestashop modules folder. No files will be overwritten, only added
+
+3. Go to the admin panel. Select Modules and then Payments. Locate the PayXpert entry in the module list and select install
+
+4. After installation, select Configure and setup your information
+
+5. Save your settings and you'll be ready to start using the module
+
+Support
+============
+
+Please visit the PayXpert website (http://www.payxpert.com) for our support contact details.
\ No newline at end of file