Reversing Donations and Canceling Recurring Profiles¶
This API lets you refund donations and cancel recurring donation profiles through the same REST endpoints used to fetch them.
A reversal on an order or transaction calls the payment processor to request a refund or void. A cancel on a recurring profile stops future charges but does not refund anything that has already been charged.
Warning
Reversals are permanent. Once a charge has been reversed at the processor
there is no way to undo it — the donor’s card has been credited and the
transaction is marked reversed in ActionKit. If you want the donation
back, the donor has to make a new one.
The staff account you authenticate with must have permission to manage donations.
Background: Orders, Transactions, and Recurring Profiles¶
Before reversing a donation it helps to know how the three relevant resources relate:
/rest/v1/order/(core_order) — one row per donation action. For a recurring donation there is exactly one order per recurring profile, not one order per charge./rest/v1/transaction/(core_transaction) — one row per processor interaction (sale, credit, etc.) attached to an order. A recurring profile’s single order accumulates multiple transaction rows over time, one per successful or failed charge./rest/v1/orderrecurring/(core_orderrecurring) — the recurring profile (schedule, account, status, etc).
This means a recurring donation has one order, one orderrecurring, and many transactions. When picking which endpoint to use, read the next two sections.
To do this |
Use |
|---|---|
Refund a one-time donation |
|
Refund a specific recurring charge |
|
Stop a recurring profile |
|
Reverse An Order¶
POST to /rest/v1/order/<order_id>/reverse/ to reverse the order’s
initial payment. The request body is ignored.
$ curl -i -u user:password -X POST \
https://docs.actionkit.com/rest/v1/order/12345/reverse/
HTTP/1.1 202 ACCEPTED
After a successful reversal the order’s status becomes reversed and
the underlying transaction’s status becomes reversed. If the order
has already been reversed the endpoint returns 400 Bad Request:
{ "order_id": "Order has already been reversed." }
Note
Don’t use this endpoint for recurring donations. If you want to reverse payments, reverse the specific transaction instead — see Reverse A Transaction. If you want to stop future payments, see Cancel A Recurring Profile.
When you GET an order whose status is completed, the response
includes a "reverse" URL pointing at this endpoint, so clients can
discover the action without hard-coding the URL pattern:
{
"id": 12345,
"status": "completed",
"reverse": "/rest/v1/order/12345/reverse/",
...
}
Reverse A Transaction¶
POST to /rest/v1/transaction/<transaction_id>/reverse/ to reverse a
specific transaction. This is the right endpoint for refunding one charge
in a recurring series. The request body is ignored.
Note
<transaction_id> is the ActionKit primary key
(core_transaction.id), not the processor’s transaction ID
(core_transaction.trans_id). This is a common mistake.
$ curl -i -u user:password -X POST \
https://docs.actionkit.com/rest/v1/transaction/98765/reverse/
HTTP/1.1 202 ACCEPTED
After a successful reversal the transaction’s status becomes
reversed. If the transaction has already been reversed the endpoint
returns 400 Bad Request:
{ "order_id": "Transaction has already been reversed." }
Note
Only full reversals are supported through the API. Partial refunds must be issued through the admin interface.
As with orders, completed transactions include a discoverable "reverse"
URL in their GET response.
To find the transactions attached to an order, filter the transaction list
by order:
GET /rest/v1/transaction/?order=12345
Cancel A Recurring Profile¶
POST to /rest/v1/orderrecurring/<orderrecurring_id>/cancel/ to cancel a
recurring profile. This stops future charges but does not refund
anything that has already been charged. To refund past charges, reverse the
relevant transactions (see Reverse A Transaction). The request body is
ignored.
$ curl -i -u user:password -X POST \
https://docs.actionkit.com/rest/v1/orderrecurring/4567/cancel/
HTTP/1.1 202 ACCEPTED
The profile must be in an active state (active, pending, or
past_due). If it is already in a terminal state the endpoint returns
400 Bad Request with the current status:
{ "orderrecurring_id": "OrderRecurring is not active: Canceled by user" }
When you GET an active recurring profile, the response includes a
"cancel" URL pointing at this endpoint.
Note
This is the operational cancel endpoint, which talks to the payment processor. If you instead need to record a cancellation that already happened in an external system (an import stub workflow), see Cancellations Of Existing Profiles in the Donation Push API.