GoCardless transaction data

Overview

What’s loyal or Loyal?


Transaction data

Loyal plans to leverage Open Banking data to track consumer spending at merchants and assign loyalty levels based on transaction history.
So far, I’ve pretended like I have the actual data export by adding a unique ID for consumers. This is to help me derive the transaction value at merchants to find the correct loyalty level for a consumer at a merchant.
I’m super flexible how this goes - it can change however. The only need is that I want to be able to take the transaction data, identify a merchant, identify a user, to then calculate the value spend by a user at a merchant over a set period (such as 3 months).
So the key requirements are as follows:
Enable consumers to link their bank account data
Enable Loyal to collect the transaction data of consumers, including unique user identifier (ideally one that relates to existing user ID in the Google Sheet spreadsheet - the row ID)
Glide can do the rest (identify if the transaction is within the last 3 months, sum of transactions per merchant, identify loyalty level, show loyalty level)




Bank account details

The related bank account (Pat’s GBP Revolut):
{
"account": {
"resourceId": "c930d845-4d2d-41e9-ba2c-455403efed29",
"iban": "GB56REVO00997072302771",
"scan": "04007530970857",
"currency": "GBP",
"ownerName": "PATRICK EDWARD MITCHELL"
}
}


Transaction data:

1. Structure for Card Payments

An example of actual transaction data:
{
"transactionId": "67c5f8c5-7664-aa7c-86c6-e9406e4eace9",
"bookingDate": "2025-03-03",
"valueDate": "2025-03-04",
"bookingDateTime": "2025-03-03T18:45:25.325307Z",
"valueDateTime": "2025-03-04T11:33:00.356336Z",
"transactionAmount": {
"amount": "-41.63",
"currency": "GBP"
},
"creditorName": "Ver*fulham Wine Bar A",
"remittanceInformationUnstructuredArray": [
"Ver*fulham Wine Bar A"
],
"proprietaryBankTransactionCode": "CARD_PAYMENT",
"internalTransactionId": "e000a23fbca8dbb6ea38e54fe1293be1"
}


Card payment fields explained
Field
Description
transactionId
Unique ID of the transaction.
bookingDate
The date the transaction was recorded.
valueDate
The date the money was actually deducted.
transactionAmount.amount
Negative amount (-) → Indicates money left the account.
transactionAmount.currency
The currency of the transaction (GBP).
creditorName
The merchant/entity that received the payment.
remittanceInformationUnstructuredArray
Additional transaction details, often a reference or description.
proprietaryBankTransactionCode
"CARD_PAYMENT" → Indicates a payment made using a debit/credit card.
internalTransactionId
Internal identifier for the transaction within the banking system.
There are no rows in this table


info

As you can see, there is no user identified in this transaction data. It seems we will need to do this - to be able to associate a consumer with the transaction.


There are unique identifier for merchants exists in the data - so not a problem. For example, “Ver*fulham Wine Bar A” is the credito name for Fulham wine bar - which is in the transaction data.

There is an identifier for the merchant - "Ver*fulham Wine Bar A".
info

Transaction data for MVP

For the MVP, we only actually need the ‘Card payment’ type transaction data - where users spend money at merchants. This will allow us to not worry about refunds, credits, payments, etc. This may make users feel more comfortable with sharing data and reduce sensitivity of data stored.
In an ideal world, we’d have all the data to use for transactions but to also better categorise users.




2. Structure for Bank Transfers (Outgoing)


{
"transactionId": "67be26b2-e55b-aac8-a233-5a6b60177458",
"bookingDate": "2025-02-25",
"valueDate": "2025-02-25",
"bookingDateTime": "2025-02-25T20:23:14.983363Z",
"valueDateTime": "2025-02-25T20:23:15.229458Z",
"transactionAmount": {
"amount": "-22.00",
"currency": "GBP"
},
"creditorName": "MELISSA JANINE REYNOLDS",
"creditorAccount": {
"iban": "GB82REVO00997019365135"
},
"debtorName": "PATRICK EDWARD MITCHELL",
"debtorAccount": {
"iban": "GB56REVO00997072302771"
},
"remittanceInformationUnstructuredArray": [
"To Melissa R"
],
"proprietaryBankTransactionCode": "TRANSFER",
"internalTransactionId": "b7a47944c454273e99f023cb9113d990"
}


Outgoing bank transfers fields explained
Field
Description
transactionId
Unique ID of the transaction.
bookingDate
When the transaction was recorded.
valueDate
When the money was actually deducted.
transactionAmount.amount
Negative amount (-) → Indicates money was transferred out.
transactionAmount.currency
Currency (GBP).
creditorName
The recipient of the transfer (Melissa Janine Reynolds).
creditorAccount.iban
The IBAN of the recipient.
debtorName
The sender of the transfer (Patrick Edward Mitchell).
debtorAccount.iban
The IBAN of the sender (Patrick's account).
remittanceInformationUnstructuredArray
Reference message for the transaction.
proprietaryBankTransactionCode
"TRANSFER" → Indicates a bank transfer.
There are no rows in this table



3. Structure for Bank Transfers (Incoming)


{
"transactionId": "67be266f-b79c-ab5b-a811-f4bcca495555",
"bookingDate": "2025-02-25",
"valueDate": "2025-02-25",
"bookingDateTime": "2025-02-25T20:22:07.170046Z",
"valueDateTime": "2025-02-25T20:22:07.319056Z",
"transactionAmount": {
"amount": "500.00",
"currency": "GBP"
},
"debtorName": "MITCHELL P",
"debtorAccount": {
"bban": "40071451678760"
},
"remittanceInformationUnstructuredArray": [
"Payment from Mitchell P",
"Transfer"
],
"proprietaryBankTransactionCode": "TOPUP",
"internalTransactionId": "206bb1ba6280c9fda7764b05c4a2305c"
}




Incoming bank transfers fields explained
Field
Description
transactionId
Unique ID of the transaction.
bookingDate
When the transaction was recorded.
valueDate
When the money was actually credited.
transactionAmount.amount
Positive amount (+) → Indicates money was received.
transactionAmount.currency
Currency (GBP).
debtorName
The sender of the transfer (Mitchell P).
debtorAccount.bban
The bank account number of the sender.
remittanceInformationUnstructuredArray
Reference message for the transaction.
proprietaryBankTransactionCode
"TOPUP" → Indicates a deposit into the account.
There are no rows in this table



4. Structure for Fees & Charges


{
"transactionId": "67c1023e-837e-a5c2-9fe9-800a5c3e553b",
"bookingDate": "2025-02-28",
"valueDate": "2025-02-28",
"bookingDateTime": "2025-02-28T00:24:30.069149Z",
"valueDateTime": "2025-02-28T00:24:30.070656Z",
"transactionAmount": {
"amount": "-14.99",
"currency": "GBP"
},
"remittanceInformationUnstructuredArray": [
"Metal Repricing 1 plan fee"
],
"proprietaryBankTransactionCode": "FEE",
"internalTransactionId": "a8cee66058da30f678ca1a791aeb9057"
}




Fees fields explained:
Field
Description
transactionId
Unique ID of the transaction.
bookingDate
When the transaction was recorded.
valueDate
When the money was deducted.
transactionAmount.amount
Negative amount (-) → Indicates a charge was deducted.
transactionAmount.currency
Currency (GBP).
remittanceInformationUnstructuredArray
Description of the fee.
proprietaryBankTransactionCode
"FEE" → Indicates a bank charge or subscription fee.
There are no rows in this table


How Loyal plans to use data

Here’s a process flow of how I want to use the transactions data. So far in the app, I have taken a direct transaction data dump and added a unique user ID to the end.This unique user ID is the row ID that Glide automatically creates for each new app user. As the GoCardless transaction does not include a unique use ID, I have added this manually. In an ideal world, this would be automatic.

Assuming we have this transaction data with a user unique ID that relates to Glide app, I identify which transactions are within the last 3 months through a Glide App function. I then sum the value of transactions in the last 3 months, per merchant. I then turn this into an absolute value (as it is negative).

This gives me the transaction value per merchant for a given consumer, to help me determine the loyalty level a consumer has for each merchant. The Glide app then has logic to show the consumer the correct loyalty level and rewards (i.e. spend is £350.23 at Fulham Wine Bar over the last 3 months, and the Gold threshold is £300 → thus the consumer is a gold rewards level).



In the Glide app, we are able to link to webpages - could this be how we let consumers link their bank account data, powered by GoCardless or another open banking solution?
image.png


Considerations

Data security

I appreciate we are dealing with transactions and bank data. The idea is to have a pilot with 100 friends. I plan to only use this data to calculate the spend over the last 3 months, and never analyse this data (as far as the Pilot goes). So we won’t analyse or manipulate the data in any form, other than to derive the loyalty level for a given merchant.
After the Pilot, hopefully we can validate we’re going after the right product with hte right solution. Then I would start to focus on data security.

However, the less sensitive data we store the better. It would be great to understand what data do we need at a minimum - to avoid storing user’s card details, etc.

Multiple bank accounts

I imagine this will be a problem in the future, but let’s focus on 1 bank account.
Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
CtrlP
) instead.