Skip to content

Record a donation

Donations record as OrderDonation lines on an Order. To record a gift, you create an order. This recipe shows the simplest case — a Cash payment, no items, one fund — and how the result attaches to a daily batch automatically.

For card payments, see Charge a card.

  • orders:create
  • orders:view (to inspect the resulting order)
  • batches:view (to inspect the resulting batch)

Donations land in a Fund (general operating, building, scholarship, etc.). List the funds your tenant has configured:

Terminal window
curl -sS \
-H "X-Api-Key: $AURA_API_KEY" \
"https://api.auradonors.com/api/tenants/$TENANT_ID/funds" | jq '.[] | {id, name, isTaxDeductible}'

Pick the right id for the donation. Fund metadata changes rarely — cache it on your side.

Terminal window
FUND_ID="00000000-0000-0000-0000-000000000001"
CONTACT_ID=1834
IDEMPOTENCY_KEY=$(uuidgen)
curl -sS -X POST \
-H "X-Api-Key: $AURA_API_KEY" \
-H "Content-Type: application/json" \
-d "$(cat <<JSON
{
"contactId": $CONTACT_ID,
"items": [],
"donations": [
{ "fundId": "$FUND_ID", "amount": 100.00 }
],
"billingAddress": {
"line1": "1 Market St",
"city": "San Francisco",
"stateProvince": "CA",
"postalCode": "94105",
"country": "US"
},
"saveBillingToContact": false,
"saveShippingToContact": false,
"payments": [
{
"paymentMethod": "Cash",
"amount": 100.00,
"savePaymentMethod": false
}
],
"idempotencyKey": "$IDEMPOTENCY_KEY"
}
JSON
)" \
"https://api.auradonors.com/api/tenants/$TENANT_ID/orders"

Cash payments don’t touch a payment processor — the order returns immediately with OrderStatus = "Completed" and the payment row’s PaymentStatus = "Captured".

The response is 201 Created with the full OrderDto:

{
"id": "9c4a7b2d-...",
"orderNumber": 10042,
"contactId": 1834,
"orderStatus": "Completed",
"donationSubtotal": 100.00,
"totalAmount": 100.00,
"donations": [
{ "id": "...", "fundId": "...", "amount": 100.00, "isTaxDeductible": true }
],
"payments": [
{
"id": "...",
"paymentMethod": "Cash",
"amount": 100.00,
"paymentStatus": "Captured",
"batchId": "f1e2d3c4-..."
}
]
}

Note the payments[0].batchId. Auto-batch picked the right batch by matching the payment method (Cash) to a BatchType named the same way, grouped by department and calendar day. If no matching open batch existed, one was created.

Terminal window
BATCH_ID=$(echo "$response" | jq -r '.payments[0].batchId')
curl -sS \
-H "X-Api-Key: $AURA_API_KEY" \
"https://api.auradonors.com/api/tenants/$TENANT_ID/batches/$BATCH_ID"

Returns the batch’s daily totals, count, status (Open until an operator reconciles and closes it), and the list of attached payments.

Even though Cash payments can’t double-charge a processor, the idempotencyKey field is still the right call: it stops a network blip from creating two Order rows for the same gift.

Mint a fresh Guid per logical gift and never reuse it. See Idempotency for the full retry contract.

The isTaxDeductible flag on each OrderDonation is snapshotted from the fund at creation time. If you flip a fund’s isTaxDeductible setting later, the historical donations keep the flag they had when the order was recorded — that’s the contract the tax-statement generator relies on. Don’t post-edit.

StatuserrorsFix
400{"": ["Contact not found."]}The contactId doesn’t exist in this tenant.
400{"": ["Contact is not active."]}Reactivate the contact first.
400{"Donations[0].FundId": ["Not a valid GUID."]}Check the fund id.
400{"": ["Donation amount must equal payment total."]}Donations + items + shipping + handling + tax + processing fee must sum to the payments total.
400{"": ["The batch is closed."]}A specific batchId was supplied and it’s already closed. Drop the field to let auto-batch pick.

Just include multiple entries in donations:

"donations": [
{ "fundId": "fund-general", "amount": 80.00 },
{ "fundId": "fund-scholarship", "amount": 20.00 }
]

The total payment must still equal the sum of all donations + line items

  • shipping + handling + tax + processing fee.
  • Receipt the donation via tax-statement flows (operator-driven for v1 — see Resources → out of scope).
  • Subscribe to order.created and order_donation.created to replicate the gift into your warehouse: see Listen for events.