Periodically (usually once every working day), we’ll pay out payments your user has collected to their nominated bank account. When this happens, a “payout” record will be created which represents the transfer of funds.
We’ll generally send a single payout each day for each currency a user collects in. However, we may split the funds into multiple payouts if there are a very large number of payments to pay out.
A payout will not necessarily only contain payments collected through your integration - it may contain others if your user is also using our API, the Dashboard or another integration.
When a payout is sent to your user, you’ll receive a webhook with resource_type
“payouts” and action
“paid”. In addition, for each payment that has been paid out, we’ll
send webhooks with resource_type
“payments” and action
“paid_out”. The links[payout]
attribute of that webhook will include the ID of the payout the payment appears in.
For more details on handling webhooks, see the “Staying up-to-date with webhooks” section earlier in this guide.
For the majority of integrations, that’ll be enough. But some integrations (for example, accountancy software) will want to go further in understanding exactly what makes up a payout. If you want to do more complex reconciliation (for example to build a business’s accounts), the best way to understand what’s inside a payout is to use the Payout Items API.
Using the Payout Items API
The Payout Items API lets you see the individual transactions that made up the total amount of a payout.
You can think of a payout in terms of credits and debits. When we collect a payment on your user’s behalf, we add the money collected to their GoCardless balance - that’s a credit. But there can also be debits against that balance - for example, GoCardless’ fees, app fees that you charge for using your integration or deductions for chargebacks.
When we make a payout, we bundle up all of the outstanding credits and debits into it and reset the user’s balance to zero.
For each item in a payout, we expose an amount
(which will be positive for a credit, or
negative for a debit) and will be in the customers currency (i.e the currency the payment
was taken in), a type
(which explains the reason for the credit or debit) and links
to
any relevant resources (usually a payment, links.payment
).
There are ten types of payout item:
Type | Description | Credit or debit | Links |
---|---|---|---|
Payment paid out (payment_paid_out ) |
A payment was successfully collected from a customer, and is being passed on to your user | Credit | links.payment |
Payment failed (payment_failed ) |
A payment appeared to have been collected from a customer successfully, but then the bank told us that it had in fact failed, so it is being deducted | Debit | links.payment |
Payment charged back (payment_charged_back ) |
A payment was successfully collected from a customer, but then the customer contacted their bank to reverse the transaction, so it is being deducted | Debit | links.payment |
Payment refunded (payment_refunded ) |
A payment was successfully collected from a customer, and then partially or fully refunded at your user's request, so the refunded amount is being deducted | Debit | links.payment, links.mandate |
GoCardless fee (gocardless_fee ) |
GoCardless deducted its transaction fee from an incoming payment, or refunded its transaction fee when a payment failed or was charged back | Credit/Debit | links.payment |
App fee (app_fee ) |
Partner integrations can add an "app fee" on top of GoCardless's fees. GoCardless deducted such a fee from an incoming payment, or refunded it when a payment failed or was charged back | Credit/Debit | links.payment |
Revenue share (revenue_share ) |
GoCardless paid out a commission to a partner for a successful payment, or
deducted it for a late failure or chargeback. Partner integrations can receive a
share of GoCardless' fees when users collect payments through their integration.
These do not appear in merchant payouts, since they are part of the
gocardless_fee , but they will appear in partner payouts when they
receive the commission. |
Credit/Debit | links.payment |
Customer refunded (refund ) |
A refund was sent to a customer, not related to any particular payment, so the refunded amount is being deducted This feature is in private beta. | Debit | links.mandate |
Refund Funds returned (refund_funds_returned ) |
A refund made at your request, and previously deducted from a payout failed to reach the customer, so the refunded amount is being credited. | Credit | links.payment, links.mandate |
Surcharge fee (surcharge_fee ) |
GoCardless deducted a surcharge fee as the payment failed or was charged back, or refunded a surcharge fee as the bank or customer cancelled the chargeback. | Credit/Debit | links.payment |
To see how these can fit together in the real world, let’s imagine a payout as an example:
Description | Type | Amount |
---|---|---|
Payment successfully collected from Nick | payment_paid_out |
+€20.00 |
GoCardless fee for payment collected from Nick | gocardless_fee |
-€0.20 |
App fee for payment collected from Nick | app_fee |
-€1.00 |
Refund issued for Andrew's payment, collected last week | payment_refunded |
-€5.00 |
Bianca's payment from last week, which was charged back | payment_charged_back |
-€10.00 |
Refund of GoCardless fee for charged back payment | gocardless_fee |
+€0.10 |
Refund of app fee for charged back payment | app_fee |
+€0.50 |
Total | +€4.40 |
With the Payout Items API, you can look inside a payout and see the transactions that make it up, allowing you to, for example, “explain” transactions on your user’s bank statement.
When you receive a “payout paid” webhook (resource_type
“payouts” and action
“paid”),
you can then query the Payout Items API:
<?php
require 'vendor/autoload.php';
$user = User::where(['gocardless_organisation_id' => $event->links['organisation']])->firstOrFail();
$client = new \GoCardlessPro\Client([
'access_token' => $user->gocardless_access_token,
'environment' => \GoCardlessPro\Environment::SANDBOX
]);
$payout_id = $event->links['payout'];
$payout = $client->payouts()->get($payout_id);
echo $payout->amount;
$payout_items = $client
->payoutItems()
->all(["params" => ["payout" => $payout_id]]);
foreach ($payout_items as $payout_item) {
echo $payout_item->amount;
echo $payout_item->type;
echo $payout_item->links->payment;
}
import os
import gocardless_pro
from myinvoicingapp.models import User
#...
def process_payout_event(self, event):
user = User.object.get(gocardless_organisation_id=event['links']['organisation'])
client = gocardless_pro.Client(
access_token=user.gocardless_access_token,
environment='sandbox'
)
payout_id = event['links']['payout']
payout = client.payouts.get(payout_id)
print payout.amount
payout_items = client.payout_items.all(
params={ "payout": payout_id }
).records
for payout_item in payout_items:
print payout_item.amount
print payout_item.type
print payout_item.links.payment
require 'gocardless_pro'
def process_payment_paid_out(event)
user = User.find_by(gocardless_organisation_id: event.links.organisation)
client = GoCardlessPro::Client.new(
access_token: user.gocardless_access_token,
environment: :sandbox
)
payout_id = event.links.payout
payout = client.payouts.find(payout_id)
puts payout.amount
client.payout_items.all(params: { payout: payout_id }).each do |payout_item|
puts payout_item.amount
puts payout_item.type
puts payout_item.links.payment
end
end
package com.myInvoicingApp;
import com.gocardless.resources.Event;
import com.gocardless.resources.Payout;
import com.gocardless.resources.PayoutItem;
import com.gocardless.GoCardlessClient;
import com.myInvoicingApp.User;
public class PayoutsWebhookHandler {
public static void handlePayoutPaidEvent(Event event) {
User user = User.getUserByGoCardlessID(event.getLinks().getOrganisation());
GoCardlessClient client = GoCardlessClient
.newBuilder(user.gocardlessAccessToken)
.withEnvironment(GoCardlessClient.Environment.SANDBOX)
.build();
String payoutId = event.getLinks().getPayout();
Payout payout = client.payouts().get(payoutId).execute();
for (PayoutItem payoutItem : client.payoutItems().all().withPayout(payoutId).execute()) {
System.out.println(payoutItem.getAmount());
System.out.println(payoutItem.getType());
System.out.println(payoutItem.getLinks().getPayment());
}
}
}
const handlePayoutPaidEvent = async eventResource => {
const payoutId = eventResource.links.payout;
const payout = await client.payouts.find(payoutId);
console.log(payout.id);
const payoutItemsRequest = {
payout: payoutId
};
for await (let payoutItem of client.payoutItems.all(payoutItemsRequest)) {
console.log(payoutItem.amount);
console.log(payoutItem.type);
console.log(payoutItem.links.payment);
}
};
public void HandlePayoutPaidEvent(GoCardless.Resources.Event eventResource)
{
var user = db.Users.Single(user => user.GoCardlessID == eventResource.Links.Organisation);
var client = GoCardlessClient.Create(
user.GoCardlessAccessToken,
GoCardlessClient.Environment.SANDBOX
);
var payoutId = eventResource.Links.Payout;
var payoutResponse = await client.Payouts.GetAsync(payoutId);
var payout = paymentResponse.Payout;
Console.WriteLine(payout.Id);
var payoutItemsRequest = new GoCardless.Services.PayoutItemListRequest()
{
Payout = payoutId
};
var payoutItems = client.PayoutItems.All(payoutItemsRequest);
foreach (GoCardless.Resources.PayoutItem payoutItem in payoutItems)
{
Console.WriteLine(payoutItem.Amount);
Console.WriteLine(payoutItem.Type);
Console.WriteLine(payoutItem.Links.Payment);
}
}
For full details on the Payout Items API, head over to our reference documentation.