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/month directly to GoCardless. BACS doesn't support those parameters at all, so the plugin instead computes a concrete start_date and 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 month sent 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:

  1. All required fields have values.
  2. Interval is within valid range (weekly 1–104, monthly 1–24, yearly 1).
  3. Day of month is 1–28, if set.
  4. Amount is within the transaction limits set in plugin settings.

GoCardless drop-in doesn't appear

Check:

  1. Form has a WPdirectdebit feed attached.
  2. Site is connected to GoCardless for the active mode (Settings page).
  3. Browser console has no JavaScript errors.

Mandate created but subscription didn't

Check:

  1. Subscription interval is within limits (see above).
  2. Interval unit is set (weekly, monthly, or yearly).
  3. 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:

  1. Webhook URL is correct in the GoCardless dashboard for the active mode.
  2. The matching webhook secret (Live or Sandbox) is entered in WPDD Settings.
  3. 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.
  4. 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:

  1. Entry has WPDD metadata (mandate or subscription ID).
  2. WordPress's Privacy Framework is enabled.

API Integration

For custom integrations:


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.