Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Gocardless Laravel Package

omnipay/gocardless

View on GitHub
Deep Wiki
Context7

Getting Started

This is a legacy Omnipay driver for the old GoCardless API, not GoCardless Pro. Last release was 2015, so treat it as an existing-integration maintenance package rather than something to adopt for a new Laravel app.

  1. Install with the matching Omnipay version:
composer require omnipay/gocardless

Check what Composer resolves for omnipay/common and Guzzle; older Omnipay versions often conflict with modern Laravel dependencies.

  1. Look first at:
  • vendor/omnipay/gocardless/src/Gateway.php — supported gateway parameters and request methods.
  • vendor/omnipay/gocardless/src/Message/ — the exact request/response classes and parameter names.
  • The package README/tests — the redirect flow differs from modern GoCardless Pro examples.
  1. Register the gateway once in a service provider:
// app/Providers/OmnipayServiceProvider.php
public function register(): void
{
    $this->app->singleton('omnipay.gocardless', function () {
        return \Omnipay\Omnipay::create('GoCardless')->initialize([
            'merchantId'  => config('services.gocardless.merchant_id'),
            'appId'       => config('services.gocardless.app_id'),
            'appSecret'   => config('services.gocardless.app_secret'),
            'accessToken' => config('services.gocardless.access_token'),
            'testMode'    => (bool) config('services.gocardless.test'),
        ]);
    });
}
  1. First use case: a redirect-based payment/mandate setup. Create the redirect, send the user to GoCardless, then complete the purchase on the callback route:
$response = app('omnipay.gocardless')->purchase([
    'amount'      => '10.00',
    'currency'    => 'GBP',
    'description' => 'Invoice #123',
    'returnUrl'   => route('gocardless.callback'),
    'cancelUrl'   => route('gocardless.cancel'),
])->send();

if ($response->isRedirect()) {
    return redirect($response->getRedirectUrl());
}

The exact callback parameters depend on the legacy API flow; confirm them in CompletePurchaseRequest rather than guessing from GoCardless Pro documentation.

Implementation Patterns

Bind the gateway, don’t instantiate it in controllers. Use a singleton or a small GoCardlessGateway wrapper so credentials, test mode, and logging live in one place.

Use an action/service class for the two-step flow. Keep controllers thin:

class StartGoCardlessPayment
{
    public function __construct(private \Omnipay\Common\GatewayInterface $gateway) {}

    public function handle(Order $order): \Omnipay\Common\Message\ResponseInterface
    {
        return $this->gateway->purchase([
            'amount'      => number_format($order->total / 100, 2, '.', ''),
            'currency'    => 'GBP',
            'description' => "Order {$order->id}",
            'returnUrl'   => route('gocardless.callback'),
            'cancelUrl'   => route('gocardless.cancel'),
        ])->send();
    }
}

Persist state before redirecting. Store the order ID, amount, currency, and a local correlation/state token in your database. On return, validate that state before calling completePurchase(). Do not trust query parameters alone.

Store the gateway reference and status. After a successful response, save:

$response = app('omnipay.gocardless')->completePurchase($params)->send();

if ($response->isSuccessful()) {
    $order->update([
        'gateway_reference' => $response->getTransactionReference(),
        'status'            => 'paid',
    ]);
}

Use a unique index on your own order/reference column so duplicate callbacks cannot double-process a payment.

Decouple with Laravel events. Dispatch PaymentCompleted / PaymentFailed events from the action class, then handle emails, invoicing, and fulfilment in listeners. This makes it easier to replace the gateway later.

Test with a fake binding. Unit tests should not hit GoCardless. Bind a fake GatewayInterface that returns a mocked ResponseInterface:

$this->app->instance('omnipay.gocardless', $fakeGateway);

Reserve real sandbox tests for the redirect/complete round trip, if the legacy sandbox is still available to your account.

Keep secrets out of code and logs. Read credentials from config/services.php backed by .env. Redact accessToken, appSecret, and full gateway responses before logging.

Gotchas and Tips

  • This targets the deprecated legacy GoCardless API. It will not work with GoCardless Pro or Bank Account Data/Nordigen. For new work, use GoCardless Pro’s official gocardless/gocardless-pro SDK or direct API calls behind a Laravel service.
  • Dependency conflicts are likely. A 2015 package may pull old omnipay/common and Guzzle versions that conflict with Laravel 8+. Run composer why-not omnipay/gocardless and test installation in a branch before committing.
  • PHP compatibility is uncertain. Expect issues on PHP 8.x. If you must keep it, pin PHP/package versions or isolate the integration in a small internal service.
  • Credentials are legacy-shaped. merchantId, appId, appSecret, and accessToken are not the same as a GoCardless Pro access token. Mixing documentation from Pro will waste time.
  • Amount handling deserves tests. Omnipay typically accepts decimal strings while GoCardless APIs often use minor units. Verify the driver’s conversion and rounding with values like 0.01, 10.00, and 10.99.
  • Currency is effectively GBP-only for this legacy flow. Do not assume EUR/SEPA support.
  • Redirect URLs must match exactly. Use absolute HTTPS URLs and keep return/cancel routes stable across environments.
  • Error handling is thin. Catch Omnipay\Common\Exception\InvalidRequestException and InvalidResponseException, log a redacted context, and show users a generic failure page.
  • No built-in Laravel webhook handling. If you need asynchronous notifications, implement the endpoint and signature verification separately; don’t assume this driver provides it.
  • Extension points exist but are rarely worth it. You can subclass Gateway or register custom request classes via Omnipay’s gateway factory, but for a deprecated API the better extension point is usually a thin application-level adapter that lets you swap in GoCardless Pro later.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle