{"id":841317,"date":"2026-09-09T12:21:13","date_gmt":"2026-09-09T12:21:13","guid":{"rendered":"https:\/\/www.knowband.com\/blog\/?p=841317\/"},"modified":"2026-09-30T09:34:14","modified_gmt":"2026-09-30T09:34:14","slug":"prestashop-payment-gateway-integration","status":"publish","type":"post","link":"https:\/\/www.knowband.com\/blog\/prestashop-blog\/prestashop-payment-gateway-integration\/","title":{"rendered":"Integrating a Custom Payment Gateway in PrestaShop: Technical Requirements, API Flow, and Real-World OPC Challenges"},"content":{"rendered":"<p><span style=\"font-weight: 400;\">Integrating a payment gateway into PrestaShop can look straightforward on paper.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The gateway provides API documentation, sandbox credentials, authentication keys, callback URLs, and a few endpoints. The PrestaShop module then sends the payment request, receives the response, creates the order, and redirects the customer to the confirmation page.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">In a real PrestaShop store, however, the payment gateway is rarely working alone.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The moment a store uses a <a href=\"https:\/\/www.knowband.com\/prestashop-one-page-supercheckout\">One Page Checkout<\/a> (OPC) module such as SuperCheckout, multiple payment modules, custom payment flows, iframes, JavaScript-based payment methods, and additional checkout customizations can all interact with each other.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">This is where many payment integrations become difficult.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">During payment gateway compatibility work, we have encountered cases where a payment method worked perfectly with PrestaShop&#8217;s default checkout but behaved differently inside OPC. For example, a payment provider could display correctly on the standard checkout while options such as BLIK, bank selection, or BNPL disappeared inside SuperCheckout.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The important lesson was that integrating a payment gateway is not only about making the API call work. It is about making the entire payment lifecycle work correctly inside the PrestaShop checkout.<\/span><\/p>\n<h2><strong>1.0 What Does a Custom Payment Gateway Actually Need?<\/strong><\/h2>\n<p><a href=\"https:\/\/www.knowband.com\/blog\/wp-content\/uploads\/2026\/09\/ChatGPT-Image-Sep-9-2026-05_49_41-PM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-841318 size-full\" src=\"https:\/\/www.knowband.com\/blog\/wp-content\/uploads\/2026\/09\/ChatGPT-Image-Sep-9-2026-05_49_41-PM.png\" alt=\"What Does a Custom Payment Gateway Actually Need?\" width=\"1254\" height=\"1254\" srcset=\"https:\/\/www.knowband.com\/blog\/wp-content\/uploads\/2026\/09\/ChatGPT-Image-Sep-9-2026-05_49_41-PM.png 1254w, https:\/\/www.knowband.com\/blog\/wp-content\/uploads\/2026\/09\/ChatGPT-Image-Sep-9-2026-05_49_41-PM-300x300.png 300w, https:\/\/www.knowband.com\/blog\/wp-content\/uploads\/2026\/09\/ChatGPT-Image-Sep-9-2026-05_49_41-PM-1024x1024.png 1024w, https:\/\/www.knowband.com\/blog\/wp-content\/uploads\/2026\/09\/ChatGPT-Image-Sep-9-2026-05_49_41-PM-150x150.png 150w, https:\/\/www.knowband.com\/blog\/wp-content\/uploads\/2026\/09\/ChatGPT-Image-Sep-9-2026-05_49_41-PM-768x768.png 768w, https:\/\/www.knowband.com\/blog\/wp-content\/uploads\/2026\/09\/ChatGPT-Image-Sep-9-2026-05_49_41-PM-60x60.png 60w\" sizes=\"auto, (max-width: 1254px) 100vw, 1254px\" \/><\/a><\/p>\n<p><span style=\"font-weight: 400;\">At a high level, a PrestaShop payment integration needs to handle five things:<\/span><\/p>\n<ol>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Display the payment method at checkout.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Send the customer or payment data to the gateway.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Receive and validate the gateway response.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Create or update the PrestaShop order correctly.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Return the customer to the appropriate confirmation or error page.<\/span><\/li>\n<\/ol>\n<p dir=\"ltr\">A typical payment module extends rather than the base class.<\/p>\n<p dir=\"ltr\">The payment module normally works with hooks such as:<\/p>\n<p dir=\"ltr\">The hook is responsible for making the payment method available to the checkout.<\/p>\n<p dir=\"ltr\">The hook handles what the customer sees after returning from the payment process.<\/p>\n<p><span style=\"font-weight: 400;\">For example:<\/span><\/p>\n<pre>public function hookPaymentOptions($params)\r\n{\r\nif (!$this-&gt;active || !$this-&gt;checkCurrency($params['cart'])) {\r\nreturn [];\r\n}\r\n\r\n$paymentOption = new PaymentOption();\r\n\r\n$paymentOption\r\n-&gt;setCallToActionText($this-&gt;l('Pay by Card'))\r\n-&gt;setAction(\r\n$this-&gt;context-&gt;link-&gt;getModuleLink(\r\n$this-&gt;name,\r\n'redirect',\r\n[],\r\ntrue\r\n)\r\n);\r\n\r\nreturn [$paymentOption];\r\n}<\/pre>\n<p><span style=\"font-weight: 400;\">The important point is that this hook should not simply assume that the payment method can always be displayed.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Currency, country, carrier, customer state, cart amount, module configuration, and gateway availability can all affect whether the payment method should be shown.<\/span><\/p>\n<h2><strong>2.0 The Part That Changes Everything: OPC<\/strong><\/h2>\n<p><span style=\"font-weight: 400;\">The default PrestaShop checkout and a Prestashop One Page Checkout module do not necessarily process payment methods in exactly the same way.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">This was one of the most important lessons from working with multiple payment modules.<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><\/p>\n<p><span style=\"font-weight: 400;\">With the default checkout, a payment module generally controls its own payment option rendering and payment flow.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">With an OPC, the checkout module becomes another layer between the payment module and the customer. That means the following can interact:<\/span><\/p>\n<pre><b>Customer<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>OPC \/ SuperCheckout<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Payment options<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Payment module<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Gateway API<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Gateway response<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Payment module<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>OPC \/ PrestaShop<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Order confirmation<\/b><\/pre>\n<p><span style=\"font-weight: 400;\">A payment module can therefore be completely correct from an API perspective and still fail to behave correctly inside an OPC.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">This is why payment compatibility testing should always include both:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">PrestaShop default checkout<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">The actual OPC used by the store<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">Testing only the default checkout can give a false sense that the integration is complete.<\/span><\/p>\n<h2><strong>3.0 A Real-World Example: PayU Options Missing Inside OPC<\/strong><\/h2>\n<p><span style=\"font-weight: 400;\">One of the practical issues we encountered involved PayU payment options.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">On the standard PrestaShop checkout, PayU was able to display its available payment methods correctly. However, inside SuperCheckout, some payment options were missing.<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><\/p>\n<p><span style=\"font-weight: 400;\">For example, depending on the configuration and cart:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">BLIK was not consistently visible.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">The bank-selection list did not expand correctly.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">Some BNPL\/payment rows were missing.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">In some cases, BLIK appeared and then disappeared.<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">At first glance, this looked like a PayU API problem. It wasn&#8217;t.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The important diagnostic step was comparing the payment flow between the default checkout and SuperCheckout.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">When the same payment module works on the default checkout but fails inside OPC, the investigation should move beyond the gateway API.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">We need to check how the OPC builds the payment methods and what information it passes to the payment modules.<\/span><\/p>\n<h2><strong>4.0 Payment Amount Can Affect Payment Method Visibility<\/strong><\/h2>\n<p><span style=\"font-weight: 400;\">One particularly important part of this investigation was the cart amount. Payment gateways frequently have minimum and maximum transaction limits. For example:<\/span><\/p>\n<pre><b>Payment Method<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Check cart amount<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Minimum amount? Maximum amount?<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Eligible \/ Not eligible<\/b><\/pre>\n<p><span style=\"font-weight: 400;\">During the PayU compatibility investigation, we traced the payment-method filtering logic to the cart amount being passed through the payment-method checks.<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The relevant flow involved PrestaShop&#8217;s cart calculation and payment-method filtering, including logic around:<\/span><\/p>\n<pre>Cart::BOTH<\/pre>\n<p><span style=\"font-weight: 400;\">and:<\/span><\/p>\n<pre><b>PayMethodsCache::checkMinMax<\/b><\/pre>\n<p><span style=\"font-weight: 400;\">This matters because a payment option can disappear from checkout without the API itself returning an error.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The gateway may simply be considered ineligible for the amount received by the payment module. That gives us an important debugging rule:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">If a payment option disappears from an OPC, don&#8217;t immediately assume that the payment API is broken. First verify the cart amount, currency, minimum\/maximum limits, and the values reaching the payment-method eligibility checks.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">This becomes even more important when discounts, shipping costs, taxes, vouchers, or custom checkout calculations are involved.<\/span><\/p>\n<h2><strong>5.0 Why Payment Methods Can Work in Default Checkout but Fail in SuperCheckout<\/strong><\/h2>\n<p><span style=\"font-weight: 400;\">A useful way to investigate these problems is to compare the two checkout environments.<\/span><\/p>\n<h3><strong>5.1 Default PrestaShop checkout<\/strong><\/h3>\n<pre><b>Cart<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>PaymentOptionsFinder<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>paymentOptions hooks<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Payment modules<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Payment options<\/b><\/pre>\n<h3><strong>5.2 OPC checkout<\/strong><\/h3>\n<pre><b>Cart<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>SuperCheckout<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Payment methods<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Payment modules<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Additional OPC processing<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Rendered payment UI<\/b><\/pre>\n<p><span style=\"font-weight: 400;\">The second flow has additional moving parts.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Therefore, when debugging a payment issue, we don&#8217;t only check: &#8220;Does the payment module work?&#8221;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">We check: <\/span><span style=\"font-weight: 400;\">&#8220;Does the payment module work when its output is consumed and rendered by this particular checkout implementation?&#8221;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">That distinction saved a considerable amount of debugging time.<\/span><\/p>\n<h2><strong>6.0 PaymentOption Is Only One Part of the Integration<\/strong><span style=\"font-weight: 400;\"><br \/>\n<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">From PrestaShop 1.7 onward, payment modules generally use outputting payment HTML through the older payment hook approach.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">A payment option can contain information such as:<\/span><\/p>\n<pre><b>$paymentOption<\/b>\r\n<b>-&gt;setCallToActionText(...)<\/b>\r\n<b>-&gt;setAction(...)<\/b>\r\n<b>-&gt;setInputs(...)<\/b>\r\n<b>-&gt;setAdditionalInformation(...)<\/b><\/pre>\n<p><span style=\"font-weight: 400;\">objects instead of directly<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Different gateways require different combinations.<\/span><\/p>\n<h3><strong>6.1 Redirect-based gateway<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">The customer clicks the payment method and is redirected to the gateway.<\/span><\/p>\n<pre><b>Checkout<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>PaymentOption<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Module controller<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Gateway<\/b><\/pre>\n<h3><strong>6.2 Embedded payment form<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">The payment fields are displayed directly in the checkout.<\/span><\/p>\n<pre><b>Checkout<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>PaymentOption<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Card\/payment form<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Gateway API<\/b><\/pre>\n<h3><strong>6.3 Iframe-based payment<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">The gateway&#8217;s interface is embedded into the checkout.<\/span><\/p>\n<pre><b>Checkout<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>PaymentOption<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Iframe<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Gateway<\/b><\/pre>\n<p><span style=\"font-weight: 400;\">The last two approaches require additional attention because JavaScript, DOM manipulation, iframe loading, and OPC refreshes can affect the payment interface.<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><\/p>\n<h2><strong>7.0 JavaScript Becomes Critical with OPC<\/strong><\/h2>\n<p><span style=\"font-weight: 400;\">This is one area that generic payment-integration guides often overlook.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">An OPC can dynamically refresh portions of the checkout when the customer changes:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">delivery address<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">country<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">carrier<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">payment method<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">billing information<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">shipping method<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">When that happens, payment-related HTML can be replaced.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">A JavaScript event that worked during the initial page load may therefore stop working after an AJAX refresh.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">For example:<\/span><\/p>\n<pre><b>Initial checkout load<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Payment JS initialized<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Customer changes payment\/shipping information<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>OPC refreshes payment section<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Original DOM replaced<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Payment JS no longer attached<\/b><\/pre>\n<p><span style=\"font-weight: 400;\">This can produce confusing symptoms.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The payment method may appear initially, but clicking it does nothing. An iframe may disappear.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">A bank list may stop expanding.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">A payment option may appear and disappear after another checkout field changes.<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Therefore, compatibility work often requires changes not only in PHP but also in the payment module&#8217;s JavaScript.<\/span><\/p>\n<h2><strong>8.0 A Real Example: SimplyLease + SuperCheckout<\/strong><\/h2>\n<p><span style=\"font-weight: 400;\">Another example involved SimplyLease integration with SuperCheckout. The problem was not limited to the gateway API.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Some SimplyLease information and calculator elements were part of the checkout\/payment presentation and needed to work correctly inside the SuperCheckout flow.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The compatibility changes involved both module templates and SuperCheckout-side JavaScript integration. The files involved included:<\/span><\/p>\n<pre><b>modules\/simplylease\/views\/templates\/hook\/payment_info.tpl modules\/simplylease\/views\/templates\/hook\/product_calculator.tpl<\/b>\r\n\r\n<b>modules\/supercheckout\/controllers\/front\/SupercheckoutCore.php modules\/supercheckout\/views\/js\/front\/supercheckout.js\r\n<\/b><b>modules\/supercheckout\/views\/js\/front\/simplylease_supercheckout.js<\/b><\/pre>\n<p><span style=\"font-weight: 400;\">This is a good example of why payment compatibility sometimes requires changes outside the payment gateway module itself.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The payment provider may expose the correct data, but the checkout still has to:<\/span><\/p>\n<ol>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Render it.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Preserve it during checkout refreshes.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Initialize the required JavaScript.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Keep the payment information synchronized with the current cart.<\/span><\/li>\n<\/ol>\n<h2><strong>9.0 Another Common Problem: Payment Method Not Appearing<\/strong><\/h2>\n<p><span style=\"font-weight: 400;\">We also encountered cases where a payment method such as Comfino did not appear in SuperCheckout even though the payment module itself was installed and configured.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">This type of issue should be investigated systematically.<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Check:<\/span><\/p>\n<h3><strong>9.1 Is the module active?<\/strong><\/h3>\n<pre><b>$this-&gt;active<\/b><\/pre>\n<h3><strong>9.2 Is the currency supported?<\/strong><\/h3>\n<pre><b>$this-&gt;checkCurrency($params['cart'])<\/b><\/pre>\n<h3><strong>9.3 Is the country supported?<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">Some gateways restrict payment methods based on the customer&#8217;s country.<\/span><\/p>\n<h3><strong>9.4 Is the cart total within the gateway limits?<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">Minimum and maximum transaction values can prevent a method from being displayed.<\/span><\/p>\n<h3><strong>9.5 Is the carrier supported?<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">Some payment modules restrict payment methods by carrier.<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><\/p>\n<h3><strong>9.6 Is OPC filtering the method?<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">The payment module can return valid methods that are collected, filtered, or rendered.<\/span><span style=\"font-weight: 400;\"> But the OPC can still modify how payment<\/span><\/p>\n<h3><strong>9.7 Is JavaScript hiding or replacing the element?<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">A payment method can technically be returned by PHP but still not be visible in the final checkout.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">This is why browser developer tools are as important as PHP logs when debugging payment integrations.<\/span><\/p>\n<h2><strong>10.0 Hooks We Actually Need to Pay Attention To<\/strong><\/h2>\n<p><span style=\"font-weight: 400;\">A custom payment integration should not be treated as a single-hook implementation.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The exact hooks depend on the gateway and checkout architecture, but some are especially important.<\/span><\/p>\n<h3>10.1 paymentOptions<\/h3>\n<p><span style=\"font-weight: 400;\">This is the primary hook for exposing the payment method to the checkout.<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><\/p>\n<p><span style=\"font-weight: 400;\">It is responsible for returning<\/span> paymentOptions <span style=\"font-weight: 400;\">objects.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Typical checks include:<\/span><\/p>\n<pre><b>if (!$this-&gt;active) { return [];<\/b>\r\n<b>}<\/b>\r\n<b>if (!$this-&gt;checkCurrency($params['cart'])) { return [];<\/b>\r\n<b>}<\/b><\/pre>\n<p><span style=\"font-weight: 400;\">Additional gateway-specific restrictions can then be applied.<\/span><\/p>\n<h3>10.2 paymentReturns<\/h3>\n<p><span style=\"font-weight: 400;\">This is used after the customer has completed or returned from the payment flow. It can display:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">order reference<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">payment status<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">additional payment instructions<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">gateway-specific information<\/span><\/li>\n<\/ul>\n<h3>10.3 actionPresentPaymentOptions<\/h3>\n<p><span style=\"font-weight: 400;\">This hook becomes particularly interesting when multiple payment modules and an OPC are involved.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">It operates on the assembled payment options and can be useful when the checkout needs to inspect or modify the complete payment-option collection.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">This is different from implementing a single gateway&#8217;s paymentoptions<\/span> <span style=\"font-weight: 400;\">hook.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The distinction is important:<\/span><\/p>\n<pre><b>aymentOptions<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Each payment module contributes its option<\/b>\r\n<b>actionPresentPaymentOptions<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>The assembled payment options can be processed<\/b><\/pre>\n<p><span style=\"font-weight: 400;\">When debugging OPC compatibility, understanding where payment options are collected versus where they are finally presented can make the difference between finding the issue quickly and spending hours inside the gateway module.<\/span><\/p>\n<h2><strong>11.0 Order Creation: Never Trust the Browser<\/strong><\/h2>\n<p><span style=\"font-weight: 400;\">Once payment reaches the gateway, the next critical step is order creation. The most important PrestaShop method here is:<\/span><\/p>\n<pre>validateOrder()<\/pre>\n<p><span style=\"font-weight: 400;\">A simplified example is:<\/span><\/p>\n<pre><b>$this-&gt;module-&gt;validateOrder(<\/b>\r\n<b>$cart-&gt;id, Configuration::get('PS_OS_PAYMENT'),<\/b>\r\n<b>$amountPaid,<\/b>\r\n<b>$paymentMethod,<\/b>\r\n<b>$message, [],<\/b>\r\n<b>null, false,<\/b>\r\n<b>$customer-&gt;secure_key<\/b>\r\n<b>);<\/b><\/pre>\n<p><span style=\"font-weight: 400;\">There are three values that deserve particular attention:<\/span><\/p>\n<h3><strong>11.1 Cart ID<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">The cart must belong to the expected customer\/session and must be valid.<\/span><\/p>\n<h3><strong>11.2 Payment amount<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">Do not blindly use:<\/span><\/p>\n<pre><b>$cart-&gt;getOrderTotal()<\/b><\/pre>\n<p><span style=\"font-weight: 400;\">as proof that the gateway received that amount.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The amount should be validated against the gateway&#8217;s response.<\/span><\/p>\n<h3><strong>11.3 Secure key<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">The customer <\/span><span style=\"font-weight: 400;\">must be correctly associated with the cart\/order flow.<\/span><\/p>\n<h2><strong>12.0 Webhooks Must Be Idempotent<\/strong><\/h2>\n<p><span style=\"font-weight: 400;\">A payment gateway can send the same webhook more than once. For example:<\/span><\/p>\n<pre><b>Gateway<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Webhook<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Your server<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>200 response<\/b><\/pre>\n<p><span style=\"font-weight: 400;\">If the response is lost:<\/span><\/p>\n<pre><b>Gateway<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Webhook<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Your server<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Response lost<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Gateway retries<\/b><\/pre>\n<p><span style=\"font-weight: 400;\">If the integration creates an order every time it receives a webhook, duplicate orders become possible. Therefore, the callback should check whether the cart already has an order before creating another one. Conceptually:<\/span><\/p>\n<pre><b>if ($cart-&gt;OrderExists()) {<\/b>\r\n<b>\/\/ Already processed<\/b>\r\n<b>\/\/ Return successful response<\/b>\r\n<b>}<\/b><\/pre>\n<p><span style=\"font-weight: 400;\">The webhook handler should be designed to safely process repeated notifications.<\/span><\/p>\n<h2><strong>13.0 Synchronous vs Asynchronous Payment<\/strong><\/h2>\n<p><span style=\"font-weight: 400;\">Not every gateway confirms payment immediately.<\/span><\/p>\n<h3><strong>13.1 Synchronous<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">The gateway immediately confirms the transaction.<\/span><\/p>\n<pre><b>Customer<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Gateway<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Payment approved<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>validateOrder()<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>PS_OS_PAYMENT<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Confirmation<\/b><\/pre>\n<h3><strong>13.2 Asynchronous<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">The customer may return before the final payment confirmation arrives.<\/span><\/p>\n<pre><b>Customer<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Gateway<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Return to store<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Pending order<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Webhook<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Verify payment<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Change order state<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Payment accepted<\/b><\/pre>\n<p><span style=\"font-weight: 400;\">For asynchronous gateways, using a dedicated pending order state is often safer than immediately marking the order as paid.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Once the webhook confirms the payment:<\/span><\/p>\n<pre><b>$history = new OrderHistory();<\/b>\r\n<b>$history-&gt;id_order = (int) $order-&gt;id;<\/b>\r\n<b>$history-&gt;changeIdOrderState( Configuration::get('PS_OS_PAYMENT'),<\/b>\r\n<b>$order<\/b>\r\n<b>);<\/b>\r\n<b>$history-&gt;addWithemail(true);<\/b><\/pre>\n<p><span style=\"font-weight: 400;\">This ensures that the order-state transition goes through PrestaShop&#8217;s order-history mechanism instead of simply changing the database value.<\/span><\/p>\n<h2><strong>14.0 One of the Most Useful Debugging Techniques: Compare the Checkout Flows<\/strong><\/h2>\n<p><span style=\"font-weight: 400;\">When a payment method works in the default checkout but not in OPC, we recommend comparing the complete flow.<\/span><\/p>\n<h3><strong>Step 1: Check PHP<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">Is hookPaymentOptions() <\/span><span style=\"font-weight: 400;\">executed?<\/span><\/p>\n<h3><strong>Step 2: Inspect the returned options<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">Does the payment module actually return a<\/span> paymentOption<span style=\"font-weight: 400;\">?<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><\/p>\n<h3><strong>Step 3: Check the cart<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">Compare:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">total<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">currency<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">customer<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">country<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">carrier<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">discounts<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">taxes<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">shipping<\/span><\/li>\n<\/ul>\n<h3><strong>Step 4: Check the browser<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">Look for:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">JavaScript errors<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">missing DOM elements<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">AJAX requests<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">failed requests<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">iframe errors<\/span><\/li>\n<\/ul>\n<h3><strong>Step 5: Check the OPC<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">Determine whether SuperCheckout is:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">filtering the payment option<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">replacing its HTML<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">refreshing the payment section<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">changing the cart before the payment module runs<\/span><\/li>\n<\/ul>\n<h3><strong>Step 6: Check the gateway<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">Only after the local checkout flow is confirmed should the investigation move deeper into:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">API authentication<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">request payload<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">signature<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">response<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">webhook<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">gateway logs<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">This layered approach is much faster than starting with the gateway API every time.<\/span><\/p>\n<h2><strong>15.0 Common Payment Integration Problems We Have Seen<\/strong><\/h2>\n<p><span style=\"font-weight: 400;\">Real-world compatibility work usually exposes problems that aren&#8217;t obvious from the gateway documentation.<\/span><\/p>\n<h3><strong>15.1 Payment option disappears<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">Possible causes:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">unsupported currency<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">country restriction<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">cart amount outside gateway limits<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">carrier restriction<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">OPC filtering<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">payment module configuration<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">JavaScript hiding the method<\/span><\/li>\n<\/ul>\n<h3><strong>15.2 BLIK or another payment option appears and disappears<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">Possible causes:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">checkout AJAX refresh<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">payment-option re-rendering<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">JavaScript initialization<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">cart total changing<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">gateway eligibility being recalculated<\/span><\/li>\n<\/ul>\n<h3><strong>15.3 Bank list does not expand<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">Often investigate:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">JavaScript errors<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">dynamically replaced DOM elements<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">event handlers attached before OPC refresh<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">payment provider&#8217;s JavaScript initialization<\/span><\/li>\n<\/ul>\n<h3><strong>15.4 Iframe disappears<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">Investigate:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">checkout refresh<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">iframe initialization<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">DOM replacement<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">JavaScript execution after AJAX updates<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><\/li>\n<\/ul>\n<h3><strong>15.5 Payment succeeds, but order remains pending<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">Check:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">webhook URL<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">webhook delivery<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">signature verification<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">cart\/order lookup<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">order-state transition<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">callback authentication<\/span><\/li>\n<\/ul>\n<h3><strong>15.6 Payment method works in default checkout but not OPC<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">This is a strong indication that the problem may be in the interaction between the payment module and the OPC rather than the gateway API itself.<\/span><\/p>\n<h2><strong>16.0 Security Requirements for a Payment Module<\/strong><\/h2>\n<p><span style=\"font-weight: 400;\">Payment modules handle sensitive operations, so security cannot be treated as an optional improvement. At minimum:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Validate callback signatures.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Validate the cart\/customer relationship.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Use HTTPS.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Validate TLS certificates.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Never trust payment status supplied only by the browser.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Never store raw card information unless the architecture and compliance requirements explicitly support it.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Do not log sensitive payment information.<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\">\n<pre><span style=\"font-weight: 400;\">Avoid serialize() and unserialize () <\/span>\/ for untrusted external data.<\/pre>\n<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Validate and cast incoming values.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Protect custom AJAX and callback endpoints.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Use secure tokens where appropriate.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Make webhook processing idempotent.<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">A payment success page is not proof of payment.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The gateway&#8217;s verified server-side response is what should determine whether the order is considered paid.<\/span><\/p>\n<h2><strong>17.0 What Changes When Supporting Multiple Payment Modules?<\/strong><\/h2>\n<p><span style=\"font-weight: 400;\">Another lesson from OPC compatibility work is that adding a second or third payment module can expose problems that were not visible when only one payment method existed.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">For example:<\/span><\/p>\n<pre><b>PayPal <\/b><b>PayU<\/b>\r\n<b>Comfino<\/b>\r\n<b>SimplyLease<\/b>\r\n<b>Bank transfer<\/b><\/pre>\n<p><span style=\"font-weight: 400;\">may all contribute payment options to the same checkout. The checkout therefore has to deal with different:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">HTML structures<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">JavaScript<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">iframe requirements<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">redirects<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">API flows<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">eligibility rules<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">minimum\/maximum amounts<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">asynchronous callbacks<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">A change made for one payment method can accidentally affect another. This is why payment compatibility fixes should be narrowly scoped.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">For example, instead of changing the entire payment-option processing logic globally, identify the specific payment method and apply the compatibility handling only where required.<\/span><\/p>\n<h2><strong>18.0 Testing Should Include Real Cart Scenarios<\/strong><\/h2>\n<p><span style=\"font-weight: 400;\">Testing a payment gateway with a simple \u20ac10 product is not enough. A proper test matrix should include:<\/span><\/p>\n<table class=\"table table-hover\">\n<tbody>\n<tr>\n<td><strong>Scenario<\/strong><\/td>\n<td><strong>What to verify<\/strong><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">Single product<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Payment option appears<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">Multiple products<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Correct amount reaches gateway<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">Discount<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Final payable amount is correct<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">Shipping charge<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Gateway receives correct total<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">Tax<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Gateway amount matches order<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">Minimum gateway amount<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Method appears\/disappears correctly<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">Maximum gateway amount<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Method appears\/disappears correctly<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">Unsupported currency<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Method is hidden<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">Unsupported country<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Method is hidden<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">Default checkout<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Payment works<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">OPC<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Payment works<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">Mobile checkout<\/span><\/td>\n<td><span style=\"font-weight: 400;\">UI works<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">Failed payment<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Correct order\/payment state<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">Successful payment<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Order is created correctly<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">Webhook retry<\/span><\/td>\n<td><span style=\"font-weight: 400;\">No duplicate order<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">Customer abandonment<\/span><\/td>\n<td><span style=\"font-weight: 400;\">No incorrectly paid order<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;\">Gateway timeout<\/span><\/td>\n<td><span style=\"font-weight: 400;\">Correct pending\/error handling<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><span style=\"font-weight: 400;\">For OPC integrations, also test checkout refreshes. Change the:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">address<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">carrier<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">country<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">payment method<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">quantity<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">discount<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">and verify that the payment options remain correct after every refresh.<\/span><\/p>\n<h2><strong>19.0 A Practical Development Approach<\/strong><\/h2>\n<p><span style=\"font-weight: 400;\">Based on the issues that commonly appear in real integrations, a safer development order is:<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><\/p>\n<h3><strong>19.1 Make the gateway work with default PrestaShop checkout<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">First establish that:<\/span><\/p>\n<pre><b>PaymentOption<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Gateway request<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Gateway response<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>validateOrder()<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Confirmation<\/b><\/pre>\n<p><span style=\"font-weight: 400;\">works correctly.<\/span><\/p>\n<h3><strong>19.2 Add callback\/webhook processing<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">Do not leave asynchronous confirmation until the end.<\/span><\/p>\n<h3><strong>19.3 Add proper order-state handling<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">Test:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">success<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">failure<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">pending<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">timeout<\/span><\/li>\n<\/ul>\n<h3><strong>19.4 Test with realistic carts<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">Use discounts, shipping, taxes, different currencies, and different totals.<\/span><\/p>\n<h3><strong>19.5 Integrate with OPC<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">Only after the basic gateway flow is stable should you investigate SuperCheckout compatibility.<\/span><\/p>\n<h3><strong>19.6 Test JavaScript and dynamic refreshes<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">This is particularly important for embedded payment forms, iframes, BLIK\/bank-selection interfaces, and other interactive payment components.<\/span><\/p>\n<h3><strong>19.7 Test every payment method together<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">A checkout that supports five payment methods needs to be tested as a system, not five isolated modules.<\/span><\/p>\n<h2><strong>20.0 Should You Build a Custom Gateway or Use an Existing Module?<\/strong><\/h2>\n<p><span style=\"font-weight: 400;\">Not every gateway justifies a custom integration. A custom module makes sense when:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">the gateway is regional or niche<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">there is no maintained PrestaShop module<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">the gateway requires custom business logic<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">you need a specific subscription or settlement workflow<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">you need functionality that existing modules cannot provide<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">But building a payment integration also means accepting the maintenance responsibility. PrestaShop changes.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">PHP changes. Gateway APIs change.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Security requirements change. Checkout modules change.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">And eventually the payment provider changes something that breaks an otherwise stable integration.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">For mainstream gateways, an established and maintained module can therefore be significantly cheaper than maintaining custom payment code for several years.<\/span><\/p>\n<h2><strong>21.0 The Bigger Lesson From PrestaShop Payment Integration<\/strong><\/h2>\n<p><span style=\"font-weight: 400;\">The biggest lesson from working with payment gateways is that the API is often not the hardest part. Sending:<\/span><\/p>\n<pre><b>API request <\/b><span style=\"font-weight: 400;\">\u2192 <\/span><b>API response<\/b><\/pre>\n<p><span style=\"font-weight: 400;\">is usually straightforward.<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The difficult part is everything around it:<\/span><\/p>\n<pre><span style=\"font-weight: 400;\">\u250c\u2500\u2500 <\/span><b>Currency rules<\/b>\r\n<span style=\"font-weight: 400;\">\u251c\u2500\u2500 <\/span><b>Country rules<\/b>\r\n<span style=\"font-weight: 400;\">\u251c\u2500\u2500 <\/span><b>Cart amount<\/b>\r\n<span style=\"font-weight: 400;\">\u251c\u2500\u2500 <\/span><b>Carrier restrictions<\/b>\r\n<span style=\"font-weight: 400;\">\u251c\u2500\u2500 <\/span><b>OPC<\/b>\r\n<span style=\"font-weight: 400;\">\u251c\u2500\u2500 <\/span><b>JavaScript<\/b>\r\n<span style=\"font-weight: 400;\">\u251c\u2500\u2500 <\/span><b>Iframes<\/b>\r\n<span style=\"font-weight: 400;\">\u251c\u2500\u2500 <\/span><b>AJAX refreshes<\/b>\r\n<span style=\"font-weight: 400;\">\u251c\u2500\u2500 <\/span><b>Webhooks<\/b>\r\n<span style=\"font-weight: 400;\">\u251c\u2500\u2500 <\/span><b>Order states<\/b>\r\n<span style=\"font-weight: 400;\">\u2514\u2500\u2500 <\/span><b>Duplicate notifications<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Customer <\/b><span style=\"font-weight: 400;\">\u2192 <\/span><b>Checkout <\/b><span style=\"font-weight: 400;\">\u2192 <\/span><b>Payment Module <\/b><span style=\"font-weight: 400;\">\u2192 <\/span><b>Gateway<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Order creation<\/b>\r\n<span style=\"font-weight: 400;\">\u2193<\/span>\r\n<b>Order confirmation<\/b><\/pre>\n<p><span style=\"font-weight: 400;\">A payment integration is successful only when the entire chain behaves consistently.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">This is also why an issue such as &#8220;BLIK is missing&#8221; or &#8220;the bank list does not open&#8221; should not immediately be treated as a gateway API problem.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The actual cause could be a cart-total calculation, payment-method eligibility check, OPC rendering, JavaScript initialization, or an AJAX refresh replacing the payment interface.<\/span><\/p>\n<h2><strong>22.0 Final Checklist for a Custom PrestaShop Payment Gateway<\/strong><\/h2>\n<p><span style=\"font-weight: 400;\">Before considering the integration complete, verify:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">Payment module extends<\/span> <strong>PaymentModule<\/strong>.<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><b>paymentOptions <\/b><span style=\"font-weight: 400;\">is implemented correctly.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><b>paymentReturn <\/b><span style=\"font-weight: 400;\">is implemented where required.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">Payment options use<\/span> paymentOptions.<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">Currency restrictions are checked.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">Country and carrier restrictions are checked where applicable.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">Cart totals are validated.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">Gateway responses are verified.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">Callback signatures are validated.<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\"><strong>ValidateOrder()<\/strong> is called only after successful payment verification.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">The amount used for the order is validated against the gateway response.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">Webhooks are idempotent.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">Duplicate notifications do not create duplicate orders.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">Correct order states are used.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">Failed and pending payments are handled separately.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">Sensitive payment data is never unnecessarily logged or stored.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">HTTPS is enforced.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">Default PrestaShop checkout has been tested.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">OPC has been tested separately.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">JavaScript has been tested after AJAX checkout refreshes.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">Iframes and interactive payment elements have been tested.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">Multiple payment modules have been tested together.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">Realistic carts with discounts and shipping have been tested.<\/span><\/li>\n<\/ul>\n<h2><strong>Conclusion<\/strong><\/h2>\n<p><span style=\"font-weight: 400;\">A custom payment gateway in PrestaShop is more than an API integration.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The API is only one piece of the implementation. The real engineering challenge begins when the payment module has to coexist with PrestaShop&#8217;s checkout, an OPC such as SuperCheckout, other payment modules, dynamic JavaScript, cart recalculations, and asynchronous gateway callbacks.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Our experience with payment compatibility issues reinforced one important approach: always isolate where the failure occurs before changing code.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">If the payment method is not returned by PHP, investigate the payment module and its eligibility rules. If PHP returns it but the customer cannot see it, investigate the OPC and frontend rendering. If the UI appears but does not respond, investigate JavaScript and AJAX refreshes. If the payment succeeds but the order remains pending, investigate the callback and order-state flow.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">This approach is much more reliable than assuming every payment problem is an API problem.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">For developers working on PrestaShop payment integrations, the goal should not simply be to make a gateway accept a transaction. The goal is to make the entire payment lifecycle reliable\u2014from the first checkout render to the final verified order state\u2014even when multiple payment methods and a customized OPC are involved.<\/span><\/p>\n<div class=\"thecontent\">\n<div class=\"thecontent\">\n<p>If you have questions or need assistance with your website performance or migration, our experts are here to help. Contact the Knowband team at\u00a0<a href=\"mailto:support@knowband.com\" target=\"_blank\" rel=\"noopener\">support@knowband.com<\/a> today for reliable eCommerce plugins tailored to your eCommerce needs.<\/p>\n<h2><b>\ud83d\udc49\u00a0Explore the Module with Our Video Guide<\/b><\/h2>\n<p><iframe loading=\"lazy\" title=\"Best PrestaShop One Page Checkout Module 2025 | Knowband Official Demo\" width=\"648\" height=\"365\" src=\"https:\/\/www.youtube.com\/embed\/5FW7jKK6NMw?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/p>\n<h2><\/h2>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Integrating a payment gateway into PrestaShop can look straightforward on paper. The gateway provides API documentation, sandbox credentials, authentication keys, callback URLs, and a few endpoints. The PrestaShop module then sends the payment request, receives the response, creates the order, and redirects the customer to the confirmation page. In a real PrestaShop store, however, the [&hellip;]<\/p>\n","protected":false},"author":43,"featured_media":841316,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_kbui_enabled":"","footnotes":""},"categories":[4,1],"tags":[53246,53248,53222,53251,53245,53227,53232,53236,53247,53243,39318,53228,53241,53224,53253,53244,53242,12753,53229,53237,53238,53226,53231,53252,53239,53220,53221,53223,34560,53225,53234,53240,53250,53233,53235,53249,53230],"class_list":["post-841317","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ecommerce-blog","category-prestashop-blog","tag-blik-prestashop","tag-comfino-prestashop","tag-custom-payment-gateway-prestashop","tag-custom-payment-integration","tag-embedded-payment-form","tag-payment-gateway-api-integration","tag-payment-gateway-compatibility","tag-payment-gateway-webhooks","tag-payu-prestashop","tag-prestashop-ajax-checkout","tag-prestashop-api-integration","tag-prestashop-checkout","tag-prestashop-checkout-customization","tag-prestashop-custom-payment-module","tag-prestashop-gateway-integration","tag-prestashop-iframe-payment","tag-prestashop-javascript-checkout","tag-prestashop-one-page-checkout","tag-prestashop-opc","tag-prestashop-order-creation","tag-prestashop-order-status","tag-prestashop-payment-api","tag-prestashop-payment-compatibility","tag-prestashop-payment-development","tag-prestashop-payment-flow","tag-prestashop-payment-gateway","tag-prestashop-payment-gateway-integration","tag-prestashop-payment-integration","tag-prestashop-payment-methods","tag-prestashop-payment-module","tag-prestashop-payment-options","tag-prestashop-payment-processing","tag-prestashop-payment-security","tag-prestashop-payment-troubleshooting","tag-prestashop-webhooks","tag-simplylease-prestashop","tag-supercheckout-prestashop"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>PrestaShop Payment Gateway Integration: API &amp; OPC Guide<\/title>\n<meta name=\"description\" content=\"Learn how to integrate a custom payment gateway in PrestaShop, handle APIs, webhooks, order states, and troubleshoot OPC compatibility issues.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.knowband.com\/blog\/prestashop-blog\/prestashop-payment-gateway-integration\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"PrestaShop Payment Gateway Integration: API &amp; OPC Guide\" \/>\n<meta property=\"og:description\" content=\"Learn how to integrate a custom payment gateway in PrestaShop, handle APIs, webhooks, order states, and troubleshoot OPC compatibility issues.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.knowband.com\/blog\/prestashop-blog\/prestashop-payment-gateway-integration\/\" \/>\n<meta property=\"og:site_name\" content=\"Knowband Blog | Ecommerce Modules\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/Knowband\" \/>\n<meta property=\"article:published_time\" content=\"2026-09-09T12:21:13+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-09-30T09:34:14+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.knowband.com\/blog\/wp-content\/uploads\/2026\/09\/PrestaShop-Payment-Gateway-Integration-API-OPC-Guide.png\" \/>\n\t<meta property=\"og:image:width\" content=\"700\" \/>\n\t<meta property=\"og:image:height\" content=\"300\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Sophie\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@KnowbandPlugin\" \/>\n<meta name=\"twitter:site\" content=\"@KnowbandPlugin\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Sophie\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"15 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/prestashop-blog\\\/prestashop-payment-gateway-integration\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/prestashop-blog\\\/prestashop-payment-gateway-integration\\\/\"},\"author\":{\"name\":\"Sophie\",\"@id\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/fr\\\/#\\\/schema\\\/person\\\/ca485d026e41cbf45ae99b67d0c9ac74\"},\"headline\":\"Integrating a Custom Payment Gateway in PrestaShop: Technical Requirements, API Flow, and Real-World OPC Challenges\",\"datePublished\":\"2026-09-09T12:21:13+00:00\",\"dateModified\":\"2026-09-30T09:34:14+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/prestashop-blog\\\/prestashop-payment-gateway-integration\\\/\"},\"wordCount\":3195,\"publisher\":{\"@id\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/fr\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/prestashop-blog\\\/prestashop-payment-gateway-integration\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/PrestaShop-Payment-Gateway-Integration-API-OPC-Guide.png\",\"keywords\":[\"BLIK PrestaShop\",\"Comfino PrestaShop\",\"custom payment gateway PrestaShop\",\"custom payment integration\",\"embedded payment form\",\"payment gateway API integration\",\"payment gateway compatibility\",\"payment gateway webhooks\",\"PayU PrestaShop\",\"PrestaShop AJAX checkout\",\"PrestaShop API integration\",\"PrestaShop checkout\",\"PrestaShop checkout customization\",\"PrestaShop custom payment module\",\"PrestaShop gateway integration\",\"PrestaShop iframe payment\",\"PrestaShop JavaScript checkout\",\"Prestashop One page checkout\",\"PrestaShop OPC\",\"PrestaShop order creation\",\"PrestaShop order status\",\"PrestaShop payment API\",\"PrestaShop payment compatibility\",\"PrestaShop payment development\",\"PrestaShop payment flow\",\"PrestaShop payment gateway\",\"PrestaShop payment gateway integration\",\"PrestaShop payment integration\",\"PrestaShop payment methods\",\"PrestaShop payment module\",\"PrestaShop payment options\",\"PrestaShop payment processing\",\"PrestaShop payment security\",\"PrestaShop payment troubleshooting\",\"PrestaShop webhooks\",\"SimplyLease PrestaShop\",\"SuperCheckout PrestaShop\"],\"articleSection\":[\"Ecommerce\",\"Prestashop\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/prestashop-blog\\\/prestashop-payment-gateway-integration\\\/\",\"url\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/prestashop-blog\\\/prestashop-payment-gateway-integration\\\/\",\"name\":\"PrestaShop Payment Gateway Integration: API & OPC Guide\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/fr\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/prestashop-blog\\\/prestashop-payment-gateway-integration\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/prestashop-blog\\\/prestashop-payment-gateway-integration\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/PrestaShop-Payment-Gateway-Integration-API-OPC-Guide.png\",\"datePublished\":\"2026-09-09T12:21:13+00:00\",\"dateModified\":\"2026-09-30T09:34:14+00:00\",\"description\":\"Learn how to integrate a custom payment gateway in PrestaShop, handle APIs, webhooks, order states, and troubleshoot OPC compatibility issues.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/prestashop-blog\\\/prestashop-payment-gateway-integration\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.knowband.com\\\/blog\\\/prestashop-blog\\\/prestashop-payment-gateway-integration\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/prestashop-blog\\\/prestashop-payment-gateway-integration\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/PrestaShop-Payment-Gateway-Integration-API-OPC-Guide.png\",\"contentUrl\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/PrestaShop-Payment-Gateway-Integration-API-OPC-Guide.png\",\"width\":700,\"height\":300,\"caption\":\"Understanding custom payment gateway integration and OPC compatibility in PrestaShop\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/prestashop-blog\\\/prestashop-payment-gateway-integration\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/fr\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Integrating a Custom Payment Gateway in PrestaShop: Technical Requirements, API Flow, and Real-World OPC Challenges\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/fr\\\/#website\",\"url\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/fr\\\/\",\"name\":\"Knowband Blog | Ecommerce Modules\",\"description\":\"Magento, Prestashop, Opencart, Shopify\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/fr\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/fr\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/fr\\\/#organization\",\"name\":\"Knowband Blog | Ecommerce Modules\",\"url\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/fr\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/fr\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/wp-content\\\/uploads\\\/2016\\\/09\\\/cropped-knowband_logo-v2.png\",\"contentUrl\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/wp-content\\\/uploads\\\/2016\\\/09\\\/cropped-knowband_logo-v2.png\",\"width\":153,\"height\":61,\"caption\":\"Knowband Blog | Ecommerce Modules\"},\"image\":{\"@id\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/fr\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/Knowband\",\"https:\\\/\\\/x.com\\\/KnowbandPlugin\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/fr\\\/#\\\/schema\\\/person\\\/ca485d026e41cbf45ae99b67d0c9ac74\",\"name\":\"Sophie\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/wp-content\\\/plugins\\\/wp-user-avatar\\\/deprecated\\\/wp-user-avatar\\\/images\\\/wpua-96x96.png\",\"url\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/wp-content\\\/plugins\\\/wp-user-avatar\\\/deprecated\\\/wp-user-avatar\\\/images\\\/wpua-96x96.png\",\"contentUrl\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/wp-content\\\/plugins\\\/wp-user-avatar\\\/deprecated\\\/wp-user-avatar\\\/images\\\/wpua-96x96.png\",\"caption\":\"Sophie\"},\"description\":\"We are experts in the eCommerce industry, specializing in high-quality plugin development. With years of experience, we deliver reliable and feature-rich modules for platforms such as Magento, PrestaShop, OpenCart, and Shopify. In addition to ready-made plugins, we also provide custom module development and tailored modification services to meet unique business needs. Our team stays ahead of industry trends, ensuring every solution we build enhances store performance, user experience, and overall functionality. With a strong customer-centric approach, we have become a trusted partner for businesses seeking powerful and scalable eCommerce plugin solutions.\",\"url\":\"https:\\\/\\\/www.knowband.com\\\/blog\\\/author\\\/titiksha-dwivedi\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"PrestaShop Payment Gateway Integration: API & OPC Guide","description":"Learn how to integrate a custom payment gateway in PrestaShop, handle APIs, webhooks, order states, and troubleshoot OPC compatibility issues.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.knowband.com\/blog\/prestashop-blog\/prestashop-payment-gateway-integration\/","og_locale":"en_US","og_type":"article","og_title":"PrestaShop Payment Gateway Integration: API & OPC Guide","og_description":"Learn how to integrate a custom payment gateway in PrestaShop, handle APIs, webhooks, order states, and troubleshoot OPC compatibility issues.","og_url":"https:\/\/www.knowband.com\/blog\/prestashop-blog\/prestashop-payment-gateway-integration\/","og_site_name":"Knowband Blog | Ecommerce Modules","article_publisher":"https:\/\/www.facebook.com\/Knowband","article_published_time":"2026-09-09T12:21:13+00:00","article_modified_time":"2026-09-30T09:34:14+00:00","og_image":[{"width":700,"height":300,"url":"https:\/\/www.knowband.com\/blog\/wp-content\/uploads\/2026\/09\/PrestaShop-Payment-Gateway-Integration-API-OPC-Guide.png","type":"image\/png"}],"author":"Sophie","twitter_card":"summary_large_image","twitter_creator":"@KnowbandPlugin","twitter_site":"@KnowbandPlugin","twitter_misc":{"Written by":"Sophie","Est. reading time":"15 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.knowband.com\/blog\/prestashop-blog\/prestashop-payment-gateway-integration\/#article","isPartOf":{"@id":"https:\/\/www.knowband.com\/blog\/prestashop-blog\/prestashop-payment-gateway-integration\/"},"author":{"name":"Sophie","@id":"https:\/\/www.knowband.com\/blog\/fr\/#\/schema\/person\/ca485d026e41cbf45ae99b67d0c9ac74"},"headline":"Integrating a Custom Payment Gateway in PrestaShop: Technical Requirements, API Flow, and Real-World OPC Challenges","datePublished":"2026-09-09T12:21:13+00:00","dateModified":"2026-09-30T09:34:14+00:00","mainEntityOfPage":{"@id":"https:\/\/www.knowband.com\/blog\/prestashop-blog\/prestashop-payment-gateway-integration\/"},"wordCount":3195,"publisher":{"@id":"https:\/\/www.knowband.com\/blog\/fr\/#organization"},"image":{"@id":"https:\/\/www.knowband.com\/blog\/prestashop-blog\/prestashop-payment-gateway-integration\/#primaryimage"},"thumbnailUrl":"https:\/\/www.knowband.com\/blog\/wp-content\/uploads\/2026\/09\/PrestaShop-Payment-Gateway-Integration-API-OPC-Guide.png","keywords":["BLIK PrestaShop","Comfino PrestaShop","custom payment gateway PrestaShop","custom payment integration","embedded payment form","payment gateway API integration","payment gateway compatibility","payment gateway webhooks","PayU PrestaShop","PrestaShop AJAX checkout","PrestaShop API integration","PrestaShop checkout","PrestaShop checkout customization","PrestaShop custom payment module","PrestaShop gateway integration","PrestaShop iframe payment","PrestaShop JavaScript checkout","Prestashop One page checkout","PrestaShop OPC","PrestaShop order creation","PrestaShop order status","PrestaShop payment API","PrestaShop payment compatibility","PrestaShop payment development","PrestaShop payment flow","PrestaShop payment gateway","PrestaShop payment gateway integration","PrestaShop payment integration","PrestaShop payment methods","PrestaShop payment module","PrestaShop payment options","PrestaShop payment processing","PrestaShop payment security","PrestaShop payment troubleshooting","PrestaShop webhooks","SimplyLease PrestaShop","SuperCheckout PrestaShop"],"articleSection":["Ecommerce","Prestashop"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.knowband.com\/blog\/prestashop-blog\/prestashop-payment-gateway-integration\/","url":"https:\/\/www.knowband.com\/blog\/prestashop-blog\/prestashop-payment-gateway-integration\/","name":"PrestaShop Payment Gateway Integration: API & OPC Guide","isPartOf":{"@id":"https:\/\/www.knowband.com\/blog\/fr\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.knowband.com\/blog\/prestashop-blog\/prestashop-payment-gateway-integration\/#primaryimage"},"image":{"@id":"https:\/\/www.knowband.com\/blog\/prestashop-blog\/prestashop-payment-gateway-integration\/#primaryimage"},"thumbnailUrl":"https:\/\/www.knowband.com\/blog\/wp-content\/uploads\/2026\/09\/PrestaShop-Payment-Gateway-Integration-API-OPC-Guide.png","datePublished":"2026-09-09T12:21:13+00:00","dateModified":"2026-09-30T09:34:14+00:00","description":"Learn how to integrate a custom payment gateway in PrestaShop, handle APIs, webhooks, order states, and troubleshoot OPC compatibility issues.","breadcrumb":{"@id":"https:\/\/www.knowband.com\/blog\/prestashop-blog\/prestashop-payment-gateway-integration\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.knowband.com\/blog\/prestashop-blog\/prestashop-payment-gateway-integration\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.knowband.com\/blog\/prestashop-blog\/prestashop-payment-gateway-integration\/#primaryimage","url":"https:\/\/www.knowband.com\/blog\/wp-content\/uploads\/2026\/09\/PrestaShop-Payment-Gateway-Integration-API-OPC-Guide.png","contentUrl":"https:\/\/www.knowband.com\/blog\/wp-content\/uploads\/2026\/09\/PrestaShop-Payment-Gateway-Integration-API-OPC-Guide.png","width":700,"height":300,"caption":"Understanding custom payment gateway integration and OPC compatibility in PrestaShop"},{"@type":"BreadcrumbList","@id":"https:\/\/www.knowband.com\/blog\/prestashop-blog\/prestashop-payment-gateway-integration\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.knowband.com\/blog\/fr\/"},{"@type":"ListItem","position":2,"name":"Integrating a Custom Payment Gateway in PrestaShop: Technical Requirements, API Flow, and Real-World OPC Challenges"}]},{"@type":"WebSite","@id":"https:\/\/www.knowband.com\/blog\/fr\/#website","url":"https:\/\/www.knowband.com\/blog\/fr\/","name":"Knowband Blog | Ecommerce Modules","description":"Magento, Prestashop, Opencart, Shopify","publisher":{"@id":"https:\/\/www.knowband.com\/blog\/fr\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.knowband.com\/blog\/fr\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.knowband.com\/blog\/fr\/#organization","name":"Knowband Blog | Ecommerce Modules","url":"https:\/\/www.knowband.com\/blog\/fr\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.knowband.com\/blog\/fr\/#\/schema\/logo\/image\/","url":"https:\/\/www.knowband.com\/blog\/wp-content\/uploads\/2016\/09\/cropped-knowband_logo-v2.png","contentUrl":"https:\/\/www.knowband.com\/blog\/wp-content\/uploads\/2016\/09\/cropped-knowband_logo-v2.png","width":153,"height":61,"caption":"Knowband Blog | Ecommerce Modules"},"image":{"@id":"https:\/\/www.knowband.com\/blog\/fr\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/Knowband","https:\/\/x.com\/KnowbandPlugin"]},{"@type":"Person","@id":"https:\/\/www.knowband.com\/blog\/fr\/#\/schema\/person\/ca485d026e41cbf45ae99b67d0c9ac74","name":"Sophie","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.knowband.com\/blog\/wp-content\/plugins\/wp-user-avatar\/deprecated\/wp-user-avatar\/images\/wpua-96x96.png","url":"https:\/\/www.knowband.com\/blog\/wp-content\/plugins\/wp-user-avatar\/deprecated\/wp-user-avatar\/images\/wpua-96x96.png","contentUrl":"https:\/\/www.knowband.com\/blog\/wp-content\/plugins\/wp-user-avatar\/deprecated\/wp-user-avatar\/images\/wpua-96x96.png","caption":"Sophie"},"description":"We are experts in the eCommerce industry, specializing in high-quality plugin development. With years of experience, we deliver reliable and feature-rich modules for platforms such as Magento, PrestaShop, OpenCart, and Shopify. In addition to ready-made plugins, we also provide custom module development and tailored modification services to meet unique business needs. Our team stays ahead of industry trends, ensuring every solution we build enhances store performance, user experience, and overall functionality. With a strong customer-centric approach, we have become a trusted partner for businesses seeking powerful and scalable eCommerce plugin solutions.","url":"https:\/\/www.knowband.com\/blog\/author\/titiksha-dwivedi\/"}]}},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.knowband.com\/blog\/wp-json\/wp\/v2\/posts\/841317","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.knowband.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.knowband.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.knowband.com\/blog\/wp-json\/wp\/v2\/users\/43"}],"replies":[{"embeddable":true,"href":"https:\/\/www.knowband.com\/blog\/wp-json\/wp\/v2\/comments?post=841317"}],"version-history":[{"count":8,"href":"https:\/\/www.knowband.com\/blog\/wp-json\/wp\/v2\/posts\/841317\/revisions"}],"predecessor-version":[{"id":841888,"href":"https:\/\/www.knowband.com\/blog\/wp-json\/wp\/v2\/posts\/841317\/revisions\/841888"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.knowband.com\/blog\/wp-json\/wp\/v2\/media\/841316"}],"wp:attachment":[{"href":"https:\/\/www.knowband.com\/blog\/wp-json\/wp\/v2\/media?parent=841317"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.knowband.com\/blog\/wp-json\/wp\/v2\/categories?post=841317"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.knowband.com\/blog\/wp-json\/wp\/v2\/tags?post=841317"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}