💳 Modulo de pago — estructura y desarrollo
Actualizado: 2024-12-01
Los modulos de pago en PrestaShop extienden la clase PaymentModule en lugar de Module. Esto les da acceso a validateOrder(), el metodo central que crea el pedido, procesa el inventario y envia los emails de confirmacion.
#Extender PaymentModule
mygateway.php — estructura del modulo de pago
php
<?php
if (!defined('_PS_VERSION_')) { exit; }
class MyGateway extends PaymentModule
{
public function __construct()
{
$this->name = 'mygateway';
$this->tab = 'payments_gateways';
$this->version = '1.0.0';
$this->author = 'gmartos.es';
$this->need_instance = 1;
$this->bootstrap = true;
$this->currencies = true; // Soporte de monedas
$this->currencies_mode = 'checkbox'; // o 'radio'
parent::__construct();
$this->displayName = $this->trans('Mi Pasarela de Pago', [], 'Modules.Mygateway.Admin');
$this->description = $this->trans('Descripcion de la pasarela.', [], 'Modules.Mygateway.Admin');
$this->confirmUninstall = $this->trans('¿Seguro que deseas desinstalar?', [], 'Modules.Mygateway.Admin');
}
public function install(): bool
{
return parent::install()
&& $this->registerHook('paymentOptions')
&& $this->registerHook('paymentReturn');
}
}
#Hook displayPayment — mostrar opcion de pago
hookPaymentOptions — mostrar la opcion de pago en el checkout (PS 1.7+)
php
<?php
use PrestaShop\PrestaShop\Core\Payment\PaymentOption;
/**
* PS 1.7+: usar hookPaymentOptions (devuelve array de PaymentOption)
*/
public function hookPaymentOptions(array $params): array
{
if (!$this->active) {
return [];
}
// Verificar que la moneda activa es compatible
if (!$this->checkCurrency($params['cart'])) {
return [];
}
$option = new PaymentOption();
$option->setModuleName($this->name)
->setCallToActionText($this->trans('Pagar con Mi Pasarela', [], 'Modules.Mygateway.Shop'))
->setAction($this->context->link->getModuleLink($this->name, 'payment', [], true))
->setAdditionalInformation(
$this->context->smarty->fetch('module:mygateway/views/templates/front/payment_info.tpl')
);
return [$option];
}
private function checkCurrency(Cart $cart): bool
{
$currency = new Currency($cart->id_currency);
$currencies = $this->getCurrency($cart->id_currency);
return $currencies && in_array($currency->iso_code, ['EUR', 'USD']);
}
#Controlador de pago (execPayment)
controllers/front/payment.php — iniciar el pago
php
<?php
if (!defined('_PS_VERSION_')) { exit; }
class MyGatewayPaymentModuleFrontController extends ModuleFrontController
{
public function initContent(): void
{
parent::initContent();
$cart = $this->context->cart;
// Verificaciones de seguridad
if (!$cart->id || !$cart->id_customer) {
Tools::redirect('index.php?controller=order');
}
$total = $cart->getOrderTotal(true);
$currency = new Currency($cart->id_currency);
$customer = new Customer($cart->id_customer);
// Crear sesion de pago con la pasarela externa
$paymentSession = $this->createPaymentSession($total, $currency->iso_code);
if (!$paymentSession) {
$this->errors[] = $this->trans('Error al conectar con la pasarela.', [], 'Modules.Mygateway.Shop');
$this->redirectWithNotifications('index.php?controller=order');
return;
}
// Guardar datos en session para la validacion posterior
$this->context->cookie->__set('mygateway_session_id', $paymentSession['id']);
$this->context->cookie->__set('mygateway_cart_id', (string) $cart->id);
$this->context->cookie->write();
// Redirigir a la URL de pago de la pasarela
Tools::redirect($paymentSession['payment_url']);
}
}
#Validar el pedido con validateOrder()
controllers/front/confirmation.php — confirmar pago y crear pedido
php
<?php
if (!defined('_PS_VERSION_')) { exit; }
class MyGatewayConfirmationModuleFrontController extends ModuleFrontController
{
public function initContent(): void
{
parent::initContent();
// Verificar el pago con la pasarela
$sessionId = $this->context->cookie->mygateway_session_id;
$cartId = (int) $this->context->cookie->mygateway_cart_id;
$paymentResult = $this->module->verifyPayment($sessionId);
if (!$paymentResult || $paymentResult['status'] !== 'paid') {
$this->errors[] = 'Pago no confirmado.';
Tools::redirect('index.php?controller=order&step=1');
return;
}
$cart = new Cart($cartId);
$customer = new Customer($cart->id_customer);
$currency = new Currency($cart->id_currency);
$total = (float) $cart->getOrderTotal(true);
// CREAR EL PEDIDO — el metodo mas importante de PaymentModule
$this->module->validateOrder(
$cartId, // id_cart
Configuration::get('PS_OS_PAYMENT'), // id_order_state (pagado)
$total, // amount_paid
$this->module->displayName, // payment_method
null, // message (optional)
['transaction_id' => $paymentResult['id']], // extra_vars
$currency->id, // currency_special
false, // dont_touch_amount
$customer->secure_key // secure_key
);
Tools::redirect('index.php?controller=order-confirmation'
. '&id_cart=' . $cartId
. '&id_module=' . $this->module->id
. '&id_order=' . $this->module->currentOrder
. '&key=' . $customer->secure_key
);
}
}
#Flujo completo del checkout
| Paso | URL/Controller | Descripcion |
|---|---|---|
| 1. Checkout | /proceso-compra | Cliente elige el metodo de pago (hookPaymentOptions) |
| 2. Inicio pago | /module/mygateway/payment | PaymentFrontController crea sesion en la pasarela |
| 3. Redireccion | URL pasarela externa | Cliente introduce sus datos de pago |
| 4. Callback | /module/mygateway/confirmation | Pasarela redirige de vuelta con resultado |
| 5. Validacion | validateOrder() | Se crea el pedido en PrestaShop |
| 6. Confirmacion | /confirmacion-pedido | Pagina final de exito al cliente |
Descargar en Markdown
Pensado para pegar en ChatGPT, Claude u otra IA. Incluye solo el contenido de esta pagina.