Introduction
Give A Little provides Point of Donation (POD) software for charitable organisations, enabling quick and cost-effective acceptance of digital payments.
It's very early days for our developer interface however functionality exposed to 3rd parties is growing and if there are specific things you are wanting to achieve with your own integrations please do feel free to get in touch with us at hello@givealittle.co.
Service URLs
Depending on what you are doing you will interact with either our website, or our API. Generally, if you are interacting with us programmatically you will connect to the API, if your user needs to visit our site, you will interact with the website.
Test
Website: https://test-givealittle.cyb.dev
API: https://api.test-givealittle.cyb.dev
Production
Website: https://givealittle.co
API: https://api.givealittle.co
For Platforms with a custom domain you will use your custom domain as the 'Website' service URL
Testing
When testing, use our test system (see Service URLs). You can sign up for an account in test just as you would in production. You will still need to go through verification, but there's no need to upload evidence - just make sure you provide an email address we can contact you on.
Test payments
If you are using Stripe for payment processing, donations made on our test site will automatically be done in test mode. You can find Stripe test card details at https://stripe.com/docs/testing#cards.
If you are using SumUp you will need to request a test account from SumUp that you can then connect with your test Give A Little account. You can contact SumUp at support@sumup.com.
Web Donations
To enable you to create your own donation pages and widgets we expose two endpoints, one for retrieving web campaign configuration and another for initiating a web donation.
Retrieve Web Campaign configuration
Retrieving Web Campaign configuration is done via our REST API.
For a campaign to be available through the API it must be a web campaign (i.e. not an app campaign) and also be published. Campaigns can be published in the admin site.
Service: API
URL: /webdonations/campaigns/{campaignId}
Method: GET
Auth required: No
Request parameters:
campaignId
The ID of the campaign to retrieve the configuration of
campaignId
can be found either in the admin console or via a Platform's onboarding flow.
Successful response
Code: 200
Example payload:
{
"currency": "GBP",
"version": 3,
"charityName": "Example Charity",
"showCustomAmount": false,
"allowRecurring": true,
"heading": "Children's Cancer Trust UK",
"primaryColour": "#000000",
"accentColour": "#e70808",
"background": "https://test-givealittle.cyb.dev/files/abc-123/childrens-cancer-trust-mockup.jpg",
"buttonAlignment": "bottom",
"items": [
{
"amount": 3.0
},
{
"amount": 5.0
},
{
"amount": 10.0
}
],
"message": "Helping the next generation fight cancer.",
"id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"type": "webBackground"
}
Response properties:
- currency: The ISO currency code this charity accepts donations in
- version: A number that is incremented when a campaign changes
- charityName: The name of the charity whose campaign this is
- showCustomAmount:
true
if a donor is allowed to donate an amount not specified initems
,false
otherwise - allowRecurring:
true
if a donor is allowed to set up a monthly recurring donation,false
otherwise - heading: A heading message to display to donors
- primaryColour: A hex colour, used as the predominant colour of the campaign
- accentColour: A hex colour, used as the accent colour of the campaign
- background: The URL of an image to use as the background of the campaign
- banner: The URL of an image to use as the banner of the campaign
- imageSize: A hint as to how to size an image, can be one of 'cover', 'contain' or 'auto'
- buttonAlignment: A hint as to how to align any buttons, can be one of 'top', 'middle', 'bottom'
- items: An array of objects defining the donation amounts to offer. This will contain up to 6 amounts.
- message: A message to display to donors
- id: A unique identifier for this campaign, this will be the same as used in the request
- type: One of 'webBasic', 'webBanner' or 'webBackground'. These are templates chosen within Give A Little, the response body may be slightly different for each.
Error responses
- Code: 404
Reason: No campaign was found with the provided ID. This could mean the ID is wrong, or that the campaign has not been published. - Code: 500
Reason: There was an internal error in the API.
Initiate a Web Donation
A Web Donation is initiated by redirecting a donor to the Give A Little website along with some parameters describing what the donor is wanting to do.
Service: Website
URL: /{campaignId}/initiate-donation?amount=&recurring=&returnUrl=
Method: GET
Auth required: No
Request parameters:
campaignId
The ID of the campaign to retrieve the configuration ofamount
The donation amount a donor has chosenrecurring
Whether the donor has chosen to give every monthreturnUrl
The URL to return the donor to at the end of the donation flow
Successful response
When successful, this call will redirect the donor to the payment form. The flow will continue based on the Web
Campaign's configuration until the donor gets to the Thank You page. Here, if included in the original request the donor
will have the chance to return to the returnUrl
.
Error responses
- Code: 404
Reason: No campaign was found with the provided ID. This could mean the ID is wrong, or that the campaign has not been published. - Code: 500
Reason: There was an internal error in the API.
Platforms
If you have a website where you would like to host a full donation flow on behalf of your users you can register with us as a platform. As a platform you are able to set up a quick onboarding flow, enabling your users to link their Give A Little account with your service and automatically publish a template web campaign.
Features
- Initiate a registration flow to link your users with Give A Little and publish a campaign
- Host campaign pages on your own URL, e.g. https://giving.{yourdomain} (requires CNAME setup)
- Receive reporting on donations made to your users
Get started
To get started with this, please get in touch with us at hello@givealittle.co.
Event Hooks [BETA]
Event hooks are a way for you to receive events when things happen within Give A Little that you might be interested in.
Getting started
While we are building this functionality the setup for an event hook is hidden. When you would like a hook added please get in touch with as at hello@givealittle.co.
Receiving events
To begin receiving events you will need a target configured, e.g. https://example.org/events/2022-11-22
.
We currently support sending events over https or SFTP. If you'd like another protocol added, let us know!
Versioning
We recommend including the API version in your target's path to help with migrating to new versions when they are
available. You'll note above the example https target's URL is https://example.org/events/2022-11-22
, where
'2022-11-22' is the API version it is expecting.
https
To configure an https target you will need to provide an endpoint that accepts a POST and returns a 2XX response code when a request has been successful.
Each request to this endpoint will include a header, GiveALittle-Signature
, containing a timestamp and HMAC-SHA512
signature. We will provide you with a shared secret that can be used to verify these signatures. The header
value will look something like:
t=1669272921,v1=107bb0e4b33378583863f02418e63bebb1addd16008a6485f234fae910ad2f82552593a08d7e9b5d51b565f6e821c8cad4c37f121db9adb008b1c4e627d5b58
In this line, t=
denotes the timestamp in seconds since the epoch. v1=
denotes the signature.
To verify this signature you will need to generate the HMAC-SHA512 hash of the timestamp and the event data concatenated
together, e.g. {timestamp}.{event}
using the shared secret we provide you. This data should be combined exactly as
received to ensure that the calculated signature matches the provided signature.
import com.google.common.hash.Hashing;
import java.nio.charset.StandardCharsets;
String payload = String.format("%d.%s", timestamp, data);
String signature = Hashing
.hmacSha512(secret.getBytes(StandardCharsets.UTF_8))
.newHasher()
.putString(payload, StandardCharsets.UTF_8)
.hash()
.toString();
SFTP
To configure an SFTP target you will need to provide a URL pointing at your SFTP server, including credentials and
the path you want the event files stored at, e.g. sftp://user:password@example.org/2022-11-22
. You will also need to
provide an RSA public key we can use to encrypt data we will store on your SFTP server. You can generate a public/private key
pair using ssh-keygen:
ssh-keygen -t rsa -b 4096
Events will be stored in encrypted files formatted as {eventId}.json.pgp
. Decrypt these using your private key to get
the event data.
// Load private key
byte[] keyBytes = Base64.getDecoder().decode(key);
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey privateKey = kf.generatePrivate(spec);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedBytes = cipher.doFinal(encrypted);
Order of events
We attempt to send events in the order that they happened. This is not always possible, for example if there is an error sending an event it will be retried but another event may occur and be successfully sent in the meantime.
Events
All events will have a type
and a timestamp
. The type tells you what event you've received and the timestamp when
the event was dispatched.
email-address-added
This is sent when a donor adds their email address.
{
"type": "email-address-added",
"timestamp": "2022-12-05T00:02:28.779440Z",
"donor": {
"id": "d917a5fa-ac22-4d7a-8880-ca8438b9cddc",
"emailAddress": "gal@example.org"
}
}
donor.id: The unique identifier of the donor
donor.emailAddress: The email address of the donor
marketing-consent-given
This is sent when a donor gives marketing consent.
{
"type": "marketing-consent-given",
"timestamp": "2022-12-05T00:02:28.779440Z",
"donor": {
"id": "d917a5fa-ac22-4d7a-8880-ca8438b9cddc"
},
"email": true,
"phone": false,
"post": false
}
donor.id: The unique identifier of the donor
email: Whether consent was given for email contact
phone: Whether consent was given for phone contact
post: Whether consent was given for postal contact
marketing-consent-revoked
This is sent when a donor revokes marketing consent.
{
"type": "marketing-consent-revoked",
"timestamp": "2022-12-05T00:02:28.779440Z",
"donor": {
"id": "d917a5fa-ac22-4d7a-8880-ca8438b9cddc"
}
}
donor.id: The unique identifier of the donor
phone-number-added
This is sent when a donor adds their phone number.
{
"type": "phone-number-added",
"timestamp": "2022-12-05T00:02:28.779440Z",
"donor": {
"id": "d917a5fa-ac22-4d7a-8880-ca8438b9cddc",
"phoneNumber": "02212345678"
}
}
donor.id: The unique identifier of the donor
donor.phoneNumber: The phone number of the donor
tax-scheme-joined
This is sent when a donor joins a tax scheme, for example Gift Aid.
{
"type": "tax-scheme-joined",
"timestamp": "2022-12-05T00:02:28.779440Z",
"donor": {
"id": "d917a5fa-ac22-4d7a-8880-ca8438b9cddc",
"firstName": "T",
"lastName": "Hawkins",
"address": {
"line1": "1 Phipp St",
"postcode": "EC2A 4DS"
}
},
"declaration": {
"createdAt": "2022-12-05T00:01:12.012320Z",
"type": "GIFT_AID",
"text": "I would like to ...",
"applyToPast": true,
"applyToFuture": true
}
}
donor.id: The unique identifier of the donor who made this declaration
donor.firstName: The donor's first name
donor.lastName: The donor's last name
donor.address.line1: The first line of the donor's address
donor.address.postcode: The postcode of the donor's address
declaration.createdAt: When the declaration was made
declaration.type: The type of declaration, this will be consistent with the tax scheme in the country you operate in
declaration.text: The text of the declaration
declaration.applyToPast: Whether or not this declaration can be applied to historic donations this donor made
declaration.applyToFuture: Whether or not this declaration can be automatically applied to any future donations this donor makes
tax-scheme-left
This is sent when a donor leaves a tax scheme.
{
"type": "tax-scheme-left",
"timestamp": "2022-12-05T00:02:28.779440Z",
"donor": {
"id": "d917a5fa-ac22-4d7a-8880-ca8438b9cddc"
}
}
donor.id: The unique identifier of the donor
transaction-created
This is sent when a donation payment has been made and verified.
{
"type": "transaction-created",
"timestamp": "2022-12-05T00:02:28.779440Z",
"transaction": {
"id": "150ba915-a845-488f-b999-67312efbbe13",
"amount": 2.0,
"timestamp": "2022-12-05T00:02:24Z"
},
"donor": {
"id": "d917a5fa-ac22-4d7a-8880-ca8438b9cddc"
},
"campaign": {
"id": "00000000-0000-0000-0000-000000000001",
"name": "Web Basic"
}
}
transaction.id: The unique identifier of the transaction
transaction.amount: The total amount of the transaction
transaction.timestamp: The time the transaction was made, this will be different to the timestamp of the event
donor.id: The unique identifier of the donor who made this transaction
campaign.id: The unique identifier of the campaign this transaction was made to
campaign.name: The name of the campaign this transaction was made to
donors-merged
This is sent when a donor record is merged with another donor record. Records may be merged when an anonymous donor adds an email address that matches another email address in the system.
{
"type": "donors-merged",
"timestamp": "2022-12-05T00:02:28.779440Z",
"donorId": "d917a5fa-ac22-4d7a-8880-ca8438b9cddc",
"mergedId": "a9799e3e-d693-4bd2-92fd-b5b6ed3bf492"
}
donorId: The unique identifier of the primary donor record that was matched with another record
mergedId: The unique identifier of the donor record that was merged into the primary donor record