---
title: "A donation with every order"
description: "Above a basket amount, you give, and your customer chooses the charity."
canonical: https://www.charitips.com/docs/use-cases/donation-per-order
---

# A donation with every order

> Above a basket amount, you give, and your customer chooses the charity.

- **Who pays**: Your company
- **Starts with**: A purchase
- **Tax receipt**: In your company's name
- Needs [API access](https://www.charitips.com/docs/overview/plans.md#api-access-for-webhooks-and-credentials) on a validated account. [Plans](https://www.charitips.com/docs/overview/plans.md#what-every-flow-needs)

Interactive demo on the page. The same flow as a build spec: https://www.charitips.com/docs/demos/checkout.md

**This demo is one example**: 2 € for every order over 50 €. The same flow also covers:

- [A percentage of each order](https://www.charitips.com/docs/use-cases/donation-per-order/gym-shop.md): The amount follows the basket, for example 1 % of every order, instead of a fixed sum.
- [The charity picker is a Charitips widget](https://www.charitips.com/docs/use-cases/donation-per-order.md#show-the-charities): A widget on your confirmation page lists the charities and records the choice, so you build no picker.
- [The customer chooses by email](https://www.charitips.com/docs/use-cases/delivered-gift.md#send-the-gift-by-email): A time-limited campaign emails the customer a link to pick the charity after the order.
- [First order only](https://www.charitips.com/docs/use-cases/achievement.md): Only a customer's first order triggers a donation, as a welcome gift.
- [Marketplace sellers pay for it](https://www.charitips.com/docs/use-cases/marketplace-split.md): Each seller gets its own account under yours and is billed for the donations on its orders.

**Variants**: the same flow in other sectors, each with its build spec.

- [Online store](https://www.charitips.com/docs/use-cases/donation-per-order/running-store.md) (Retail): An online store adds 2 € to every order over 50 €, paid by the store. The customer picks the charity on the confirmation page; if they skip it, the donation still goes to one. 2 € for every order over 50 €, or 1 % of each order. Build spec: https://www.charitips.com/docs/demos/checkout.md
- [Museum shop](https://www.charitips.com/docs/use-cases/donation-per-order/museum-shop.md) (Culture and events): A museum shop gives 2 € on every order over 50 € of prints or books. The shop pays; the visitor picks the charity on the confirmation page or later, from their order history. 2 € for every order over 50 €, or 1 % of each order. Build spec: https://www.charitips.com/docs/demos/checkout/museum-shop.md
- [Gym accessories shop](https://www.charitips.com/docs/use-cases/donation-per-order/gym-shop.md) (Health and sport): A gym's accessories shop gives 2 € on each order over 50 €, or 1 % of the order. The gym pays, and the member picks the charity once the order is confirmed. 2 € for every order over 50 €, or 1 % of each order. Build spec: https://www.charitips.com/docs/demos/checkout/gym-shop.md

## Build it
- **Calls**: [`create-charities-selection`](https://www.charitips.com/docs/api-reference/create-charities-selection.md), [`create-campaign`](https://www.charitips.com/docs/api-reference/create-campaign.md), [`activate-campaign`](https://www.charitips.com/docs/api-reference/activate-campaign.md), [`create-donation`](https://www.charitips.com/docs/api-reference/create-donation.md), [`claim-donation`](https://www.charitips.com/docs/api-reference/claim-donation.md)
- **Webhooks**: `donation_create`, `donation_update`

### Create the campaign

Once, create a charities selection with the charities you want to offer, create the campaign with its `charitiesSelectionId`, then activate it, as in [steps 3 to 5 of Your first donation](https://www.charitips.com/docs/get-started/first-donation.md#3-pick-your-charities). It works as a charity cashback for an online store: the customer picks the charity after paying, so your checkout stays as it is.

```bash
curl -X POST https://api.sandbox.charitips.com/v1/campaigns \
  -H "Authorization: Bearer $CHARITIPS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Order donations",
    "charitiesSelectionId": "<charitiesSelectionId>"
  }'
```

### Give on each paid order

When an order is paid, create a donation with the order id as `uniqueExternalId`. `amount` is in cents. Create it from your payment webhook, not from the browser: if the customer closes the tab, the donation still exists.

```bash
curl -X POST https://api.sandbox.charitips.com/v1/donations \
  -H "Authorization: Bearer $CHARITIPS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "campaignId": "<campaignId>",
    "amount": 200,
    "uniqueExternalId": "<orderId>"
  }'
```

### Show the charities

Read the selection with its charities from your server and render them on the confirmation page. Each charity comes with its `charityId`, `name` and `logoUrl`. The list changes only when you edit the selection: cache it rather than reading it for every order.

```bash
curl "https://api.sandbox.charitips.com/v1/charities-selections/<charitiesSelectionId>?includeCharities=true" \
  -H "Authorization: Bearer $CHARITIPS_TOKEN"
```

### Claim it for the customer's charity

Claim the donation for the charity the customer picks. If the customer never chooses, the donation is assigned automatically when it expires or when the campaign closes. No donation is lost.

```bash
curl -X POST https://api.sandbox.charitips.com/v1/donations/<donationId>/claim \
  -H "Authorization: Bearer $CHARITIPS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "charityId": "<charityId>"
  }'
```

### Listen for the claim

Create a webhook for `donation_update` once, with [Create a webhook](https://www.charitips.com/docs/api-reference/create-webhook.md). Each delivery, shortened here, holds `event`, `payload`, the donation as it is now, and `diff`, the fields that changed. When `diff` holds a `charityId`, the donation is claimed, by the customer or automatically: find the order with `payload.uniqueExternalId`. Verify the signature first, as shown in [Webhooks configuration](https://www.charitips.com/docs/webhooks/configuration.md), and key your handler on `donationId` and `status`, since a delivery can arrive more than once.

```json
{
  "event": "donation_update",
  "payload": { "donationId": "<donationId>", "status": "DONE", "charityId": "<charityId>", "uniqueExternalId": "<orderId>" },
  "diff": { "status": "DONE", "charityId": "<charityId>" }
}
```

## Edge cases

- **Your payment webhook fires twice.** The second create returns `409 Unique constraint failed on uniqueExternalId`. Treat it as success.
- **The order is refunded.** [Delete the donation](https://www.charitips.com/docs/api-reference/delete-donation.md) before it is billed or paid out; after that the API answers 403 (`Donation already invoiced`, `Donation already paid` or `Donation already processed`). Once claimed, its amount is fixed.
- **You want the choice by email instead.** Use a time-limited campaign with `sendingMode` set to `EMAIL` and pass the customer in `donor` with the day to send it in `sendingDate`: Charitips sends the email.

## Related pages

- [Campaigns](https://www.charitips.com/docs/concepts/campaigns.md)
- [Donation lifecycle](https://www.charitips.com/docs/concepts/donation-lifecycle.md)
- [Webhooks](https://www.charitips.com/docs/webhooks/configuration.md)
