Partners

Introduction Connect your merchants Getting your users verified Setting up mandates Sending money Integration Checklist UX Guides & Resources Taking your integration live

Partners: Send Money

You’ll need to provide a way for your merchants to initiate outbound payments so they can send money to their chosen recipients.

Prerequisites for Outbound Payments

Before you can start sending money through GoCardless, make sure the following are in place:

  • Your merchants must be fully onboarded with GoCardless.

  • Outbound Payments must be enabled for each merchant. This setting is applied at the merchant level, so even if you - as a partner - have Outbound Payments enabled, you won’t be able to create outbound payments on a merchant’s behalf unless it’s enabled for them too.

  • Anyone in your merchants’ organisations who will be sending money needs their own GoCardless Dashboard user account with read-write/admin permissions.

  • These users must also have SMS-based 2FA turned on to be able to receive payment authorisation codes.

How it works

The Outbound Payments API allows you to initiate payouts from a merchant’s bank account to a recipient. Instead of building complex compliance flows yourself, GoCardless handles the regulatory heavy lifting, including Strong Customer Authentication (SCA) and Confirmation of Payee (CoP) through an API response model.

The flowchart below provides a high-level overview of the Outbound Payment Initiation process from partner apps:

The overall flow consists of the following stages:

1. Authenticate

Ensure your merchant has Outbound Payments enabled and use their unique access token to make API requests.

2. Initiate the Payment

Call the Create Outbound Payment API, which performs CoP and automatically determines whether SCA is required.

3. Handle outcomes

Ensure to handle 3 outcomes: 

  • An immediate 201 Created response for payments that are exempt from SCA.

  • A 403 insufficient_permissions_continue_on_dashboard response, which includes a dashboard link for the user to complete SCA

  • An API error for incorrectly provided parameters

4.1 Redirect

When SCA is required, redirect the user to the GoCardless Dashboard, where they can review the payment details and enter an SMS code to finalise the transfer.

4.2 Complete payment

When the payment is exempt from SCA, display CoP results and call Approve Outbound Payment API to send the payment.

Making API Calls on behalf of your merchant

You must have gotten and saved merchants' access tokens after following the steps here. To make an API call against a merchant's account, you will have to use the saved access token. See an example below:

1<?php 2require 'vendor/autoload.php'; 3 4$client = new \GoCardlessPro\Client([ 5 // You'll need to identify the user that the customer is paying and fetch their 6 // access token 7 'access_token' => $user->gocardlessAccessToken, 8 // Change me to LIVE when you're ready to go live 9 'environment' => \GoCardlessPro\Environment::SANDBOX 10]);

Outbound Payment Initiation

To initiate outbound payment, use either the Create Outbound Payment API or the Create Withdrawal API.

Refer to the guides here to learn how to create a recipient and here to learn about the types of outbound payments, and the required parameters.

When you’re initiating outbound payments from an app, the key thing to be aware of is how Confirmation of Payee(CoP) and Strong Customer Authentication (SCA) work for you.

UK regulations require UK Payment Service Providers to implement CoP. GoCardless automatically runs these checks for every outbound payment (read more about verifications for Outbound Payments here).

GoCardless is responsible for carrying out SCA, so we require your app to use our SCA solution. The regulations do allow a few exemptions, and at GoCardless, we support Trusted Beneficiary (more details here). 

When a recipient with a full or partially matched CoP results receives their first payment with a successful SCA, they are added to a trusted list. This means future payments to this recipient will not trigger the GoCardless SCA flow.

For your app, this means:

  • Payments that qualify for an SCA exemption can be initiated directly through the API without redirecting.

  • Payments requiring SCA must be initiated via a redirect to the GoCardless Dashboard so the user can complete authentication.

Handling Outcomes

Payment qualifies for an SCA exemption

If the payment qualifies for an SCA exemption, it will be initiated immediately. You’ll receive a 201 Created response with the payment details, including its ID for tracking (see here to learn about tracking outbound payments). At this point the payment has been created, the next step is to approve it so it can be sent.

Payment requires SCA

If an outbound payment does not qualify for an SCA exemption and must be completed via payment initiation APIs will return a 403 insufficient_permissions_continue_on_dashboard.

The error response includes a dashboard link containing all the outbound payment parameters you provided, along with an HMAC to ensure the data cannot be modified outside your app or the current API call.

Please see the response example below:

HTTP/1.1 403 Content-Type: application/json { "error": { "message": "Unauthorised to perform this action via the API due to compliance. Please continue via the dashboard.", "errors": [ { "reason": "insufficient_permissions_continue_on_dashboard", "message": "Unauthorised to perform this action via the API due to compliance. Please continue via the dashboard.", "links": { "dashboard": "https://manage.gocardless.com/send-payment/partner-app?amount=100&hmac=MIGHAkIAzLuSvWrCWk8b4g37%2FZgpd9sz8ksM9Sh6%2FcZUjgnkHVgKvqNuI8kMPYlm%2Bolo8ThTiwS3LAAuDxzhKGToOxvFcLICQWfJgKwqjjHt1I8LheV1tPgfv5A1J3z%2Flzaa8u40VSQWzPqB%2B5IIxjuPNCwdl1hEvXLx1PRkCl1M29uTtvYBM5dM&recipientBankAccount=BA0001238&scheme=faster_payments" } } ], "documentation_url": "https://developer.gocardless.com/api-reference#insufficient_permissions_continue_on_dashboard", "type": "invalid_api_usage", "request_id": "89a7f8ef-7159-4b4b-8d75-14d5885d3a0b", "code": 403 } }

When you receive a 403 insufficient_permissions_continue_on_dashboard response, you don’t need to display CoP results or handle payment approval in your app. This will be done on the dashboard — simply open the provided dashboard link in a new browser tab or window. We will communicate payment updates back to your app via the postMessage Web API.

See this section for more details about what happens on redirect.

See this section for more details about how to listen to events from GoCardless via the postMessage Web API.

Errors

If you receive an error other than 403 insufficient_permissions_continue_on_dashboard, it usually means the payment parameters are invalid. Make sure your integration can handle these validation errors. GoCardless always returns validation errors first, before checking whether the payment needs to be completed via the dashboard. For example, if a payment does not qualify for an SCA exemption but contains invalid parameters, you’ll receive a 422 error response with the validation error. This allows your app to fix the input before redirecting the user to the dashboard.

Outbound Payment Completion

In your app, make sure to show the CoP results to the user before they approve the payment. This helps them confirm that the payment is going to the correct recipient.

Once the user has reviewed the CoP results and is ready to proceed, call the Approve Outbound Payment API to submit the payment to the banks.

What happens after redirect

Once your user is redirected to the dashboard link, they will see the GoCardless Sign-In page. They must enter their GoCardless username and password.

After successfully logging in, the user will be taken to the Outbound Payment Review page, where they can view the payment details provided by your app, along with the CoP results for the payment.

If the user is satisfied with the payment details, they can click “Send payment”. They will then receive an SMS with an authorisation code, which they must enter to approve the payment.

Entering the code completes SCA and approves the payment. The payment will then be submitted shortly and recorded as originating from your app.

Handle events from redirect

Let’s now work on keeping your app notified about the events from the redirects on the dashboard. When your app opens a dashboard link in a new browser window or tab, the dashboard flow will send information back to your app using window.opener.postMessage

Example:

  1. Your app opens a new tab (e.g., a redirect link from GoCardless):

    1const gocardlessTab = window.open(gocardlessDashboardUrl, "_blank");
  2. The dashboard flow runs in that new tab.

  3. When something happens (e.g., a payment is approved or errored), the dashboard sends a message back to your app:

    1window.opener.postMessage({ 2  eventName: "success", 3  payload: { outboundPaymentId: "OUT12345"} 4});
  4. Your app receives and handles the message using a message event listener.

How to add a Message Listener in Your App:

The GoCardless dashboard flow currently sends two types of events:

  • “success” means SCA was completed and the payment was created. The event payload includes the outbound payment ID, which you can use to track its status if needed.

  • “failure” can occur for several reasons, such as a failed or expired SCA or an error while creating the payment. In these cases, the dashboard flow will display an error screen explaining what went wrong.

In the page that opened the new tab, add:

1window.addEventListener("message", (event) => { 2 // Validate the origin for security 3 if (event.origin !== "https://manage.gocardless.com/") { 4 return; 5 } 6 7 if (event.data.eventName === "success") { 8 // Refresh UI, show success, etc. 9 } 10 11 if (event.data.eventName === "failure") { 12 // Handle errors 13 } 14});

It’s possible for a user to abandon the flow before completing it by closing the tab or popup window. Because postMessage cannot detect when a window is closed, you’ll need to use window polling if you want to track and handle this scenario in your app:

1const gocardlessTab = window.open(gocardlessDashboardUrl, "_blank"); 2 3// Check every 500ms whether popup was closed 4const timer = setInterval(() => { 5 if (gocardlessTab.closed) { 6 clearInterval(timer); 7 console.log("GoCardless Flow tab was closed by the user."); 8 9 // Handle as a cancellation or fallback 10 } 11}, 500); 12