Module Maintenance + création du module Recette
This commit is contained in:
49
local/modules/PayPlugModule/Command/TreatOrderMultiPaymentCommand.php
Executable file
49
local/modules/PayPlugModule/Command/TreatOrderMultiPaymentCommand.php
Executable file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace PayPlugModule\Command;
|
||||
|
||||
use PayPlugModule\Event\PayPlugPaymentEvent;
|
||||
use PayPlugModule\Model\OrderPayPlugMultiPayment;
|
||||
use PayPlugModule\Model\OrderPayPlugMultiPaymentQuery;
|
||||
use Propel\Runtime\ActiveQuery\Criteria;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Thelia\Command\ContainerAwareCommand;
|
||||
|
||||
class TreatOrderMultiPaymentCommand extends ContainerAwareCommand
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName("payplug:treat:multi_payment")
|
||||
->setDescription("Treat multi payment order");
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$this->initRequest();
|
||||
$dispatcher = $this->getDispatcher();
|
||||
$today = (new \DateTime())->setTime(0,0,0,0);
|
||||
|
||||
$todayPlannedOrderPayments = OrderPayPlugMultiPaymentQuery::create()
|
||||
->filterByPaidAt(null, Criteria::ISNULL)
|
||||
->filterByPlannedAt($today)
|
||||
->find();
|
||||
|
||||
/** @var OrderPayPlugMultiPayment $todayPlannedOrderPayment */
|
||||
foreach ($todayPlannedOrderPayments as $todayPlannedOrderPayment) {
|
||||
$output->writeln($todayPlannedOrderPayment->getId());
|
||||
|
||||
$order = $todayPlannedOrderPayment->getOrder();
|
||||
$paymentEvent = @(new PayPlugPaymentEvent())->buildFromOrder($order)
|
||||
->setAmount($todayPlannedOrderPayment->getAmount())
|
||||
->setPaymentMethod($todayPlannedOrderPayment->getPaymentMethod())
|
||||
->setInitiator("MERCHANT");
|
||||
|
||||
$dispatcher->dispatch(PayPlugPaymentEvent::CREATE_PAYMENT_EVENT, $paymentEvent);
|
||||
|
||||
$todayPlannedOrderPayment->setPaymentId($paymentEvent->getPaymentId())
|
||||
->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
77
local/modules/PayPlugModule/Config/config.xml
Executable file
77
local/modules/PayPlugModule/Config/config.xml
Executable file
@@ -0,0 +1,77 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<config xmlns="http://thelia.net/schema/dic/config"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://thelia.net/schema/dic/config http://thelia.net/schema/dic/config/thelia-1.0.xsd">
|
||||
|
||||
<loops>
|
||||
<!-- sample definition
|
||||
<loop name="MySuperLoop" class="PayPlugModule\Loop\MySuperLoop" />
|
||||
-->
|
||||
</loops>
|
||||
|
||||
<forms>
|
||||
<form name="payplugmodule_configuration_form" class="PayPlugModule\Form\ConfigurationForm" />
|
||||
<form name="payplugmodule_order_action_form" class="PayPlugModule\Form\OrderActionForm" />
|
||||
<form name="payplugmodule_order_action_form_refund" class="PayPlugModule\Form\OrderRefundForm" />
|
||||
</forms>
|
||||
|
||||
<commands>
|
||||
<command class="PayPlugModule\Command\TreatOrderMultiPaymentCommand" />
|
||||
</commands>
|
||||
|
||||
<services>
|
||||
<service id="payplugmodule_payment_service" class="PayPlugModule\Service\PaymentService">
|
||||
<argument type="service" id="event_dispatcher"/>
|
||||
</service>
|
||||
<service id="payplugmodule_order_status_service" class="PayPlugModule\Service\OrderStatusService">
|
||||
<argument type="service" id="event_dispatcher"/>
|
||||
</service>
|
||||
<service id="payplugmodule_notification_listener" class="PayPlugModule\EventListener\NotificationListener">
|
||||
<argument type="service" id="event_dispatcher"/>
|
||||
<argument type="service" id="payplugmodule_order_status_service"/>
|
||||
<tag name="kernel.event_subscriber"/>
|
||||
</service>
|
||||
<service id="payplugmodule_payment_listener" class="PayPlugModule\EventListener\PaymentListener">
|
||||
<argument type="service" id="event_dispatcher"/>
|
||||
<argument type="service" id="payplugmodule_order_status_service"/>
|
||||
<tag name="kernel.event_subscriber"/>
|
||||
</service>
|
||||
<service id="payplugmodule_order_listener" class="PayPlugModule\EventListener\OrderListener">
|
||||
<argument type="service" id="payplugmodule_payment_service"/>
|
||||
<tag name="kernel.event_subscriber"/>
|
||||
</service>
|
||||
<service id="payplugmodule_form_extend_order_listener" class="PayPlugModule\EventListener\FormExtend\OrderFormListener">
|
||||
<argument type="service" id="request_stack"/>
|
||||
<tag name="kernel.event_subscriber"/>
|
||||
</service>
|
||||
<service id="payplugmodule_conformation_emil_listener" class="PayPlugModule\EventListener\ConfirmationEmailListener">
|
||||
<argument type="service" id="mailer"/>
|
||||
<tag name="kernel.event_subscriber"/>
|
||||
</service>
|
||||
</services>
|
||||
|
||||
<hooks>
|
||||
<hook id="payplugmodule_back_hook" class="PayPlugModule\Hook\BackHookManager">
|
||||
<tag name="hook.event_listener" event="order-edit.payment-module-bottom" type="back" method="onOrderEditPaymentModuleBottom"/>
|
||||
<tag name="hook.event_listener" event="order.edit-js " type="back" templates="js:PayPlugModule/order_pay_plug.js"/>
|
||||
</hook>
|
||||
<hook id="payplugmodule_front_hook" class="PayPlugModule\Hook\FrontHookManager">
|
||||
<argument type="service" id="thelia.taxengine"/>
|
||||
<tag name="hook.event_listener" event="order-invoice.after-javascript-include" type="front" method="onOrderInvoiceAfterJsInclude"/>
|
||||
<tag name="hook.event_listener" event="order-invoice.payment-extra" type="front" method="onOrderInvoicePaymentExtra"/>
|
||||
</hook>
|
||||
</hooks>
|
||||
|
||||
<!--
|
||||
<exports>
|
||||
|
||||
</exports>
|
||||
-->
|
||||
|
||||
<!--
|
||||
<imports>
|
||||
|
||||
</imports>
|
||||
-->
|
||||
</config>
|
||||
32
local/modules/PayPlugModule/Config/module.xml
Executable file
32
local/modules/PayPlugModule/Config/module.xml
Executable file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module xmlns="http://thelia.net/schema/dic/module"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://thelia.net/schema/dic/module http://thelia.net/schema/dic/module/module-2_2.xsd">
|
||||
<fullnamespace>PayPlugModule\PayPlugModule</fullnamespace>
|
||||
<descriptive locale="en_US">
|
||||
<title>PayPlug payment module</title>
|
||||
<subtitle>https://www.payplug.com</subtitle>
|
||||
</descriptive>
|
||||
<descriptive locale="fr_FR">
|
||||
<title>Module de paiement PayPlug</title>
|
||||
<subtitle>https://www.payplug.com/fr</subtitle>
|
||||
</descriptive>
|
||||
<logo>payplug.png</logo>
|
||||
<images-folder>images</images-folder>
|
||||
<languages>
|
||||
<language>en_US</language>
|
||||
<language>fr_FR</language>
|
||||
</languages>
|
||||
<version>1.0.5</version>
|
||||
<authors>
|
||||
<author>
|
||||
<name>Vincent Lopes-Vicente</name>
|
||||
<email>vlopes@openstudio.fr</email>
|
||||
</author>
|
||||
</authors>
|
||||
<type>payment</type>
|
||||
<thelia>2.4.0</thelia>
|
||||
<stability>other</stability>
|
||||
<mandatory>0</mandatory>
|
||||
<hidden>0</hidden>
|
||||
</module>
|
||||
28
local/modules/PayPlugModule/Config/routing.xml
Executable file
28
local/modules/PayPlugModule/Config/routing.xml
Executable file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<routes xmlns="http://symfony.com/schema/routing"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
|
||||
|
||||
<route id="admin.payplugmodule.config" path="/admin/module/PayPlugModule">
|
||||
<default key="_controller">PayPlugModule\Controller\Admin\ConfigurationController::viewAction</default>
|
||||
</route>
|
||||
<route id="admin.payplugmodule.config.save" path="/admin/module/payplugmodule/configuration" methods="POST">
|
||||
<default key="_controller">PayPlugModule\Controller\Admin\ConfigurationController::saveAction</default>
|
||||
</route>
|
||||
<route id="admin.payplugmodule.order.refund" path="/admin/payplugmodule/order/refund" methods="POST">
|
||||
<default key="_controller">PayPlugModule\Controller\Admin\OrderController::refundAction</default>
|
||||
</route>
|
||||
<route id="admin.payplugmodule.order.capture" path="/admin/payplugmodule/order/capture" methods="POST">
|
||||
<default key="_controller">PayPlugModule\Controller\Admin\OrderController::captureAction</default>
|
||||
</route>
|
||||
|
||||
<route id="payplugmodule_notification" path="/payplug/notification">
|
||||
<default key="_controller">PayPlugModule\Controller\NotificationController::entryPoint</default>
|
||||
</route>
|
||||
|
||||
<route id="payplugmodule_delete_card" path="/payplug/card/delete">
|
||||
<default key="_controller">PayPlugModule\Controller\CardController::deleteCurrentCustomerCard</default>
|
||||
</route>
|
||||
|
||||
</routes>
|
||||
57
local/modules/PayPlugModule/Config/schema.xml
Executable file
57
local/modules/PayPlugModule/Config/schema.xml
Executable file
@@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<database defaultIdMethod="native" name="thelia"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://thelia.net/schema/dic/config http://thelia.net/schema/dic/config/thelia-1.0.xsd">
|
||||
|
||||
<table name="order_pay_plug_data" namespace="PayPlugModule\Model">
|
||||
<column name="id" type="INTEGER" required="true" primaryKey="true"/>
|
||||
<column name="amount_refunded" scale="6" size="16" type="DECIMAL" />
|
||||
<column name="need_capture" type="TINYINT" default="0"/>
|
||||
<column name="capture_expire_at" type="TIMESTAMP" />
|
||||
<column name="captured_at" type="TIMESTAMP" />
|
||||
|
||||
<foreign-key foreignTable="order" onDelete="CASCADE" onUpdate="CASCADE">
|
||||
<reference local="id" foreign="id" />
|
||||
</foreign-key>
|
||||
</table>
|
||||
|
||||
<table name="pay_plug_card" namespace="PayPlugModule\Model">
|
||||
<column name="uuid" type="VARCHAR" size="150" primaryKey="true"/>
|
||||
<column name="customer_id" type="INTEGER"/>
|
||||
<column name="brand" type="VARCHAR" size="255" />
|
||||
<column name="last_4" type="VARCHAR" size="255" />
|
||||
<column name="expire_month" type="INTEGER" />
|
||||
<column name="expire_year" type="INTEGER" />
|
||||
|
||||
<foreign-key foreignTable="customer" onDelete="CASCADE" onUpdate="CASCADE">
|
||||
<reference local="customer_id" foreign="id" />
|
||||
</foreign-key>
|
||||
</table>
|
||||
|
||||
<table name="order_pay_plug_multi_payment" namespace="PayPlugModule\Model">
|
||||
<column autoIncrement="true" name="id" type="INTEGER" required="true" primaryKey="true"/>
|
||||
<column name="order_id" type="INTEGER" required="true" primaryKey="true"/>
|
||||
<column name="amount" scale="6" size="16" type="DECIMAL" />
|
||||
<column name="is_first_payment" type="TINYINT" default="0"/>
|
||||
<column name="planned_at" type="TIMESTAMP" />
|
||||
<column name="payment_method" type="VARCHAR" size="255" />
|
||||
<column name="payment_id" type="VARCHAR" size="255" />
|
||||
<column name="paid_at" type="TIMESTAMP" />
|
||||
<column name="amount_refunded" scale="6" size="16" type="DECIMAL" default="0"/>
|
||||
|
||||
<foreign-key foreignTable="order" onDelete="CASCADE" onUpdate="CASCADE">
|
||||
<reference local="order_id" foreign="id" />
|
||||
</foreign-key>
|
||||
</table>
|
||||
|
||||
<table name="pay_plug_module_delivery_type" namespace="PayPlugModule\Model">
|
||||
<column autoIncrement="true" name="id" primaryKey="true" required="true" type="INTEGER" />
|
||||
<column name="module_id" type="integer" />
|
||||
<column name="delivery_type" size="255" type="VARCHAR" />
|
||||
<foreign-key foreignTable="module" name="fk_pay_plug_module_delivery_type_module_id" onDelete="CASCADE" onUpdate="RESTRICT">
|
||||
<reference foreign="id" local="module_id" />
|
||||
</foreign-key>
|
||||
</table>
|
||||
|
||||
<external-schema filename="local/config/schema.xml" referenceOnly="true" />
|
||||
</database>
|
||||
2
local/modules/PayPlugModule/Config/sqldb.map
Executable file
2
local/modules/PayPlugModule/Config/sqldb.map
Executable file
@@ -0,0 +1,2 @@
|
||||
# Sqlfile -> Database map
|
||||
thelia.sql=thelia
|
||||
97
local/modules/PayPlugModule/Config/thelia.sql
Normal file
97
local/modules/PayPlugModule/Config/thelia.sql
Normal file
@@ -0,0 +1,97 @@
|
||||
|
||||
# This is a fix for InnoDB in MySQL >= 4.1.x
|
||||
# It "suspends judgement" for fkey relationships until are tables are set.
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
-- ---------------------------------------------------------------------
|
||||
-- order_pay_plug_data
|
||||
-- ---------------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `order_pay_plug_data`;
|
||||
|
||||
CREATE TABLE `order_pay_plug_data`
|
||||
(
|
||||
`id` INTEGER NOT NULL,
|
||||
`amount_refunded` DECIMAL(16,6),
|
||||
`need_capture` TINYINT DEFAULT 0,
|
||||
`capture_expire_at` DATETIME,
|
||||
`captured_at` DATETIME,
|
||||
PRIMARY KEY (`id`),
|
||||
CONSTRAINT `order_pay_plug_data_fk_19ea48`
|
||||
FOREIGN KEY (`id`)
|
||||
REFERENCES `order` (`id`)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE CASCADE
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
-- ---------------------------------------------------------------------
|
||||
-- pay_plug_card
|
||||
-- ---------------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `pay_plug_card`;
|
||||
|
||||
CREATE TABLE `pay_plug_card`
|
||||
(
|
||||
`uuid` VARCHAR(150) NOT NULL,
|
||||
`customer_id` INTEGER,
|
||||
`brand` VARCHAR(255),
|
||||
`last_4` VARCHAR(255),
|
||||
`expire_month` INTEGER,
|
||||
`expire_year` INTEGER,
|
||||
PRIMARY KEY (`uuid`),
|
||||
INDEX `pay_plug_card_fi_7e8f3e` (`customer_id`),
|
||||
CONSTRAINT `pay_plug_card_fk_7e8f3e`
|
||||
FOREIGN KEY (`customer_id`)
|
||||
REFERENCES `customer` (`id`)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE CASCADE
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
-- ---------------------------------------------------------------------
|
||||
-- order_pay_plug_multi_payment
|
||||
-- ---------------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `order_pay_plug_multi_payment`;
|
||||
|
||||
CREATE TABLE `order_pay_plug_multi_payment`
|
||||
(
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`order_id` INTEGER NOT NULL,
|
||||
`amount` DECIMAL(16,6),
|
||||
`is_first_payment` TINYINT DEFAULT 0,
|
||||
`planned_at` DATETIME,
|
||||
`payment_method` VARCHAR(255),
|
||||
`payment_id` VARCHAR(255),
|
||||
`paid_at` DATETIME,
|
||||
`amount_refunded` DECIMAL(16,6) DEFAULT 0,
|
||||
PRIMARY KEY (`id`,`order_id`),
|
||||
INDEX `order_pay_plug_multi_payment_fi_75704f` (`order_id`),
|
||||
CONSTRAINT `order_pay_plug_multi_payment_fk_75704f`
|
||||
FOREIGN KEY (`order_id`)
|
||||
REFERENCES `order` (`id`)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE CASCADE
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
-- ---------------------------------------------------------------------
|
||||
-- pay_plug_module_delivery_type
|
||||
-- ---------------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `pay_plug_module_delivery_type`;
|
||||
|
||||
CREATE TABLE `pay_plug_module_delivery_type`
|
||||
(
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`module_id` INTEGER,
|
||||
`delivery_type` VARCHAR(255),
|
||||
PRIMARY KEY (`id`),
|
||||
INDEX `fi_pay_plug_module_delivery_type_module_id` (`module_id`),
|
||||
CONSTRAINT `fk_pay_plug_module_delivery_type_module_id`
|
||||
FOREIGN KEY (`module_id`)
|
||||
REFERENCES `module` (`id`)
|
||||
ON UPDATE RESTRICT
|
||||
ON DELETE CASCADE
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
# This restores the fkey checks, after having unset them earlier
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
9
local/modules/PayPlugModule/Config/update/1.0.2.sql
Normal file
9
local/modules/PayPlugModule/Config/update/1.0.2.sql
Normal file
@@ -0,0 +1,9 @@
|
||||
# This is a fix for InnoDB in MySQL >= 4.1.x
|
||||
# It "suspends judgement" for fkey relationships until are tables are set.
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
ALTER TABLE `order_pay_plug_multi_payment` ADD COLUMN `amount_refunded` DECIMAL(16,6) DEFAULT 0;
|
||||
ALTER TABLE `order_pay_plug_multi_payment` DROP COLUMN `refunded_at`;
|
||||
|
||||
# This restores the fkey checks, after having unset them earlier
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
27
local/modules/PayPlugModule/Config/update/1.0.3.sql
Normal file
27
local/modules/PayPlugModule/Config/update/1.0.3.sql
Normal file
@@ -0,0 +1,27 @@
|
||||
# This is a fix for InnoDB in MySQL >= 4.1.x
|
||||
# It "suspends judgement" for fkey relationships until are tables are set.
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
|
||||
-- ---------------------------------------------------------------------
|
||||
-- pay_plug_module_delivery_type
|
||||
-- ---------------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `pay_plug_module_delivery_type`;
|
||||
|
||||
CREATE TABLE `pay_plug_module_delivery_type`
|
||||
(
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`module_id` INTEGER,
|
||||
`delivery_type` VARCHAR(255),
|
||||
PRIMARY KEY (`id`),
|
||||
INDEX `fi_pay_plug_module_delivery_type_module_id` (`module_id`),
|
||||
CONSTRAINT `fk_pay_plug_module_delivery_type_module_id`
|
||||
FOREIGN KEY (`module_id`)
|
||||
REFERENCES `module` (`id`)
|
||||
ON UPDATE RESTRICT
|
||||
ON DELETE CASCADE
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
# This restores the fkey checks, after having unset them earlier
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
72
local/modules/PayPlugModule/Controller/Admin/ConfigurationController.php
Executable file
72
local/modules/PayPlugModule/Controller/Admin/ConfigurationController.php
Executable file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace PayPlugModule\Controller\Admin;
|
||||
|
||||
use PayPlugModule\Form\ConfigurationForm;
|
||||
use PayPlugModule\Model\PayPlugConfigValue;
|
||||
use PayPlugModule\Model\PayPlugModuleDeliveryTypeQuery;
|
||||
use PayPlugModule\PayPlugModule;
|
||||
use PayPlugModule\Service\OrderStatusService;
|
||||
use Thelia\Controller\Admin\BaseAdminController;
|
||||
use Thelia\Core\Security\AccessManager;
|
||||
use Thelia\Core\Security\Resource\AdminResources;
|
||||
use Thelia\Core\Translation\Translator;
|
||||
|
||||
class ConfigurationController extends BaseAdminController
|
||||
{
|
||||
public function viewAction()
|
||||
{
|
||||
// Create default order statuses
|
||||
/** @var OrderStatusService $orderStatusesService */
|
||||
$orderStatusesService = $this->container->get('payplugmodule_order_status_service');
|
||||
$orderStatusesService->initAllStatuses();
|
||||
$deliveryModuleFormFields = ConfigurationForm::getDeliveryModuleFormFields();
|
||||
|
||||
return $this->render(
|
||||
"PayPlugModule/configuration",
|
||||
compact('deliveryModuleFormFields')
|
||||
);
|
||||
}
|
||||
|
||||
public function saveAction()
|
||||
{
|
||||
if (null !== $response = $this->checkAuth(array(AdminResources::MODULE), 'PayPlugModule', AccessManager::UPDATE)) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$form = $this->createForm('payplugmodule_configuration_form');
|
||||
|
||||
try {
|
||||
$data = $this->validateForm($form)->getData();
|
||||
|
||||
foreach ($data as $key => $value) {
|
||||
if (in_array($key, PayPlugConfigValue::getConfigKeys())) {
|
||||
PayPlugModule::setConfigValue($key, $value);
|
||||
}
|
||||
|
||||
$explodedKey = explode(':', $key);
|
||||
if ($explodedKey[0] === ConfigurationForm::DELIVERY_MODULE_TYPE_KEY_PREFIX) {
|
||||
$moduleId = $explodedKey[1];
|
||||
$payPlugModuleDeliveryType = PayPlugModuleDeliveryTypeQuery::create()->filterByModuleId($moduleId)->findOneOrCreate();
|
||||
$payPlugModuleDeliveryType->setDeliveryType($value)
|
||||
->save();
|
||||
}
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
$this->setupFormErrorContext(
|
||||
Translator::getInstance()->trans(
|
||||
"Error",
|
||||
[],
|
||||
PayPlugModule::DOMAIN_NAME
|
||||
),
|
||||
$e->getMessage(),
|
||||
$form
|
||||
);
|
||||
return $this->viewAction();
|
||||
}
|
||||
|
||||
return $this->generateSuccessRedirect($form);
|
||||
}
|
||||
|
||||
}
|
||||
84
local/modules/PayPlugModule/Controller/Admin/OrderController.php
Executable file
84
local/modules/PayPlugModule/Controller/Admin/OrderController.php
Executable file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace PayPlugModule\Controller\Admin;
|
||||
|
||||
use PayPlugModule\PayPlugModule;
|
||||
use PayPlugModule\Service\PaymentService;
|
||||
use Thelia\Controller\Admin\BaseAdminController;
|
||||
use Thelia\Core\Security\AccessManager;
|
||||
use Thelia\Core\Security\Resource\AdminResources;
|
||||
use Thelia\Core\Translation\Translator;
|
||||
use Thelia\Model\OrderQuery;
|
||||
|
||||
class OrderController extends BaseAdminController
|
||||
{
|
||||
public function refundAction()
|
||||
{
|
||||
if (null !== $response = $this->checkAuth(array(AdminResources::MODULE), 'PayPlugModule', AccessManager::UPDATE)) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$form = $this->createForm('payplugmodule_order_action_form_refund');
|
||||
|
||||
try {
|
||||
$data = $this->validateForm($form)->getData();
|
||||
$order = OrderQuery::create()
|
||||
->findOneById($data['order_id']);
|
||||
|
||||
$amountToRefund = (int)($data['refund_amount'] * 100);
|
||||
|
||||
/** @var PaymentService $paymentService */
|
||||
$paymentService = $this->container->get('payplugmodule_payment_service');
|
||||
$paymentService->doOrderRefund($order, $amountToRefund);
|
||||
} catch (\Exception $e) {
|
||||
$this->setupFormErrorContext(
|
||||
Translator::getInstance()->trans(
|
||||
"Error",
|
||||
[],
|
||||
PayPlugModule::DOMAIN_NAME
|
||||
),
|
||||
$e->getMessage(),
|
||||
$form
|
||||
);
|
||||
}
|
||||
|
||||
// Sleep to let time for PayPlug to send validation
|
||||
sleep(2);
|
||||
$url = $this->retrieveSuccessUrl($form);
|
||||
return $this->generateRedirect($url.'#orderPayPlug');
|
||||
}
|
||||
|
||||
public function captureAction()
|
||||
{
|
||||
if (null !== $response = $this->checkAuth(array(AdminResources::MODULE), 'PayPlugModule', AccessManager::UPDATE)) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$form = $this->createForm('payplugmodule_order_action_form');
|
||||
|
||||
try {
|
||||
$data = $this->validateForm($form)->getData();
|
||||
$order = OrderQuery::create()
|
||||
->findOneById($data['order_id']);
|
||||
|
||||
/** @var PaymentService $paymentService */
|
||||
$paymentService = $this->container->get('payplugmodule_payment_service');
|
||||
$paymentService->doOrderCapture($order);
|
||||
} catch (\Exception $e) {
|
||||
$this->setupFormErrorContext(
|
||||
Translator::getInstance()->trans(
|
||||
"Error",
|
||||
[],
|
||||
PayPlugModule::DOMAIN_NAME
|
||||
),
|
||||
$e->getMessage(),
|
||||
$form
|
||||
);
|
||||
}
|
||||
|
||||
// Sleep to let time for PayPlug to send validation
|
||||
sleep(2);
|
||||
$url = $this->retrieveSuccessUrl($form);
|
||||
return $this->generateRedirect($url.'#orderPayPlug');
|
||||
}
|
||||
}
|
||||
22
local/modules/PayPlugModule/Controller/CardController.php
Executable file
22
local/modules/PayPlugModule/Controller/CardController.php
Executable file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace PayPlugModule\Controller;
|
||||
|
||||
use PayPlugModule\Model\PayPlugCardQuery;
|
||||
use Thelia\Controller\Front\BaseFrontController;
|
||||
use Thelia\Core\HttpFoundation\Request;
|
||||
|
||||
class CardController extends BaseFrontController
|
||||
{
|
||||
public function deleteCurrentCustomerCard(Request $request)
|
||||
{
|
||||
$customerId = $request->getSession()->getCustomerUser()->getId();
|
||||
|
||||
if (null !== $card = PayPlugCardQuery::create()->findOneByCustomerId($customerId)) {
|
||||
$card->delete();
|
||||
}
|
||||
|
||||
return $this->generateRedirect($this->getSession()->getReturnToUrl());
|
||||
}
|
||||
|
||||
}
|
||||
28
local/modules/PayPlugModule/Controller/NotificationController.php
Executable file
28
local/modules/PayPlugModule/Controller/NotificationController.php
Executable file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace PayPlugModule\Controller;
|
||||
|
||||
use PayPlugModule\Event\Notification\UnknownNotificationEvent;
|
||||
use PayPlugModule\Service\PaymentService;
|
||||
use Thelia\Controller\Front\BaseFrontController;
|
||||
use Thelia\Core\HttpFoundation\Request;
|
||||
use Thelia\Core\HttpFoundation\Response;
|
||||
use Thelia\Log\Tlog;
|
||||
|
||||
class NotificationController extends BaseFrontController
|
||||
{
|
||||
public function entryPoint(Request $request)
|
||||
{
|
||||
/** @var PaymentService $paymentService */
|
||||
$paymentService = $this->container->get('payplugmodule_payment_service');
|
||||
Tlog::getInstance()->addAlert('Notification received');
|
||||
Tlog::getInstance()->addAlert($request->getContent());
|
||||
|
||||
$notificationResource = $paymentService->getNotificationResource($request);
|
||||
|
||||
$notificationEvent = new UnknownNotificationEvent($notificationResource);
|
||||
$this->dispatch(UnknownNotificationEvent::UNKNOWN_NOTIFICATION_EVENT, $notificationEvent);
|
||||
|
||||
return new Response();
|
||||
}
|
||||
}
|
||||
37
local/modules/PayPlugModule/Event/Notification/PaymentNotificationEvent.php
Executable file
37
local/modules/PayPlugModule/Event/Notification/PaymentNotificationEvent.php
Executable file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace PayPlugModule\Event\Notification;
|
||||
|
||||
use Payplug\Resource\Payment;
|
||||
use Thelia\Core\Event\ActionEvent;
|
||||
|
||||
class PaymentNotificationEvent extends ActionEvent
|
||||
{
|
||||
const PAYMENT_NOTIFICATION_EVENT = "payplugmodule_payment_notification_event";
|
||||
|
||||
/** @var Payment */
|
||||
protected $resource;
|
||||
|
||||
public function __construct(Payment $resource)
|
||||
{
|
||||
$this->resource = $resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Payment
|
||||
*/
|
||||
public function getResource(): Payment
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Payment $resource
|
||||
* @return PaymentNotificationEvent
|
||||
*/
|
||||
public function setResource(Payment $resource): PaymentNotificationEvent
|
||||
{
|
||||
$this->resource = $resource;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
37
local/modules/PayPlugModule/Event/Notification/RefundNotificationEvent.php
Executable file
37
local/modules/PayPlugModule/Event/Notification/RefundNotificationEvent.php
Executable file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace PayPlugModule\Event\Notification;
|
||||
|
||||
use Payplug\Resource\Refund;
|
||||
use Thelia\Core\Event\ActionEvent;
|
||||
|
||||
class RefundNotificationEvent extends ActionEvent
|
||||
{
|
||||
const REFUND_NOTIFICATION_EVENT = "payplugmodule_refund_notification_event";
|
||||
|
||||
/** @var Refund */
|
||||
protected $resource;
|
||||
|
||||
public function __construct(Refund $resource)
|
||||
{
|
||||
$this->resource = $resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Refund
|
||||
*/
|
||||
public function getResource(): Refund
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Refund $resource
|
||||
* @return RefundNotificationEvent
|
||||
*/
|
||||
public function setResource(Refund $resource): RefundNotificationEvent
|
||||
{
|
||||
$this->resource = $resource;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
37
local/modules/PayPlugModule/Event/Notification/UnknownNotificationEvent.php
Executable file
37
local/modules/PayPlugModule/Event/Notification/UnknownNotificationEvent.php
Executable file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace PayPlugModule\Event\Notification;
|
||||
|
||||
use Payplug\Resource\IVerifiableAPIResource;
|
||||
use Thelia\Core\Event\ActionEvent;
|
||||
|
||||
class UnknownNotificationEvent extends ActionEvent
|
||||
{
|
||||
const UNKNOWN_NOTIFICATION_EVENT = "payplugmodule_unknown_notification_event";
|
||||
|
||||
/** @var IVerifiableAPIResource */
|
||||
protected $resource;
|
||||
|
||||
public function __construct(IVerifiableAPIResource $resource)
|
||||
{
|
||||
$this->resource = $resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return IVerifiableAPIResource
|
||||
*/
|
||||
public function getResource(): IVerifiableAPIResource
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IVerifiableAPIResource $resource
|
||||
* @return UnknownNotificationEvent
|
||||
*/
|
||||
public function setResource(IVerifiableAPIResource $resource): UnknownNotificationEvent
|
||||
{
|
||||
$this->resource = $resource;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
1605
local/modules/PayPlugModule/Event/PayPlugPaymentEvent.php
Executable file
1605
local/modules/PayPlugModule/Event/PayPlugPaymentEvent.php
Executable file
File diff suppressed because it is too large
Load Diff
249
local/modules/PayPlugModule/Event/PayPlugProduct.php
Normal file
249
local/modules/PayPlugModule/Event/PayPlugProduct.php
Normal file
@@ -0,0 +1,249 @@
|
||||
<?php
|
||||
|
||||
namespace PayPlugModule\Event;
|
||||
|
||||
use PayPlugModule\Model\PayPlugModuleDeliveryType;
|
||||
use PayPlugModule\PayPlugModule;
|
||||
use Thelia\Core\Translation\Translator;
|
||||
use Thelia\Model\Base\OrderProduct;
|
||||
use Thelia\Model\Base\OrderProductTax;
|
||||
use Thelia\Model\ConfigQuery;
|
||||
|
||||
class PayPlugProduct
|
||||
{
|
||||
/** @var string */
|
||||
protected $brand;
|
||||
|
||||
/** @var string */
|
||||
protected $expectedDeliveryDate;
|
||||
|
||||
/** @var string */
|
||||
protected $deliveryLabel;
|
||||
|
||||
/** @var string */
|
||||
protected $deliveryType;
|
||||
|
||||
/** @var string */
|
||||
protected $merchantItemId;
|
||||
|
||||
/** @var string */
|
||||
protected $name;
|
||||
|
||||
/** @var integer */
|
||||
protected $price;
|
||||
|
||||
/** @var integer */
|
||||
protected $quantity;
|
||||
|
||||
/** @var integer */
|
||||
protected $totalAmount;
|
||||
|
||||
public function buildFromOrderProduct(OrderProduct $orderProduct, PayPlugModuleDeliveryType $payPlugModuleDeliveryType = null)
|
||||
{
|
||||
$storeName = ConfigQuery::read(
|
||||
'store_name',
|
||||
Translator::getInstance()->trans(
|
||||
'Unknown',
|
||||
[],
|
||||
PayPlugModule::DOMAIN_NAME
|
||||
)
|
||||
);
|
||||
|
||||
$deliveryType = $payPlugModuleDeliveryType !== null ? $payPlugModuleDeliveryType->getDeliveryType() : 'carrier';
|
||||
// Brand can't be find from order product but it's required so set store name as brand or "Unknown"
|
||||
$this->setBrand($storeName);
|
||||
$this->setExpectedDeliveryDate(date('Y-m-d'));
|
||||
$this->setDeliveryLabel($storeName);
|
||||
$this->setDeliveryType($deliveryType);
|
||||
$this->setMerchantItemId($orderProduct->getId());
|
||||
$this->setName($orderProduct->getTitle());
|
||||
|
||||
$orderProductTaxes = $orderProduct->getOrderProductTaxes();
|
||||
$tax = array_reduce(
|
||||
iterator_to_array($orderProductTaxes),
|
||||
function ($accumulator, OrderProductTax $orderProductTax) {
|
||||
return $accumulator + $orderProductTax->getAmount();
|
||||
},
|
||||
0
|
||||
);
|
||||
$promoTax = array_reduce(
|
||||
iterator_to_array($orderProductTaxes),
|
||||
function ($accumulator, OrderProductTax $orderProductTax) {
|
||||
return $accumulator + $orderProductTax->getPromoAmount();
|
||||
},
|
||||
0
|
||||
);
|
||||
|
||||
$taxedPrice = round((float) $orderProduct->getPrice() + $tax, 2);
|
||||
$taxedPromoPrice = round((float) $orderProduct->getPromoPrice() + $promoTax, 2);
|
||||
|
||||
$price = $orderProduct->getWasInPromo() ? $taxedPromoPrice : $taxedPrice;
|
||||
$this->setPrice($price * 100);
|
||||
$this->setQuantity($orderProduct->getQuantity());
|
||||
$this->setTotalAmount($price * $orderProduct->getQuantity() * 100);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getBrand()
|
||||
{
|
||||
return $this->brand;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $brand
|
||||
* @return PayPlugProduct
|
||||
*/
|
||||
public function setBrand(string $brand): PayPlugProduct
|
||||
{
|
||||
$this->brand = $brand;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getExpectedDeliveryDate()
|
||||
{
|
||||
return $this->expectedDeliveryDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $expectedDeliveryDate
|
||||
* @return PayPlugProduct
|
||||
*/
|
||||
public function setExpectedDeliveryDate(string $expectedDeliveryDate): PayPlugProduct
|
||||
{
|
||||
$this->expectedDeliveryDate = $expectedDeliveryDate;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDeliveryLabel()
|
||||
{
|
||||
return $this->deliveryLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $deliveryLabel
|
||||
* @return PayPlugProduct
|
||||
*/
|
||||
public function setDeliveryLabel(string $deliveryLabel): PayPlugProduct
|
||||
{
|
||||
$this->deliveryLabel = $deliveryLabel;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDeliveryType()
|
||||
{
|
||||
return $this->deliveryType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $deliveryType
|
||||
* @return PayPlugProduct
|
||||
*/
|
||||
public function setDeliveryType(string $deliveryType): PayPlugProduct
|
||||
{
|
||||
$this->deliveryType = $deliveryType;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getMerchantItemId()
|
||||
{
|
||||
return $this->merchantItemId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $merchantItemId
|
||||
* @return PayPlugProduct
|
||||
*/
|
||||
public function setMerchantItemId(string $merchantItemId): PayPlugProduct
|
||||
{
|
||||
$this->merchantItemId = $merchantItemId;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return PayPlugProduct
|
||||
*/
|
||||
public function setName(string $name): PayPlugProduct
|
||||
{
|
||||
$this->name = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getPrice()
|
||||
{
|
||||
return $this->price;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $price
|
||||
* @return PayPlugProduct
|
||||
*/
|
||||
public function setPrice(int $price): PayPlugProduct
|
||||
{
|
||||
$this->price = $price;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getQuantity()
|
||||
{
|
||||
return $this->quantity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $quantity
|
||||
* @return PayPlugProduct
|
||||
*/
|
||||
public function setQuantity(int $quantity): PayPlugProduct
|
||||
{
|
||||
$this->quantity = $quantity;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getTotalAmount()
|
||||
{
|
||||
return $this->totalAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $totalAmount
|
||||
* @return PayPlugProduct
|
||||
*/
|
||||
public function setTotalAmount(int $totalAmount): PayPlugProduct
|
||||
{
|
||||
$this->totalAmount = $totalAmount;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
86
local/modules/PayPlugModule/EventListener/ConfirmationEmailListener.php
Executable file
86
local/modules/PayPlugModule/EventListener/ConfirmationEmailListener.php
Executable file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace PayPlugModule\EventListener;
|
||||
|
||||
use PayPlugModule\PayPlugModule;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Thelia\Core\Event\Order\OrderEvent;
|
||||
use Thelia\Core\Event\TheliaEvents;
|
||||
use Thelia\Log\Tlog;
|
||||
use Thelia\Mailer\MailerFactory;
|
||||
|
||||
/**
|
||||
* Class ConfirmationEmailListener
|
||||
* @package PayPlugModule\EventListeners
|
||||
* @author franck allimant <franck@cqfdev.fr>
|
||||
*/
|
||||
class ConfirmationEmailListener implements EventSubscriberInterface
|
||||
{
|
||||
/**
|
||||
* @var MailerFactory
|
||||
*/
|
||||
protected $mailer;
|
||||
|
||||
public function __construct(MailerFactory $mailer)
|
||||
{
|
||||
$this->mailer = $mailer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param OrderEvent $event
|
||||
*
|
||||
* @throws \Exception if the message cannot be loaded.
|
||||
*/
|
||||
public function sendConfirmationEmail(OrderEvent $event)
|
||||
{
|
||||
if (PayPlugModule::getConfigValue('send_confirmation_message_only_if_paid')) {
|
||||
// We send the order confirmation email only if the order is paid
|
||||
$order = $event->getOrder();
|
||||
|
||||
if (! $order->isPaid() && $order->getPaymentModuleId() == PayPlugModule::getModuleId()) {
|
||||
$event->stopPropagation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if we are the order payment module, and if order new status is paid, send a confirmation email to the customer.
|
||||
*
|
||||
* @param OrderEvent $event
|
||||
* @param $eventName
|
||||
* @param EventDispatcherInterface $dispatcher
|
||||
* @throws \Propel\Runtime\Exception\PropelException
|
||||
*/
|
||||
public function updateStatus(OrderEvent $event, $eventName, EventDispatcherInterface $dispatcher)
|
||||
{
|
||||
$order = $event->getOrder();
|
||||
|
||||
if ($order->isPaid() && $order->getPaymentModuleId() == PayPlugModule::getModuleId()) {
|
||||
// Send confirmation email if required.
|
||||
if (PayPlugModule::getConfigValue('send_confirmation_message_only_if_paid')) {
|
||||
$dispatcher->dispatch(TheliaEvents::ORDER_SEND_CONFIRMATION_EMAIL, $event);
|
||||
}
|
||||
|
||||
Tlog::getInstance()->debug("Confirmation email sent to customer " . $order->getCustomer()->getEmail());
|
||||
}
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
TheliaEvents::ORDER_UPDATE_STATUS => array('updateStatus', 128),
|
||||
TheliaEvents::ORDER_SEND_CONFIRMATION_EMAIL => array('sendConfirmationEmail', 129)
|
||||
);
|
||||
}
|
||||
}
|
||||
70
local/modules/PayPlugModule/EventListener/FormExtend/OrderFormListener.php
Executable file
70
local/modules/PayPlugModule/EventListener/FormExtend/OrderFormListener.php
Executable file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace PayPlugModule\EventListener\FormExtend;
|
||||
|
||||
use PayPlugModule\Model\PayPlugConfigValue;
|
||||
use PayPlugModule\PayPlugModule;
|
||||
use PayPlugModule\Service\PaymentService;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Thelia\Core\Event\Order\OrderEvent;
|
||||
use Thelia\Core\Event\TheliaEvents;
|
||||
use Thelia\Core\Event\TheliaFormEvent;
|
||||
use Thelia\Core\HttpFoundation\Request;
|
||||
|
||||
class OrderFormListener implements EventSubscriberInterface
|
||||
{
|
||||
const THELIA_CUSTOMER_ORDER_PAYMENT_FROM_NAME = 'thelia_order_payment';
|
||||
|
||||
const PAY_PLUG_MULTI_PAYMENT_FIELD_NAME = 'pay_plug_multi_payment';
|
||||
|
||||
/** @var Request */
|
||||
protected $request;
|
||||
|
||||
public function __construct(RequestStack $requestStack)
|
||||
{
|
||||
$this->request = $requestStack->getCurrentRequest();
|
||||
}
|
||||
|
||||
public function addMultiPaymentField(TheliaFormEvent $event)
|
||||
{
|
||||
if (!PayPlugModule::getConfigValue(PayPlugConfigValue::MULTI_PAYMENT_ENABLED)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$event->getForm()->getFormBuilder()
|
||||
->add(
|
||||
self::PAY_PLUG_MULTI_PAYMENT_FIELD_NAME,
|
||||
CheckboxType::class
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
public function checkMultiPaymentSelected(OrderEvent $event)
|
||||
{
|
||||
$this->request->getSession()->set(self::PAY_PLUG_MULTI_PAYMENT_FIELD_NAME, 0);
|
||||
$formData = $this->request->get(self::THELIA_CUSTOMER_ORDER_PAYMENT_FROM_NAME);
|
||||
|
||||
if (!isset($formData[self::PAY_PLUG_MULTI_PAYMENT_FIELD_NAME]) || 0 == $formData[self::PAY_PLUG_MULTI_PAYMENT_FIELD_NAME]) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->request->getSession()->set(self::PAY_PLUG_MULTI_PAYMENT_FIELD_NAME, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of event names this subscriber wants to listen to.
|
||||
*
|
||||
* @return array The event names to listen to
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
TheliaEvents::FORM_AFTER_BUILD.'.'.self::THELIA_CUSTOMER_ORDER_PAYMENT_FROM_NAME => array('addMultiPaymentField', 64),
|
||||
TheliaEvents::ORDER_SET_PAYMENT_MODULE => array('checkMultiPaymentSelected', 64)
|
||||
);
|
||||
}
|
||||
}
|
||||
209
local/modules/PayPlugModule/EventListener/NotificationListener.php
Executable file
209
local/modules/PayPlugModule/EventListener/NotificationListener.php
Executable file
@@ -0,0 +1,209 @@
|
||||
<?php
|
||||
|
||||
namespace PayPlugModule\EventListener;
|
||||
|
||||
use Payplug\Resource\Refund;
|
||||
use Payplug\Resource\Payment;
|
||||
use PayPlugModule\Event\Notification\UnknownNotificationEvent;
|
||||
use PayPlugModule\Event\Notification\PaymentNotificationEvent;
|
||||
use PayPlugModule\Event\Notification\RefundNotificationEvent;
|
||||
use PayPlugModule\Model\OrderPayPlugData;
|
||||
use PayPlugModule\Model\OrderPayPlugDataQuery;
|
||||
use PayPlugModule\Model\OrderPayPlugMultiPayment;
|
||||
use PayPlugModule\Model\OrderPayPlugMultiPaymentQuery;
|
||||
use PayPlugModule\Model\PayPlugCard;
|
||||
use PayPlugModule\Model\PayPlugCardQuery;
|
||||
use PayPlugModule\Model\PayPlugConfigValue;
|
||||
use PayPlugModule\PayPlugModule;
|
||||
use PayPlugModule\Service\OrderStatusService;
|
||||
use Propel\Runtime\Collection\Collection;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Thelia\Core\Event\Order\OrderEvent;
|
||||
use Thelia\Core\Event\TheliaEvents;
|
||||
use Thelia\Model\Order;
|
||||
use Thelia\Model\OrderQuery;
|
||||
use Thelia\Model\OrderStatusQuery;
|
||||
|
||||
class NotificationListener implements EventSubscriberInterface
|
||||
{
|
||||
/** @var OrderStatusService */
|
||||
protected $orderStatusService;
|
||||
|
||||
/** @var EventDispatcherInterface */
|
||||
protected $dispatcher;
|
||||
|
||||
public function __construct(EventDispatcherInterface $dispatcher, OrderStatusService $orderStatusService)
|
||||
{
|
||||
$this->dispatcher = $dispatcher;
|
||||
$this->orderStatusService = $orderStatusService;
|
||||
}
|
||||
|
||||
public function handleUnknownNotification(UnknownNotificationEvent $event)
|
||||
{
|
||||
$resource = $event->getResource();
|
||||
switch(true) {
|
||||
case $resource instanceof Payment:
|
||||
$paymentNotificationEvent = new PaymentNotificationEvent($resource);
|
||||
$this->dispatcher->dispatch(PaymentNotificationEvent::PAYMENT_NOTIFICATION_EVENT, $paymentNotificationEvent);
|
||||
break;
|
||||
case $resource instanceof Refund:
|
||||
$refundNotificationEvent = new RefundNotificationEvent($resource);
|
||||
$this->dispatcher->dispatch(RefundNotificationEvent::REFUND_NOTIFICATION_EVENT, $refundNotificationEvent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function handlePaymentNotification(PaymentNotificationEvent $event)
|
||||
{
|
||||
$transactionRef = $event->getResource()->id;
|
||||
if (!$transactionRef) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$order = OrderQuery::create()
|
||||
->filterByPaymentModuleId(PayPlugModule::getModuleId())
|
||||
->filterByTransactionRef($transactionRef)
|
||||
->findOne();
|
||||
|
||||
if (null === $order) {
|
||||
return;
|
||||
}
|
||||
|
||||
$orderPayPlugData = OrderPayPlugDataQuery::create()
|
||||
->findOneById($order->getId());
|
||||
|
||||
if (null === $orderPayPlugData) {
|
||||
return;
|
||||
}
|
||||
|
||||
$paymentResource = $event->getResource();
|
||||
|
||||
$orderStatusId = OrderStatusQuery::getCancelledStatus()->getId();
|
||||
|
||||
$orderPayPlugMultiPayment = OrderPayPlugMultiPaymentQuery::create()
|
||||
->findByOrderId($order->getId());
|
||||
|
||||
// Multi payment is really different
|
||||
if ($orderPayPlugMultiPayment->count() > 0) {
|
||||
$this->handleMultiPaymentNotification($paymentResource, $order, $orderPayPlugData, $orderPayPlugMultiPayment);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($orderPayPlugData->getNeedCapture()) {
|
||||
// Handle differed payment
|
||||
if ($paymentResource->is_paid) {
|
||||
$orderPayPlugData->setCapturedAt((new \DateTime()))
|
||||
->save();
|
||||
// Don't update status on capture
|
||||
$orderStatusId = null;
|
||||
} elseif ($paymentResource->authorization->authorized_at) {
|
||||
$orderStatusId = PayPlugModule::getConfigValue(PayPlugConfigValue::DIFFERED_PAYMENT_AUTHORIZED_CAPTURE_STATUS);
|
||||
$orderPayPlugData->setCaptureExpireAt($paymentResource->authorization->expires_at)
|
||||
->save();
|
||||
}
|
||||
} elseif ($paymentResource->is_paid) {
|
||||
// Handle classic payment
|
||||
$orderStatusId = OrderStatusQuery::getPaidStatus()->getId();
|
||||
}
|
||||
|
||||
if (null !== $orderStatusId) {
|
||||
$event = (new OrderEvent($order))
|
||||
->setStatus($orderStatusId);
|
||||
$this->dispatcher->dispatch(TheliaEvents::ORDER_UPDATE_STATUS, $event);
|
||||
}
|
||||
|
||||
if (null !== $paymentResource->card->id) {
|
||||
$cardData = $paymentResource->card;
|
||||
$cardExist = PayPlugCardQuery::create()
|
||||
->filterByCustomerId($order->getCustomerId())
|
||||
->filterByUuid($cardData->id)
|
||||
->findOne();
|
||||
|
||||
if (null === $cardExist) {
|
||||
(new PayPlugCard())
|
||||
->setUuid($cardData->id)
|
||||
->setCustomerId($order->getCustomerId())
|
||||
->setBrand($cardData->brand)
|
||||
->setLast4($cardData->last4)
|
||||
->setExpireMonth($cardData->exp_month)
|
||||
->setExpireYear($cardData->exp_year)
|
||||
->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function handleMultiPaymentNotification($paymentResource, Order $order, OrderPayPlugData $orderPayPlugData, Collection $orderMultiPayments)
|
||||
{
|
||||
/** @var OrderPayPlugMultiPayment $orderMultiPayment */
|
||||
foreach ($orderMultiPayments as $orderMultiPayment) {
|
||||
$orderMultiPayment->setPaymentMethod($paymentResource->card->id);
|
||||
|
||||
if ($paymentResource->id === $orderMultiPayment->getPaymentId()) {
|
||||
$orderStatusId = OrderStatusQuery::getCancelledStatus()->getId();
|
||||
|
||||
if ($paymentResource->is_paid) {
|
||||
$orderMultiPayment->setPaidAt(new \DateTime());
|
||||
$orderStatusId = OrderStatusQuery::getPaidStatus()->getId();
|
||||
}
|
||||
|
||||
// Update order status only for first payment
|
||||
if ($orderMultiPayment->getIsFirstPayment()) {
|
||||
$event = (new OrderEvent($order))
|
||||
->setStatus($orderStatusId);
|
||||
$this->dispatcher->dispatch(TheliaEvents::ORDER_UPDATE_STATUS, $event);
|
||||
}
|
||||
}
|
||||
|
||||
$orderMultiPayment->save();
|
||||
}
|
||||
}
|
||||
|
||||
public function handleRefundNotification(RefundNotificationEvent $event)
|
||||
{
|
||||
$transactionRef = $event->getResource()->payment_id;
|
||||
if (!$transactionRef) {
|
||||
return;
|
||||
}
|
||||
|
||||
$order = OrderQuery::create()
|
||||
->filterByPaymentModuleId(PayPlugModule::getModuleId())
|
||||
->filterByTransactionRef($transactionRef)
|
||||
->findOne();
|
||||
|
||||
$multiPayment = OrderPayPlugMultiPaymentQuery::create()
|
||||
->findOneByPaymentId($transactionRef);
|
||||
|
||||
if (null !== $multiPayment) {
|
||||
$multiPayment->setAmountRefunded((int)$multiPayment->getAmountRefunded() + $event->getResource()->amount)
|
||||
->save();
|
||||
$order = $multiPayment->getOrder();
|
||||
}
|
||||
|
||||
if (null === $order) {
|
||||
return;
|
||||
}
|
||||
|
||||
$orderPayPlugData = OrderPayPlugDataQuery::create()
|
||||
->findOneById($order->getId());
|
||||
|
||||
$orderPayPlugData->setAmountRefunded((int)$orderPayPlugData->getAmountRefunded() + $event->getResource()->amount)
|
||||
->save();
|
||||
|
||||
$event = (new OrderEvent($order))
|
||||
->setStatus(OrderStatusQuery::getRefundedStatus()->getId());
|
||||
$this->dispatcher->dispatch(TheliaEvents::ORDER_UPDATE_STATUS, $event);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return [
|
||||
UnknownNotificationEvent::UNKNOWN_NOTIFICATION_EVENT => ['handleUnknownNotification', 128],
|
||||
PaymentNotificationEvent::PAYMENT_NOTIFICATION_EVENT => ['handlePaymentNotification', 128],
|
||||
RefundNotificationEvent::REFUND_NOTIFICATION_EVENT => ['handleRefundNotification', 128]
|
||||
];
|
||||
}
|
||||
}
|
||||
59
local/modules/PayPlugModule/EventListener/OrderListener.php
Executable file
59
local/modules/PayPlugModule/EventListener/OrderListener.php
Executable file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace PayPlugModule\EventListener;
|
||||
|
||||
use PayPlugModule\Model\OrderPayPlugData;
|
||||
use PayPlugModule\Model\OrderPayPlugDataQuery;
|
||||
use PayPlugModule\Model\PayPlugConfigValue;
|
||||
use PayPlugModule\PayPlugModule;
|
||||
use PayPlugModule\Service\PaymentService;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Thelia\Core\Event\Order\OrderEvent;
|
||||
use Thelia\Core\Event\TheliaEvents;
|
||||
|
||||
class OrderListener implements EventSubscriberInterface
|
||||
{
|
||||
/** @var PaymentService */
|
||||
protected $paymentService;
|
||||
|
||||
public function __construct(PaymentService $paymentService)
|
||||
{
|
||||
$this->paymentService = $paymentService;
|
||||
}
|
||||
|
||||
public function onOrderUpdateStatus(OrderEvent $event)
|
||||
{
|
||||
$order = $event->getOrder();
|
||||
|
||||
$orderPayPlugData = OrderPayPlugDataQuery::create()
|
||||
->findOneById($order->getId());
|
||||
|
||||
if (null === $orderPayPlugData || false == $orderPayPlugData->getNeedCapture()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->handleCapture($event, $orderPayPlugData);
|
||||
}
|
||||
|
||||
protected function handleCapture(OrderEvent $event, OrderPayPlugData $orderPayPlugData)
|
||||
{
|
||||
// If already captured do nothing
|
||||
if (null !== $orderPayPlugData->getCapturedAt()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If new status is not trigger status do nothing
|
||||
if (PayPlugModule::getConfigValue(PayPlugConfigValue::DIFFERED_PAYMENT_TRIGGER_CAPTURE_STATUS) != $event->getStatus()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->paymentService->doOrderCapture($event->getOrder());
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return [
|
||||
TheliaEvents::ORDER_UPDATE_STATUS => ['onOrderUpdateStatus', 64]
|
||||
];
|
||||
}
|
||||
}
|
||||
208
local/modules/PayPlugModule/EventListener/PaymentListener.php
Executable file
208
local/modules/PayPlugModule/EventListener/PaymentListener.php
Executable file
@@ -0,0 +1,208 @@
|
||||
<?php
|
||||
|
||||
namespace PayPlugModule\EventListener;
|
||||
|
||||
use Payplug\Exception\PayplugException;
|
||||
use Payplug\Payment;
|
||||
use PayPlugModule\Event\PayPlugPaymentEvent;
|
||||
use PayPlugModule\Model\OrderPayPlugData;
|
||||
use PayPlugModule\Model\OrderPayPlugMultiPaymentQuery;
|
||||
use PayPlugModule\Service\OrderStatusService;
|
||||
use PayPlugModule\Service\PaymentService;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Thelia\Core\Event\Order\OrderEvent;
|
||||
use Thelia\Core\Event\TheliaEvents;
|
||||
|
||||
class PaymentListener extends PaymentService implements EventSubscriberInterface
|
||||
{
|
||||
/** @var OrderStatusService */
|
||||
protected $orderStatusService;
|
||||
|
||||
public function __construct(EventDispatcherInterface $dispatcher, OrderStatusService $orderStatusService)
|
||||
{
|
||||
parent::__construct($dispatcher);
|
||||
$this->orderStatusService = $orderStatusService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send refund to PayPlug, set payment url and id to event
|
||||
*
|
||||
* @param PayPlugPaymentEvent $paymentEvent
|
||||
* @throws \Payplug\Exception\ConfigurationNotSetException
|
||||
*/
|
||||
public function createPayment(PayPlugPaymentEvent $paymentEvent)
|
||||
{
|
||||
try {
|
||||
$parameters = $paymentEvent->getFormattedPaymentParameters();
|
||||
$payPlugPayment = Payment::create($parameters);
|
||||
|
||||
$paymentEvent->setPaymentId($payPlugPayment->id)
|
||||
->setIsPaid($payPlugPayment->is_paid)
|
||||
->setPaymentUrl($payPlugPayment->hosted_payment->payment_url);
|
||||
|
||||
} catch (PayplugException $exception) {
|
||||
throw new \Exception($this->formatErrorMessage($exception), 0, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send refund to PayPlug
|
||||
*
|
||||
* @param PayPlugPaymentEvent $paymentEvent
|
||||
* @throws \Payplug\Exception\ConfigurationNotSetException
|
||||
* @throws \Payplug\Exception\InvalidPaymentException
|
||||
*/
|
||||
public function createRefund(PayPlugPaymentEvent $paymentEvent)
|
||||
{
|
||||
try {
|
||||
$payPlugPayment = Payment::retrieve($paymentEvent->getPaymentId());
|
||||
$data = null;
|
||||
if ($paymentEvent->getAmount()) {
|
||||
$data = ['amount' => $paymentEvent->getAmount()];
|
||||
}
|
||||
$payPlugPayment->refund($data);
|
||||
} catch (PayplugException $exception) {
|
||||
throw new \Exception($this->formatErrorMessage($exception), 0, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send capture to PayPlug
|
||||
*
|
||||
* @param PayPlugPaymentEvent $paymentEvent
|
||||
* @throws \Payplug\Exception\ConfigurationNotSetException
|
||||
*/
|
||||
public function createCapture(PayPlugPaymentEvent $paymentEvent)
|
||||
{
|
||||
try {
|
||||
$payPlugPayment = Payment::retrieve($paymentEvent->getPaymentId());
|
||||
|
||||
$paymentCapture = $payPlugPayment->capture();
|
||||
} catch (PayplugException $exception) {
|
||||
throw new \Exception($this->formatErrorMessage($exception), 0, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch create payment for an order and set payment id to order transaction ref
|
||||
*
|
||||
* @param PayPlugPaymentEvent $paymentEvent
|
||||
*/
|
||||
public function orderPayment(PayPlugPaymentEvent $paymentEvent)
|
||||
{
|
||||
$this->dispatcher->dispatch(PayPlugPaymentEvent::CREATE_PAYMENT_EVENT, $paymentEvent);
|
||||
|
||||
$order = $paymentEvent->getOrder();
|
||||
|
||||
$orderPayPlugData = (new OrderPayPlugData())
|
||||
->setId($order->getId());
|
||||
|
||||
if ($paymentEvent->isCapture()) {
|
||||
$orderPayPlugData->setNeedCapture(1);
|
||||
}
|
||||
|
||||
$orderPayPlugData->save();
|
||||
|
||||
$orderEvent = new OrderEvent($paymentEvent->getOrder());
|
||||
$orderEvent->setTransactionRef($paymentEvent->getPaymentId());
|
||||
$this->dispatcher->dispatch(TheliaEvents::ORDER_UPDATE_TRANSACTION_REF, $orderEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch refund for an order
|
||||
*
|
||||
* @param PayPlugPaymentEvent $paymentEvent
|
||||
* @throws \Payplug\Exception\ConfigurationNotSetException
|
||||
* @throws \Payplug\Exception\InvalidPaymentException
|
||||
*/
|
||||
public function orderRefund(PayPlugPaymentEvent $paymentEvent)
|
||||
{
|
||||
$multiPayments = OrderPayPlugMultiPaymentQuery::create()
|
||||
->findByOrderId($paymentEvent->getOrder()->getId());
|
||||
|
||||
if (count($multiPayments) > 0) {
|
||||
$amountToRefund = $paymentEvent->getAmount();
|
||||
foreach ($multiPayments as $multiPayment) {
|
||||
if ($amountToRefund <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If already refunded => do nothing
|
||||
if ($multiPayment->getAmountRefunded() >= $multiPayment->getAmount()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If not paid => cancel it
|
||||
if ($multiPayment->getPaidAt() === null) {
|
||||
$multiPayment->setPlannedAt(null)
|
||||
->save();
|
||||
continue;
|
||||
}
|
||||
|
||||
$currentPaymentAmountToRefund = $multiPayment->getAmount()-$multiPayment->getAmountRefunded();
|
||||
$currentPaymentAmountToRefund = $currentPaymentAmountToRefund > $amountToRefund ? $amountToRefund : $currentPaymentAmountToRefund;
|
||||
// Else refund it
|
||||
$refundPaymentEvent = clone $paymentEvent;
|
||||
$refundPaymentEvent->setPaymentId($multiPayment->getPaymentId())
|
||||
->setAmount($currentPaymentAmountToRefund);
|
||||
$this->dispatcher->dispatch(PayPlugPaymentEvent::CREATE_REFUND_EVENT, $refundPaymentEvent);
|
||||
$amountToRefund = $amountToRefund - $currentPaymentAmountToRefund;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
$this->dispatcher->dispatch(PayPlugPaymentEvent::CREATE_REFUND_EVENT, $paymentEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch capture for an order
|
||||
*
|
||||
* @param PayPlugPaymentEvent $paymentEvent
|
||||
* @throws \Payplug\Exception\ConfigurationNotSetException
|
||||
* @throws \Payplug\Exception\InvalidPaymentException
|
||||
*/
|
||||
public function orderCapture(PayPlugPaymentEvent $paymentEvent)
|
||||
{
|
||||
$this->dispatcher->dispatch(PayPlugPaymentEvent::CREATE_CAPTURE_EVENT, $paymentEvent);
|
||||
}
|
||||
|
||||
protected function formatErrorMessage(PayplugException $exception)
|
||||
{
|
||||
$response = json_decode($exception->getHttpResponse(), true);
|
||||
|
||||
$details = "";
|
||||
|
||||
|
||||
if (isset($response['details'])) {
|
||||
$details = implode(' -', array_map(
|
||||
function ($v, $k) {
|
||||
$errors = [];
|
||||
foreach ($v as $field => $error) {
|
||||
$errors[] = "$field : $error";
|
||||
}
|
||||
return " [$k] ".implode(";", $errors)." .";
|
||||
},
|
||||
$response['details'],
|
||||
array_keys($response['details'])
|
||||
));
|
||||
}
|
||||
|
||||
return $response['message'] . $details;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return [
|
||||
PayPlugPaymentEvent::CREATE_PAYMENT_EVENT => ['createPayment', 128],
|
||||
PayPlugPaymentEvent::CREATE_REFUND_EVENT => ['createRefund', 128],
|
||||
PayPlugPaymentEvent::CREATE_CAPTURE_EVENT => ['createCapture', 128],
|
||||
PayPlugPaymentEvent::ORDER_PAYMENT_EVENT => ['orderPayment', 128],
|
||||
PayPlugPaymentEvent::ORDER_REFUND_EVENT => ['orderRefund', 128],
|
||||
PayPlugPaymentEvent::ORDER_CAPTURE_EVENT => ['orderCapture', 128]
|
||||
];
|
||||
}
|
||||
}
|
||||
255
local/modules/PayPlugModule/Form/ConfigurationForm.php
Executable file
255
local/modules/PayPlugModule/Form/ConfigurationForm.php
Executable file
@@ -0,0 +1,255 @@
|
||||
<?php
|
||||
|
||||
namespace PayPlugModule\Form;
|
||||
|
||||
use PayPlugModule\Model\PayPlugConfigValue;
|
||||
use PayPlugModule\PayPlugModule;
|
||||
use PayPlugModule\Service\OrderStatusService;
|
||||
use PayPlugModule\Model\PayPlugModuleDeliveryTypeQuery;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Thelia\Core\Translation\Translator;
|
||||
use Thelia\Form\BaseForm;
|
||||
use Thelia\Model\Base\ModuleQuery;
|
||||
use Thelia\Model\Module;
|
||||
use Thelia\Model\OrderStatusQuery;
|
||||
use Thelia\Module\BaseModule;
|
||||
|
||||
class ConfigurationForm extends BaseForm
|
||||
{
|
||||
const DELIVERY_MODULE_TYPE_KEY_PREFIX = "module_delivery_type";
|
||||
|
||||
protected function buildForm()
|
||||
{
|
||||
$orderStatuses = OrderStatusQuery::create()
|
||||
->find();
|
||||
|
||||
$orderStatusChoices = [];
|
||||
foreach ($orderStatuses as $orderStatus) {
|
||||
$orderStatusChoices[$orderStatus->getId()] = $orderStatus->getTitle();
|
||||
}
|
||||
|
||||
/** @var OrderStatusService $orderStatusesService */
|
||||
$orderStatusesService = $this->container->get('payplugmodule_order_status_service');
|
||||
|
||||
$this->formBuilder
|
||||
->add(
|
||||
PayPlugConfigValue::OFFER,
|
||||
ChoiceType::class,
|
||||
[
|
||||
'choices' => [
|
||||
'starter' => 'Starter',
|
||||
'pro' => 'Pro',
|
||||
'premium' => 'Premium',
|
||||
],
|
||||
"data" => PayPlugModule::getConfigValue(PayPlugConfigValue::OFFER),
|
||||
"label"=> Translator::getInstance()->trans("Select your PayPlug offer", [], PayPlugModule::DOMAIN_NAME),
|
||||
"required" => true
|
||||
]
|
||||
)
|
||||
->add(
|
||||
PayPlugConfigValue::PAYMENT_ENABLED,
|
||||
CheckboxType::class,
|
||||
[
|
||||
"data" => !!PayPlugModule::getConfigValue(PayPlugConfigValue::PAYMENT_ENABLED, false),
|
||||
"label"=> Translator::getInstance()->trans("Enable payment by PayPlug", [], PayPlugModule::DOMAIN_NAME),
|
||||
"required" => false
|
||||
]
|
||||
)
|
||||
->add(
|
||||
PayPlugConfigValue::API_MODE,
|
||||
ChoiceType::class,
|
||||
[
|
||||
'choices' => [
|
||||
'live' => 'Live',
|
||||
'test' => 'Test',
|
||||
],
|
||||
"data" => PayPlugModule::getConfigValue(PayPlugConfigValue::API_MODE),
|
||||
"label"=> Translator::getInstance()->trans("Choose API mode", [], PayPlugModule::DOMAIN_NAME),
|
||||
"required" => true
|
||||
]
|
||||
)
|
||||
->add(
|
||||
PayPlugConfigValue::LIVE_API_KEY,
|
||||
TextType::class,
|
||||
[
|
||||
"data" => PayPlugModule::getConfigValue(PayPlugConfigValue::LIVE_API_KEY),
|
||||
"label"=> Translator::getInstance()->trans("Live API secret key", [], PayPlugModule::DOMAIN_NAME),
|
||||
"label_attr" => ['help' => Translator::getInstance()->trans("Look here %link", ['%link' => "<a target='_blank' href='https://portal.payplug.com/#/configuration/api'>Api configuration</a>"], PayPlugModule::DOMAIN_NAME)],
|
||||
"required" => true
|
||||
]
|
||||
)
|
||||
->add(
|
||||
PayPlugConfigValue::TEST_API_KEY,
|
||||
TextType::class,
|
||||
[
|
||||
"data" => PayPlugModule::getConfigValue(PayPlugConfigValue::TEST_API_KEY),
|
||||
"label"=> Translator::getInstance()->trans("Test API secret key", [], PayPlugModule::DOMAIN_NAME),
|
||||
"label_attr" => ['help' => Translator::getInstance()->trans("Look here %link", ['%link' => "<a target='_blank' href='https://portal.payplug.com/#/configuration/api'>Api configuration</a>"], PayPlugModule::DOMAIN_NAME)],
|
||||
"required" => true
|
||||
]
|
||||
)
|
||||
->add(
|
||||
PayPlugConfigValue::PAYMENT_PAGE_TYPE,
|
||||
ChoiceType::class,
|
||||
[
|
||||
'choices' => [
|
||||
'hosted_page' => Translator::getInstance()->trans("Hosted page", [], PayPlugModule::DOMAIN_NAME),
|
||||
'lightbox' => Translator::getInstance()->trans("Lightbox", [], PayPlugModule::DOMAIN_NAME),
|
||||
// Todo implement payplug JS
|
||||
//'payplug_js' => Translator::getInstance()->trans("Payplug.js", [], PayPlugModule::DOMAIN_NAME)
|
||||
],
|
||||
"data" => PayPlugModule::getConfigValue(PayPlugConfigValue::PAYMENT_PAGE_TYPE),
|
||||
"label"=> Translator::getInstance()->trans("Payment page type", [], PayPlugModule::DOMAIN_NAME),
|
||||
"label_attr" => ['help' => Translator::getInstance()->trans("Hosted page will redirect your customer to a payment page / Lightbox will open a payment pop up in your website.", [], PayPlugModule::DOMAIN_NAME)],
|
||||
"required" => true
|
||||
]
|
||||
)
|
||||
->add(
|
||||
PayPlugConfigValue::ONE_CLICK_PAYMENT_ENABLED,
|
||||
CheckboxType::class,
|
||||
[
|
||||
"data" => !!PayPlugModule::getConfigValue(PayPlugConfigValue::ONE_CLICK_PAYMENT_ENABLED),
|
||||
"label"=> Translator::getInstance()->trans("Enable one click payment", [], PayPlugModule::DOMAIN_NAME),
|
||||
"label_attr" => ['help' => Translator::getInstance()->trans("This will allow your customer to save their card fo future order.", [], PayPlugModule::DOMAIN_NAME)],
|
||||
"required" => false
|
||||
]
|
||||
)
|
||||
->add(
|
||||
PayPlugConfigValue::MULTI_PAYMENT_ENABLED,
|
||||
CheckboxType::class,
|
||||
[
|
||||
"data" => !!PayPlugModule::getConfigValue(PayPlugConfigValue::MULTI_PAYMENT_ENABLED),
|
||||
"label"=> Translator::getInstance()->trans("Enabled multi-payment", [], PayPlugModule::DOMAIN_NAME),
|
||||
"label_attr" => ['help' => Translator::getInstance()->trans("Enable payment in 2,3 or 4 times", [], PayPlugModule::DOMAIN_NAME)],
|
||||
"required" => false
|
||||
]
|
||||
)
|
||||
->add(
|
||||
PayPlugConfigValue::MULTI_PAYMENT_TIMES,
|
||||
ChoiceType::class,
|
||||
[
|
||||
'choices' => [
|
||||
'2' => Translator::getInstance()->trans("2 times", [], PayPlugModule::DOMAIN_NAME),
|
||||
'3' => Translator::getInstance()->trans("3 times", [], PayPlugModule::DOMAIN_NAME),
|
||||
'4' => Translator::getInstance()->trans("4 times", [], PayPlugModule::DOMAIN_NAME)
|
||||
],
|
||||
"data" => PayPlugModule::getConfigValue(PayPlugConfigValue::MULTI_PAYMENT_TIMES),
|
||||
"label"=> Translator::getInstance()->trans("Payment in ", [], PayPlugModule::DOMAIN_NAME),
|
||||
"required" => false
|
||||
]
|
||||
)
|
||||
->add(
|
||||
PayPlugConfigValue::MULTI_PAYMENT_MINIMUM,
|
||||
TextType::class,
|
||||
[
|
||||
"data" => PayPlugModule::getConfigValue(PayPlugConfigValue::MULTI_PAYMENT_MINIMUM),
|
||||
"label"=> Translator::getInstance()->trans("Minimum amount ", [], PayPlugModule::DOMAIN_NAME),
|
||||
"required" => false
|
||||
]
|
||||
)
|
||||
->add(
|
||||
PayPlugConfigValue::MULTI_PAYMENT_MAXIMUM,
|
||||
TextType::class,
|
||||
[
|
||||
"data" => PayPlugModule::getConfigValue(PayPlugConfigValue::MULTI_PAYMENT_MAXIMUM),
|
||||
"label"=> Translator::getInstance()->trans("Maximum amount ", [], PayPlugModule::DOMAIN_NAME),
|
||||
"required" => false
|
||||
]
|
||||
)
|
||||
->add(
|
||||
PayPlugConfigValue::DIFFERED_PAYMENT_ENABLED,
|
||||
CheckboxType::class,
|
||||
[
|
||||
"data" => !!PayPlugModule::getConfigValue(PayPlugConfigValue::DIFFERED_PAYMENT_ENABLED),
|
||||
"label"=> Translator::getInstance()->trans("Enabled differed payment", [], PayPlugModule::DOMAIN_NAME),
|
||||
"label_attr" => ['help' => Translator::getInstance()->trans("Trigger the payment on order status change (max : 7 days after)", [], PayPlugModule::DOMAIN_NAME)],
|
||||
"required" => false
|
||||
]
|
||||
)
|
||||
->add(
|
||||
PayPlugConfigValue::DIFFERED_PAYMENT_AUTHORIZED_CAPTURE_STATUS,
|
||||
ChoiceType::class,
|
||||
[
|
||||
'choices' => $orderStatusChoices,
|
||||
"data" => PayPlugModule::getConfigValue(PayPlugConfigValue::DIFFERED_PAYMENT_AUTHORIZED_CAPTURE_STATUS, $orderStatusesService->findOrCreateAuthorizedCaptureOrderStatus()->getId()),
|
||||
"label"=> Translator::getInstance()->trans("Which status to set when a capture is authorized", [], PayPlugModule::DOMAIN_NAME),
|
||||
"required" => false
|
||||
]
|
||||
)
|
||||
->add(
|
||||
PayPlugConfigValue::DIFFERED_PAYMENT_TRIGGER_CAPTURE_STATUS,
|
||||
ChoiceType::class,
|
||||
[
|
||||
'choices' => $orderStatusChoices,
|
||||
"data" => PayPlugModule::getConfigValue(PayPlugConfigValue::DIFFERED_PAYMENT_TRIGGER_CAPTURE_STATUS),
|
||||
"label"=> Translator::getInstance()->trans("Capture the payment after order get the status", [], PayPlugModule::DOMAIN_NAME),
|
||||
"required" => false
|
||||
]
|
||||
)
|
||||
->add(
|
||||
PayPlugConfigValue::DIFFERED_PAYMENT_CAPTURE_EXPIRED_STATUS,
|
||||
ChoiceType::class,
|
||||
[
|
||||
'choices' => $orderStatusChoices,
|
||||
"data" => PayPlugModule::getConfigValue(PayPlugConfigValue::DIFFERED_PAYMENT_CAPTURE_EXPIRED_STATUS, $orderStatusesService->findOrCreateExpiredCaptureOrderStatus()->getId()),
|
||||
"label"=> Translator::getInstance()->trans("What status to set on expired capture ", [], PayPlugModule::DOMAIN_NAME),
|
||||
"required" => false
|
||||
]
|
||||
)
|
||||
->add(
|
||||
PayPlugConfigValue::SEND_CONFIRMATION_MESSAGE_ONLY_IF_PAID,
|
||||
CheckboxType::class,
|
||||
[
|
||||
"data" => !!PayPlugModule::getConfigValue(PayPlugConfigValue::SEND_CONFIRMATION_MESSAGE_ONLY_IF_PAID),
|
||||
"label"=> Translator::getInstance()->trans("Send order confirmation on payment success", [], PayPlugModule::DOMAIN_NAME),
|
||||
"label_attr" => ['help' => Translator::getInstance()->trans("If checked, the order confirmation message is sent to the customer only when the payment is successful. The order notification is always sent to the shop administrator", [], PayPlugModule::DOMAIN_NAME)],
|
||||
"required" => false
|
||||
]
|
||||
)
|
||||
;
|
||||
|
||||
foreach (self::getDeliveryModuleFormFields() as $deliveryModuleFormField)
|
||||
{
|
||||
$this->formBuilder
|
||||
->add(
|
||||
$deliveryModuleFormField['name'],
|
||||
ChoiceType::class,
|
||||
[
|
||||
'required' => false,
|
||||
'label' => $deliveryModuleFormField['moduleCode'],
|
||||
'choices' => [
|
||||
'carrier' => Translator::getInstance()->trans('Carrier ', [], PayPlugModule::DOMAIN_NAME),
|
||||
'storepickup' => Translator::getInstance()->trans('Store pick up ', [], PayPlugModule::DOMAIN_NAME),
|
||||
'networkpickup' => Translator::getInstance()->trans('Network pick up ', [], PayPlugModule::DOMAIN_NAME),
|
||||
'travelpickup' => Translator::getInstance()->trans('Travel pick up ', [], PayPlugModule::DOMAIN_NAME),
|
||||
'edelivery' => Translator::getInstance()->trans('E-Delivery ', [], PayPlugModule::DOMAIN_NAME)
|
||||
],
|
||||
'data' => $deliveryModuleFormField['value']
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public static function getDeliveryModuleFormFields()
|
||||
{
|
||||
$deliveryModules = ModuleQuery::create()
|
||||
->filterByType(BaseModule::DELIVERY_MODULE_TYPE)
|
||||
->find();
|
||||
|
||||
return array_map(function (Module $deliveryModule) {
|
||||
$oneyModuleDeliveryType = PayPlugModuleDeliveryTypeQuery::create()->filterByModuleId($deliveryModule->getId())->findOne();
|
||||
return [
|
||||
'name' => self::DELIVERY_MODULE_TYPE_KEY_PREFIX.':'.$deliveryModule->getId(),
|
||||
'moduleCode' => $deliveryModule->getCode(),
|
||||
'value' => $oneyModuleDeliveryType !== null ? $oneyModuleDeliveryType->getDeliveryType() : null
|
||||
];
|
||||
}, iterator_to_array($deliveryModules));
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return "payplugmodule_configuration_form";
|
||||
}
|
||||
}
|
||||
23
local/modules/PayPlugModule/Form/OrderActionForm.php
Executable file
23
local/modules/PayPlugModule/Form/OrderActionForm.php
Executable file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace PayPlugModule\Form;
|
||||
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Thelia\Form\BaseForm;
|
||||
|
||||
class OrderActionForm extends BaseForm
|
||||
{
|
||||
protected function buildForm()
|
||||
{
|
||||
$this->formBuilder
|
||||
->add(
|
||||
'order_id',
|
||||
TextType::class
|
||||
);
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return "payplugmodule_order_action_form";
|
||||
}
|
||||
}
|
||||
24
local/modules/PayPlugModule/Form/OrderRefundForm.php
Normal file
24
local/modules/PayPlugModule/Form/OrderRefundForm.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace PayPlugModule\Form;
|
||||
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
|
||||
class OrderRefundForm extends OrderActionForm
|
||||
{
|
||||
protected function buildForm()
|
||||
{
|
||||
parent::buildForm();
|
||||
|
||||
$this->formBuilder
|
||||
->add(
|
||||
'refund_amount',
|
||||
TextType::class
|
||||
);
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return parent::getName().'_refund';
|
||||
}
|
||||
}
|
||||
65
local/modules/PayPlugModule/Hook/BackHookManager.php
Executable file
65
local/modules/PayPlugModule/Hook/BackHookManager.php
Executable file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace PayPlugModule\Hook;
|
||||
|
||||
|
||||
use PayPlugModule\Model\OrderPayPlugData;
|
||||
use PayPlugModule\Model\OrderPayPlugDataQuery;
|
||||
use PayPlugModule\Model\OrderPayPlugMultiPaymentQuery;
|
||||
use PayPlugModule\PayPlugModule;
|
||||
use Propel\Runtime\Map\TableMap;
|
||||
use Thelia\Core\Event\Hook\HookRenderEvent;
|
||||
use Thelia\Core\Hook\BaseHook;
|
||||
use Thelia\Model\OrderQuery;
|
||||
use Thelia\Model\OrderStatus;
|
||||
|
||||
class BackHookManager extends BaseHook
|
||||
{
|
||||
/**
|
||||
* @param HookRenderEvent $event
|
||||
* @throws \Propel\Runtime\Exception\PropelException
|
||||
*/
|
||||
public function onOrderEditPaymentModuleBottom(HookRenderEvent $event)
|
||||
{
|
||||
$order = OrderQuery::create()
|
||||
->filterByPaymentModuleId(PayPlugModule::getModuleId())
|
||||
->filterById($event->getArgument('order_id'))
|
||||
->findOne();
|
||||
|
||||
if (null === $order) {
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var OrderPayPlugData $orderPayPlugData */
|
||||
$orderPayPlugData = OrderPayPlugDataQuery::create()
|
||||
->findOneById($order->getId());
|
||||
|
||||
if (null === $orderPayPlugData) {
|
||||
return;
|
||||
}
|
||||
|
||||
$orderPayPlugMultiPayments = OrderPayPlugMultiPaymentQuery::create()
|
||||
->filterByOrderId($order->getId())
|
||||
->find()
|
||||
->toArray(null, false,TableMap::TYPE_CAMELNAME);
|
||||
|
||||
$isPaid = !in_array($order->getOrderStatus()->getCode(), [OrderStatus::CODE_NOT_PAID, OrderStatus::CODE_CANCELED]);
|
||||
$event->add(
|
||||
$this->render(
|
||||
'PayPlugModule/order_pay_plug.html',
|
||||
array_merge(
|
||||
$event->getArguments(),
|
||||
[
|
||||
'isPaid' => $isPaid,
|
||||
'currency' => $order->getCurrency()->getSymbol()
|
||||
],
|
||||
$orderPayPlugData->toArray(TableMap::TYPE_CAMELNAME),
|
||||
[
|
||||
'multiPayments' => $orderPayPlugMultiPayments
|
||||
]
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
95
local/modules/PayPlugModule/Hook/FrontHookManager.php
Executable file
95
local/modules/PayPlugModule/Hook/FrontHookManager.php
Executable file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
namespace PayPlugModule\Hook;
|
||||
|
||||
use PayPlugModule\Model\PayPlugCardQuery;
|
||||
use PayPlugModule\Model\PayPlugConfigValue;
|
||||
use PayPlugModule\PayPlugModule;
|
||||
use Thelia\Core\Event\Hook\HookRenderEvent;
|
||||
use Thelia\Core\Hook\BaseHook;
|
||||
use Thelia\Model\Country;
|
||||
use Thelia\TaxEngine\TaxEngine;
|
||||
|
||||
class FrontHookManager extends BaseHook
|
||||
{
|
||||
/** @var TaxEngine */
|
||||
protected $taxEngine;
|
||||
|
||||
public function __construct(TaxEngine $taxEngine)
|
||||
{
|
||||
$this->taxEngine = $taxEngine;
|
||||
}
|
||||
|
||||
public function onOrderInvoiceAfterJsInclude(HookRenderEvent $event)
|
||||
{
|
||||
$payPlugModuleId = PayPlugModule::getModuleId();
|
||||
if (PayPlugModule::getConfigValue(PayPlugConfigValue::PAYMENT_PAGE_TYPE) === "lightbox") {
|
||||
$event->add($this->render(
|
||||
'PayPlugModule/order-invoice-after-js-include.html',
|
||||
compact('payPlugModuleId')
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
public function onOrderInvoicePaymentExtra(HookRenderEvent $event)
|
||||
{
|
||||
if ((int)$event->getArgument('module') !== PayPlugModule::getModuleId()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->displayOneClickPayment($event);
|
||||
$this->displayMultiPayment($event);
|
||||
}
|
||||
|
||||
protected function displayMultiPayment(HookRenderEvent $event)
|
||||
{
|
||||
if (!PayPlugModule::getConfigValue(PayPlugConfigValue::MULTI_PAYMENT_ENABLED)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$nTimes = PayPlugModule::getConfigValue(PayPlugConfigValue::MULTI_PAYMENT_TIMES);
|
||||
$minimumAmount = PayPlugModule::getConfigValue(PayPlugConfigValue::MULTI_PAYMENT_MINIMUM);
|
||||
$maximumAmount = PayPlugModule::getConfigValue(PayPlugConfigValue::MULTI_PAYMENT_MAXIMUM);
|
||||
|
||||
/** @var Country $country */
|
||||
$country = $this->taxEngine->getDeliveryCountry();
|
||||
|
||||
$cart = $this->getSession()->getSessionCart();
|
||||
$cartAmount = $cart->getTaxedAmount($country);
|
||||
if ($cartAmount <= $minimumAmount || $cartAmount >= $maximumAmount) {
|
||||
return;
|
||||
}
|
||||
|
||||
$event->add(
|
||||
$this->render(
|
||||
'PayPlugModule/multi-payment.html',
|
||||
compact("nTimes")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
protected function displayOneClickPayment(HookRenderEvent $event)
|
||||
{
|
||||
if (!PayPlugModule::getConfigValue(PayPlugConfigValue::ONE_CLICK_PAYMENT_ENABLED)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$customerId = $this->getSession()->getCustomerUser()->getId();
|
||||
|
||||
$payPlugCard = PayPlugCardQuery::create()
|
||||
->findOneByCustomerId($customerId);
|
||||
|
||||
if (null === $payPlugCard) {
|
||||
return;
|
||||
}
|
||||
|
||||
$event->add(
|
||||
$this->render(
|
||||
'PayPlugModule/one-click-payment.html',
|
||||
[
|
||||
'last4' => $payPlugCard->getLast4()
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
' refunded' => 'Remboursé',
|
||||
'Adjust amount' => 'Ajuster le montant',
|
||||
'Amount' => 'Montant',
|
||||
'Canceled' => 'Annulé',
|
||||
'Capture order' => 'Déclencher le paiement de cette commande',
|
||||
'Differed payment' => 'Paiement différé ',
|
||||
'Do you really want to capture this order ?' => 'Voulez vous vraiment déclencher le paiement de cette commande ?',
|
||||
'Do you really want to refund this order ?' => 'Voulez vous vraiment rembourser cette commande ?',
|
||||
'Force the capture for this order' => 'Forcer le déclenchement du paiement',
|
||||
'Multi payment' => 'Paiement en plusieurs fois',
|
||||
'Order without shipping' => 'La commande sans les frais de port',
|
||||
'Paid at' => 'Payé le ',
|
||||
'PayPlug API configuration' => 'Configuration API PayPlug',
|
||||
'PayPlug basic payment configuration' => 'Configuration de paiement basique',
|
||||
'PayPlug delivery type configuration' => 'Configuration des types de livraison PayPlug',
|
||||
'PayPlug module configuration' => 'PayPlug module configuration',
|
||||
'PayPlug offer' => 'Offre PayPlug',
|
||||
'PayPlug order data' => 'Données de commande PayPlug',
|
||||
'PayPlug premium offer configuration' => 'Configuration de paiement offre Premium',
|
||||
'PayPlug pro offer configuration' => 'Configuration de paiement offre Pro',
|
||||
'Payment capture will expire on ' => 'L\'empreinte de paiement expirera le ',
|
||||
'Payment n° ' => 'Paiement n° ',
|
||||
'Payment was captured at ' => 'Paiement déclenché le ',
|
||||
'Payments in several times are not guaranteed, a default may occur on future due dates.' => 'Les paiements en plusieurs fois ne sont pas garantis. Un défaut de paiement peut survenir lors des échéances futures.',
|
||||
'Planned at' => 'Prévu le ',
|
||||
'Please select a Pay Plug delivery type correspondance for each delivery modules' => 'Veuillez choisir un type de livraison PayPlug sur chaques modules de livraison',
|
||||
'Products' => 'Produits',
|
||||
'Refund' => 'Remboursement',
|
||||
'Refund order' => 'Rembourser la commande ',
|
||||
'Refunded at' => 'Remboursé le ',
|
||||
'Save' => 'Enregistrer',
|
||||
'The entire order' => 'La commande totale',
|
||||
'To trigger the payments on planned date please add a daily cron on this Thelia command ' => 'Pour déclencher les paiements programmés veuillez ajouter cette commande Thelia a un cron journalier ',
|
||||
'What do you want refund' => 'Que voulez-vous rembourser',
|
||||
);
|
||||
34
local/modules/PayPlugModule/I18n/en_US.php
Executable file
34
local/modules/PayPlugModule/I18n/en_US.php
Executable file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
'2 times' => '2 times',
|
||||
'3 times' => '3 times',
|
||||
'4 times' => '4 times',
|
||||
'Capture the payment after order get the status' => 'Capture the payment after order get the status',
|
||||
'Choose API mode' => 'Choose API mode',
|
||||
'Enable one click payment' => 'Enable one click payment',
|
||||
'Enable payment by PayPlug' => 'Enable payment by PayPlug',
|
||||
'Enable payment in 2,3 or 4 times' => 'Enable payment in 2,3 or 4 times',
|
||||
'Enabled differed payment' => 'Enabled differed payment',
|
||||
'Enabled multi-payment' => 'Enabled multi-payment',
|
||||
'Error' => 'Error',
|
||||
'Hosted page' => 'Hosted page',
|
||||
'Hosted page will redirect your customer to a payment page / Lightbox will open a payment pop up in your website.' => 'Hosted page will redirect your customer to a payment page / Lightbox will open a payment pop up in your website.',
|
||||
'If checked, the order confirmation message is sent to the customer only when the payment is successful. The order notification is always sent to the shop administrator' => 'If checked, the order confirmation message is sent to the customer only when the payment is successful. The order notification is always sent to the shop administrator',
|
||||
'Invalid payment parameter, %parameter should not be null or empty.' => 'Invalid payment parameter, %parameter should not be null or empty.',
|
||||
'Lightbox' => 'Lightbox',
|
||||
'Live API secret key' => 'Live API secret key',
|
||||
'Look here %link' => 'Look here %link',
|
||||
'Maximum amount ' => 'Maximum amount ',
|
||||
'Minimum amount ' => 'Minimum amount ',
|
||||
'Payment in ' => 'Payment in ',
|
||||
'Payment page type' => 'Payment page type',
|
||||
'Payplug.js' => 'Payplug.js',
|
||||
'Select your PayPlug offer' => 'Select your PayPlug offer',
|
||||
'Send order confirmation on payment success' => 'Send order confirmation on payment success',
|
||||
'Test API secret key' => 'Test API secret key',
|
||||
'This will allow your customer to save their card fo future order.' => 'This will allow your customer to save their card fo future order.',
|
||||
'Trigger the payment on order status change (max : 7 days after)' => 'Trigger the payment on order status change (max : 7 days after)',
|
||||
'What status to set on expired capture ' => 'What status to set on expired capture ',
|
||||
'Which status to set when a capture is authorized' => 'Which status to set when a capture is authorized',
|
||||
);
|
||||
39
local/modules/PayPlugModule/I18n/fr_FR.php
Executable file
39
local/modules/PayPlugModule/I18n/fr_FR.php
Executable file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
'2 times' => '2 fois',
|
||||
'3 times' => '3 fois',
|
||||
'4 times' => '4 fois',
|
||||
'Capture the payment after order get the status' => 'Déclenché le paiement lorsque la commande as le statut',
|
||||
'Carrier ' => 'Transporteur',
|
||||
'Choose API mode' => 'Choisissez le mode de l\'API',
|
||||
'E-Delivery ' => 'Livraison en ligne',
|
||||
'Enable one click payment' => 'Activer le paiement en un clic',
|
||||
'Enable payment by PayPlug' => 'Activer le paiement par PayPlug',
|
||||
'Enable payment in 2,3 or 4 times' => 'Activer le paiement en 2, 3 ou 4 fois.',
|
||||
'Enabled differed payment' => 'Activer le paiement différé',
|
||||
'Enabled multi-payment' => 'Activer le paiement en plusieurs fois',
|
||||
'Error' => 'Erreur',
|
||||
'Hosted page' => 'Hosted page',
|
||||
'Hosted page will redirect your customer to a payment page / Lightbox will open a payment pop up in your website.' => 'Hosted page redirige le client sur une page de paiement / Lightbox ouvre une pop-up de paiement sur votre site.',
|
||||
'If checked, the order confirmation message is sent to the customer only when the payment is successful. The order notification is always sent to the shop administrator' => 'Si la case est cochée, le message de confirmation de commande est envoyé au client seulement quand le paiment est réussi. La notification de commande est toujours envoyée à l\'administrateur du site',
|
||||
'Invalid payment parameter, %parameter should not be null or empty.' => 'Paramètre de paiement invalide, %parameter ne doit pas être nulle ou vide.',
|
||||
'Lightbox' => 'Lightbox',
|
||||
'Live API secret key' => 'Live API secret key',
|
||||
'Look here %link' => 'Regardez ici %link',
|
||||
'Maximum amount ' => 'Montant maximum',
|
||||
'Minimum amount ' => 'Montant minimum',
|
||||
'Network pick up ' => 'Point retrait',
|
||||
'Payment in ' => 'Paiement en ',
|
||||
'Payment page type' => 'Type de la page de paiement',
|
||||
'Payplug.js' => 'Payplug.js',
|
||||
'Select your PayPlug offer' => 'Séléctionner votre offre PayPlug',
|
||||
'Send order confirmation on payment success' => 'Confirmation de commande si le paiement réussit',
|
||||
'Store pick up ' => 'Retrait en magasin',
|
||||
'Test API secret key' => 'Test API secret key',
|
||||
'This will allow your customer to save their card fo future order.' => 'Cela permettra a vos clients d\'enregistrer leur carte pour leur commande futur.',
|
||||
'Trigger the payment on order status change (max : 7 days after)' => 'Déclencher le paiement au changement de statut (max : 7 jour après)',
|
||||
'Unknown' => 'Inconnue',
|
||||
'What status to set on expired capture ' => 'Quel statut pour les commandes dont l\'empreinte a expirée ',
|
||||
'Which status to set when a capture is authorized' => 'Quel staut mettre quand l\'empreinte est autorisé',
|
||||
);
|
||||
9
local/modules/PayPlugModule/I18n/frontOffice/default/fr_FR.php
Executable file
9
local/modules/PayPlugModule/I18n/frontOffice/default/fr_FR.php
Executable file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
'A payment card ending by %last4 has been previously saved at your request. Payment for your order will be made immediately after clicking the "Next Step" button.' => 'Une carte de paiement finissant par %last4 as été enregitrée précédemment a votre demande. Le paiement de cette commande seras fait automatiquement après un clic sur le bouton "Etape suivante".',
|
||||
'One click payment is available !' => 'Paiement en un clic disponible !',
|
||||
'Pay in %n times without fees.' => 'Paiement en %n fois sans frais.',
|
||||
'To clear your payment card details, <a href="%url">please click here</a>' => 'Pour supprimer ces informations de paiement, <a href="%url">cliquez ici</a>',
|
||||
'You will be asked to save your payment card data.' => 'Ils vous sera demandé d\'enregistrer votre carte bancaire.',
|
||||
);
|
||||
20
local/modules/PayPlugModule/Model/OrderPayPlugData.php
Executable file
20
local/modules/PayPlugModule/Model/OrderPayPlugData.php
Executable file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace PayPlugModule\Model;
|
||||
|
||||
use PayPlugModule\Model\Base\OrderPayPlugData as BaseOrderPayPlugData;
|
||||
|
||||
/**
|
||||
* Skeleton subclass for representing a row from the 'order_pay_plug_data' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
*/
|
||||
class OrderPayPlugData extends BaseOrderPayPlugData
|
||||
{
|
||||
|
||||
}
|
||||
20
local/modules/PayPlugModule/Model/OrderPayPlugDataQuery.php
Executable file
20
local/modules/PayPlugModule/Model/OrderPayPlugDataQuery.php
Executable file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace PayPlugModule\Model;
|
||||
|
||||
use PayPlugModule\Model\Base\OrderPayPlugDataQuery as BaseOrderPayPlugDataQuery;
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'order_pay_plug_data' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
*/
|
||||
class OrderPayPlugDataQuery extends BaseOrderPayPlugDataQuery
|
||||
{
|
||||
|
||||
}
|
||||
20
local/modules/PayPlugModule/Model/OrderPayPlugMultiPayment.php
Executable file
20
local/modules/PayPlugModule/Model/OrderPayPlugMultiPayment.php
Executable file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace PayPlugModule\Model;
|
||||
|
||||
use PayPlugModule\Model\Base\OrderPayPlugMultiPayment as BaseOrderPayPlugMultiPayment;
|
||||
|
||||
/**
|
||||
* Skeleton subclass for representing a row from the 'order_pay_plug_multi_payment' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
*/
|
||||
class OrderPayPlugMultiPayment extends BaseOrderPayPlugMultiPayment
|
||||
{
|
||||
|
||||
}
|
||||
20
local/modules/PayPlugModule/Model/OrderPayPlugMultiPaymentQuery.php
Executable file
20
local/modules/PayPlugModule/Model/OrderPayPlugMultiPaymentQuery.php
Executable file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace PayPlugModule\Model;
|
||||
|
||||
use PayPlugModule\Model\Base\OrderPayPlugMultiPaymentQuery as BaseOrderPayPlugMultiPaymentQuery;
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'order_pay_plug_multi_payment' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
*/
|
||||
class OrderPayPlugMultiPaymentQuery extends BaseOrderPayPlugMultiPaymentQuery
|
||||
{
|
||||
|
||||
}
|
||||
20
local/modules/PayPlugModule/Model/PayPlugCard.php
Executable file
20
local/modules/PayPlugModule/Model/PayPlugCard.php
Executable file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace PayPlugModule\Model;
|
||||
|
||||
use PayPlugModule\Model\Base\PayPlugCard as BasePayPlugCard;
|
||||
|
||||
/**
|
||||
* Skeleton subclass for representing a row from the 'pay_plug_card' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
*/
|
||||
class PayPlugCard extends BasePayPlugCard
|
||||
{
|
||||
|
||||
}
|
||||
20
local/modules/PayPlugModule/Model/PayPlugCardQuery.php
Executable file
20
local/modules/PayPlugModule/Model/PayPlugCardQuery.php
Executable file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace PayPlugModule\Model;
|
||||
|
||||
use PayPlugModule\Model\Base\PayPlugCardQuery as BasePayPlugCardQuery;
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'pay_plug_card' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
*/
|
||||
class PayPlugCardQuery extends BasePayPlugCardQuery
|
||||
{
|
||||
|
||||
}
|
||||
58
local/modules/PayPlugModule/Model/PayPlugConfigValue.php
Executable file
58
local/modules/PayPlugModule/Model/PayPlugConfigValue.php
Executable file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace PayPlugModule\Model;
|
||||
|
||||
|
||||
use PayPlugModule\PayPlugModule;
|
||||
|
||||
class PayPlugConfigValue
|
||||
{
|
||||
const OFFER = "offer";
|
||||
const PAYMENT_ENABLED = "payment_enabled";
|
||||
const API_MODE = "api_mode";
|
||||
const LIVE_API_KEY = "live_api_key";
|
||||
const TEST_API_KEY = "test_api_key";
|
||||
const PAYMENT_PAGE_TYPE = "payment_page_type";
|
||||
const ONE_CLICK_PAYMENT_ENABLED = "one_click_payment_enabled";
|
||||
const MULTI_PAYMENT_ENABLED = "multi_payment_enabled";
|
||||
const MULTI_PAYMENT_TIMES = "multi_payment_times";
|
||||
const MULTI_PAYMENT_MINIMUM = "multi_payment_minimum";
|
||||
const MULTI_PAYMENT_MAXIMUM = "multi_payment_maximum";
|
||||
const DIFFERED_PAYMENT_ENABLED = "differed_payment_enabled";
|
||||
const DIFFERED_PAYMENT_AUTHORIZED_CAPTURE_STATUS = "differed_payment_authorized_capture_status";
|
||||
const DIFFERED_PAYMENT_TRIGGER_CAPTURE_STATUS = "differed_payment_trigger_capture_status";
|
||||
const DIFFERED_PAYMENT_CAPTURE_EXPIRED_STATUS = "differed_payment_capture_expired_status";
|
||||
const SEND_CONFIRMATION_MESSAGE_ONLY_IF_PAID = "send_confirmation_message_only_if_paid";
|
||||
|
||||
public static function getConfigKeys()
|
||||
{
|
||||
return [
|
||||
self::OFFER,
|
||||
self::PAYMENT_ENABLED,
|
||||
self::API_MODE,
|
||||
self::LIVE_API_KEY,
|
||||
self::TEST_API_KEY,
|
||||
self::PAYMENT_PAGE_TYPE,
|
||||
self::ONE_CLICK_PAYMENT_ENABLED,
|
||||
self::MULTI_PAYMENT_ENABLED,
|
||||
self::MULTI_PAYMENT_TIMES,
|
||||
self::MULTI_PAYMENT_MINIMUM,
|
||||
self::MULTI_PAYMENT_MAXIMUM,
|
||||
self::DIFFERED_PAYMENT_ENABLED,
|
||||
self::DIFFERED_PAYMENT_TRIGGER_CAPTURE_STATUS,
|
||||
self::DIFFERED_PAYMENT_AUTHORIZED_CAPTURE_STATUS,
|
||||
self::DIFFERED_PAYMENT_CAPTURE_EXPIRED_STATUS,
|
||||
self::SEND_CONFIRMATION_MESSAGE_ONLY_IF_PAID
|
||||
];
|
||||
}
|
||||
|
||||
public static function getApiKey()
|
||||
{
|
||||
if (PayPlugModule::getConfigValue(self::API_MODE, 'test') === 'live') {
|
||||
return PayPlugModule::getConfigValue(self::LIVE_API_KEY);
|
||||
}
|
||||
|
||||
return PayPlugModule::getConfigValue(self::TEST_API_KEY);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace PayPlugModule\Model;
|
||||
|
||||
use PayPlugModule\Model\Base\PayPlugModuleDeliveryType as BasePayPlugModuleDeliveryType;
|
||||
|
||||
/**
|
||||
* Skeleton subclass for representing a row from the 'pay_plug_module_delivery_type' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
*/
|
||||
class PayPlugModuleDeliveryType extends BasePayPlugModuleDeliveryType
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace PayPlugModule\Model;
|
||||
|
||||
use PayPlugModule\Model\Base\PayPlugModuleDeliveryTypeQuery as BasePayPlugModuleDeliveryTypeQuery;
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'pay_plug_module_delivery_type' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
*/
|
||||
class PayPlugModuleDeliveryTypeQuery extends BasePayPlugModuleDeliveryTypeQuery
|
||||
{
|
||||
|
||||
}
|
||||
137
local/modules/PayPlugModule/PayPlugModule.php
Executable file
137
local/modules/PayPlugModule/PayPlugModule.php
Executable file
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace PayPlugModule;
|
||||
|
||||
use PayPlugModule\EventListener\FormExtend\OrderFormListener;
|
||||
use PayPlugModule\Model\PayPlugConfigValue;
|
||||
use PayPlugModule\Service\PaymentService;
|
||||
use Propel\Runtime\Connection\ConnectionInterface;
|
||||
use Symfony\Component\Finder\Finder;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Thelia\Core\HttpFoundation\JsonResponse;
|
||||
use Thelia\Core\Template\TemplateDefinition;
|
||||
use Thelia\Install\Database;
|
||||
use Thelia\Model\Order;
|
||||
use Thelia\Module\AbstractPaymentModule;
|
||||
use Thelia\Tools\URL;
|
||||
|
||||
class PayPlugModule extends AbstractPaymentModule
|
||||
{
|
||||
/** @var string */
|
||||
const DOMAIN_NAME = 'payplugmodule';
|
||||
|
||||
|
||||
public function postActivation(ConnectionInterface $con = null)
|
||||
{
|
||||
if (!$this->getConfigValue('is_initialized', false)) {
|
||||
$database = new Database($con);
|
||||
$database->insertSql(null, [__DIR__ . "/Config/thelia.sql"]);
|
||||
}
|
||||
}
|
||||
|
||||
public function update($currentVersion, $newVersion, ConnectionInterface $con = null)
|
||||
{
|
||||
$finder = Finder::create()
|
||||
->name('*.sql')
|
||||
->depth(0)
|
||||
->sortByName()
|
||||
->in(__DIR__ . DS . 'Config' . DS . 'update');
|
||||
|
||||
$database = new Database($con);
|
||||
|
||||
/** @var \SplFileInfo $file */
|
||||
foreach ($finder as $file) {
|
||||
if (version_compare($currentVersion, $file->getBasename('.sql'), '<')) {
|
||||
$database->insertSql(null, [$file->getPathname()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function isValidPayment()
|
||||
{
|
||||
/** @var PaymentService $paymentService */
|
||||
$paymentService = $this->container->get('payplugmodule_payment_service');
|
||||
return $paymentService->isPayPlugAvailable();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function pay(Order $order)
|
||||
{
|
||||
try {
|
||||
/** @var PaymentService $paymentService */
|
||||
$paymentService = $this->container->get('payplugmodule_payment_service');
|
||||
|
||||
$slice = 1;
|
||||
|
||||
$isMultiPayment = $this->getRequest()->getSession()->get(OrderFormListener::PAY_PLUG_MULTI_PAYMENT_FIELD_NAME, 0);
|
||||
if ($isMultiPayment) {
|
||||
$orderTotalAmount = $order->getTotalAmount();
|
||||
|
||||
$minAmount = PayPlugModule::getConfigValue(PayPlugConfigValue::MULTI_PAYMENT_MINIMUM);
|
||||
$maxAmount = PayPlugModule::getConfigValue(PayPlugConfigValue::MULTI_PAYMENT_MAXIMUM);
|
||||
|
||||
if ($minAmount <= $orderTotalAmount && $maxAmount >= $orderTotalAmount) {
|
||||
$slice = PayPlugModule::getConfigValue(PayPlugConfigValue::MULTI_PAYMENT_TIMES);
|
||||
}
|
||||
}
|
||||
|
||||
$payment = $paymentService->sendOrderPayment(
|
||||
$order,
|
||||
PayPlugModule::getConfigValue(PayPlugConfigValue::DIFFERED_PAYMENT_ENABLED, false),
|
||||
PayPlugModule::getConfigValue(PayPlugConfigValue::ONE_CLICK_PAYMENT_ENABLED, false),
|
||||
$slice
|
||||
);
|
||||
|
||||
$forceRedirect = false;
|
||||
if (true === $payment['isPaid']) {
|
||||
$forceRedirect = true;
|
||||
$payment['url'] = URL::getInstance()->absoluteUrl('/order/placed/'.$order->getId());
|
||||
}
|
||||
|
||||
if ($this->getRequest()->isXmlHttpRequest()) {
|
||||
return new JsonResponse(
|
||||
[
|
||||
'paymentUrl' => $payment['url'],
|
||||
'forceRedirect' => $forceRedirect
|
||||
]
|
||||
);
|
||||
}
|
||||
} catch (\Exception $exception) {
|
||||
if ($this->getRequest()->isXmlHttpRequest()) {
|
||||
return new JsonResponse(['error' => $exception->getMessage()], 400);
|
||||
}
|
||||
return RedirectResponse::create(URL::getInstance()->absoluteUrl('error'));
|
||||
}
|
||||
|
||||
return new RedirectResponse($payment['url']);
|
||||
}
|
||||
|
||||
public function getHooks()
|
||||
{
|
||||
return [
|
||||
[
|
||||
"type" => TemplateDefinition::BACK_OFFICE,
|
||||
"code" => "payplugmodule.configuration.bottom",
|
||||
"title" => [
|
||||
"en_US" => "Bottom of PayPlug configuration page",
|
||||
"fr_FR" => "Bas de la page de configuration PayPlug",
|
||||
],
|
||||
"block" => false,
|
||||
"active" => true,
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
17
local/modules/PayPlugModule/Readme.md
Executable file
17
local/modules/PayPlugModule/Readme.md
Executable file
@@ -0,0 +1,17 @@
|
||||
# Pay Plug Module
|
||||
|
||||
Thelia module for the payment solution PayPlug https://www.payplug.com
|
||||
|
||||
## Installation
|
||||
|
||||
### Composer
|
||||
|
||||
Add it in your main thelia composer.json file
|
||||
|
||||
```
|
||||
composer require thelia/pay-plug-module:~1.0.0
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Go to module configuration page select the offer you have with PayPlug (starter, pro or premium) and you will see the options who corresponding to your offer.
|
||||
103
local/modules/PayPlugModule/Service/OrderStatusService.php
Executable file
103
local/modules/PayPlugModule/Service/OrderStatusService.php
Executable file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace PayPlugModule\Service;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Thelia\Core\Event\OrderStatus\OrderStatusCreateEvent;
|
||||
use Thelia\Core\Event\TheliaEvents;
|
||||
use Thelia\Model\OrderStatusQuery;
|
||||
|
||||
class OrderStatusService
|
||||
{
|
||||
const REFUND_PENDING_ORDER_STATUS_CODE = "refund_pending";
|
||||
|
||||
const AUTHORIZED_CAPTURE_ORDER_STATUS_CODE = "authorized_capture";
|
||||
const EXPIRED_CAPTURE_ORDER_STATUS_CODE = "expired_capture";
|
||||
|
||||
public function __construct(EventDispatcherInterface $dispatcher)
|
||||
{
|
||||
$this->dispatcher = $dispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* @var EventDispatcherInterface
|
||||
*/
|
||||
protected $dispatcher;
|
||||
|
||||
public function initAllStatuses()
|
||||
{
|
||||
$this->findOrCreateRefundPendingOrderStatus();
|
||||
$this->findOrCreateAuthorizedCaptureOrderStatus();
|
||||
$this->findOrCreateExpiredCaptureOrderStatus();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Thelia\Model\OrderStatus
|
||||
*/
|
||||
public function findOrCreateRefundPendingOrderStatus()
|
||||
{
|
||||
$refundPendingOrderStatus = OrderStatusQuery::create()
|
||||
->findOneByCode($this::REFUND_PENDING_ORDER_STATUS_CODE);
|
||||
|
||||
if (null !== $refundPendingOrderStatus) {
|
||||
return $refundPendingOrderStatus;
|
||||
}
|
||||
|
||||
$refundPendingOrderStatusEvent = (new OrderStatusCreateEvent())
|
||||
->setCode(self::REFUND_PENDING_ORDER_STATUS_CODE)
|
||||
->setColor("#A7A7A7")
|
||||
->setLocale('en_US')
|
||||
->setTitle('Refund pending');
|
||||
|
||||
$this->dispatcher->dispatch(TheliaEvents::ORDER_STATUS_CREATE, $refundPendingOrderStatusEvent);
|
||||
|
||||
return $refundPendingOrderStatusEvent->getOrderStatus();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Thelia\Model\OrderStatus
|
||||
*/
|
||||
public function findOrCreateAuthorizedCaptureOrderStatus()
|
||||
{
|
||||
$authorizedCaptureOrderStatus = OrderStatusQuery::create()
|
||||
->findOneByCode($this::AUTHORIZED_CAPTURE_ORDER_STATUS_CODE);
|
||||
|
||||
if (null !== $authorizedCaptureOrderStatus) {
|
||||
return $authorizedCaptureOrderStatus;
|
||||
}
|
||||
|
||||
$authorizedCaptureOrderStatus = (new OrderStatusCreateEvent())
|
||||
->setCode(self::AUTHORIZED_CAPTURE_ORDER_STATUS_CODE)
|
||||
->setColor("#71ED71")
|
||||
->setLocale('en_US')
|
||||
->setTitle('Authorized capture');
|
||||
|
||||
$this->dispatcher->dispatch(TheliaEvents::ORDER_STATUS_CREATE, $authorizedCaptureOrderStatus);
|
||||
|
||||
return $authorizedCaptureOrderStatus->getOrderStatus();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Thelia\Model\OrderStatus
|
||||
*/
|
||||
public function findOrCreateExpiredCaptureOrderStatus()
|
||||
{
|
||||
$expiredCaptureOrderStatus = OrderStatusQuery::create()
|
||||
->findOneByCode($this::EXPIRED_CAPTURE_ORDER_STATUS_CODE);
|
||||
|
||||
if (null !== $expiredCaptureOrderStatus) {
|
||||
return $expiredCaptureOrderStatus;
|
||||
}
|
||||
|
||||
$expiredCaptureOrderStatus = (new OrderStatusCreateEvent())
|
||||
->setCode(self::EXPIRED_CAPTURE_ORDER_STATUS_CODE)
|
||||
->setColor("#4B4B4B")
|
||||
->setLocale('en_US')
|
||||
->setTitle('Expired capture');
|
||||
|
||||
$this->dispatcher->dispatch(TheliaEvents::ORDER_STATUS_CREATE, $expiredCaptureOrderStatus);
|
||||
|
||||
return $expiredCaptureOrderStatus->getOrderStatus();
|
||||
}
|
||||
|
||||
}
|
||||
152
local/modules/PayPlugModule/Service/PaymentService.php
Executable file
152
local/modules/PayPlugModule/Service/PaymentService.php
Executable file
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
|
||||
namespace PayPlugModule\Service;
|
||||
|
||||
use Payplug\Notification;
|
||||
use Payplug\Payment;
|
||||
use Payplug\Payplug;
|
||||
use PayPlugModule\Event\PayPlugPaymentEvent;
|
||||
use PayPlugModule\Model\OrderPayPlugMultiPayment;
|
||||
use PayPlugModule\Model\PayPlugCardQuery;
|
||||
use PayPlugModule\Model\PayPlugConfigValue;
|
||||
use PayPlugModule\PayPlugModule;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Thelia\Core\HttpFoundation\Request;
|
||||
use Thelia\Model\Order;
|
||||
|
||||
class PaymentService
|
||||
{
|
||||
/**
|
||||
* @var EventDispatcherInterface
|
||||
*/
|
||||
protected $dispatcher;
|
||||
|
||||
public function __construct(EventDispatcherInterface $dispatcher)
|
||||
{
|
||||
$this->dispatcher = $dispatcher;
|
||||
self::initAuth();
|
||||
}
|
||||
|
||||
public function isPayPlugAvailable()
|
||||
{
|
||||
if (!PayPlugModule::getConfigValue(PayPlugConfigValue::PAYMENT_ENABLED, false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check API availability
|
||||
try {
|
||||
Payment::listPayments(1);
|
||||
} catch (\Exception $exception) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Order $order
|
||||
* @return array
|
||||
* @throws \Propel\Runtime\Exception\PropelException
|
||||
*/
|
||||
public function sendOrderPayment(
|
||||
Order $order,
|
||||
bool $capture = false,
|
||||
bool $allowSaveCard = false,
|
||||
int $paymentSlice = 1
|
||||
) {
|
||||
$paymentEvent = (new PayPlugPaymentEvent())
|
||||
->buildFromOrder($order)
|
||||
->setCapture($capture)
|
||||
->setAllowSaveCard($allowSaveCard);
|
||||
|
||||
if (null !== $card = PayPlugCardQuery::create()->findOneByCustomerId($order->getCustomerId())) {
|
||||
$paymentEvent->setPaymentMethod($card->getUuid())
|
||||
->setInitiator('PAYER')
|
||||
->setAllowSaveCard(false);
|
||||
}
|
||||
|
||||
$firstPayment = null;
|
||||
if ($paymentSlice > 1) {
|
||||
$totalAmount = $paymentEvent->getAmount();
|
||||
$firstAmount = round($totalAmount / $paymentSlice) + $totalAmount % $paymentSlice;
|
||||
$paymentEvent->setForceSaveCard(true)
|
||||
->setAllowSaveCard(false)
|
||||
->setPaymentMethod(null)
|
||||
->setAmount($firstAmount);
|
||||
$today = (new \DateTime())->setTime(0,0,0,0);
|
||||
|
||||
$firstPayment = (new OrderPayPlugMultiPayment())
|
||||
->setAmount($paymentEvent->getAmount())
|
||||
->setOrder($order)
|
||||
->setPlannedAt($today)
|
||||
->setPaymentId($paymentEvent->getPaymentId())
|
||||
->setIsFirstPayment(true);
|
||||
$firstPayment->save();
|
||||
|
||||
for ($paymentCount = 1; $paymentCount < $paymentSlice ; $paymentCount++) {
|
||||
$paymentDay = (clone $today)->add((new \DateInterval('P'.intval($paymentCount * 30).'D')));
|
||||
$multiPayment = (new OrderPayPlugMultiPayment())
|
||||
->setAmount(round($totalAmount / $paymentSlice))
|
||||
->setOrder($order)
|
||||
->setPlannedAt($paymentDay);
|
||||
$multiPayment->save();
|
||||
}
|
||||
}
|
||||
|
||||
$this->dispatcher->dispatch(PayPlugPaymentEvent::ORDER_PAYMENT_EVENT, $paymentEvent);
|
||||
|
||||
if (null !== $firstPayment) {
|
||||
$firstPayment->setPaymentId($paymentEvent->getPaymentId())
|
||||
->save();
|
||||
|
||||
}
|
||||
|
||||
$isPaid = $paymentEvent->isPaid();
|
||||
|
||||
// If one click payment consider it as isPaid (redirect to order/placed)
|
||||
if (!$isPaid && $paymentEvent->isCapture() && null !== $paymentEvent->getPaymentMethod()) {
|
||||
$isPaid = true;
|
||||
}
|
||||
|
||||
return [
|
||||
'id' => $paymentEvent->getPaymentId(),
|
||||
'url' => $paymentEvent->getPaymentUrl(),
|
||||
'isPaid' => $isPaid
|
||||
];
|
||||
}
|
||||
|
||||
public function doOrderCapture(Order $order)
|
||||
{
|
||||
$paymentEvent = (new PayPlugPaymentEvent())
|
||||
->buildFromOrder($order);
|
||||
|
||||
$this->dispatcher->dispatch(PayPlugPaymentEvent::ORDER_CAPTURE_EVENT, $paymentEvent);
|
||||
}
|
||||
|
||||
public function doOrderRefund(Order $order, int $amountRefund = null)
|
||||
{
|
||||
$paymentEvent = (new PayPlugPaymentEvent())
|
||||
->buildFromOrder($order);
|
||||
|
||||
if (null !== $amountRefund) {
|
||||
$paymentEvent->setAmount($amountRefund);
|
||||
}
|
||||
|
||||
$this->dispatcher->dispatch(PayPlugPaymentEvent::ORDER_REFUND_EVENT, $paymentEvent);
|
||||
}
|
||||
|
||||
public function getNotificationResource(Request $request)
|
||||
{
|
||||
return Notification::treat($request->getContent());
|
||||
}
|
||||
|
||||
public function initAuth()
|
||||
{
|
||||
return Payplug::init(
|
||||
[
|
||||
'secretKey' => PayPlugConfigValue::getApiKey(),
|
||||
'apiVersion' => '2019-08-06'
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
13
local/modules/PayPlugModule/composer.json
Executable file
13
local/modules/PayPlugModule/composer.json
Executable file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "thelia/pay-plug-module",
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"type": "thelia-module",
|
||||
"require": {
|
||||
"thelia/installer": "~1.1",
|
||||
"payplug/payplug-php": "^3.2",
|
||||
"giggsey/libphonenumber-for-php": "^8.12"
|
||||
},
|
||||
"extra": {
|
||||
"installer-name": "PayPlugModule"
|
||||
}
|
||||
}
|
||||
BIN
local/modules/PayPlugModule/images/payplug.png
Executable file
BIN
local/modules/PayPlugModule/images/payplug.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 9.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
@@ -0,0 +1,408 @@
|
||||
{extends file="admin-layout.tpl"}
|
||||
|
||||
{block name="after-bootstrap-css"}
|
||||
|
||||
{/block}
|
||||
|
||||
{block name="no-return-functions"}
|
||||
{$admin_current_location = 'module'}
|
||||
{/block}
|
||||
|
||||
{block name="page-title"}{intl l='PayPlug module configuration' d='payplugmodule.bo.default'}{/block}
|
||||
|
||||
{block name="check-resource"}admin.module{/block}
|
||||
{block name="check-access"}view{/block}
|
||||
{block name="check-module"}PayPlug{/block}
|
||||
|
||||
{block name="main-content"}
|
||||
<style>
|
||||
.block {
|
||||
padding: 20px;
|
||||
border-bottom: 2px solid #00AB7A;
|
||||
}
|
||||
.block h2 {
|
||||
color: #00AB7A;
|
||||
}
|
||||
.block .block {
|
||||
border: 2px solid rgba(0, 211, 152, 0.61);
|
||||
}
|
||||
</style>
|
||||
<div class="col-md-12">
|
||||
<div class="panel panel-default">
|
||||
{form name="payplugmodule_configuration_form"}
|
||||
<form action="{url path="/admin/module/payplugmodule/configuration"}" method="POST">
|
||||
{form_hidden_fields form=$form}
|
||||
|
||||
{if $form_error}
|
||||
<div class="alert alert-danger">{$form_error_message}</div>
|
||||
{/if}
|
||||
|
||||
{form_field form=$form field='success_url'}
|
||||
<input type="hidden" name="{$name}" value="{url path={navigate to="current"}}"/>
|
||||
{/form_field}
|
||||
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
<div class="block col-md-12">
|
||||
<img style="height: 34px;" src="{image file='PayPlugModule/assets/logo-payplug.png' source="PayPlugModule"}" alt="Payment configuration" class="img-responsive" />
|
||||
</div>
|
||||
<div class="block col-md-12">
|
||||
<div class="col-md-12">
|
||||
<h2>{intl l="PayPlug offer" d='payplugmodule.bo.default'}</h2>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
{form_field form=$form field="offer"}
|
||||
<div class="form-group {if $error}has-error{/if}">
|
||||
<label class="control-label">{$label}{if $required}<span class="required">*</span>{/if}</label>
|
||||
<br>
|
||||
{$inputOfferName = {$name}}
|
||||
{foreach from=$choices item=choice}
|
||||
<input id="{$name}_{$choice->value}" name="{$name}" type="radio" value="{$choice->value}" {if $data == $choice->value}checked{/if} />
|
||||
<label class="control-label" for="{$name}_{$choice->value}">{$choice->label}</label>
|
||||
{/foreach}
|
||||
{if ! empty($label_attr.help)}
|
||||
<span class="help-block">{$label_attr.help}</span>
|
||||
{/if}
|
||||
</div>
|
||||
{/form_field}
|
||||
</div>
|
||||
</div>
|
||||
<div class="block col-md-12">
|
||||
<div class="col-md-12">
|
||||
<h2>{intl l="PayPlug API configuration" d='payplugmodule.bo.default'}</h2>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
{form_field form=$form field="api_mode"}
|
||||
<div class="form-group {if $error}has-error{/if}">
|
||||
<label class="control-label" for="{$name}">
|
||||
|
||||
{$label}{if $required}<span class="required">*</span>{/if}
|
||||
<br>
|
||||
<select class="form-control" name="{$name}" id="{$name}">
|
||||
{foreach from=$choices item=choice}
|
||||
<option value="{$choice->value}" {if $data == $choice->value}selected{/if}>{$choice->label}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</label>
|
||||
|
||||
{if ! empty($label_attr.help)}
|
||||
<span class="help-block">{$label_attr.help}</span>
|
||||
{/if}
|
||||
</div>
|
||||
{/form_field}
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
{form_field form=$form field='live_api_key'}
|
||||
<label for="{$name}" class="control-label">{$label}</label>
|
||||
<input id="{$name}" class="form-control" type="text" name="{$name}" value="{$data}"/>
|
||||
{if ! empty($label_attr.help)}
|
||||
<span class="help-block">{$label_attr.help nofilter}</span>
|
||||
{/if}
|
||||
{/form_field}
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
{form_field form=$form field='test_api_key'}
|
||||
<label for="{$name}" class="control-label">{$label}</label>
|
||||
<input id="{$name}" class="form-control" type="text" name="{$name}" value="{$data}"/>
|
||||
{if ! empty($label_attr.help)}
|
||||
<span class="help-block">{$label_attr.help nofilter}</span>
|
||||
{/if}
|
||||
{/form_field}
|
||||
</div>
|
||||
</div>
|
||||
<div class="block col-md-12" id="basic_configuration">
|
||||
<div class="col-md-12">
|
||||
<h2>{intl l="PayPlug basic payment configuration" d='payplugmodule.bo.default'}</h2>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
{form_field form=$form field="payment_enabled"}
|
||||
<div class="form-group {if $error}has-error{/if}">
|
||||
<label class="control-label" for="{$name}">
|
||||
<input type="checkbox" name="{$name}" id="{$name}" {if $data}checked{/if}/>
|
||||
{$label}
|
||||
{if $required}<span class="required">*</span>{/if}
|
||||
</label>
|
||||
|
||||
{if ! empty($label_attr.help)}
|
||||
<span class="help-block">{$label_attr.help}</span>
|
||||
{/if}
|
||||
</div>
|
||||
{/form_field}
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
{form_field form=$form field="payment_page_type"}
|
||||
<div class="form-group {if $error}has-error{/if}">
|
||||
<label class="control-label" for="{$name}">
|
||||
{$label}{if $required}<span class="required">*</span>{/if}
|
||||
<br>
|
||||
<select class="form-control" name="{$name}" id="{$name}">
|
||||
{foreach from=$choices item=choice}
|
||||
<option value="{$choice->value}" {if $data == $choice->value}selected{/if}>{$choice->label}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</label>
|
||||
|
||||
{if ! empty($label_attr.help)}
|
||||
<span class="help-block">{$label_attr.help}</span>
|
||||
{/if}
|
||||
</div>
|
||||
{/form_field}
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
{render_form_field field="send_confirmation_message_only_if_paid"}
|
||||
</div>
|
||||
</div>
|
||||
<div class="block col-md-12" id="pro_configuration">
|
||||
<div class="col-md-12">
|
||||
<h2>{intl l="PayPlug pro offer configuration" d='payplugmodule.bo.default'}</h2>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
{form_field form=$form field="one_click_payment_enabled"}
|
||||
<div class="form-group {if $error}has-error{/if}">
|
||||
<label class="control-label" for="{$name}">
|
||||
<input type="checkbox" name="{$name}" id="{$name}" {if $data}checked{/if}/>
|
||||
{$label}
|
||||
|
||||
</label>
|
||||
|
||||
{if ! empty($label_attr.help)}
|
||||
<span class="help-block">{$label_attr.help}</span>
|
||||
{/if}
|
||||
</div>
|
||||
{/form_field}
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
{form_field form=$form field="multi_payment_enabled"}
|
||||
{$inputMultiPaymentName = $name}
|
||||
<div class="form-group {if $error}has-error{/if}">
|
||||
<label class="control-label" for="{$name}">
|
||||
<input type="checkbox" name="{$name}" id="{$name}" {if $data}checked{/if}/>
|
||||
{$label}
|
||||
</label>
|
||||
|
||||
{if ! empty($label_attr.help)}
|
||||
<span class="help-block">{$label_attr.help}</span>
|
||||
{/if}
|
||||
</div>
|
||||
{/form_field}
|
||||
</div>
|
||||
<div class="block col-md-12" id="multi_payment_fields">
|
||||
<div class="alert alert-warning">
|
||||
{intl l="Payments in several times are not guaranteed, a default may occur on future due dates." d='payplugmodule.bo.default'}
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
{form_field form=$form field='multi_payment_minimum'}
|
||||
<label for="auth_key" class="control-label">{$label}</label>
|
||||
<input id="auth_key" class="form-control" type="number" min="0" name="{$name}" value="{$data}"/>
|
||||
{/form_field}
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
{form_field form=$form field='multi_payment_maximum'}
|
||||
<label for="auth_key" class="control-label">{$label}</label>
|
||||
<input id="auth_key" class="form-control" type="number" min="0" name="{$name}" value="{$data}"/>
|
||||
{/form_field}
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
{form_field form=$form field="multi_payment_times"}
|
||||
<div class="form-group {if $error}has-error{/if}">
|
||||
<label class="control-label" for="{$name}">
|
||||
{$label}{if $required}<span class="required">*</span>{/if}
|
||||
<br>
|
||||
<select class="form-control" name="{$name}" id="{$name}">
|
||||
{foreach from=$choices item=choice}
|
||||
<option value="{$choice->value}" {if $data == $choice->value}selected{/if}>{$choice->label}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</label>
|
||||
{if ! empty($label_attr.help)}
|
||||
<span class="help-block">{$label_attr.help}</span>
|
||||
{/if}
|
||||
</div>
|
||||
{/form_field}
|
||||
</div>
|
||||
<div class="alert alert-info col-md-12">
|
||||
<p>
|
||||
{intl l="To trigger the payments on planned date please add a daily cron on this Thelia command " d='payplugmodule.bo.default'}
|
||||
<strong>php Thelia payplug:treat:multi_payment</strong>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="block col-md-12" id="premium_configuration">
|
||||
<div class="col-md-12">
|
||||
<h2>{intl l="PayPlug premium offer configuration" d='payplugmodule.bo.default'}</h2>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
{form_field form=$form field="differed_payment_enabled"}
|
||||
{$inputDifferedPaymentName = $name}
|
||||
<div class="form-group {if $error}has-error{/if}">
|
||||
<label class="control-label" for="{$name}">
|
||||
<input type="checkbox" name="{$name}" id="{$name}" {if $data}checked{/if}/>
|
||||
{$label}
|
||||
</label>
|
||||
|
||||
{if ! empty($label_attr.help)}
|
||||
<span class="help-block">{$label_attr.help}</span>
|
||||
{/if}
|
||||
</div>
|
||||
{/form_field}
|
||||
</div>
|
||||
<div class="block col-md-12" id="differed_payment_fields">
|
||||
<div class="col-md-4">
|
||||
{form_field form=$form field="differed_payment_authorized_capture_status"}
|
||||
<div class="form-group {if $error}has-error{/if}">
|
||||
<label class="control-label" for="{$name}">
|
||||
{$label}{if $required}<span class="required">*</span>{/if}
|
||||
<br>
|
||||
<select class="form-control" name="{$name}" id="{$name}">
|
||||
{loop type="order-status" name="order-status-select" backend_context="1"}
|
||||
<option value="{$ID}" {if $data == $ID}selected{/if}>{$TITLE}</option>
|
||||
{/loop}
|
||||
</select>
|
||||
</label>
|
||||
{if ! empty($label_attr.help)}
|
||||
<span class="help-block">{$label_attr.help}</span>
|
||||
{/if}
|
||||
</div>
|
||||
{/form_field}
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
{form_field form=$form field="differed_payment_trigger_capture_status"}
|
||||
<div class="form-group {if $error}has-error{/if}">
|
||||
<label class="control-label" for="{$name}">
|
||||
{$label}{if $required}<span class="required">*</span>{/if}
|
||||
<br>
|
||||
<select class="form-control" name="{$name}" id="{$name}">
|
||||
{loop type="order-status" name="order-status-select" backend_context="1"}
|
||||
<option value="{$ID}" {if $data == $ID}selected{/if}>{$TITLE}</option>
|
||||
{/loop}
|
||||
</select>
|
||||
</label>
|
||||
{if ! empty($label_attr.help)}
|
||||
<span class="help-block">{$label_attr.help}</span>
|
||||
{/if}
|
||||
</div>
|
||||
{/form_field}
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
{form_field form=$form field="differed_payment_capture_expired_status"}
|
||||
<div class="form-group {if $error}has-error{/if}">
|
||||
<label class="control-label" for="{$name}">
|
||||
{$label}{if $required}<span class="required">*</span>{/if}
|
||||
<br>
|
||||
<select class="form-control" name="{$name}" id="{$name}">
|
||||
{loop type="order-status" name="order-status-select" backend_context="1"}
|
||||
<option value="{$ID}" {if $data == $ID}selected{/if}>{$TITLE}</option>
|
||||
{/loop}
|
||||
</select>
|
||||
</label>
|
||||
{if ! empty($label_attr.help)}
|
||||
<span class="help-block">{$label_attr.help}</span>
|
||||
{/if}
|
||||
</div>
|
||||
{/form_field}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="block col-md-12" id="delivery_type_configuration">
|
||||
<div class="col-md-12">
|
||||
<h2>{intl l="PayPlug delivery type configuration" d='payplugmodule.bo.default'}</h2>
|
||||
<p>{intl l="Please select a Pay Plug delivery type correspondance for each delivery modules" d='payplugmodule.bo.default'}</p>
|
||||
</div>
|
||||
<div class="block col-md-12" id="differed_payment_fields">
|
||||
{foreach from=$deliveryModuleFormFields item="deliveryModuleFormField"}
|
||||
<div class="col-md-3">
|
||||
{form_field form=$form field=$deliveryModuleFormField['name']}
|
||||
<label class="control-label" for="{$name}">
|
||||
{$label}{if $required}<span class="required">*</span>{/if}
|
||||
<select class="form-control" name="{$name}" id="{$name}">
|
||||
{foreach from=$choices item=choice}
|
||||
<option value="{$choice->value}" {if $data == $choice->value}selected{/if}>{$choice->label}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</label>
|
||||
{if ! empty($label_attr.help)}
|
||||
<span class="help-block">{$label_attr.help}</span>
|
||||
{/if}
|
||||
{/form_field}
|
||||
</div>
|
||||
{/foreach}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<input type="submit" class="btn btn-success form-control" value="{intl l="Save" d='payplugmodule.bo.default'}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{/form}
|
||||
</div>
|
||||
{hook name="payplugmodule.configuration.bottom"}
|
||||
</div>
|
||||
{/block}
|
||||
|
||||
{block name="javascript-initialization"}
|
||||
|
||||
{/block}
|
||||
|
||||
{block name="javascript-last-call"}
|
||||
<script type="text/javascript">
|
||||
var inputOfferName = "{$inputOfferName}";
|
||||
var inputMultiPaymentName = "{$inputMultiPaymentName}";
|
||||
var inputDifferedPaymentName = "{$inputDifferedPaymentName}";
|
||||
{literal}
|
||||
jQuery(function($) {
|
||||
displayConfigurationBlock();
|
||||
displayMultiPaymentBlock();
|
||||
displayDifferedPaymentBlock();
|
||||
|
||||
$('input[name="'+inputOfferName+'"]').click(function(){
|
||||
displayConfigurationBlock();
|
||||
});
|
||||
|
||||
$('input[name="'+inputMultiPaymentName+'"]').click(function(){
|
||||
displayMultiPaymentBlock();
|
||||
});
|
||||
|
||||
$('input[name="'+inputDifferedPaymentName+'"]').click(function(){
|
||||
displayDifferedPaymentBlock();
|
||||
});
|
||||
|
||||
function displayConfigurationBlock() {
|
||||
var inputOfferChecked = $('input[name="'+inputOfferName+'"]:checked');
|
||||
var proConfigurationBlock = $("#pro_configuration");
|
||||
var premiumConfigurationBlock = $("#premium_configuration");
|
||||
|
||||
proConfigurationBlock.hide();
|
||||
premiumConfigurationBlock.hide();
|
||||
|
||||
if (inputOfferChecked.val() === 'pro') {
|
||||
proConfigurationBlock.show();
|
||||
} else if (inputOfferChecked.val() === 'premium') {
|
||||
proConfigurationBlock.show();
|
||||
premiumConfigurationBlock.show();
|
||||
}
|
||||
}
|
||||
|
||||
function displayMultiPaymentBlock() {
|
||||
var multiPaymentBlock = $("#multi_payment_fields");
|
||||
multiPaymentBlock.hide();
|
||||
if( $('input[name="'+inputMultiPaymentName+'"]').is(':checked') ){
|
||||
multiPaymentBlock.show();
|
||||
}
|
||||
}
|
||||
|
||||
function displayDifferedPaymentBlock() {
|
||||
var differedPaymentBlock = $("#differed_payment_fields");
|
||||
differedPaymentBlock.hide();
|
||||
if( $('input[name="'+inputDifferedPaymentName+'"]').is(':checked') ){
|
||||
differedPaymentBlock.show();
|
||||
}
|
||||
}
|
||||
});
|
||||
{/literal}
|
||||
</script>
|
||||
{/block}
|
||||
@@ -0,0 +1,168 @@
|
||||
<div id="orderPayPlug" class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4>{intl l="PayPlug order data" d='payplugmodule.bo.default'}</h4>
|
||||
</div>
|
||||
<div>
|
||||
{form name="payplugmodule_order_action_form_refund"}
|
||||
{if $form_error}
|
||||
<div class="alert alert-danger">{$form_error_message}</div>
|
||||
{/if}
|
||||
{/form}
|
||||
{form name="payplugmodule_order_action_form"}
|
||||
{if $form_error}
|
||||
<div class="alert alert-danger">{$form_error_message}</div>
|
||||
{/if}
|
||||
{/form}
|
||||
</div>
|
||||
<table class="table table-condensed table-left-aligned">
|
||||
<tbody>
|
||||
{if $amountRefunded || $isPaid}
|
||||
<tr>
|
||||
<th>{intl l="Refund" d='payplugmodule.bo.default'}</th>
|
||||
<td></td>
|
||||
<td>
|
||||
{loop type="order" name="refund-order-amount" id=$order_id customer="*" with_prev_next_info="true" backend_context="1"}
|
||||
{$orderTotalAmount = $TOTAL_TAXED_AMOUNT}
|
||||
{$orderTotalAmountWithoutShipping = $TOTAL_TAXED_AMOUNT-$POSTAGE}
|
||||
{/loop}
|
||||
{if $amountRefunded}
|
||||
<div class="alert alert-info">{format_money number=$amountRefunded/100} {intl l=" refunded" d='payplugmodule.bo.default'}</div>
|
||||
{/if}
|
||||
{if $orderTotalAmount > ($amountRefunded/100) }
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<label for="quick_select_amount_refund">{intl l="What do you want refund" d='payplugmodule.bo.default'}</label>
|
||||
<select class="form-control" name="" id="quick_select_amount_refund" multiple="true">
|
||||
<option value="{$orderTotalAmount}" selected>{intl l="The entire order" d='payplugmodule.bo.default'} ---- {format_money number=$orderTotalAmount currency_id=$CURRENCY}</option>
|
||||
<option value="{$orderTotalAmountWithoutShipping}">{intl l="Order without shipping" d='payplugmodule.bo.default'} ----{format_money number=$orderTotalAmountWithoutShipping currency_id=$CURRENCY}</option>
|
||||
<optgroup label="{intl l="Products" d='payplugmodule.bo.default'}" >
|
||||
{loop type="order_product" name="order-products" order=$order_id}
|
||||
<option value="{$REAL_TOTAL_TAXED_PRICE}">[{$PRODUCT_SALE_ELEMENTS_REF}] {$TITLE} ---- {format_money number=$REAL_TOTAL_TAXED_PRICE currency_id=$CURRENCY} </option>
|
||||
{/loop}
|
||||
</optgroup>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label for="input_amount_refund">{intl l="Adjust amount" d='payplugmodule.bo.default'}</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon glyphicon glyphicon-chevron-right"></span>
|
||||
<input id="input_amount_refund" class="form-control" type="number" max="{$orderTotalAmount - $amountRefunded/100}" value="{$orderTotalAmount - $amountRefunded/100}">
|
||||
<span class="input-group-addon">{currency attr="symbol"}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label for=""></label>
|
||||
<a class="btn btn-block btn-success image-delete" href="#order_refund_dialog" data-toggle="modal">
|
||||
{intl l="Refund" d='payplugmodule.bo.default'}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</td>
|
||||
</tr>
|
||||
{/if}
|
||||
{if $needCapture}
|
||||
<tr>
|
||||
<th>{intl l="Differed payment" d='payplugmodule.bo.default'}</th>
|
||||
{if null == $capturedAt}
|
||||
<td>{intl l="Payment capture will expire on " d='payplugmodule.bo.default'}{format_date date=$captureExpireAt}</td>
|
||||
<td>
|
||||
<a class="btn btn-block btn-success image-delete" href="#order_capture_dialog" data-toggle="modal">
|
||||
{intl l="Force the capture for this order" d='payplugmodule.bo.default'}
|
||||
</a>
|
||||
</td>
|
||||
{else}
|
||||
<td></td>
|
||||
<td>
|
||||
{intl l="Payment was captured at " d='payplugmodule.bo.default'}{format_date date=$capturedAt}
|
||||
</td>
|
||||
{/if}
|
||||
</tr>
|
||||
{/if}
|
||||
{if count($multiPayments) > 0}
|
||||
<tr>
|
||||
<th>{intl l="Multi payment" d='payplugmodule.bo.default'}</th>
|
||||
<td colspan="2">
|
||||
<table class="table table-condensed table-left-aligned">
|
||||
<tr>
|
||||
<th>{intl l="Payment n° " d='payplugmodule.bo.default'}</th>
|
||||
<th>{intl l="Amount" d='payplugmodule.bo.default'}</th>
|
||||
<th>{intl l="Planned at" d='payplugmodule.bo.default'}</th>
|
||||
<th>{intl l="Paid at" d='payplugmodule.bo.default'}</th>
|
||||
<th>{intl l="Refunded at" d='payplugmodule.bo.default'}</th>
|
||||
</tr>
|
||||
{$paymentCount = 1}
|
||||
{foreach from=$multiPayments item=multiPayment}
|
||||
<tr>
|
||||
<td>{$paymentCount}</td>
|
||||
<td>{format_money number=$multiPayment['amount']/100}</td>
|
||||
<td>{if $multiPayment['plannedAt']}{format_date date=$multiPayment['plannedAt']}{else}{intl l="Canceled" d='payplugmodule.bo.default'}{/if}</td>
|
||||
<td>{if $multiPayment['paidAt']}{format_date date=$multiPayment['paidAt']}{/if}</td>
|
||||
<td>{if $multiPayment['refundedAt']}{format_date date=$multiPayment['refundedAt']}{/if}</td>
|
||||
</tr>
|
||||
{$paymentCount = $paymentCount + 1}
|
||||
{/foreach}
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
{/if}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{capture "refund_dialog"}
|
||||
{form name="payplugmodule_order_action_form_refund"}
|
||||
{form_hidden_fields form=$form}
|
||||
{if $form_error}
|
||||
<div class="alert alert-danger">{$form_error_message}</div>
|
||||
{/if}
|
||||
{form_field form=$form field='success_url'}
|
||||
<input type="hidden" name="{$name}" value="{url path={navigate to="current"}}"/>
|
||||
{/form_field}
|
||||
{form_field form=$form field="order_id"}
|
||||
<input type="hidden" name="{$name}" value="{$order_id}">
|
||||
{/form_field}
|
||||
{form_field form=$form field="refund_amount"}
|
||||
<input id="refund_amount" type="hidden" name="{$name}" value="{$orderTotalAmount}">
|
||||
{/form_field}
|
||||
{/form}
|
||||
{/capture}
|
||||
|
||||
{include
|
||||
file = "includes/generic-confirm-dialog.html"
|
||||
|
||||
dialog_id = "order_refund_dialog"
|
||||
dialog_title = {intl l="Refund order" d="payplugmodule.bo.default"}
|
||||
dialog_message = {intl l="Do you really want to refund this order ?" d="payplugmodule.bo.default"}
|
||||
|
||||
form_method = "POST"
|
||||
form_action = {url path='/admin/payplugmodule/order/refund'}
|
||||
form_content = {$smarty.capture.refund_dialog nofilter}
|
||||
}
|
||||
|
||||
{capture "capture_dialog"}
|
||||
{form name="payplugmodule_order_action_form"}
|
||||
{form_hidden_fields form=$form}
|
||||
{if $form_error}
|
||||
<div class="alert alert-danger">{$form_error_message}</div>
|
||||
{/if}
|
||||
{form_field form=$form field='success_url'}
|
||||
<input type="hidden" name="{$name}" value="{url path={navigate to="current"}}"/>
|
||||
{/form_field}
|
||||
{form_field form=$form field="order_id"}
|
||||
<input type="hidden" name="{$name}" value="{$order_id}">
|
||||
{/form_field}
|
||||
{/form}
|
||||
{/capture}
|
||||
|
||||
{include
|
||||
file = "includes/generic-confirm-dialog.html"
|
||||
|
||||
dialog_id = "order_capture_dialog"
|
||||
dialog_title = {intl l="Capture order" d="payplugmodule.bo.default"}
|
||||
dialog_message = {intl l="Do you really want to capture this order ?" d="payplugmodule.bo.default"}
|
||||
|
||||
form_method = "POST"
|
||||
form_action = {url path='/admin/payplugmodule/order/capture'}
|
||||
form_content = {$smarty.capture.capture_dialog nofilter}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
var inputAmountRefund = $('#input_amount_refund');
|
||||
var maxAmountRefund = parseFloat(inputAmountRefund.attr('max'));
|
||||
|
||||
$("#quick_select_amount_refund").change(function (e) {
|
||||
var amountToRefund = 0;
|
||||
var selected = $(e.target).val();
|
||||
|
||||
if (null !== selected) {
|
||||
amountToRefund = selected.reduce(function (a, c) {
|
||||
return parseFloat(a) + parseFloat(c);
|
||||
});
|
||||
}
|
||||
|
||||
amountToRefund = amountToRefund > maxAmountRefund ? maxAmountRefund : amountToRefund;
|
||||
inputAmountRefund.val(amountToRefund).trigger('change');
|
||||
});
|
||||
|
||||
inputAmountRefund.change(function (e) {
|
||||
var amountToRefund = $(e.target).val() > maxAmountRefund ? maxAmountRefund : $(e.target).val();
|
||||
$("#refund_amount").val(amountToRefund);
|
||||
});
|
||||
@@ -0,0 +1,8 @@
|
||||
{form_field form=$form field='pay_plug_multi_payment'}
|
||||
<p>
|
||||
<input id="{$name}" type="checkbox" name="{$name}" value="1">
|
||||
<label for="{$name}">{intl l='Pay in %n times without fees.' n={$nTimes} d='payplugmodule.fo.default'}</label>
|
||||
<br>
|
||||
{intl l='You will be asked to save your payment card data.' n={url path='/payplug/card/delete'} d='payplugmodule.fo.default'}
|
||||
</p>
|
||||
{/form_field}
|
||||
@@ -0,0 +1,6 @@
|
||||
<p><strong>{intl l='One click payment is available !' d='payplugmodule.fo.default'}</strong></p>
|
||||
<p>
|
||||
{intl l='A payment card ending by %last4 has been previously saved at your request. Payment for your order will be made immediately after clicking the "Next Step" button.' last4=$last4 d='payplugmodule.fo.default'}
|
||||
<br>
|
||||
{intl l='To clear your payment card details, <a href="%url">please click here</a>' url={url path='/payplug/card/delete'} d='payplugmodule.fo.default'}.
|
||||
</p>
|
||||
@@ -0,0 +1,34 @@
|
||||
<script type="text/javascript" src="https://api.payplug.com/js/1/form.latest.js"></script>
|
||||
|
||||
<script>
|
||||
var payPlugModuleId = '{$payPlugModuleId}';
|
||||
|
||||
{literal}
|
||||
var form = document.getElementById('form-cart-payment');
|
||||
form.addEventListener('submit', function (event) {
|
||||
var payPlugRadio = $('#payment_'+payPlugModuleId);
|
||||
if(payPlugRadio.is(':checked')) {
|
||||
event.preventDefault();
|
||||
|
||||
var form = $(this);
|
||||
var url = form.attr('action');
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: url,
|
||||
data: form.serialize(),
|
||||
}).success(function (data) {
|
||||
if (true === data.forceRedirect) {
|
||||
window.location.replace(data.paymentUrl);
|
||||
} else {
|
||||
Payplug.showPayment(data.paymentUrl);
|
||||
}
|
||||
}).fail(function (data) {
|
||||
var payPlugLi = payPlugRadio.parent().parent();
|
||||
console.log(payPlugLi);
|
||||
console.log(data.responseJSON.error);
|
||||
payPlugLi.prepend('<div class="alert alert-danger">Error : '+data.responseJSON.error+'</div>');
|
||||
})
|
||||
}
|
||||
});
|
||||
{/literal}
|
||||
</script>
|
||||
Reference in New Issue
Block a user