Skip to content

Donation Completed Message

When a donation is made in an embedded donation form, it triggers an event (via postMessage) that your application can consume. The format for the postMessage payload is a stringified JSON object specifying the associated data, so be sure to parse the JSON before using it. Alternatively, if you have a webhook endpoint configured, you will be notified of donations that way. See our webhook documentation for more information.

{
"message": "DonateCompleted",
"data": { }
}

Every payload’s data object carries currencyType and pending. Read currencyType first — it tells you which of the remaining keys are present and how to interpret them.

currencyTypeAdditional keysWhen
fiatcurrency, amount, fees, tip, totalA donation denominated in a fiat currency.
cryptocurrency, amountA crypto donation. amount is denominated in the native asset, to eight decimal places.
otherNoneNo amount or no currency is available at the time of the donation. Stock donations work this way — the real figures arrive later by webhook.
KeyTypeDescription
currencyTypestringOne of fiat, crypto or other. Determines which other keys are present.
pendingbooleanWhether the money had settled at the time we sent the message. See Pending donations.
currencystringFor fiat, an uppercase ISO 4217 code such as "USD" or "EUR". For crypto, the asset ticker.
amountstringThe donor’s gift. This never includes any fees the donor chose to cover.
feesstring | nullWhat the donor actually paid to cover processing costs, or null if they were not charged any. This is not a quote of what covering costs would have cost.
tipstring | nullWhat the donor actually tipped, or null if they did not tip.
totalstringWhat was actually charged.

For fiat donations, total always satisfies:

total == amount + (fees ?? 0) + (tip ?? 0)

All money values are decimal strings, not numbers — "50.00", not 50. Do not assume two decimal places. On fiat donations the number of decimal places follows the currency’s exponent, so a zero-decimal currency such as JPY sends "196" rather than "196.00". On crypto donations, amount always carries eight decimal places — "0.00051234".

pending marks money that has not settled at the point we notify your page.

pendingPayment methods
trueACH/bank, wire, check, pledge, DAF, stock
falseCard, Apple Pay, Google Pay, PayPal, Venmo, employee wallet, crypto

Crypto donations are deliberately false: we do not send the message until the transfer has been observed on-chain.

A fiat donation of $20.00 with a $3.00 tip, paid by card:

{
"message": "DonateCompleted",
"data": {
"currencyType": "fiat",
"pending": false,
"currency": "USD",
"amount": "20.00",
"fees": null,
"tip": "3.00",
"total": "23.00"
}
}

A fiat donation of $20.00 where the donor accepted covering the processing costs, paid by card:

{
"message": "DonateCompleted",
"data": {
"currencyType": "fiat",
"pending": false,
"currency": "USD",
"amount": "20.00",
"fees": "1.93",
"tip": null,
"total": "21.93"
}
}

A crypto donation, denominated in the native asset:

{
"message": "DonateCompleted",
"data": {
"currencyType": "crypto",
"pending": false,
"currency": "BTC",
"amount": "0.00051234"
}
}

A stock donation, where no amount or currency is available yet:

{
"message": "DonateCompleted",
"data": {
"currencyType": "other",
"pending": true
}
}

Listen for message events on your page, confirm the event came from us, parse the string into a JSON object, and then branch on currencyType to decide how to read the amounts.

Example code consuming the donation completed message

Section titled “Example code consuming the donation completed message”
const donationCompleted = data => {
switch (data.currencyType) {
case 'fiat':
// data.currency is an ISO 4217 code, e.g. "USD"
return showThankYou(data.amount, data.currency, data.pending)
case 'crypto':
// data.currency is an asset ticker, e.g. "BTC"
return showCryptoThankYou(data.amount, data.currency)
case 'other':
// No amount available yet — the figures arrive later by webhook
return showThankYou()
}
}
const handleMessage = e => {
if (e.origin != 'https://www.pledge.to') return
const payload = JSON.parse(e.data)
if (payload.message === 'DonateCompleted') {
donationCompleted(payload.data)
}
}
addEventListener('message', handleMessage)