The development of this version has cost 1,700 euros. The accumulated cost for this year is 5,234 euros. The accumulated cost since the first version is 40,724 euros, but the cost for you is only the license from 79€.
New version 2.0.0 of the module Redsys for PrestaShop Premium. It is a major version: it expands compatibility to PrestaShop 1.7, 8, and 9 (PHP 7.4 or higher) and, above all, reinforces the security of payment confirmation.
2.0.0
New:
- Compatibility with PrestaShop 1.7 (PHP 7.4+). The module now installs and works on PrestaShop 1.7 on PHP 7.4 or higher, remaining fully compatible with PrestaShop 8 and 9 / PHP 8.x. The minimum PHP requirement has been lowered from 8.1 to 7.4 in the installation guard, in
ps_versions_compliancy(minimum now 1.7.0.0) and incomposer.json. PHP 7.1, 7.2, and 7.3 are not compatible as they are at the end of their life cycle; a 1.7.7.x store still using those versions must upgrade its PHP to 7.4 before installation.
Improved:
- PHP 8.0 exclusive language constructs have been replaced with equivalents compatible with PHP 7.4, with no behavioral changes: all expressions
match()converted toswitch(8 cases), the typemixedremoved and documented in the docblock (4 cases) and union types removed from method signatures and moved to the docblock (6 cases). Modern PHP 7.4 features (arrow functions, typed properties, nullable types, andstrict_types) remain intact. - Payment errors are now always logged. A new helper,
Ps_redsys_gateway::persistPaymentError(), saves the specific reason for the failure as a private order message plus an entry in the extended log, and the failure routes of the IPN and confirmation now write a non-misleading reason (for example, "approval code without authorization code; payment NOT confirmed" or "notification without Ds_Response"). No payment failure goes unreported.
Security:
- [Critical] An order could be marked as PAID without a verified Redsys authorization. The golden rule "never mark an order as paid unless Redsys has actually authorized the payment" is now enforced through a single source of truth,
Ps_redsys_gateway::isRedsysPaymentAuthorised(), which requires that theDs_Responseis present and strictly within the range [0,99] and that there is a non-emptyDs_AuthorisationCode. This closes the trap(int) null === 0(an absent response code was interpreted as 0 = success) and the case of missing authorization code (a confirmed payment without an authorization number). The check applies to the IPN (controllers/front/ipn.php), to URL confirmation (controllers/front/confirmation.php), to Paygold (PaygoldService), and to the REST authorization checkpoint (RedsysRestService::trataPeticion), covering Apple Pay, Google Pay, Bizum, InSite, OneClick, saved card, and Paygold. Symptom fixed: Apple Pay orders shown as paid without any money being charged or anything appearing in the Redsys panel. - [Critical] The public AJAX endpoint
expresspay?action=createOrderwas creating the order directly in paid status (REDSYS_ORDER_STATE_COMPLETED) using atransaction_idprovided by the customer and without Redsys verification. It now forcespendingState=true, so it can only create a pending or awaiting payment order; the paid status is applied later, exclusively, by the verified IPN signature. As a defense in depth,ExpressCheckoutService::createOrderFromExpressPayrejects the paid status when there is no authorization reference and safely falls back to pending. - [Critical] The Inespay IPN (
controllers/front/inespayipn.php) was creating a PAID order relying on the fieldcodStatusof an unauthenticated notification (no signature, no HMAC, no server confirmation), allowing an order to be confirmed without any real bank payment. It nowInespayApiService::validateCallback()verifies the signature exactly as specified by the Inespay API v2.2: HmacSHA256 over thedataReturnBase64 encoded using the account API KEY, expressed in lowercase hexadecimal and then Base64 encoded, compared againstsignatureDataReturn. Fails closed: a notification withoutdataReturnand a validsignatureDataReturnis rejected and the order is never marked as paid. ThecodStatustrusted (OK / SETTLED) is read from the signed payloaddataReturn, not from the raw POST body.





