Donation Push API

This API endpoint is meant to provide an easy way to send donation data to ActionKit for donations that have been processed elsewhere (eg, through ActBlue). It tries to make the simple case easy, while totally ignoring any complicated cases.

You can send information about an order, a user, and a page in a single request, and objects that don't exist in the database will be created. You can also create, update and cancel recurring profiles.

There are 4 related endpoints in this API:

Endpoint Description
/rest/v1/donationpush/ Add one-time donations and create recurring donation profiles.
/rest/v1/recurringpaymentpush/ Add recurring payments to a previously pushed profile.
/rest/v1/profileupdatepush/ Update a previously pushed profile.
/rest/v1/profilecancelpush/ Cancel a previously pushed profile.

Note

This API endpoint will not process donations. You must use a page that is using an Import Stub or send a payment_account name of an Import Stub with the order.

DonationPush

The input is a dictionary, the following keys are required:

The following keys are optional:

Refer to the Input details section for more details.

Example

Here is a sample request and response.

POST'd to /rest/v1/donationpush/, this request would find or create a DonationPage named "pushit" using the payment_account "Default Import Stub", find or create a User "donor@example.com" and create an Order of $34 for the User.

POST /rest/v1/donationpush/
{
    "donationpage": {
        "name": "pushit",
        "payment_account": "Default Import Stub"
    },
    "order": {
        "amount": "34.00",
        "card_code": "007",
        "card_num": "4111111111111111",
        "exp_date_month": "12",
        "exp_date_year": "2015"
    },
    "user": {
        "address1": "123 Main St.",
        "city": "City",
        "country": "United States",
        "email": "[email protected]",
        "first_name": "Donor",
        "last_name": "Example",
        "state": "NY",
        "zip": "10014"
    }
}

Here's the response from a development server, the IDs and timestamps are obviously dependent on the server.

200 OK
{
    "akid": ".514.lQVxcW",
    "created_at": "2014-11-03T16:03:21.672820",
    "created_user": false,
    "fields": {},
    "id": 5,
    "ip_address": "86.73.198.132",
    "is_forwarded": false,
    "link": null,
    "mailing": null,
    "opq_id": "",
    "order": {
        "account": "Default Import Stub",
        "action": "/rest/v1/donationaction/5/",
        "card_num_last_four": "1111",
        "created_at": "2014-11-03T16:03:21.895203",
        "currency": "USD",
        "id": 2,
        "import_id": null,
        "orderdetails": [],
        "orderrecurrings": [],
        "resource_uri": "/rest/v1/order/2/",
        "shipping_address": null,
        "status": "completed",
        "total": "34.00",
        "total_converted": "34.00",
        "transactions": [
            "/rest/v1/transaction/2/"
        ],
        "updated_at": "2014-11-03T16:03:21.925342",
        "user": "/rest/v1/user/514/",
        "user_detail": "/rest/v1/orderuserdetail/2/"
    },
    "page": "/rest/v1/donationpage/12/",
    "referring_mailing": null,
    "referring_user": null,
    "resource_uri": "/rest/v1/donationaction/5/",
    "source": "restful_api",
    "status": "complete",
    "subscribed_user": false,
    "taf_emails_sent": null,
    "type": "Donation",
    "updated_at": "2014-11-03T16:03:21.861623",
    "user": "/rest/v1/user/514/"
}

Input Details

This section describes in more detail the data you can send for the order, recurring profiles, user, donationpage, and action.

Order

Required fields:

  • amount
  • card_num, a dummy cc number, the last four digits are saved to core_order.card_num_last_four
  • card_code, literal string "007"
  • exp_date_month, 2 digit month
  • exp_date_year, 4 digit year

Amount is required in the order or in a list of orderdetails. The amounts in both will be summed for you to create the resulting total in Order. Amounts should be supplied as a string like "10.00", not a bare integer or float value.

The card_num and card_code are required.

The "card_num" value can not be empty, but it shouldn't be a valid credit card number. The last four characters of the value you send will be saved in the core_order table, so you can send the full card number (but don't do that), or just the last four digits, or a placeholder value such as "4111111111111111".

The value for card_code must be 007, unless ActionKit support has told you otherwise. See Donation Action Requests for more details.

Optional fields:

  • orderdetails, an array of order items and amounts
[ { "candidate": { "name": "Big Time Candidate" }, "amount": "13" },
{ "candidate": { "name": "Smaller Time Cnadidate" }, "amount: "5.00" } ]

We currently only support Candidates. The candidate dictionary should contain a name or an id field, e.g. { "id": 2 }. ActionKit will never update the name of a candidate from a request to /donationpush/

  • created_at, timestamp for the order and action will be set, and for the user if this action creates a new one
  • donation_date, timestamp for order will be set
You can use the created_at field to date the order and action. It will also date the user if the action creates a new user. Timestamps must be in Greenwich Mean Time (GMT) time zone. You can use the field donation_date to date only the order.
  • payment_account, the name of a configured Import Stub payment account.

Import Stubs are payment accounts that do no actual processing. ActionKit support will add Import Stub payment accounts for you. You can use the stubs to add donations to DonationPages, without processing the donations in ActionKit.

Sending a payment_account with your request will override the payment_account of the DonationPage configured in ActionKit.

  • donation_import_id, a unique ID that ActionKit will only import once
If you provide donation_import_id, ActionKit will check the database for orders with the same ID and return a 409 CONFLICT if one is found. The headers will include a Location of the existing order.
  • currency, a three letter ISO currency code
If you provide a currency, ActionKit will save it to the order (and recurring order), and save a converted amount (using current exchange rates).
  • donation_currency, a three letter ISO currency code - DEPRECATED
  • total_converted, an amount in USD of the donation
If you send donation_currency with the request (as part of the order), ActionKit will save the Order with this currency in the currency column, and set total_converted to a converted USD amount. You can send total_converted if you wish to directly set the converted amount.
  • trans_id, the ID of the transaction in the remote system
Recurring Profiles

You can send recurring profiles through in the same way, by supplying additional fields with the order.

Required fields:

  • recurring_id, The profile ID in the remote system. This must be unique for the selected payment account. Duplicates are allowed if they are on different payment accounts.

Optional fields:

  • recurring_period, One of "weeks" or "months" (defaults to "months")
  • recurring_start, The date that the recurring charges start (optional, defaults to today + recurring_period + one day, just like real recurring donations do)

If a recurring_id is present, posting to the endpoint will create a core_orderrecurring entry and a core_transaction entry with type “recurring_order_create” in addition to the usual core_order, page, action, and user objects. The recurring_id will be stored in core_orderrecurring.recurring_id. You will use that same recurring_id to push future payments and profile changes.

Note

This will not create a payment, just the profile. This is consistent with the way that Braintree processes recurring orders, but unlike some other processors. You can add payments with the recurring payment endpoint below.

User

Required fields:

  • email or akid

Optional fields:

  • first_name
  • last_name
  • address1
  • city
  • country
  • state / region
  • zip / postal
  • source

At least one of "email" or "akid" is required. The "name" field is required unless a user with the given email address already exists. The address-related fields are optional and may be skipped if you want to avoid overwriting the user's current location.

  • fields

A list of custom user fields and values to assign to the user.

"fields': { "favorite_color": "#333300",
"favorite_flavor": ["Blueberry", "Vanilla"] }

ActionKit will remove the user prefix if you include it on the field names, will replace the value(s) of individual existing user fields, but will not replace the full set of existing fields.

  • lists

A list of dictionaries describing Lists to which the user should be subscribed. You can send lists in two formats, a dictionary containing a name key or a simple ID.

lists: [ 2, { "name": "Another To Create" }, 45 ]

By default, users will be subsribed to the list associated with the DonationPage in ActionKit. You can send an empty list to prevent a user from being subscribed.

lists: []
  • akid

If you include an akid, the action source will be set to the mailing id included in the akid. If the email submitted does not match the email of the user in the akid, the user id and the mailing id from the akid will be saved as the action's referring_user_id and referring_mailing_id, respectively.

  • source

The source field will be used to set the value of core_user.source as well as core_action.source. You can set a distinct source for the action using an additional source field in the action data.

DonationPage

Required fields:

  • name, a URL safe name for the page

Optional fields:

OMG SO MANY!!

You can send any field supported by the RESTful API here. We don't really recommend creating DonationPages this way, but you can. See /rest/v1/donationpage/schema/ for the full list of fields.

ActionKit will create the DonationPage if it does not exist, but will never update an existing page based on input provided here.

Action

Optional fields:

  • created_at, a timestamp for the action
  • source, a string used for the source field in the core_action table. If no source is set in user, this will be used for the core_user source field as well.
  • fields, a dictionary of action fields
  • skip_confirmation, if true do not send the confirmation email

Recurring Payments And Attempts

If you've created the recurring profile, then you can push recurring payments by POSTing to the endpoint /rest/v1/recurringpaymentpush/. These can be successful payments or even failed payments that you want to capture for reporting purposes.

Required fields (one or the other, with order_id taking precedence):

  • order_id - The order_id of the recurring order in ActionKit
  • recurring_id - The profile ID in the remote system. Matched against core_orderrecurring.recurring_id. If there are duplicate recurring_id entries in your data, you must specify order_id instead.

Optional fields:

  • created_at - Sets the timestamp on the core_transaction record
  • amount - Defaults to the amount in the profile
  • currency - Defaults to currency in the profile
  • trans_id - ID of the transaction in the remote system.
  • success - Boolean, defaults to True
  • status - One of "completed", "failed", "reversed", defaults to "completed"
  • failure_code - A failure code from the remote system
  • failure_description - A failure description from the remote system
  • failure_message - A failure message from the remote system.

We will not generate errors for disagreeing with the period specified, e.g. if you set up a profile with recurring_period of "months" but only give us one payment every year, it won’t trigger any errors on our end.

Failed attempts may be pushed, indicated by the status and success parameters. Details of the failure can be passed in the failure_* parameters, although we will not do any verification of these. They will simply be stored for future reference.

Updates To Existing Profiles

You can update previously pushed recurring order profiles by POSTing to /rest/v1/profileupdatepush/. Note that this will only update pushed profiles tied to import stub accounts.

Required fields (one or the other, with order_id taking precedence):

  • order_id - The order_id of the recurring order in ActionKit
  • recurring_id - The profile ID in the remote system. Matched against core_orderrecurring.recurring_id. If there are duplicate recurring_id entries in your data, you must specify order_id instead.

Optional fields (only pass those you are changing):

  • recurring_period, One of "weeks" or "months" (defaults to "months")
  • recurring_start, The date that the recurring charges start (optional, defaults to today + recurring_period + one day, just like real recurring donations do)
  • card_num - The last four digits will be stored in core_orderrecurring.card_num
  • exp_date_month - Card expiration month in MM format
  • exp_date_year - Card expiration year in YY format
  • exp_date - Card expiration date in MMYY format (alternate for passing them separately)
  • amount
  • currency
  • trans_id - ID of the transaction in the remote system.
  • created_at - Sets the timestamp on the core_transaction record

This will update the row in core_orderrecurring and create a row in core_transaction with type "recurring_order_update".

Cancellations Of Existing Profiles

To cancel a previously pushed profile, you can POST to /rest/v1/profilecancelpush/. Again, this will only cancel pushed profiles tied to import stub accounts.

Required fields (either recurring_id or order_id, with order_id taking precedence):

  • order_id - The order_id of the recurring order in ActionKit
  • recurring_id - The profile ID in the remote system. Matched against core_orderrecurring.recurring_id. If there are duplicate recurring_id entries in your data, you must specify order_id instead.
  • canceled_by - One of "user", "admin", "processor", "failure", "expired"

Optional fields:

  • trans_id - ID of the transaction in the remote system.
  • created_at - Sets the timestamp on the core_transaction record

The row in core_orderecurring will be changed to a cancellation status based on the reason parameter. A core_transaction row will be created with type “recurring_order_cancel”.

Errors

Bad requests will return a status code of 400, with information in the body about the invalid input.

For example, an invalid payment account would return:

{ "donationpage": {
    "payment_account": [
       "'Default Authorize.net' is not a valid payment account for this call, it uses a real processor. Available import stub payment accounts: 'Default Import Stub', 'European Import Stub'" ]}}

Errors that occur during action processing, and not the Donation Push setups, will be keyed as "errors".

{ "errors": {"amount:invalid": [
    "The amount you entered does not appear to be a valid dollar amount."]}})