# Subscription Gateway Capabilities > How WooNooW decides which payment gateways can auto-debit subscription > renewals, and how merchants can override that decision. ## Why this exists Before this system, a subscription renewal would attempt to call `$gateway->process_subscription_renewal_payment($order, $subscription)` if the gateway *happened* to implement that method. That had three problems: 1. **Capability was invisible** — the merchant had no way to see, declare, or override which gateways supported subscription auto-renew. 2. **The default was unsafe** — a gateway without the method silently fell through to manual payment. The system "worked," but the merchant believed auto-debit was happening and customers were surprised when they had to log in and pay manually. 3. **No override was possible** — a merchant running a custom Stripe wrapper that *does* support auto-debit could not declare it, and a merchant using stock Stripe could not opt out. ## What it is now A **per-gateway capability table** that the merchant (or a WooNooW defaults policy) controls explicitly. The system consults the table at renewal time and decides whether to attempt auto-debit or fall through to manual. PHP method existence alone is no longer authoritative. ### Storage ``` wp_option('woonoow_gateway_subscription_capabilities', [ '' => [ 'subscription_auto_renew' => bool ], ... ]) ``` ### Decision flow For a renewal where the subscription's stored `payment_method` is ``: 1. If the site-level `force_manual_renewal` setting is on, fall through to manual. (Kill switch — see below.) 2. Look up `` in the merged capability map (defaults < stored overrides < `woonoow_gateway_subscription_capabilities` filter). 3. If the lookup returns `subscription_auto_renew = true`, attempt auto-debit via the gateway's `process_subscription_renewal_payment` method. On success, run `handle_renewal_success`. On failure, fall through to manual and notify the customer. 4. If the lookup is missing or false, skip auto-debit entirely, create a manual renewal order, and send the `renewal_payment_due` email. The decision is made by `WooNooW\Modules\Subscription\GatewayCapabilities::should_attempt_auto_renew($gateway_id)`. ## Built-in defaults | Gateway ID | Default auto-renew | Why | |---------------------|--------------------|-----| | `paypal` | true | PayPal Reference Transactions supports recurring | | `stripe` | true | With a WooNooW Stripe adapter implementing the contract | | `stripe_cc` | true | Alias for stripe credit card | | `stripe_sepa` | true | SEPA Direct Debit supports recurring | | `dodo` | true | Dodo Payments supports recurring subscriptions | | `tripay` | false | VA/QRIS/e-wallet — no recurring | | `midtrans` | false | VA/QRIS/e-wallet — no recurring | | `xendit` | false | Indonesian credit card requires customer re-auth (BI/PCI-DSS) | | `doku` | false | Indonesian manual-only | | `duitku` | false | Indonesian manual-only | | `cheque`, `bacs`, `cod` | false | Offline / no auto-debit | | **any unknown** | false | Safe default | The default for any unknown gateway is `false`. A merchant who has a custom adapter for an unknown gateway can flip the toggle in the admin UI (Settings → Modules → Subscription → Gateway Auto-Renew Capabilities). ## Why per-gateway, not site-level "billing mode" A site-level "manual vs auto" toggle asks the merchant to understand a concept that does not exist in their head. The merchant thinks in **payment gateways**. A checkbox next to each gateway in the admin is data the merchant already knows. Additionally: - Different merchants use different gateways. A site-level toggle forces a single behavior even when the merchant runs two gateways (one auto-capable, one not) for different products. - The capability is a property of the **integration**, not of the **store**. The merchant did not choose "manual mode" — they chose Tripay, and Tripay is a manual gateway. - The capability can change as WooNooW ships new adapters. A per-gateway table updates as adapters ship. ## Site-level kill switch There is one site-level override: - `force_manual_renewal` (default **off**) — when on, all renewals are manual regardless of the per-gateway capability table. Useful as a kill switch during an incident or regulatory change. This lives in the standard module settings form (Settings → Modules → Subscription) and is not on the gateway capability matrix screen. ## Admin UI `Settings → Modules → Subscription` now has two sections: 1. **Configuration** — the standard 12-field schema (button text, pause/cancel permissions, retry policy, kill switch, etc.). Driven by the existing `SubscriptionSettings` schema. 2. **Gateway Auto-Renew Capabilities** — one row per WooCommerce payment gateway with a per-gateway toggle. Built dynamically from `WC()->payment_gateways()`. The merchant can flip a gateway on or off, and the change is persisted via `POST /woonoow/v1/subscriptions/gateway-capabilities`. When the kill switch is on, every row shows a "Forced manual" badge and the per-gateway toggles are disabled. ## Customer messaging The order-pay response (`/checkout/order/{id}`) and the subscription detail response both include `gateway_supports_auto_renew`. The customer-spa OrderPay page renders a different callout for manual gateways (amber) versus auto-renew gateways (blue): - **Auto-renew:** "Your subscription will renew automatically on the date shown below." - **Manual:** "Your saved payment method cannot be charged automatically for this gateway, so please complete the payment to continue your subscription." This ensures the customer is never promised auto-debit that the system will not deliver. ## Extending the table (for gateway adapter authors) A gateway adapter or third-party plugin can extend the capability table at boot time via the `woonoow_gateway_subscription_capabilities` filter: ```php add_filter('woonoow_gateway_subscription_capabilities', function ($caps) { $caps['my_custom_stripe'] = ['subscription_auto_renew' => true]; return $caps; }); ``` The adapter is then responsible for implementing `process_subscription_renewal_payment(WC_Order $order, $subscription)` on its gateway class. If the method does not exist, the capability declaration is meaningless — the renewal will fall through to manual. ## Migration / no migration This is a behavioral improvement, not a schema change. Existing subscriptions keep their `payment_method` value. The capability table is consulted at renewal time, not retroactively. If a merchant upgrades WooNooW and previously relied on PHP method existence alone, the renewal will continue to work — but the merchant will now see the capability matrix and can confirm or override each gateway.