Bypass all resource restrictions, passwords, and keys? Read here!
Decryption key:
WooCommerce RedSys Gateway v32.1.0
2026.09.09 - version 32.1.0
* SECURITY: The plugin was writing the address of every shopper's order-received page into its own log file on every payment, and that address contains the order key - the private token that WooCommerce puts in the shopper's payment link and that this plugin requires before it will show an order. Anyone able to read the log file could therefore open those orders and see the name, email, telephone and addresses on them. It happened whether or not the shop had switched debug logging on, because this one place wrote to the log without checking that setting. It now respects the debug setting like every other log the plugin writes, and the key is replaced with "[redacted]" before anything is written, so it is not recorded even with logging switched on. That replacement was then applied to every log line the plugin writes rather than to the one that was reported: around ninety further lines across the gateways printed the same addresses whenever debug logging was on, including the ones that dump the whole message sent to the bank. Log files already written still contain those addresses: if you have them, delete them.
* FIX: With InSite, paying with a card the shopper had saved could take the money and still show the order as failed. When the bank approves such a payment without asking the shopper to confirm with their bank app - which is what happens with a saved card - the plugin was looking for the result in the wrong place, found nothing, and treated "nothing" as a refusal. The charge had already gone through, so shoppers who were told the payment had failed paid a second time and were charged twice. The result is now read from the bank's own signed answer, the same one the rest of the payment already uses. It affected the classic checkout and the block checkout equally, and it also affected subscription renewals. Reported by two shops within days of each other, one of whom traced it to the exact line - thank you.
* FIX: On the card gateway, a payment made with a saved card was completed on the strength of an authorisation number alone, without checking the bank's actual answer beside it. A refused payment that still carried something in that field would therefore mark the order as paid, and the shop would send the goods without having been paid. Both are now required to agree before an order is completed. If the bank's answer is missing altogether the payment is not completed, because there is nothing left that says it was approved; a shop whose bank genuinely omits that field can restore the previous behaviour on purpose with the redsys_allow_payment_without_ds_response filter, which is documented and which cannot be used to accept a payment the bank actually refused.
* FIX: On stores using certain checkout plugins - Fluid Checkout among them - every payment was refused by Redsys with the error SIS0574. The bank requires a short description of the shopper's browser with each payment (its language, its screen size and similar), which the plugin collects through hidden fields it adds to the checkout. Those fields were being added at the moment the card gateway was built, which on those stores happens after another plugin has already asked WooCommerce for the definitive list of checkout fields - and WooCommerce builds that list once and never again. The fields were therefore never created, never filled in and never sent, and the bank refused the payment. They are now added as soon as the plugin loads, before anything can ask for the list, which affects every gateway that needs them - the card gateway, Bizum and the wallets - not only InSite. In InSite the browser description now also travels with the rest of the payment data instead of depending on the order alone, so it survives a checkout that rebuilds itself. Reported by an integrator who had already proved the diagnosis - thank you.
* SECURITY: The page that forwards a shopper to Redsys (and to Bizum) accepted any order number typed into its address, without checking that the person asking for it was the person who placed that order. Because order numbers run in sequence, someone could step through them and read the data the plugin sends to the bank for other customers' orders: name, email, telephone and the billing and delivery address, together with the amount and the description of what was bought. No card number, no security code and no signature key were ever exposed, and nothing could be paid or modified this way. That page now requires the order key that WooCommerce puts in the shopper's own payment link, so a request that does not belong to the order is refused with a "Forbidden" page instead of being answered. The same check was added to the payment pop-up on the checkout page. Reported by the security team at Tivify (TVUP Streaming Media), who described the problem clearly and gave us the time to fix it before saying anything publicly - thank you.
* FIX: If a payment was cancelled or refused, the shopper came back to the shop but the order was left pending and the basket was not restored. The address the plugin gave the bank to send the shopper back to was written in the form used for links inside a web page, not the form used for a real address, so the shop received the return without the order reference, its number or its security token and had nothing to cancel. It affected Bizum, Google Pay, Apple Pay, direct debit, bank transfer, InSite and the card gateway whenever the "return to" setting is set to cancel the order. On MasterPass the same address was being sent completely empty, because of a typing mistake of a single character repeated on three lines. All of it now goes through a single shared piece of code, so a gateway added in the future cannot get it wrong again.
* FIX: In the pop-up (modal) payment mode, cancelling a payment did nothing and the shopper was left on the cart with the order still pending. The address the plugin sent the browser to was being written into the page in a way the browser reads as a link inside a document rather than as a web address, so everything after the first parameter was discarded - the order reference, its number and its security token all disappeared, and WooCommerce had nothing to cancel. The same flaw affected the address the shopper is returned to after paying, where it silently dropped a tracking parameter. Both are fixed, in the card gateway and in the InSite gateway, and the corrected behaviour was verified in a real browser.
* FIX: The checkout could die with a critical error, instead of sending the shopper to the bank, for a logged-in customer whose customer record had never been changed since it was created. The plugin builds a set of security data for the bank on every payment, and one of the fields is the date the customer account was last modified - which WooCommerce leaves empty for an account that has never been touched, typically one created by an import, a migration, or automatically by another plugin. The plugin read that empty date as if it were a real date and the payment page stopped there. It now falls back to the date the account was created, which is what "never modified" means, and the same protection was added to the equivalent code used by subscriptions - where the same empty date was silently being reported to the bank as "modified today", which is wrong information for the bank's fraud checks.
* SECURITY: The three preauthorization buttons in the order screen (authorise, cancel, charge a deposit) and the PayGold customer search accepted their requests without a security token. The permission check was already in place, so only a shop manager or administrator could ever use them, and nobody else could have run them - but an administrator who was already logged in could have been tricked into firing one from another website without noticing. All four now carry and verify a WordPress security token, which closes that path.
* FIX: Redsys and the other gateways could disappear from the checkout for everyone, including ordinary shoppers, on stores where the "show only to these users" list in test mode had never been filled in. The plugin read that empty setting as "show it to one user whose id is nothing", which matches nobody, so the payment method was hidden from every visitor. It only affected stores whose settings were written by something other than the settings screen - an import, a migration, or the plugin's own management API - because saving that screen by hand stores a different empty value that never triggered it. Fixed in the nine gateways that shared the same code.
* FIX: Subscriptions paid with Apple Pay or Google Pay by a customer without an account never obtained the recurring payment permission from the bank, so the first renewal failed with a note saying there was no card. It happened on stores where the general "allow customers to create an account during checkout" option is switched off, which is common on stores that allow guest checkout: the wallet payment paths never saw WooCommerce Subscriptions' own override of that option, so no account was created and, without an account, the bank permission could not be stored. Fixed in the four places that handle it (Apple Pay and Google Pay, on both the classic and the block checkout).
* FIX: The block checkout's payment script was built against a version of React that WordPress itself does not accept. A development-only dependency pulled a newer React into the build, and WordPress rejects elements produced by it, so the payment method could fail to appear on the block checkout. The build now pins the version WordPress uses and the script has been rebuilt.
* CHANGE: When a subscription renewal fails, the note added to the order now says exactly which step failed and which merchant code and terminal were used for the attempt. Until now all six possible failures wrote the same uninformative note, which made a failed renewal almost impossible to diagnose without access to the store - especially on stores where the debug log is not being written.
* CHANGE: When Apple Pay cannot validate the shop with Apple, the log now records Apple's own explanation and whether the certificate files can be read. Apple answers with a generic "Expectation Failed" and puts the real reason in the body of its reply, which was never being recorded, so those failures used to be a dead end.
* NEW: The WooCommerce status report (WooCommerce - Status) now also lists what is switched on in the Redsys "Advanced settings" tab: push notifications, sequential invoices, QR codes, saved cards, order status overrides, conditional rules, subscriptions, e-mail reconciliation, the agentic commerce protocols and the management app API. Credentials are never printed - each one is reported only as set or not set. It is included when you copy the report to send it for support, which is the point: a support request now arrives with the configuration already in it.
* CHANGE: The distributed plugin no longer contains the project's own development and build scripts, its local test environment configuration, its editor and git-hook directories, its developer README or an internal security review document. None of it was ever loaded when the plugin runs, but none of it belongs on a shop's server either. What the package contains is now checked automatically, before every release, against a list of what the plugin really ships, so something added to the project in the future cannot travel inside the zip unnoticed.
* FIX: The cart and the checkout could become noticeably slow, for logged-out visitors too, on stores with saved cards or subscriptions. The plugin's internal helper WCRed() built a brand new copy of its global object every single time it was called, and that object registers three WordPress hooks the moment it is built. WordPress does not replace those hooks, it adds them, so on a store where the helper is called once per saved card or subscription the same three checks ended up registered hundreds of times and were re-run, all of them, every time WooCommerce assembled the list of available payment gateways. On a store that reported the problem this reached around 438 duplicated registrations per page load and about 1.7 seconds of PHP work on the cart page, of which only 56 milliseconds were database queries. The helper now builds that object once and reuses it, so the hooks are registered exactly once per request. Nothing about the plugin's behaviour changes: the object holds no per-request data. The same one-object-per-request treatment was applied to the WCPSD2() helper, which had the identical shape.
* FIX: On a small share of stores the Agentic Commerce (UCP) message-signing key was written in a form that could never be used, so every signature check against it failed and the published key document did not follow the standard. When the plugin created that key, one of its two coordinates occasionally came back from OpenSSL one byte shorter than the standard requires - about 1 store in 135 - and the plugin stored it as it was instead of padding it. From that moment the store could not verify its own signatures, and no external agent could either, until the key was rotated. The key is now stored padded to the required length, and a key already stored in the short form is repaired automatically the first time it is read, so no merchant has to rotate anything.
* FIX: On shops running PHP 8.0 or older, switching on the e-mail reconciliation broke the page with a server error instead of simply not working. The plugin now checks first and leaves a clear note in its log. The feature itself still needs PHP 8.1.
* SECURITY: The Agentic Commerce Protocol could end up switched on without anyone choosing it, on shops that update automatically. It publishes addresses that machines can talk to, so it is meant to be off unless you turn it on - and now it is. If you did switch it on, nothing changes for you.
* FIX: Background jobs were piling up into dozens of copies of themselves in the WooCommerce scheduled actions list. Fixed everywhere the plugin schedules anything, and the copies already there are cleared automatically.
* CHANGE: The e-mail reconciliation job now exists only while that feature is switched on, and only once. Before, it was created on every shop and woke up every five minutes doing nothing.
* FIX: A notification to the mobile app could be lost without any error if it was sent at the wrong moment.
* FIX: PHP warnings appeared in the server log on every visit to the "pay for order" page, from the Apple Pay and Google Pay gateways. Nothing was broken for shoppers, but the debug log for those gateways was not recording anything from that step - so anyone trying to diagnose a problem there was looking at a fault, not at silence. Reported by a merchant, and found in three gateways rather than the one reported - thank you.
* FIX: Turning the debug log on to look into a card payment problem produced warnings instead of the information you turned it on for.
* FIX: The "Connect with Google" button in the e-mail reconciliation settings was never displayed. Granting access was already possible by filling in the Google details and pressing "Save changes", so this restores a shortcut rather than unlocking the feature.
* SECURITY: The Google library bundled with the plugin has been updated, fixing two flaws in the part that makes network requests.
* CHANGE: All the translations are complete again. Sixty-nine texts added by recent versions were still showing in English - settings labels, the status report, and a few messages a shopper can see. Spanish, Catalan, Basque, Galician, French and Portuguese are back at one hundred per cent.
* NEW: You can now decide whether customers are offered "Add a credit card for Subscriptions" in My account - Payment methods. Until now that option appeared by itself as soon as a subscriptions plugin was active, with no way to remove it, which is not what every shop wants: on a shop where the card for a subscription is always captured during the purchase, it only invited customers to store a card nothing would ever charge. The new switch is in Redsys - Advanced settings - Saved Cards, it starts switched on so nothing changes for shops that were already offering it, and switching it off leaves the 1-click card on its own. It is also reported in the WooCommerce status report.
* FIX: The plugin sent the shop an e-mail saying "Redsys is not sending tokenization fields" after payments in which Redsys had sent every one of them. The check behind that notice tested a variable that does not exist anywhere in the plugin, and a test on something that does not exist is always true, so the warning went out on every payment that saved a card. Merchants were taking it to their bank, which correctly answered that the terminal was fine. The notice now reports only real absences, and it names in the log which field was missing - the expiry date, the card brand or the card number - instead of only saying that something was. It also had to stop reading the brand after the plugin had turned it into a display name, because that conversion answers "Unknown" when there is no brand, which would have turned the warning into one that could never appear at all. The same block was writing "unknown" as the card number in the debug log on every payment, through a variable name that carried one letter too many; it now writes the real masked number.
* FIX: Searching the Redsys tokens screen (WooCommerce - Redsys tokens) by e-mail or username could not find any card saved after the first twenty-five. The screen asked the database for one page of tokens and then searched inside that page, and since it asked for them in no particular order, that page was always the twenty-five oldest tokens in the shop - so the recently saved cards, which are the only ones anybody looks for, were unreachable. The search now runs in the database, over every token, and the listing arrives newest first. The counter above the table and the list below it can no longer disagree, sorting by username or e-mail now sorts the whole table instead of the visible page, and the screen no longer loads every token in the shop into memory just to count them, which on shops with thousands of saved cards it did on every page load.
* CHANGE: The token that guards the "add a card" link is now compared in constant time, like every other secret this plugin compares. Timing that comparison over the internet is not a practical attack, so nothing was exploitable; the inconsistency was the defect, because this was the one comparison left behind when the rest were migrated during the signature work.
Decryption key:
WooCommerce RedSys Gateway v32.0.0
2026.07.28 - version 32.0.0
* NEW: Manage your store from a native app. This release turns on the management app API that until now shipped hidden inside the plugin. Your store can be connected to PackDesk, the native macOS management app, to work with orders, refunds, products and customers without opening the WordPress dashboard. The API is served under the redsys-manager/v1 namespace and is strictly opt-in: it is OFF by default, it requires HTTPS and an active license, and no app can reach the store until a merchant enables it. It provides an order picking queue and order updates, product and customer routes, a "changes" delta feed so the app syncs only what changed, safe write retries through an Idempotency-Key header, and a request rate limit applied per employee (per user, never per IP), so several employees sharing a single connection never interfere with each other.
* NEW: A new "Behaviors towards the APP" section in the Redsys advanced settings (WooCommerce - Settings - Redsys - Advanced Settings) to control how the store behaves towards the app: enable or disable the API, allow or restrict refunds for the Customer service profile (refunds are limited to the Administrator profile by default), require a minimum app version, and set the requests-per-minute limit per employee (default 300, set 0 to disable it).
* NEW: A per-user "App profile" on the WordPress user edit screen, so each employee who connects from the app operates under a profile - for example Administrator or Customer service - that decides what the app lets them see and do, including whether they may issue refunds.
* NEW: A new "Apps and Plugins" section in the Redsys advanced settings: a read-only overview of the native app and the rest of the plugins, websites and skills, all reachable from one place.
* CHANGE: Compatibility declared with WooCommerce 11. The plugin's "WC tested up to" header now reads 11.0, so WooCommerce no longer warns that the gateway has not been tested with the version you are running. The minimum supported WooCommerce is unchanged (7.4).
* NEW: PackDesk is now published on the Mac App Store, and the official "Download on the Mac App Store" button is shown at the top of the "Behaviors towards the APP" section and in the featured-app area of "Apps and Plugins", so the app can be installed straight from the store settings. The button uses Apple's own artwork in the language of the administrator viewing it - English, Spanish, Catalan, French or Portuguese, with English used for Basque and Galician because Apple does not publish a badge for them - and it opens the App Store of each visitor's own country. The app entry now shows the published version instead of the beta, and states that it requires macOS 26 Tahoe or later.
* FIX: The product QR code did not appear on stores whose media library is offloaded to an external service such as Cloudflare Images. The QR image was registered in the media library correctly, but the plugin saved and displayed a URL it had built by hand from the local uploads folder instead of asking WordPress for the attachment's real URL, so on an offloaded store that address pointed at a file that is no longer served locally and the image was broken. The QR URL is now resolved through the media library (wp_get_attachment_url), the attachment id is stored alongside it, and the address is resolved every time the QR is shown, so it follows the file wherever it is served - including offloading that was enabled after the QR was created. Existing QR codes are healed automatically the first time their product is opened; if one cannot be matched, the "Regenerate QR Code" link rebuilds it correctly.
* FIX: A Bizum payment could be charged at the bank yet leave the order pending, with the log showing "Signature verification failed in successful_request". The order-completion step in one of the two Bizum gateways verified the bank notification with the gateway's plain configured signature key, while the operation had been signed with the per-order key actually used for it - as happens on stores with a per-user or dual/test terminal, or the bizum_modify_data_to_send filter. The notification passed the first validation and was then rejected by this second check, so the money was taken but the order stayed pending. The order-completion step now resolves the signing key exactly like the notification validation - and like the other Bizum gateway already did - from the order meta, then the request transient, then the settings key for the order's customer, so both agree.
Decryption key:
WooCommerce RedSys Gateway v31.0.5
*** Redsys Gateway Change Log ***
2026.07.02 - version 31.0.5
* FIX: Subscription renewals could still get stuck in an endless SIS0051 ("número de pedido repetido") loop after 31.0.4. The 31.0.4 fix released the stored order number only when the decline arrived as a signed Ds_Response without an authorisation code, but Redsys reports a duplicate order number as a plain errorCode (SIS0051) in the trataPeticion response, which the plugin handles through the request-error path — so the stored number was never released and every retry resent the exact same DS_MERCHANT_ORDER (already burned at Redsys by attempts made before updating), failing again with SIS0051 forever. Renewal charges now ALWAYS generate a brand-new order number at the start of every attempt and never read a previously stored one: the iniciaPeticion/trataPeticion pair of the attempt shares that freshly generated number (so they cannot mismatch, SIS0502), duplicate concurrent workers are stopped by the renewal lock before the number is generated, and the last number sent is still persisted to order meta so refunds and the payment notification (IPN) resolve the right order. Stores stuck in the SIS0051 loop self-heal on the next scheduled retry after updating, with no manual action needed. Applies to the Redirection and InSite gateways and every subscription plugin routing through them (Google Pay / Apple Pay delegate to Redirection).
2026.07.01 - version 31.0.4
* FIX: Subscription renewals (with any subscription plugin) now respect the configured Redsys order-number type and no longer fail on retry with "número de pedido repetido" (SIS0051). Two problems are fixed. First, the renewal charge generated the Redsys order number ignoring the "Type of order number" setting (redsysordertype/subfix): it always fell back to the default random scheme instead of the type configured for the gateway, unlike the initial checkout payment. It now passes the gateway so renewals honour the same order-number type as checkout. Second, the order number was persisted for the whole order lifetime, so when a renewal charge was declined and the subscription plugin retried it on the same renewal order, the exact same DS_MERCHANT_ORDER was resent and Redsys blocked the legitimate retry as a duplicate. The distinction between a "flow" and a "retry" is now explicit: a single payment flow (its iniciaPeticion/trataPeticion pair, concurrent renewal workers, and any Action-Scheduler re-run of a process that died mid-charge) keeps the same order number to avoid crossing Id Opers (SIS0502) and to stay idempotent against double charges; but once Redsys confirms a decline (a signed response with no authorisation code, i.e. no money moved), the number is released so the next retry generates a fresh, unique one honouring the configured type. The reset fires ONLY on a confirmed decline, never on transport/timeout errors where the outcome is unknown, so a lost-response re-run can never double charge. Applies to the Redirection and InSite gateways and to every subscription plugin that routes through them (WooCommerce Subscriptions, Subscriptions for WooCommerce, YITH, WebToffee, SUMO, Advanced Subscriptions; Google Pay and Apple Pay delegate to the Redirection gateway). As a safety net, whenever no valid order-number type is configured (empty or a legacy/unrecognised value) the generator now ALWAYS falls back to the default "3 random digits + zeros + order id" scheme, the only one that never collides on retries. Note: the "simple order number" type has no random component, so it is incompatible with subscription retries by design and should not be used when subscriptions are active.
Decryption key:
WooCommerce RedSys Gateway v31.0.3
*** Redsys Gateway Change Log ***
2026.06.27 - version 31.0.3
* SECURITY: Removed a notification signature-bypass that could let an anonymous request mark an order as paid when the SHA-256 secret was left empty/misconfigured. The Redsys IPN listener (public wc-api endpoint) had a legacy fallback that, when no secret was configured, accepted a notification solely because the posted Ds_MerchantCode matched the merchant FUC - a public, non-secret value an attacker can supply. That merchant-code-only acceptance has been removed from every gateway (Redirection, Bizum, Bizum InSite, Google Pay checkout and redirection, Apple Pay, PayGold, Direct Debit, MasterPass and Bank Transfer): when there is no secret to verify the HMAC, the request now fails closed (HTTP rejection) instead of being trusted. In addition, the shared verification routine (WooRedsysAPI::verify_signature_notif) now returns false whenever the merchant key or the received signature is empty, so neither check_ipn_request_is_valid() nor successful_request() can complete a payment on an attacker-computable empty-key HMAC. InSite already required a valid signature (no merchant-code fallback) and Inespay is unaffected (it matches orders by its own payin id). Real stores are unaffected because a configured secret is mandatory to take payments in the first place.
* NEW: "Apps and Plugins" section under Redsys Advanced -> Redsys Advanced Settings. A read-only landing page that showcases the native macOS management app (with download, requirements and "coming soon" platforms) and lists the rest of the free and premium plugins, websites and portals, Claude skills and developer profiles by José Conti, each grouped by type with a link. Every list is filterable (redsys_apps_plugins_mac_app, redsys_apps_plugins_free, redsys_apps_plugins_premium, redsys_apps_plugins_webs, redsys_apps_plugins_skills, redsys_apps_plugins_profiles).
* FIX: Bizum notifications were rejected with a signature verification error, leaving the order unpaid even though the payment had been authorized at Redsys. The merchant key and the order number were correct (the request signature matched perfectly), but the notification signature is an HMAC computed over the Ds_MerchantParameters string exactly as received, and Bizum notifications arrive with the trailing base64 "=" padding stripped while Redsys signs over the canonically padded value, so the locally computed HMAC never matched. The shared notification routine (create_merchant_signature_notif in WooRedsysAPI) now re-pads the payload to a multiple of four before hashing, and the verification (verify_signature_notif) now compares both signatures ignoring the trailing "=" padding (which carries no entropy, so the comparison stays constant-time). Card payloads are already canonical and are left untouched, so every other gateway keeps working unchanged. This routine is shared by all notification handlers (Redirection, Bizum, InSite, PayGold, Google Pay, Apple Pay, Direct Debit, Bank Transfer and the REST/A2A clients).
* FIX: Card and wallet notifications could be rejected with a "signature mismatch", so the customer returning to the thank-you page (and the server-to-server IPN) failed to mark the order as paid until a later IPN retry happened to succeed; refunds and PayGold links paid later could stay unconfirmed. Two padding issues are involved: besides the Bizum payload padding above, Redsys delivers the notification signature (Ds_Signature) in URL-safe base64 with the trailing "=" stripped, while the locally computed signature keeps it - so a strict comparison fails for ordinary card payments too. The padding-tolerant comparison lives in verify_signature_notif(), but most handlers were still comparing the signature inline with a strict hash_equals()/!== that re-introduced the sensitivity. Every handler now delegates to verify_signature_notif(), so the fix reaches all of them: card Redirection (both IPN validators and the capture/refund REST-SOAP response checks), Bizum, Bizum InSite, InSite (IPN, successful_request and the two REST-response validators), PayGold, Google Pay (checkout and redirection), Apple Pay, Direct Debit, Bank Transfer, MasterPass and the InSite REST client. Regression introduced when the per-gateway signature checks were unified onto verify_signature_notif() with a strict, padding-sensitive comparison.
* FIX: Bizum notifications on multi-currency / dual-terminal stores (those routing each order to a different terminal through the bizum_modify_data_to_send filter or a conditional rule) now resolve the real per-order signing key before verifying the signature (the customer-adjusted settings key, the transient saved when the payment form was generated, or the _redsys_secretsha256 order meta), and an unverifiable notification is rejected with HTTP 400.
* FIX: InSite card payments that required a 3DS challenge showed a blank verification screen in Safari (iPhone/Mac), so the customer could not enter the SMS code/PIN and the payment failed (the same flow worked in Chrome). The challenge itself was already a full-page, top-level navigation, but before it the plugin redirected the browser to the issuer's 3DS Method URL (threeDSMethodURL) to fingerprint the browser, and Safari's Intelligent Tracking Prevention blocks the third-party cookies that step needs, leaving a blank ACS page (symptom: the ACS URL arrives with ";jsessionidpa=" because the cookies are not flowing). The 3DS Method browser step is optional, so the plugin no longer redirects the browser to threeDSMethodURL: it always sends threeDSCompInd = 'N' and continues straight to authentication. Applied to every InSite flow - new card and saved card (one-click/token), on both block and classic (shortcode) checkouts - and to the Redirection gateway's REST/token flows (pay_with_token_c, receipt_page and successful_request), since the same blank screen could appear when charging a saved-card token.
* FIX: When an InSite card payment failed because a required checkout field was missing or its data did not match (for example an empty surname produced a "signature mismatch"), the error message blamed the card ("...enter your card details again"), so customers thought their card had been rejected and abandoned the order. The message is now neutral and points to the checkout fields first: it asks the customer to check that all the checkout fields (name, surname, address, etc.) and the card details are filled in correctly before trying again. Applied to both the classic and block (Blocks) checkouts.
* FIX: Refunds and delayed payments of orders with large order IDs (the "1 billion bug" already fixed for instant checkout) were recorded against the wrong order, or not recorded at all. The Redsys notification (IPN) recovers the WooCommerce order ID from the order number through clean_order_number(), which first looks up a transient saved when the order number was generated and otherwise fell back to a substr/ltrim heuristic that drops the high-order digits of IDs with 10 or more digits. That transient has a 1h TTL, so the fallback was hit whenever the notification arrives more than an hour after the order number was generated: every refund (processed days or weeks later) and PayGold payment links (paid by the customer later), among others. Three changes make this robust for every payment method: (1) the shared refund routine (ask_for_refund) now re-saves the order-number to real-order-ID mapping at refund time with a 24h TTL; (2) clean_order_number() now, when the transient is gone, reverse-looks up the order by the persisted order-number meta (_payment_order_number_redsys / _redsys_transaction_id2) before ever using the lossy heuristic; and (3) PayGold now persists the order number to meta when the link is created, so a link paid much later still resolves to the exact order. Applies to every gateway (Redirection, InSite, Bizum, Bizum InSite, Google Pay, Apple Pay, PayGold and Direct Debit). Inespay is unaffected (it matches orders by its own payin id).
* DEV: Removed the noisy debug console.log output from the production (minified) frontend scripts (Apple Pay, Google Pay, capture-order-id and the express-checkout modals). The Apple Pay express script in particular logged on every DOM change (it watches the whole document for its button), which flooded the browser console on the Blocks checkout. The minified files now strip console.log/console.warn/console.info/console.debug while keeping console.error; the un-minified sources are unchanged for development.
* FIX: InSite card payments on the block-based (Blocks) checkout failed the FIRST time with "msg18" (the customer saw "check that the checkout/card fields are filled in") and only worked on the second attempt. The Redsys InSite SDK requires the page to send a "domain" message to the card iframe so Redsys can validate the merchant; the SDK does this through an inline onload="setMerchantDomain(0)" on the iframe. The block script overwrote that handler with its own iframe.onload (used to size the iframe) right after the first render, so the merchant domain was never sent and Redsys rejected the tokenisation with msg18 ("incorrect validation by the commerce"). On the automatic form refresh the overwrite did not run, so the second attempt worked. The plugin now calls setMerchantDomain explicitly after building the form (as the SDK's own pay-button integration does) and no longer overwrites the iframe onload, so the first attempt works.
* FIX/DEV: InSite Blocks checkout - made the Redsys postMessage handling more robust and added end-to-end diagnostics. The handler now accepts messages from any Redsys subdomain (sis.redsys.es, sis-t.redsys.es, sis-d.redsys.es) instead of requiring an exact host/port match (Redsys posts from more than one host), removes any listener left by a previous render so a single token cannot trigger multiple submissions, and clears the token/error fields after reading them so a stale re-fire cannot resend. When InSite debug logging is enabled, the whole client-side tokenisation step (order number, Redsys postMessage, token/error code, save and place-order) is mirrored into the "insite" WooCommerce log, so first-attempt failures that never reach PHP can be diagnosed.
* FIX: InSite card payments on the block-based (Blocks) checkout were rejected by Redsys with SIS0574 ("EMV3DS authentication operation rejected, browserUserAgent not indicated"): the 3DS browser fingerprint (user agent, screen size, language, colour depth, timezone) never reached the order, because the hook that normally copies it onto the order (woocommerce_checkout_create_order) does not run on the Store API (Blocks) checkout. The InSite Blocks form now collects the fingerprint and sends it together with the operation token, and it is written onto the real order (next to the token) before process_payment runs, so the EMV3DS authentication has the data it needs.
* FIX: InSite card payments on the block-based (Blocks) checkout were rejected with an "error code without token" (shown to the customer as "check that the checkout/card fields are filled in"), so the card could not even be tokenised after a few attempts. Because the order does not exist yet on the Blocks checkout (order id 0), the prepared Redsys order number was generated from id 0, which produced an almost constant value - only ~999 possible numbers, all ending in nine zeros - and Redsys rejects a reused order number ("pedido repetido", SIS0051). When the draft order id is not yet available, the InSite Blocks form now uses the same temporary order number as the InSite shortcode checkout (create_checkout_insite_number: always starts with 1, globally unique through a shared incremental counter), so it never collides; when the draft order id is available, the Redsys number is built from it. The number is re-linked to the real order id when the order is placed.
* FIX: InSite card payments on the block-based (Blocks) checkout failed: the customer saw a misleading "check that the checkout/card fields are filled in" error and the order was never paid (the browser console showed a 404 on the save_order_data request). The cause is that current WooCommerce no longer creates the order until the customer presses "Place order" - during card entry the Blocks checkout store returns order id 0 - so the InSite operation token (idOper) and the prepared Redsys order number could not be persisted: the previous flow posted them to a REST route (save_order_data) that tried to attach them to order 0 and returned "Invalid order" (404), and the generated order number was mapped to order 0 (so even a later notification could not find the order). Now, when the card is tokenised, the token and the prepared order number are stored in the WooCommerce session via admin-ajax (the WC session is not available on custom REST routes, which is why the prior REST approach could not use it), and they are moved onto the real order while WooCommerce is creating it from the checkout request (woocommerce_store_api_checkout_update_order_from_request), before process_payment runs, so process_payment_block() finds _insite_token and _payment_order_number_redsys as it does on the classic checkout. The order-number transient is also re-mapped to the real order id so the notification (IPN) resolves the order. The browser-fingerprint (3DS) data already used this same session route. The classic/shortcode checkout is unaffected.
Decryption key:
WooCommerce RedSys Gateway v31.0.2
Version 31.0.2Released on 2026.06.16
- The redsys_modify_data_to_send filter now receives 'context' => 'add_payment_method' and 'user_id' in the data array for the "Add payment method" flow, so custom snippets and conditional rules can route the tokenization to the right terminal (terminal + SHA256) without relying on an order that does not exist in this flow.
- Adding a card from My Account ("Add payment method") on multicurrency stores could be rejected by Redsys with a currency error. The request was sent with the customer's session currency (e.g. ARS, 32) but the default terminal, which is configured for another currency (e.g. EUR, 978). Card tokenization is a zero-amount operation with no order behind it, so if no filter or conditional rule routes the request to another terminal, the store base currency is now sent, always matching the default terminal configuration.
- Adding a card from My Account (or via the profile email link) always registered the card at Redsys as one-click (DS_MERCHANT_COF_TYPE 'C'), even when the customer selected the subscriptions option. The token type was read from the wrong internal key, so 'R' was never sent. The token was stored correctly as R in WooCommerce, but the COF agreement was created as C at Redsys, which could cause some issuers to decline later subscription renewals (MIT) made with those tokens. Cards added with the subscriptions option now correctly send DS_MERCHANT_COF_TYPE 'R'. Tokens created while the bug was present cannot be reclassified; if a renewal is declined, ask the customer to re-add the card.
- Payments made with a saved card (token R) and subscription renewals did not honor the preauthorization settings. With "Preauthorize all orders" enabled (or a product marked for preauthorization), the charge was executed as a regular sale (type 0) but the order was still marked as "Preauthorized", so confirming the preauthorization later failed at Redsys with SIS0059 ("No operation exists on which to perform the confirmation"). Both flows now send a real type 1 preauthorization that can be confirmed later, and an order is only marked as "Preauthorized" when a real preauthorization was executed. This also enables preauthorized subscription renewals (for example goods sold by weight, where each renewal is adjusted before the final charge).
- Updated all translations.
- The merchant SHA-256 secret key is no longer written in plain text to the WooCommerce debug logs. All debug entries now mask the key, showing only its last 4 characters, via the new WCRed()->mask_secret() helper. Applied across all gateways (Redirection, InSite, Bizum, Google Pay, Apple Pay, PayGold, Direct Debit and the Blocks support classes).
- Redsys notification (IPN) signatures are now verified with hash_equals() (constant-time comparison) in all notification handlers, unifying them with the verification already used by InSite and the REST client. Hardening against timing attacks.
- The single-token delete AJAX handler in the tokens management screen now requires the manage_woocommerce capability in addition to the nonce, matching the bulk-delete handler.
WooCommerce RedSys Gateway v31.0.1
Versione 31.0.1Released on 2026.06.09
- Bizum on the payment page (Bizum InSite) did not send the description to Redsys. The actual charge from the modal is made through the REST API (trataPeticionREST), and that request did not include the DS_MERCHANT_PRODUCTDESCRIPTION parameter, so the configured "Redsys Description" (for example "Order ID") reached the Redsys panel empty. The description is now computed from the selected setting and sent in the REST request.
- The countdown in the Bizum payment-page modal showed 7 minutes. It now correctly shows 5 minutes, and the server-side time control that redirects to the checkout has been adjusted accordingly (60 iterations * 5 seconds = 5 minutes).
WooCommerce RedSys Gateway v30.4.1
Version 30.4.1Released on 2026.05.05
=
- "Redsys email to customer" toggle in Redsys Advanced Settings → General to control whether DS_MERCHANT_EMAIL_TITULAR is sent to Redsys. When enabled and the Redsys terminal is configured to notify customers, Redsys sends its own purchase confirmation email to the buyer. Disabled by default — WooCommerce already sends its own order email, so existing installations stop forwarding the customer email to Redsys after the update. Applied to both Redsys Redirection and InSite gateways (classic and Blocks checkouts).
- Apple Pay Express button on the product page failed to open the payment sheet on iOS Safari mobile when the Express custom fields feature was enabled. The pre-payment AJAX call (modal lookup or modal save) ran between the click handler and ApplePaySession.begin(), invalidating the iOS user-activation gesture so Safari silently aborted the session. The button still worked on desktop because desktop Safari is more permissive about gesture propagation.
- Inline Express custom fields on the product page. When the feature is enabled and there are fields to collect, the form is now rendered above the Apple Pay / Google Pay buttons instead of in a post-click modal, with debounced auto-save to session. The click handler validates locally and starts ApplePaySession.begin() synchronously, preserving the iOS user gesture.
- Express custom fields modal AJAX no longer fires when there are no fields to collect on the current page. The product page now precomputes whether any classic or Blocks-registered additional fields exist and disables the modal lookup entirely when the field set is empty, avoiding the gesture-breaking AJAX even on pages where the feature is enabled but no fields apply.
- Inline Express custom fields on the product page now try both Blocks and Classic contexts when reading additional fields, so fields registered through the Blocks API are also rendered on classic product pages.
- Inespay periodic mandate now sends the recurring amount of the subscription instead of the parent order total. The gateway reads the recurring price from WooCommerce Subscriptions, SUMO Subscriptions, YITH WooCommerce Subscriptions, Subscriptions for WooCommerce (WP Swings) and Advanced Subscriptions for WooCommerce, and falls back to the order total only when no subscription amount can be detected. The order note created on mandate creation now includes the recurring amount that was actually sent to Inespay.
- Advanced Subscriptions for WooCommerce (ASWC) support in Inespay — the gateway detects the subscription id from order meta (aswc_subscription) and reads frequency, next payment date, end date and recurring amount via aswc_get_meta_data() to build the periodic mandate.
- Inespay return handler now keeps the intermediate "Creating the mandate…" screen visible for a few seconds even when the periodic mandate link is already known on first load, so customers can read what is happening before being redirected back to Inespay to authorize the recurring mandate.
- Limited Inespay and Google Pay Redirection gateway icons to the same maximum size as Google Pay (max-width 110px, max-height 40px) in the classic checkout, preventing oversized logos when the bank-supplied image is too large.
- PHP warnings "Undefined variable $ship_address_usage / $ship_address_usage_ind" in class-wc-gateway-redsys-psd2.php when a guest customer (not logged in and no user id) checked out with a shipping address. Both variables were only initialized inside the logged-in branch but read in the outer block; they now default to first-use today, matching the existing else-branch behavior.
For activation, use this activator. Exclusively for Babiato.tech members.
https://babiato.tech/free-resources/woo-plugins-activator-activate-all-woo-products.42357/
Decryption key:
WooCommerce RedSys Gateway v30.4.0
=
- Subscriptions section in Redsys Advanced settings to configure credentials and behavior for subscription renewal payments.
- [High]: Added missing cryptographic signature verification in successful_request() for 9 payment gateways: Apple Pay, Bizum Checkout, Bizum Redirect, Google Pay Checkout, Google Pay Redirect, Direct Debit, MasterPass, PayGold, and Bank Transfer. Without this check, payment notifications could be forged to complete orders without actual payment.
- SUMO Subscriptions renewal orders failed because sumo_save_subscription_payment_info() was called with 'payment_method' => 'insite' instead of 'redsys' in the redirect gateway callback. This caused SUMO to set the wrong payment method on renewal orders, triggering the wrong gateway filter and using incorrect credentials.
- YITH WooCommerce Subscriptions were being cancelled prematurely on failed renewals for the Redsys Redirect, InSite, Apple Pay Checkout and Google Pay Checkout gateways. The "no token / expired card" path in doing_scheduled_subscription_payment() (class-wc-gateway-redsys.php and class-wc-gateway-insite-redsys.php) called ywsbs_register_failed_payment() and then returned false, causing the YITH wrapper renew_yith_subscription() to call it again. The double increment of failed_attempts cancelled subscriptions after 1–2 real failures instead of the configured 3 retries. Apple Pay and Google Pay Checkout are also fixed since they delegate to the main Redsys handler.
- version 30.3.1
- [Medium]: Fixed an authenticated account takeover vulnerability that could allow an attacker to assume any user account, including administrators.
- [Low]: Fixed unauthenticated access to order status and user data.
- PayGold link generated from admin order metabox was never saved correctly due to an impossible response code condition in send_paygold_link(). The function now uses the same validation logic as the checkout flow (response code 9998).
- Fixed undefined $description variable in paygold_metabox_save() when sending a PayGold link from the order edit screen.
- Custom notification domain (redsys_url_notify) was broken by check_url() prepending home_url() to URLs that already had a different domain. check_url() now detects absolute URLs and preserves them as-is.
- get_notify_home_url() now automatically adds https:// when the custom notification domain is saved without a scheme.
- PHP 8.3+ compatibility — Fixed deprecated warnings for passing null/false to string functions (trim, strlen) from get_option() calls in get_txnid(), get_token_type(), and connect_standard_imap().
- PHP 8.3+ compatibility — Fixed add_submenu_page(null,...) in setup guide causing strpos()/str_replace() deprecation warnings
For activation, use this activator. Exclusively for Babiato.tech members.
https://babiato.tech/free-resources/woo-plugins-activator-activate-all-woo-products.42357/
WooCommerce RedSys Gateway v30.3.1
Version 30.3.1Released on 2026.03.20
- [Medium]: Fixed an authenticated account takeover vulnerability that could allow an attacker to assume any user account, including administrators.
- [Low]: Fixed unauthenticated access to order status and user data.
- PayGold link generated from admin order metabox was never saved correctly due to an impossible response code condition in send_paygold_link(). The function now uses the same validation logic as the checkout flow (response code 9998).
- Fixed undefined $description variable in paygold_metabox_save() when sending a PayGold link from the order edit screen.
- Custom notification domain (redsys_url_notify) was broken by check_url() prepending home_url() to URLs that already had a different domain. check_url() now detects absolute URLs and preserves them as-is.
- get_notify_home_url() now automatically adds https:// when the custom notification domain is saved without a scheme.
- PHP 8.3+ compatibility — Fixed deprecated warnings for passing null/false to string functions (trim, strlen) from get_option() calls in get_txnid(), get_token_type(), and connect_standard_imap().
- PHP 8.3+ compatibility — Fixed add_submenu_page(null,...) in setup guide causing strpos()/str_replace() deprecation warnings.
=
For activation, use this activator. Exclusively for Babiato.tech members.
https://babiato.tech/free-resources/woo-plugins-activator-activate-all-woo-products.42357/
Decryption key:
WooCommerce RedSys Gateway v30.3.0
Version 30.3.0Released on 2026.03.07
- Virtual / Downloadable Products order status override in Advanced Settings. When all products in an order are virtual or downloadable, the order status can be automatically set to Completed instead of Processing.
- Redsys response code 0115 (card cancelled or account closed) now automatically deletes the stored card token, notifies the customer with instructions to add a new payment method (My account > Payment Methods), and notifies the admin.
- Admin email notification when a customer's credit card is automatically removed due to Redsys hard-decline response codes (0115, 0172, 0173).
- Improved customer email when a card is removed — now includes the last 4 digits of the card, the error code, and a direct link to add a new payment method.
- COF_INI (Credential on File initial) flag is now saved to order meta (_redsys_cof_ini) for all COF transaction types (R and C), preventing duplicate token creation when COF_INI=N.
- Conditional Rules test mode now correctly applies to the Redsys gateway URL. Previously, orders with conditional rules overriding test mode still used the default gateway URL.
- Fixed duplicate token creation when customer already has a saved card and COF_INI=N is sent to Redsys.
- Fixed undefined array key warnings in save_field_update_order_meta() when conditional rules data is incomplete.
- Fixed $redsys->debug reference using wrong variable in preauthorization logging (now uses $this->debug).
- Fixed sanitize_text_field applied before substr for HTTP_ACCEPT_LANGUAGE in Google Pay and Apple Pay Checkout, ensuring correct sanitization order.
- Google Pay Checkout now ensures WooCommerce transactional emails are initialized before calling payment_complete() in payment callbacks.