PrestaShop Payment Gateway Integration Setup
We integrate payment gateways into PrestaShop stores, connecting Stripe, PayPal, LiqPay, Fondy, CloudPayments, and other providers through the PrestaShop 8.x Payment API. Our team builds the full payment module: initialization controller, webhook callback processing, order status management, and admin configuration interface. Delivery takes two to four working days. We have built PrestaShop payment modules for 15+ e-commerce stores. Our modules comply with provider API requirements and pass security review on first submission.
A payment gateway integration done right handles edge cases that manual testing rarely catches: concurrent order validations, webhook signature verification, idempotent retries, and correct status transitions on successful payment, failure, and refund. Our modules are built for production from day one, not assembled from tutorial code.
What's Included in Our PrestaShop Payment Integration
We deliver the complete payment gateway integration turnkey. The scope covers:
- Custom payment module with all required PrestaShop hooks registered
- Payment initialization controller with cart validation and redirect to provider
- Webhook callback controller with HMAC signature verification
- Order status mapping: Pending, Paid, Failed, Refunded
- Refund processing via
actionOrderStatusUpdatehook - Admin configuration page with API key fields, test mode toggle, and order status selection
- Error handling and logging for debugging production issues
- End-to-end testing covering successful payment, failed payment, and manual refund flows
PrestaShop 8.x Payment Module Structure
modules/mypay/
├── controllers/front/
│ ├── payment.php # Payment initialization
│ └── callback.php # Webhook from provider
├── views/templates/front/
│ └── payment_infos.tpl
├── mypay.php # Main module class
└── logo.png
Main Module Class
class MyPay extends PaymentModule
{
public function __construct()
{
$this->name = 'mypay';
$this->tab = 'payments_gateways';
$this->version = '1.0.0';
$this->ps_versions_compliancy = ['min' => '8.0.0', 'max' => _PS_VERSION_];
parent::__construct();
}
public function install(): bool
{
return parent::install()
&& $this->registerHook('paymentOptions')
&& $this->registerHook('paymentReturn')
&& $this->registerHook('actionOrderStatusUpdate');
}
public function hookPaymentOptions(array $params): array
{
$option = new \PrestaShop\PrestaShop\Core\Payment\PaymentOption();
$option->setCallToActionText($this->trans('Card Payment', [], 'Modules.Mypay.Shop'))
->setAction($this->context->link->getModuleLink('mypay', 'payment', [], true));
return [$option];
}
}
Payment Initialization and Callback
// Payment controller: validate order, create payment session, redirect
public function postProcess(): void
{
$cart = $this->context->cart;
$total = (int) round($cart->getOrderTotal(true) * 100);
$currency = new Currency($cart->id_currency);
$this->module->validateOrder(
$cart->id,
Configuration::get('MYPAY_OS_PENDING'),
$cart->getOrderTotal(true),
$this->module->displayName,
null, [], (int) $currency->id, false,
(new Customer($cart->id_customer))->secure_key
);
$payment = (new MyPayApiClient(
Configuration::get('MYPAY_API_KEY'),
Configuration::get('MYPAY_SECRET_KEY')
))->createPayment([
'amount' => $total,
'currency' => $currency->iso_code,
'order_id' => Order::getIdByCartId($cart->id),
'callback_url' => $this->context->link->getModuleLink('mypay', 'callback', [], true),
]);
Tools::redirect($payment['payment_url']);
}
// Callback controller: verify signature, update order status
public function postProcess(): void
{
$raw = file_get_contents('php://input');
$data = json_decode($raw, true);
if (!hash_equals(
hash_hmac('sha256', $raw, Configuration::get('MYPAY_SECRET_KEY')),
$_SERVER['HTTP_X_SIGNATURE'] ?? ''
)) {
http_response_code(403); exit;
}
$statusMap = [
'succeeded' => Configuration::get('MYPAY_OS_PAID'),
'failed' => Configuration::get('PS_OS_ERROR'),
'cancelled' => Configuration::get('PS_OS_CANCELED'),
];
$order = Order::getByReference($data['payment_id'])->getFirst();
if ($order && isset($statusMap[$data['status']])) {
$history = new OrderHistory();
$history->id_order = $order->id;
$history->changeIdOrderState((int) $statusMap[$data['status']], $order);
$history->addWithemail(true);
}
http_response_code(200); echo 'OK'; exit;
}
Why HMAC Signature Verification Matters
Webhook endpoints without signature verification accept requests from anyone, not just the payment provider. An attacker who knows your callback URL could send a fake succeeded status and mark an unpaid order as paid. All major payment providers support HMAC or RSA signature verification, and we implement it in every integration.
PrestaShop 8.x does not provide automatic HMAC validation. We implement it explicitly in the callback controller using hash_equals to prevent timing attacks.
Refund Processing
PrestaShop does not automatically notify the payment module when an admin issues a refund from the order management panel. We subscribe to the actionOrderStatusUpdate hook and trigger a refund API call when the order transitions to the refund status:
public function hookActionOrderStatusUpdate(array $params): void
{
if ($params['newOrderStatus']->id !== (int) Configuration::get('PS_OS_REFUND')) {
return;
}
(new MyPayApiClient(
Configuration::get('MYPAY_API_KEY'),
Configuration::get('MYPAY_SECRET_KEY')
))->refund($params['order']->reference, (int) round($params['order']->total_paid * 100));
}
| Scope | Timeline |
|---|---|
| Single gateway integration (Stripe or PayPal) | 2–3 working days |
| Multiple gateways with shared callback logic | 3–4 working days |
| Custom gateway without official API docs | 4–6 working days |
Contact us to discuss your payment integration requirements. We will review your PrestaShop version, gateway choice, and order flow, then provide a fixed-price quote.
Pre-Launch Testing Checklist
Before going live, every payment integration we build passes a structured test protocol in the sandbox environment.
We test successful payment and verify the order reaches Paid status. We test failed payment and verify the order stays in Pending or moves to Failed. We test a cancelled payment from the provider's page and verify the order does not change incorrectly. We simulate a webhook retry and verify the order does not get double-updated. We test the refund flow from the PrestaShop admin and verify the refund API call fires correctly.
Only after all scenarios pass in sandbox mode do we switch to live credentials and run a real test transaction before handover.
How We Deliver
We review your PrestaShop version and gateway API docs. We set up the module scaffold. We build the payment controller. We build the callback controller with signature verification. We add the admin configuration page. We test in sandbox mode. We deploy to production. We run a live test transaction. We hand over the module with documentation.







