WP Manifestindependent plugin directory
manifest / ecommerce / paytodaywooreleases

PayToday Payment Gateway for WooCommerce WP Registry grade D. High-severity findings · 6 findingsWP RegistryHigh-severity findings · 6 findingsOpen the reportD

Releases repo for the PayToday Woocommerce payment gateway plugin for WordPress.

★ 0stars
69release downloads
≈10active sites
v1.1.3latest · 7mo ago

Install

Download paytoday_woo_v1.1.3.zip From the v1.1.3 release on GitHub, Mar 2, 2026

Upload it under Plugins → Add New Plugin → Upload Plugin, then activate.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/helloadaire/paytodaywooreleases/releases/download/v1.1.3/paytoday_woo_v1.1.3.zip
Updates itself. It ships its own updater (Plugin Update Checker), so new versions appear under Dashboard → Updates.

PayToday WooCommerce Plugin

A secure and easy-to-use payment gateway plugin that integrates PayToday payments with WooCommerce stores.

Features

  • Seamless Integration: Easy integration with WooCommerce checkout process
  • Secure Payments: Process payments securely through PayToday's payment gateway
  • Sandbox Mode: Test payments in sandbox environment before going live
  • Order Management: Automatic order status updates based on payment results
  • Custom Return URLs: Configurable return URLs for successful payments
  • WordPress Admin Integration: Full integration with WordPress admin dashboard

Requirements

  • WordPress: 5.0 or higher
  • WooCommerce: 3.0 or higher
  • PHP: 7.0 or higher
  • PayToday Account: Active PayToday merchant account with API credentials

Installation

Method 1: WordPress Admin Dashboard

  1. Download the latest release from the Releases page
  2. Log in to your WordPress admin dashboard
  3. Navigate to Plugins > Add New > Upload Plugin
  4. Choose the downloaded zip file and click Install Now
  5. Activate the plugin after installation

Method 2: Manual Installation

  1. Download and extract the plugin files
  2. Upload the paytoday_woo folder to /wp-content/plugins/
  3. Activate the plugin through the WordPress admin Plugins menu

Method 3: FTP Upload

  1. Download and extract the plugin files
  2. Upload the entire paytoday_woo folder to your /wp-content/plugins/ directory via FTP
  3. Activate the plugin in your WordPress admin panel

Configuration

  1. Navigate to WooCommerce > Settings > Payments
  2. Find "PayToday" in the payment methods list and click Manage
  3. Configure the following settings:

Required Settings

Setting Description
Enable/Disable Enable PayToday payment gateway
Title Payment method title shown to customers
Description Payment method description shown at checkout
Shop Key Your PayToday shop key (from PayToday dashboard)
Shop Handle Your PayToday shop handle
Private Key Your PayToday private key
Return URL URL where customers return after payment

Optional Settings

Setting Description Default
Sandbox Mode Enable for testing payments Disabled
Service URL PayToday service endpoint Auto-configured

Getting PayToday API Credentials

  1. Sign up for a PayToday merchant account at PayToday
  2. Log in to your PayToday dashboard
  3. Navigate to the 'API Keys' or 'Developer' section
  4. Generate or copy your:
    • Shop Key
    • Shop Handle
    • Private Key

Payment Flow

  1. Customer selects PayToday as payment method at checkout
  2. Customer is redirected to PayToday's secure payment page
  3. Customer completes payment on PayToday platform
  4. Customer is redirected back to your store
  5. Order status is automatically updated based on payment result

Testing

Sandbox Mode

  1. Enable "Sandbox Mode" in the plugin settings
  2. Use test credentials provided by PayToday
  3. Process test transactions to verify integration
  4. Disable sandbox mode when ready for live payments

Changelog

Version 1.1.0

  • Updated plugin structure and documentation
  • Improved PayToday payment gateway integration
  • Enhanced error handling and logging
  • Better WordPress coding standards compliance

Version 1.0.0

  • Initial release with PayToday plugin integration
  • Supports PayToday payments for WooCommerce
  • Basic payment processing and order management

Troubleshooting

Common Issues

Payment not processing:

  • Verify API credentials are correct
  • Check if sandbox mode settings match your environment
  • Ensure return URL is accessible

Orders not updating:

  • Verify webhook URLs are configured correctly
  • Check WordPress and server logs for errors
  • Ensure proper SSL configuration

Plugin not appearing:

  • Verify WooCommerce is active and up to date
  • Check for plugin conflicts
  • Review PHP error logs

Support

License

This plugin is licensed under the GNU General Public License v3.0. See the LICENSE file for details.

Contributing

We welcome contributions! Please feel free to submit issues and pull requests.

Security

If you discover any security-related issues, please email security@paytoday.com instead of using the issue tracker.


Made by the PayToday Team

Releases

4 releases. Each count is every asset in that release; expand a row for the breakdown.

Tag
Published
Assets
Downloads
v1.1.3 latest
Mar 2, 2026 7mo ago
paytoday_woo_v1.1.3.zip
22
Feb 3, 2026 8mo ago
paytoday_woo_v1.1.2.zip
10
Sep 17, 2025 1 year ago
paytoday_woo_v1.1.1.zip
35
Sep 17, 2025 1 year ago
paytoday_woo_v1.1.zip
2

Active-site estimate ≈10 comes from the median of recent superseded releases. Method.

D grade

Security

PayToday Payment Gateway for WooCommerce 1.1.3 · audited by WP Registry

High-severity findings.

4 high 2 medium
Audited release
1.1.3
Findings
6
Worst severity
high
Content hash
c97c63092f25f81cd1b1053f…

Findings

  • high Unauthenticated wc-api return leaks WooCommerce order keys and customer PII

    information_disclosure

    woocommerce_api_paytoday_return is public (GET /wc-api/paytoday_return or ?wc-api=paytoday_return). handle_paytoday_return() takes only sequential invoice_number (absint of GET; this is the WooCommerce order id on a default install), loads that order, and on success, pending/unknown, or even a status-API error redirects with wp_safe_redirect( $this->get_return_url( $order ) ). WooCommerce's get_return_url() is the order-received permalink plus key=wc_order_*. There is no order-key, HMAC, capability, or nonce check, and 1.1.3's 'verify via PayToday API' change does not bind the request to the payer. An unauthenticated visitor enumerates invoice_number values; any PayToday order that still has _paytoday_payment_token/_paytoday_authorization_token and is not sent down the failed-status branch yields a Location header containing the secret guest key. Opening that URL renders the standard thank-you/order-received template (billing and shipping name, email, phone, address, line items, totals) for another customer. Completed/processing orders take the success branch and leak the same way. Compared with 1.1.2 this no longer blindly payment_complete()s on GET status=success, but the PII disclosure remains fully unauthenticated.

    paytoday-woocommerce.php:1095-1160

    Recommendation

    Put the WooCommerce order key (and a server-side HMAC) on the PayToday return_url and require it before looking up or redirecting. Never send a stranger to get_return_url()/get_checkout_order_received_url() based only on a sequential invoice_number. Treat missing/unknown payment status as a generic checkout redirect, not a thank-you redirect. Rate-limit the endpoint.

  • high Nopriv payment-status AJAX and checkout popup are IDOR on any PayToday order

    missing_capability

    wp_ajax_nopriv_paytoday_check_status shares paytoday_ajax_check_status(). The only gate is wp_verify_nonce($_POST['nonce'], 'paytoday_status_check'); there is no current_user_can, no is_user_logged_in, and no check that the caller owns order_id or holds that order's key. The nonce is not bound to an order id. add_payment_popup_script() is still hooked on wp_footer (the later 'popup disabled' comment does not remove it) and, on any is_checkout() request with ?paytoday_popup=1&order_id={n}, reads _paytoday_payment_url for that id with no ownership check, then prints the payment URL and a guest nonce into inline JS. Sequential order ids plus a public checkout page are enough to find a pending PayToday order, steal its hosted payment URL, and obtain a uid-0 nonce that works for every guest for the nonce tick. POST admin-ajax.php action=paytoday_check_status with any other order_id then: queries PayToday with that order's stored merchant tokens; returns the full decoded JWT as status_data while pending; on success calls payment_complete() and returns get_checkout_order_received_url() (another order-key leak); on failed/cancelled marks the order failed. Same handler is registered for logged-in users, so a customer who placed one PayToday order can harvest every other PayToday order's thank-you URL and gateway payload.

    paytoday-woocommerce.php:1202-1283

    Recommendation

    Require the WooCommerce order key (or a per-order nonce) on both the popup script and the AJAX action; refuse order_ids the current user does not own. Do not register wp_ajax_nopriv unless the payer is a guest of that specific order. Stop returning status_data and get_checkout_order_received_url() to untrusted callers. Remove add_payment_popup_script from wp_footer if the popup flow is unused.

  • high Live PayToday shop_key, shop_handle, and private key shipped as gateway defaults

    hardcoded_credentials

    init_form_fields() sets the Live Shop Key default to f4c5fe648ba0b6ff54716bf627a09c811c6d5fd713e3e74331544b4f6c408c61, Live Shop Handle to 833::b69c2ea2985a, and PayToday Private Key to DvzOMtOpC4215y7ClqpM. WooCommerce WC_Settings_API::get_option() uses those form-field defaults when woocommerce_paytoday_settings has no override, and a merchant who enables the gateway, turns sandbox off, and clicks Save without clearing the pre-filled live fields persists them. create_configuration_intent() POSTs handle+key to the live API (https://admin.today.com.na when sandbox_mode is off), so checkout charges then hit the hardcoded merchant account rather than the store's. The same values are in the public GitHub release, so anyone can impersonate that PayToday shop. paytoday_private_key is loaded onto the gateway object but never used to verify JWTs.

    paytoday-woocommerce.php:317-351

    Recommendation

    Ship empty defaults for all secrets. Rotate the published shop_key, shop_handle, and private key at PayToday. Refuse to process live payments until the merchant has saved non-default credentials. Do not keep unused private-key material in the plugin.

  • high Payment completion trusts unsigned JWTs fetched with TLS verification disabled

    insecure_config

    create_configuration_intent(), create_payment_intent(), and query_payment_intent() all pass sslverify => false to wp_remote_post/wp_remote_get, so the store will accept any certificate for admin.today.com.na / admin.today-ww.net. decode_jwt() splits the token, base64-decodes parts[1], and json_decode()s it with no HMAC/signature check, even though a PayToday Private Key setting exists. handle_paytoday_return, paytoday_ajax_check_status, and check_payment_status then treat data.intent.transaction_status === 'completed'|'success' as gospel and call $order->payment_complete(). An attacker who can MITM the server's outbound HTTPS (shared-host neighbor, rogue DNS, local HTTP proxy, compromised extra hop) can return a forged three-part JWT whose payload marks the order paid without a real PayToday settlement. This is payment-gateway tamper with a network-position requirement, not a unauth HTTP-to-wp-admin bypass.

    paytoday-woocommerce.php:659-693

    Recommendation

    Drop sslverify => false (use the default true). Verify the JWT with PayToday's signing key/HMAC before reading transaction_status. Fail closed on signature or TLS errors instead of calling payment_complete().

  • medium Unauthenticated init endpoint triggers payment status mutation

    missing_auth

    paytoday_manual_status_check is hooked to init with no capability, nonce, or order-key check. Any visitor who requests ?paytoday_manual_check=1&order_id={n} causes manual_check_payment_status() → check_payment_status(), which talks to PayToday with that order's stored tokens and can payment_complete() or update_status('failed'). The handler always echoes 'Manual status check triggered for Order #{id}' when the gateway is registered, so it is a production test probe. Status still follows the PayToday API (this is not the 1.1.2 GET-status spoof), but it is unauthenticated state change plus a cheap order-id oracle and an unauthenticated way to drive outbound merchant-authenticated API calls.

    paytoday-woocommerce.php:1187-1200

    Recommendation

    Remove this probe from production builds, or restrict it to manage_woocommerce with a nonce. Do not echo order ids or success text to anonymous clients.

  • medium Unconditional error_log of shop keys, payment tokens, checkout POST, and all order meta

    information_disclosure

    Debug logging is not gated on WP_DEBUG or the unused gateway 'debug' option (the private log() helper is, but almost every path uses error_log() instead). The constructor logs shop_handle and a shop_key prefix on every gateway init. create_configuration_intent() logs the full JSON body including the live shop key. validate_fields() logs print_r($_POST, true) (checkout PII). paytoday_ajax_check_status() — reachable unauthenticated with a guest nonce — logs print_r(get_post_meta($order_id), true), which includes _paytoday_authorization_token, _paytoday_payment_token, and other order meta for an attacker-chosen id. Those lines land in the PHP error log / wp-content/debug.log, which is commonly web-reachable or shared-host readable and is enough to replay PayToday lookups or stitch with the return-URL PII leak.

    paytoday-woocommerce.php:1214-1229

    Recommendation

    Delete unconditional error_log of secrets and PII. If a debug switch is needed, use the existing $this->log() path, redact tokens/keys, and never dump full $_POST or get_post_meta(). Ensure debug.log is not web-accessible.

WP Registry hashes the installable build and reports on that exact bytes-for-bytes copy. Embargoed findings are withheld until they are disclosed, so a clean verdict means nothing public is outstanding. WP Manifest does not audit code itself.