GoCardless
yui/craft-go-cardless adds GoCardless Direct Debit payments to a store running yui/craft-plugin. Instead of card numbers, customers authorize a recurring or one-off mandate straight from their bank account — GoCardless calls this "the easy way to get paid without the chasing, stress or expensive fees."
Use it when you want to accept bank-to-bank Direct Debit (subscriptions, invoices, or one-off orders) instead of, or alongside, card payment methods.
What it does
- Runs the standard GoCardless flow out of the box: create a hosted redirect flow, the customer authorizes a mandate on GoCardless's page, the plugin completes the flow and — if enabled — creates a payment against the new mandate automatically.
- Adds a GoCardless section to the Craft control panel with a dashboard, and searchable list/detail views for payments and mandates.
- Verifies inbound GoCardless webhooks against the configured signing secret and lists received events in a Webhooks CP view.
- Keeps advanced functionality behind a Pro toggle: billing requests, billing request flows, subscriptions, and refunds are only exposed once
Enable Pro featuresis switched on in settings. - Exposes MCP tools so an AI agent can create a refund or a subscription through the same service layer the CP uses.
- Adds a License page under the plugin's CP navigation, consistent with other YUI plugins.
Where admins work with this plugin
In Craft CP, open the GoCardless section (gocardless) from the primary navigation:
- Dashboard (
gocardless) — plugin dashboard with a configurable widget layout. - Payments (
gocardless/payments) — list and detail view of GoCardless payments, with retry, cancel, refund, and sync actions. - Mandates (
gocardless/mandates) — list and detail view of customer mandates, with cancel and sync actions. - Webhooks (
gocardless/webhooks) — log of received webhook events. - Subscriptions (
gocardless/subscriptions) — only shown once Pro features are enabled. - Settings (
gocardless/settings) — plugin configuration. See Settings.
A License page is also available under the plugin's CP navigation.
How the standard payment flow works
- The storefront (or any client) calls
POST /gocardless/pay, which creates a GoCardless redirect flow and returns a hostedredirectUrl. - The customer is sent to that URL and authorizes a mandate on GoCardless.
- GoCardless returns the customer to
/gocardless/complete. The plugin completes the redirect flow, and — if Create payment after mandate setup is on and an amount was set on the original request — immediately creates a payment against the resulting mandate. - The customer is redirected to the configured success or failure URL (or, for JSON clients, a JSON response is returned instead of a redirect).
Example: starting a payment
POST /gocardless/pay
Accept: application/json
Content-Type: application/x-www-form-urlencoded
amount=2500¤cy=GBP&description=Order%201234&reference=ORDER-1234
Response:
{
"redirectFlowId": "RE0123456789",
"redirectUrl": "https://pay.gocardless.com/flow/RE0123456789",
"sessionToken": "a1b2c3..."
}
Redirect the customer's browser to redirectUrl. amount is in the smallest currency unit (e.g. pence/cents); currency defaults to the plugin's configured Default currency if omitted.
Example: completion callback
GoCardless redirects the customer back to /gocardless/complete?redirect_flow_id=RE...&session_token=.... The plugin looks up the pending payment it stored for that redirect flow, completes it with GoCardless, and (if enabled) creates the payment — then sends the browser on to the plugin's configured success/failure URL with redirect_flow_id, mandate_id, and payment_id appended as query parameters. Clients that send Accept: application/json get a JSON body with the same fields instead of a redirect.
Webhooks
Configure this endpoint in the GoCardless dashboard:
https://your-site.example/gocardless/webhook
The plugin validates the Webhook-Signature header against the Webhook secret configured in settings and records each received event, visible on the Webhooks CP page.
Requirements
- Craft CMS 5 project.
yui/craft-coreversion 1.gocardless/gocardless-pro(installed automatically as a Composer dependency) version 7.- A GoCardless account, with separate sandbox and live API access tokens.
- Composer access to
https://packages.yui.sk/.
Installation
composer config repositories.yui composer https://packages.yui.sk/
composer require yui/craft-go-cardless
php craft plugin/install gocardless
php craft migrate/all
Migrations create the plugin's mandate, payment, and webhook-event tables.
Then open Settings → Plugins → GoCardless → Credentials and enter a sandbox access token to start testing (see Settings).
Security notes
- Access tokens, the webhook secret, the Pro access token, and the creditor ID all support environment variable references (e.g.
$GOCARDLESS_ACCESS_TOKEN) via Craft's standardautosuggestFieldenv-var pattern — set them in.envrather than typing raw secrets into the settings form. - Inbound webhooks are rejected unless their
Webhook-Signatureheader matches the configured secret. - The plugin defaults to the sandbox environment. Switch Environment to Live only once the GoCardless account is ready to create real mandates and take real payments.
Developer / API reference
Service API
Use the plugin's service from PHP code via Plugin::$plugin->api (Yui\GoCardless\services\GoCardlessService):
use Yui\GoCardless\Plugin;
$flow = Plugin::$plugin->api->createRedirectFlow([
'description' => 'Order 1234',
'metadata' => ['orderId' => '1234'],
]);
| Method | Purpose |
|---|---|
client(bool $pro = false) | Returns a configured GoCardlessPro\Client, using the Pro access token when $pro is true. |
createRedirectFlow(array $params) | Creates a hosted redirect flow for the standard mandate setup. |
completeRedirectFlow(string $redirectFlowId, string $sessionToken) | Completes a redirect flow after the customer returns from GoCardless. |
createPaymentFromMandate(string $mandateId, int $amount, ?string $currency = null, array $params = []) | Creates a payment against an existing mandate. |
parseWebhook(string $body, string $signature) | Validates and decodes an inbound webhook payload. |
testConnection(bool $pro = false) | Checks that the configured credentials can reach the GoCardless API. Used by the Test connection settings action. |
createBillingRequest(array $params) (Pro) | Creates a billing request. |
createBillingRequestFlow(string $billingRequestId, array $params) (Pro) | Creates a hosted flow for a billing request. |
createSubscription(string $mandateId, array $params) (Pro) | Creates a recurring subscription against a mandate. |
createRefund(string $paymentId, int $amount, array $params = []) (Pro) | Refunds part or all of a payment. |
handleException(Throwable $exception) | Normalizes a GoCardless API exception into an array suitable for a JSON error response. |
Methods marked (Pro) still work in code with any valid GoCardless credentials — the enableProFeatures toggle only gates the CP navigation, settings fields, and the plugin's own controllers/MCP tools, not the service methods themselves.
MCP tools
When the yui/craft-mcp plugin is installed, GoCardless registers tools so an AI agent can act on payments and subscriptions directly:
GoCardlessCreateRefundTool— create a refund for a payment.GoCardlessCreateSubscriptionTool— create a subscription against a mandate.
Routes
Site (gocardless/*, anonymous-allowed):
gocardless/pay— start a redirect flow (POST).gocardless/complete— redirect-flow completion callback.gocardless/webhook— webhook receiver.
Control panel (gocardless/*):
gocardless,gocardless/dashboard— dashboard.gocardless/settings,gocardless/settings/general,gocardless/settings/credentials,gocardless/settings/pricing,gocardless/settings/restrictions,gocardless/settings/test-cards,gocardless/settings/test-connection.gocardless/payments,gocardless/payments/<id>— payment list/detail.gocardless/mandates,gocardless/mandates/<id>— mandate list/detail.gocardless/webhooks— webhook event list.gocardless/subscriptions,gocardless/subscriptions/<id>— subscription list/detail (Pro).gocardless/cp/retry-payment,gocardless/cp/cancel-payment,gocardless/cp/refund-payment,gocardless/cp/sync-payment,gocardless/cp/cancel-mandate,gocardless/cp/sync-mandate— CP write actions.gocardless/license,gocardless/license/redeem,gocardless/license/activate,gocardless/license/revoke,gocardless/license/delete,gocardless/license/copy-token— license management.
Frequently asked questions
Does GoCardless support one-off card-style payments, or only subscriptions? Both. The standard flow (redirect flow → mandate → optional immediate payment) works for a single order. Recurring billing is available separately through the Pro subscription methods.
How do I test payments before going live? GoCardless is Direct Debit, so there are no card numbers to test with. Set Environment to Sandbox in Credentials, use a sandbox access token, and GoCardless will simulate mandate confirmations automatically — see the Test cards settings tab for details.
Can I restrict GoCardless to specific countries or a date range? No, not at the plugin level. GoCardless availability (supported countries, currencies, schemes) is controlled by your GoCardless account configuration, not by the plugin's own settings.
What happens if I turn off "Create payment after mandate setup"?
The redirect flow still completes and the mandate is still created and stored, but no payment is created automatically — use createPaymentFromMandate() yourself (for example from an order-completion event) to charge the mandate when you're ready.
Do I need Pro features to accept a simple one-off payment? No. The standard redirect-flow-to-payment path works with the base plugin. Pro is only needed for billing requests, subscriptions, and refunds.