As payments are made in Pushpay, the information about those payments is made available via the Pushpay public API - a common need is to query for recent payments and then record them in a 3rd party system. This document serves as a guide to our API users who are looking to build a new integration using the API.
For guidance on how to handle rate limiting please see here.
A step-by-step process of how payment synchronization generally works.
Authentication
Code Flow: https://pushpay.io/docs/security#oauth_code_flow
Client Flow: https://pushpay.io/docs/security#oauthclientcredentials_flow
In both cases the following scopes will be needed to synchronize payments:
Retrieve the list of in-scope organizations
https://pushpay.io/docs/operations/organizations#get_v1organizations_in-scope
GET /v1/organizations/in-scope
Retrieve the list of merchant listing for each organization you have access to
https://pushpay.io/docs/operations/organizations#get_v1organizationorganizationKeymerchantlistings
GET /v1/organization/{organizationKey}/merchantlistings
For each merchant listing you will be able to:
If you plan to use Pre-configured Giving links ensure you also store the "handle"
{
"page": 0,
"pageSize": 25,
"total": 1,
"totalPages": 1,
"items": [
{
"homeCountry": "NZ",
"visibility": "Visible",
"status": "Active",
"version": 50,
"key": "MTIzOkRUclhHb1Jtc24tX3NKMGxjZzJ3cUJqb1ZlTQ",
"handle": "widgetinc",
"name": "Widgets Inc",
"address": "123 Summer Grove",
"location": {
"latitude": -36.8567852,
"longitude": 174.7583516
},
Retrieve payments at an organization level
Doing this requires less calls as you get all payments for all merchant listings (as opposed to making a call per listing)
https://pushpay.io/docs/operations/payments#get_v1organizationorganizationKeypayments
GET /v1/organization/{organizationKey}/payments
We recommend using the following query parameters:
Select a frequency for your calls e.g. every hour on the hour. In addition ensure you have an overlap to catch all the payments. E.g. at 2pm you make a call for the previous hour + 10 minutes:
https://api.pushpay.com/v1/organization/MTpZc2M4M3hOM05KMmdxOHpDQklvYkxqQWpfY2M/payments?updatedFrom=2020-01-01T12:50:00Z&updatedTo=2020-01-01T14:00:00Z
You can then poll our API every hour pushing the window forward by one hour each time. Ensure you always have that 10 minute overlap.
Donor Identification
https://pushpay.io/docs/operations/payments#get_v1organizationorganizationKeypayments
In the payment, find the payer representation - which will have a key - this is the "pushpay account key":
"payer": {
"key": "MDoxWWpVN2dpTjNzeDdfMTdCcXk1bnZjOUJ5Qzg",
"emailAddress": "joe.bloggs@test.com",
"mobileNumber": "+15555555555",
"fullName": "Joe Bloggs"
...
},
A step-by-step process of how a settlement batch import generally works.
Authentication
Code Flow:
https://pushpay.io/docs/security#oauth_code_flow
Client Flow: https://pushpay.io/docs/security#oauthclientcredentials_flow
In both cases the following scopes will be needed to synchronize payments:
Retrieve the list of in-scope organizations
https://pushpay.io/docs/operations/organizations#get_v1organizations_in-scope
GET /v1/organizations/in-scope
Retrieve the list of merchant listing for each organization you have access to
https://pushpay.io/docs/operations/organizations#get_v1organizationorganizationKeymerchantlistings
GET /v1/organization/{organizationKey}/merchantlistings
Fetch recent settlements
https://pushpay.io/docs/operations/settlements#get__v1_merchant_merchantKey_settlements
Fetch the settlements updated since last time your code checked.
GET /v1/settlements?updatedFrom=2015-12-11T00:00:00Z&page=0
The results are paged so you will need to keep fetching pages of settlements until you've read them all.
GET /v1/settlements?updatedFrom=2015-12-11T00:00:00Z&page=1
GET /v1/settlements?updatedFrom=2015-12-11T00:00:00Z&page=2
Each page of settlements details returned will include some links in the response for the next page, if there is one - using these links can simplify the process of paging in our API.
"_links": {
"self": {
"href": "https://api.pushpay.com/v1/merchant/MTpZc2M4M3hOM05KMmdxOHpDQklvYkxqQWpfY2M/settlements?updatedFrom=2015-12-11T00:00:00Z&page=1"
},
"next": {
"href": "https://api.pushpay.com/v1/merchant/MTpZc2M4M3hOM05KMmdxOHpDQklvYkxqQWpfY2M/settlements?updatedFrom=2015-12-11T00:00:00Z&page=2"
}
}
As an alternative, if it makes sense you can loop through individual merchant listings, retrieving the settlements per merchant listing (this is similar the payment import process described earlier in this document).
Loop through the in-scope merchants.
https://pushpay.io/docs/operations/settlements#get__v1_merchant_merchantKey_settlements
For each merchant you can retrieve the list of batches updated since the last time synchronization was performed (in UTC)
GET /v1/merchant/{merchantKey}/settlements?updatedFrom=2015-12-11T00:00:00Z&page=0
The results are paged so you will need to keep fetching pages of settlements until you've read them all.
GET /v1/merchant/{merchantKey}/settlements?updatedFrom=2015-12-11T00:00:00Z&page=1
GET /v1/merchant/{merchantKey}/settlements?updatedFrom=2015-12-11T00:00:00Z&page=2
Fetch the payments for a settlement.
In the details of each settlement is a link to the payments within a settlement ("settlementpayments") - fetching this will retrieve a paged list of payments.
{
"key": "MDpkQUFOQ1FzdE1BLVZfVWZFdEZkQ3dvb3YyTDg",
"name": "Settlement #1",
"totalAmount": {
"amount": "202.00",
"currency": "USD"
},
"type": "ACH",
"totalPayments": 2,
"estimatedDepositDate": "2016-01-03T07:00:00Z",
"isReconciled": true,
"_links": {
"self": {
"href": "https://api.pushpay.com/v1/settlement/MDpkQUFOQ1FzdE1BLVZfVWZFdEZkQ3dvb3YyTDg"
},
"settlementpayments": {
"href": "https://api.pushpay.com/v1/settlement/MDpkQUFOQ1FzdE1BLVZfVWZFdEZkQ3dvb3YyTDg/payments"
}
}
}
The payments are paged - you will need to retrieve all pages of payments to be able to see the entire list of payments.
GET /v1/settlement/{settlementKey}/payments?page=0
GET /v1/settlement/{settlementKey}/payments?page=1
GET /v1/settlement/{settlementKey}/payments?page=2
If your integration needs to synchronize payments constantly, rather then in batches, you can do so by configuring a webhook (either via the Merchant Admin portal, or by using the webhooks API) https://pushpay.io/docs/operations#post__v1_merchant_merchantKey_webhooks. Once the webhook is configured, every time a payment is created or updated, a POST request will be sent to the URI you configured in the webhook. The body of the events are JSON:
{
"subscription": "http://api.pushpay.com/v1/webhook/token",
"events": [
{
"date": "2015-01-02T03:04:05Z",
"eventType": "payment_created",
"entityType": "Payment",
"links": {
"merchant": "http://api.pushpay.com/v1/merchant/MTIzOkRUclhHb1Jtc24tX3NKMGxjZzJ3cUJqb1ZlTQ",
"payment: "/v1/merchant/MTIzOkRUclhHb1Jtc24tX3NKMGxjZzJ3cUJqb1ZlTQ/payment/q235azs3KMGxjZzJ3cUJqb1349s0909"
}
}
]
}
No sensitive information is included in the webhook event - it will only contain links to the affected items which can be retrieved to find more details.
A common problem for systems synchronizing payments is how to deal with bank payments which may take up to 7 days to process. Within Pushpay these payments will be immediately visible, and have a status of "Processing". At the point they succeed (or return) the status will then change to "Success" or "Failed". This could take up to 7 days to happen. In some systems you may already have the concept of a "Processing" payment, in which case the 2 systems will align well. Otherwise, there are 2 options: * Not displaying the payment until it's status has changed to Success. However, this can lead to a lot of user confusion. * Show the payment immediately, but then "handle" the uncommon case of the payment failing, rather then succeeding. We refer to this as compensation - as soon as the payment has a status of processing, treat it as a successful payment in your system. If it later fails, either void the payment in your system- OR - create a second "compensating" payment that has all the same details but a negative amount (so it negates the original payment). By doing so you provide an experience which is much less confusing to merchant administrators.
Development is always done against the sandbox environment - Pushpay does not issue production API credentials until it has seen evidence of an integration working against the sandbox environment. Sandbox access can be requested (as well as general support for the API) by sending an email to api@pushpay.com To configure sandbox access we need to know: