You are here:
Recurring Donations Pause API
Write Apex code to pause a Recurring Donation programmatically using the Pause API.
With their recurring giving, your loyal donors provide your organization with a consistent source of funding. But life happens and a donor might request to temporarily suspend their giving due to travel, job loss, or unexpected expenses.
While CRM users can Pause a Recurring Donation through the user interface, NPSP also provides an API for pausing and unpausing Recurring Donations programmatically.
Call Format
- Global Class implementing the API: Callable_API
- Global Method: call()
- Parameters: Map<String, Object>
| Name | Data Type | Required |
|---|---|---|
| PauseData | Map<Id, PauseDataObject> | Yes |
PauseDataObject JSON Format
Construct the JSON request format with PauseDataObject mapped by Recurring Donation ID.
To pause a Recurring Donation, set the startDate and endDate, but set unPause to either false or null.
| Name | Data Type | Required | Description |
|---|---|---|---|
| startDate | Date | No | The pause start date |
| endDate | Date | No | The pause end date |
| statusReason | String | No | The pause reason. Values should match the Status Reason picklist. |
| unPause | Boolean | No | Use true to unpause a Recurring Donation. |
To unpause a Recurring Donation, only unPause needs to set to true. startDate and endDate should be null.
JSON Response Format
The JSON response format shows pause information mapped by Recurring Donation ID.
| Name | Data Type | Required | Description |
|---|---|---|---|
| startDate | Date | No | The pause start date |
| endDate | Date | No | The pause end date |
| statusReason | String | No | The pause reason |
| unPause | Boolean | No | True means an unPause was requested. |
| isSuccess | Boolean | Yes | True means a successful request. |
| Error | String | Yes | A successful request returns 'OK'. A failed request returns an error message. |
Code Sample and JSON Response
Code Sample
// NOTE: Replace the "rd_id_n" in the set below with real recurring donation record ids
Map<Id,Object> rdPauseData = new Map<Id,Object>{
'rd_id_1' => new PauseData(
Date.Parse('04/01/2021'), Date.Parse('06/01/2021'), 'Vacation'
),
'rd_id_2' => new PauseData(
Date.Parse('07/01/2021'), Date.Parse('10/01/2021'), 'Job Change'
),
'rd_id_3' => new PauseData(true), /* Unpause an Rd */
'rd_id_4' => new PauseData(
Date.Parse('10/01/2021'), Date.Parse('05/01/2021'), 'Invalid Dates Test: end date before start date'
),
'rd_id_5' => new PauseData(
Date.Parse('01/01/2025'), Date.Parse('05/01/2025'), 'valid Dates Test'
),
'rd_id_6' => new PauseData(
Date.Parse('01/01/2019'), Date.Parse('03/01/2019'), 'Invalid Dates Test: start date in the past'
),
'rd_id_7' => new PauseData(
Date.Parse('10/01/2021'), Date.Parse('10/01/2025'), 'Invalid Dates Test: start and end date is more than 12 months'
),
'003C00342992343' => new PauseData(
Date.Parse('10/01/2021'), Date.Parse('05/01/2021'), 'Invalid RdId Test: Id not valid'
)
};
Map<String, Object> params = new Map<String, Object> { 'PauseData' => rdPauseData };
try {
// Convert Pause Data to Maps
for (Id key : rdPauseData.keySet()) {
String JSONPauseData = JSON.serialize(rdPauseData.get(key));
rdPauseData.put(key, (Map<String, Object>)JSON.deserializeUntyped(JSONPauseData));
}
Map<String, Object> params = new Map<String, Object> { 'PauseData' => rdPauseData };
// Convert Pause Data to Maps
for (Id key : rdPauseData.keySet()) {
String JSONPauseData = JSON.serialize(rdPauseData.get(key));
rdPauseData.put(key, (Map<String, Object>)JSON.deserializeUntyped(JSONPauseData));
}
Map<String, Object> params = new Map<String, Object> { 'PauseData' => rdPauseData };
npsp.Callable_API apiTest = new npsp.Callable_API();
String jsonResponse = String.valueOf(apiTest.call('rd2.pause', params));
Map<Id, PauseData> result =
(Map<Id, PauseData>)JSON.deserialize(jsonResponse, Map<Id, PauseData>.class);
} catch(Exception ex) {
System.debug('- Error Caught ' + ex.getMessage());
}
/**
* Object structure that is passed to the api call with the RD data to pause
* and is returned as the call response.
*/
private class PauseData {
// Values passed TO the api:
public Date startDate;
public Date EndDate;
public String statusReason;
public Boolean unPause;
// Values returned by the api:
public Boolean isSuccess;
public String error;
// Constructor to define required values to pass to the api.
public PauseData(Date startDate, Date endDate, String reason) {
this.startDate = startDate;
this.endDate = endDate;
this.statusReason = reason;
this.unPause = false;
}
// Constructor to unpause an Rd
public PauseData(Boolean unPause) {
this.unPause = unPause;
}
}JSON Response
{
"a092D000003Vp8pQAC":
{
"startDate" : 2021-06-14
"endDate" : 2021-12-16
"statusReason" : "vacation"
"unPause" : false
"isSuccess" : true
"error" : "OK"
},
"a092D000003V4nHQAC":
{
"unPause" : true
"isSuccess" : true
"error" : "OK"
},
"a092D000003V4ngQAC":
{
"startDate" : 2021-06-14
"endDate" : 2021-01-12
"statusReason" : "vacation"
"unPause" : false
"isSuccess" : false
"error" : "The pause End Date must be greater than the Start Date."
},
"a092D000003V4nIQAC":
{
"startDate" : 2021-06-14
"endDate" : 2021-12-16
"unPause" : true
"isSuccess" : false
"error" : "UnPause requests cannot include Start Date or End Date."
},
"a092D000003V4nJQAC":
{
"startDate" : 2021-06-14
"endDate" : 2025-12-16
"unPause" : true
"isSuccess" : false
"error" : "You can't pause Recurring Donations for more than a year. The pause End Date must be less than one year after the Start Date."
},
}