Reference & Troubleshooting
Technical specs, API endpoints, webhook events, and troubleshooting. Also see the FAQ for explanations of non-obvious behaviour and edge cases.
System Requirements
- WordPress 6.0+
- PHP 8.1+
- Gravity Forms 2.6+
- GoCardless account (sandbox or live)
Supported Currencies & Schemes
WPdirectdebit supports the same eight currencies GoCardless itself supports — each maps to exactly one Direct Debit scheme:
| Currency | Scheme | Region |
|---|---|---|
| GBP | Bacs | UK |
| EUR | SEPA Core | Eurozone |
| USD | ACH | USA |
| AUD | BECS | Australia |
| NZD | BECS NZ | New Zealand |
| CAD | PAD | Canada |
| SEK | Autogiro | Sweden |
| DKK | Betalingsservice | Denmark |
There is no NOK (Norwegian Krone) scheme — GoCardless doesn't offer a Direct Debit product for NOK, so it isn't offered as a currency here either. (Norwegian customers can still pay in EUR via SEPA.)
Two currencies also support an instant payment option alongside Direct Debit, for one-off payments only:
| Currency | Instant scheme | Availability |
|---|---|---|
| GBP | Faster Payments ("Instant Bank Pay") | GB only |
| EUR | SEPA Instant ("Instant Bank Pay") | DE only |
| AUD | PayTo | AU only |
Availability is gated by your site's Default country setting (Settings page) against GoCardless's current instant-payments country coverage — not by the customer's own location. See the Technical FAQ for why that trips people up.
Payment Type Specifications
Subscription Intervals
| Frequency | Min | Max |
|---|---|---|
| Weekly | 1 | 104 |
| Monthly | 1 | 24 |
| Yearly | 1 | 1 |
Monthly supports any value from 1–24, not just 1 — "every 3 months" (quarterly) and "every 6 months" (semi-annual) are both valid. Yearly is always exactly 1; GoCardless has no concept of "every 2 years" as a single subscription.
Subscription Validation Rules
- Day of month: 1–28 only. This is a hard GoCardless API limit, not a plugin choice — there's no rolling or rounding for the 29th–31st because those values are never accepted in the first place.
- BACS is handled differently: every other scheme sends
day_of_month/monthdirectly to GoCardless. BACS doesn't support those parameters at all, so the plugin instead computes a concretestart_dateand lets the subscription recur forward from there. - Free trial vs. day/month preference: mutually exclusive. Setting a trial delay (
trial_days) determines the start date by itself; a day/month preference is a separate way of pinning it. The two are never combined. - Month + day combination: for yearly subscriptions, month and day must be supplied together — GoCardless rejects
monthsent alone. - ASAP start date: payment goes out the next business day GoCardless can collect.
- Fixed start date: merchant or customer can specify an exact date; the plugin clamps it forward if it falls before GoCardless's earliest possible charge date rather than letting the request fail.
Entry Metadata
Every form entry that reaches GoCardless stores some subset of the following Gravity Forms entry meta keys:
| Key | Value |
|---|---|
wpdd_mandate_id |
GoCardless Direct Debit mandate ID |
wpdd_mandate_scheme |
Scheme of that mandate (bacs, sepa_core, etc.) |
wpdd_subscription_id |
GoCardless subscription ID |
wpdd_subscription_amount |
Subscription amount, cached for display |
wpdd_subscription_currency |
Subscription currency, cached for display |
wpdd_subscription_pending |
Set while a subscription creation is in flight (webhook fallback path) |
wpdd_subscription_create_failed |
Set if subscription creation failed after the mandate was confirmed |
wpdd_payment_id |
GoCardless payment ID (one-off or upfront fee) |
wpdd_upfront_amount / wpdd_upfront_currency |
Upfront fee amount/currency actually charged |
wpdd_pending_payment_amount / _currency / _description / _reference / _metadata |
Payment details staged before the mandate exists, used by the webhook fallback if the browser redirect never fires |
wpdd_billing_request_id |
GoCardless billing request ID |
wpdd_brf_flow_id |
GoCardless billing request flow ID for the customer's sign-up session |
wpdd_customer_id |
GoCardless customer ID |
wpdd_customer_email |
Stored for mandate-reuse lookups |
wpdd_reuse_mandate |
Set when this entry is reusing an existing customer mandate rather than creating a new one |
wpdd_organisation_id |
GoCardless organisation (creditor) ID the entry was created under |
wpdd_callback_token |
Random token verifying the customer's return from the GoCardless-hosted flow belongs to this entry |
wpdd_success_uri / wpdd_exit_uri |
Stored redirect URLs used to send the customer back to the right place after the GoCardless flow |
wpdd_status |
Current status — see Webhook Events below; a monotonic value, see the Technical FAQ |
wpdd_mode |
sandbox or live |
REST API Endpoints
All endpoints are under /wp-json/wpdirectdebit/v1/. Unless noted, all require the manage_options capability — the sole public, unauthenticated endpoint is /webhook, which is instead protected by HMAC signature verification (see Webhook Events below).
| Endpoint | Methods | Purpose |
|---|---|---|
/home |
GET | Dashboard data: account status, form list, recent sign-ups |
/home/at-a-glance |
GET | Dashboard "At a glance" panel figures |
/oauth/status |
GET | Current connection status |
/oauth/connect-url |
GET | Build the GoCardless OAuth authorisation URL |
/oauth/disconnect |
POST | Disconnect the current mode's GoCardless connection |
/settings |
GET, POST | Read/update plugin settings |
/settings/generate-salt |
GET | Generate a WPDIRECTDEBIT_SALT line to paste into wp-config.php |
/settings/audit-log |
GET | List available monthly audit log CSVs |
/settings/audit-log/{name} |
GET, DELETE | Download or delete a specific audit log CSV |
/settings/audit-log/{name}/preview |
GET | Preview an audit log CSV in the browser |
/settings/log |
GET, DELETE | Read or clear the debug log |
/customers |
GET | List GoCardless customers |
/customers/{id} |
GET, PUT | Customer detail / update |
/customers/{id}/detail |
GET | Combined customer detail view (bank accounts, mandates, payments, subscriptions) |
/customers/{id}/bank-accounts |
GET | Customer's bank accounts |
/customers/{id}/mandates |
GET | Customer's mandates |
/customers/{id}/payments |
GET | Customer's payments |
/customers/{id}/subscriptions |
GET | Customer's subscriptions |
/mandates/{id} |
PUT | Update mandate metadata |
/mandates/{id}/cancel |
POST | Cancel a mandate |
/mandates/{id}/reinstate |
POST | Reinstate a cancelled mandate |
/payments |
GET | List payments (filterable) |
/payments/{id}/cancel |
POST | Cancel a not-yet-submitted payment |
/payments/{id}/refund |
POST | Refund a paid-out payment (subject to the 7-day hold — see the Technical FAQ) |
/payments/{id}/retry |
POST | Retry a failed payment |
/payouts |
GET | List payouts |
/payouts/chart |
GET | Payouts-received chart data for the Dashboard |
/subscriptions |
GET | List subscriptions |
/subscriptions/{id} |
PUT | Edit a subscription (amount, name, reference) |
/subscriptions/{id}/pause |
POST | Pause a subscription |
/subscriptions/{id}/resume |
POST | Resume a paused subscription |
/subscriptions/{id}/cancel |
POST | Cancel a subscription |
/subscriptions/scan-groups |
GET | Scan the connected GoCardless account for existing payment/subscription patterns (powers the Scan page) |
/subscriptions/bulk-count |
GET | Count subscriptions matching a bulk-update filter |
/subscriptions/bulk-collect |
POST | Start a bulk subscription update job |
/subscriptions/bulk-process-chunk |
POST | Process one chunk of a running bulk job |
/subscriptions/bulk-job/{job_id} |
DELETE | Cancel a running bulk job |
/entries |
GET | List Gravity Forms entries with WPDD status/filtering |
/link-generator/pages |
GET | List pages, flagged by whether they embed a given form |
/link-generator/check |
GET | Check whether a form is actually embedded on a chosen page |
/link-generator/generate |
POST | Generate a payment/sign-up link and QR code |
/billing-request-templates |
GET | List GoCardless Billing Request Templates available to import |
/billing-request-templates/{id}/build-form |
POST | Build a Gravity Form from a specific template |
/forms/build |
POST | Build a standalone form (the Build Recurring Payment / Build Payment modal) |
/brf/success |
POST | Billing request flow success callback |
/brf/failure |
POST | Billing request flow failure callback |
/webhook |
POST | GoCardless webhook receiver — public route, HMAC-signature protected |
Webhook Events
Webhook events arrive as resource_type:action (colon-separated — not resource_type.action), and drive both the wpdd_status entry meta and a set of WordPress action hooks other code can attach to. The status system is monotonic — see the Technical FAQ for why a later event doesn't always overwrite an earlier one.
| Event | Fires action hook |
|---|---|
mandates:created |
wpdd_mandate_ready |
mandates:active |
wpdd_mandate_active |
mandates:failed |
wpdd_mandate_cancelled |
mandates:cancelled |
wpdd_mandate_cancelled |
mandates:expired |
— |
mandate_reused |
— |
payments:created |
— |
payments:submitted |
— |
payments:confirmed |
wpdd_payment_confirmed |
payments:paid_out |
wpdd_payment_paid_out |
payments:failed |
wpdd_payment_failed |
payments:failed_retrying (derived — see below) |
— |
payments:retrying (derived — see below) |
— |
payments:cancelled |
— |
payments:charged_back |
— |
payments:resubmission_requested |
— |
subscriptions:created |
wpdd_subscription_created |
subscriptions:finished |
— |
subscriptions:cancelled |
— |
billing_requests:fulfilled |
— |
billing_request_flows:completed |
— |
billing_request_flows:cancelled |
— |
payments:failed_retrying and payments:retrying aren't raw GoCardless event names — the plugin derives them from payments:failed (checking GoCardless's will_attempt_retry flag) and payments:resubmission_requested, so a Success+ retry-in-progress doesn't get treated as a final failure.
Custom code should hook the action hooks above, not read wpdd_status directly — see the Technical FAQ for why.
Sandbox vs. Live
Sandbox:
- Test environment, no real charges
- Its own OAuth connection, access token, and webhook secret — entirely separate from Live
- OAuth connects from any domain (no subscriber-registry check)
Live:
- Real payments, real merchant account
- Its own OAuth connection, access token, and webhook secret
- OAuth ties the connection to your site's registered URL — see the Technical FAQ if you're cloning a live site to a new domain
Important: the Live/Sandbox toggle is site-wide. There's no way to run some forms in sandbox and others live at the same time.
Troubleshooting
Form won't submit
Check:
- All required fields have values.
- Interval is within valid range (weekly 1–104, monthly 1–24, yearly 1).
- Day of month is 1–28, if set.
- Amount is within the transaction limits set in plugin settings.
GoCardless drop-in doesn't appear
Check:
- Form has a WPdirectdebit feed attached.
- Site is connected to GoCardless for the active mode (Settings page).
- Browser console has no JavaScript errors.
Mandate created but subscription didn't
Check:
- Subscription interval is within limits (see above).
- Interval unit is set (weekly, monthly, or yearly).
- The form doesn't combine a free trial with a day/month preference — that combination is disallowed on purpose (see Payment Type Specifications above).
The entry's wpdd_status will read subscription_create_failed if creation was attempted and failed — check the debug log for the underlying GoCardless error.
Webhook not received
Check:
- Webhook URL is correct in the GoCardless dashboard for the active mode.
- The matching webhook secret (Live or Sandbox) is entered in WPDD Settings.
- No WAF, security plugin, or full-page cache is intercepting POST requests to
/wp-json/wpdirectdebit/v1/webhook— see the Technical FAQ for why this is worth checking specifically. - Enable WordPress debug logging (Settings → Diagnostics) to see webhook processing errors.
GoCardless retries a failed webhook delivery multiple times at increasing intervals — check their Support Centre for the current exact schedule.
Customer data not exporting (GDPR)
Check:
- Entry has WPDD metadata (mandate or subscription ID).
- WordPress's Privacy Framework is enabled.
API Integration
For custom integrations:
- GoCardless API documentation: developer.gocardless.com/api-reference
- WPDD uses the gocardless/gocardless-pro PHP SDK
- Webhook signatures are verified via HMAC-SHA256 against the
Webhook-Signatureheader
Common Questions
Q: Can I delete a form without affecting subscriptions?
A: Yes. There are no delete hooks tying Gravity Forms to GoCardless in either direction — subscriptions and mandates keep running exactly as scheduled. You lose the ability to see or manage them from WordPress; cancel them in the GoCardless dashboard (or via WPDD, while the form/entry still exists) if you actually want to stop them.
Q: Can I import forms between sites?
A: Yes, but entry metadata won't transfer — only the form structure imports. Historical entries on the source site won't link to the imported copy.
Q: Can customers edit subscriptions after sign-up?
A: Not through WPDD directly. They need to contact you; you can then edit or cancel via the WPDD dashboard or the GoCardless dashboard.
Q: What happens if my webhook endpoint is down when GoCardless sends an event?
A: GoCardless retries failed deliveries automatically at increasing intervals over several attempts. Once your endpoint is reachable again, queued events are delivered. See GoCardless's own webhook retry documentation for the exact current schedule and cut-off.
Q: Can I batch-update subscriptions?
A: Yes — via /subscriptions/bulk-collect and the Recurring Payments page's bulk-edit flow, or directly through the GoCardless API/dashboard if you prefer.
Compliance
- PCI-DSS: WPDD never touches card data — there isn't any, since Direct Debit uses bank account details handled entirely by the GoCardless drop-in.
- SCA/3D Secure: not applicable to Direct Debit. The mandate is authorised once; individual charges don't need re-authorisation.
- GDPR: WordPress's Privacy Framework (exports/erasures) is supported — see Advanced Features.
- Liability: the merchant is liable for chargebacks, not WPDD.
Getting Help
- WordPress/Gravity Forms questions? Check their own documentation.
- GoCardless API questions? Check GoCardless's developer docs.
- WPDD-specific issue? Check the Dashboard for connection status, and enable debug logging (Settings → Diagnostics) to see what's happening under the hood.
