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.
Required scopes
Section titled “Required scopes”orders:createorders:view(to inspect the resulting order)batches:view(to inspect the resulting batch)
1. Find the fund
Section titled “1. Find the fund”Donations land in a Fund (general operating, building, scholarship,
etc.). List the funds your tenant has configured:
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.
2. Create the order
Section titled “2. Create the order”FUND_ID="00000000-0000-0000-0000-000000000001"CONTACT_ID=1834IDEMPOTENCY_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.
3. (Optional) Inspect the batch
Section titled “3. (Optional) Inspect the batch”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.
Always set idempotencyKey
Section titled “Always set idempotencyKey”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.
Tax-deductible flag
Section titled “Tax-deductible flag”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.
Common failures
Section titled “Common failures”| Status | errors | Fix |
|---|---|---|
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. |
Donations across multiple funds
Section titled “Donations across multiple funds”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.
What’s next
Section titled “What’s next”- Receipt the donation via
tax-statementflows (operator-driven for v1 — see Resources → out of scope). - Subscribe to
order.createdandorder_donation.createdto replicate the gift into your warehouse: see Listen for events.