Class Library & Invocable Methods

The SmarterPay for Salesforce package provides a comprehensive set of global classes that help with creating records, processing API/Webhook queues and communicating directly with SmarterPay Cloud.


A series of Invocable methods and Service classes are provided in the package to enable simple interface with the SmarterPay Cloud API. These can not only be used from Apex code within Salesforce, but also from Flows or even external calls using the Salesforce REST API.

Invocable methods will create the records directly in SmarterPay Cloud, the corresponding Salesforce records are created upon receipt of the webhook from SmarterPay Cloud. Values can be included in the metadata to enable lookups to the corresponding Account and Contact (or Custom object) for the record.

Invocable Method
Bank Account
Mandate



Bank Account

Action: Create or Update a Bank Account.
URL: /services/data/v56.0/actions/custom/apex/SmarterPay__InvocableUpsertBankAccount
Apex Class: InvocableUpsertBankAccount.Invocable_UpsertBankAccount

Used to create or update a bank account via the SmarterPay Cloud API.

Example Request:

{
  "inputs": [
    {
      "SortCode": "200000",
      "CustomReference": "Example Reference",
      "AccountNumber": "55779911",
      "AccountName": "John Smith",
      "metadata": {
        "additionalFields": [
          {
            "fieldValue": "0052z00000569aOAAQ",
            "fieldAPIName": "SmarterPay__Contact__c"
          }
        ]
      }
    }
  ]
}

Example Repsonse:

[
  {
    "actionName": "SmarterPay__InvocableUpsertBankAccount",
    "errors": null,
    "isSuccess": true,
    "outputValues": {
      "BankAccountSMPCId": "BA01D1LRPM4YKGK8YEQG",
      "Error": false,
      "ErrorDetails": null
    }
  }
]


Mandate

Action: Create or Update a Mandate.
URL: /services/data/v56.0/actions/custom/apex/SmarterPay__InvocableUpsertMandate
Apex Class: InvocableUpsertMandate.Invocable_UpsertMandate

Used to create or update a Mandate via the SmarterPay Cloud API

Example Request:

{
  "inputs": [
    {
      "BankAccountSMPCId": "BA015D0G80XGDG1PERW4",
      "metadata": {
        "additionalFields": [
          {
            "fieldValue": "0033G00000G98YTQAZ",
            "fieldAPIName": "SmarterPay__Contact__c"
          }
        ]
      }
    }
  ]
}

Example Repsonse:

[
  {
    "actionName": "SmarterPay__InvocableUpsertMandate",
    "errors": null,
    "isSuccess": true,
    "outputValues": {
      "Error": false,
      "ErrorDetails": null,
      "MandateSMPCId": "M01G420EJ9G64ZP1VQW"
    }
  }
]

Sometimes developers need to communicate with other third-party systems, either within the Salesforce ecosystem or off platform entirely. For example, when a SmarterPay Payment is returned as 'Successful' an Accounting system may need to be notified.

Salesforce developers have the opportunity to make use of some of the inbuilt queuing infrastructure in the SmarterPay for Salesforce package so that they can focus solely on writing the integrations. This is made available through global interfaces and definitions in Custom Metadata objects.


API Queue Processor

To implement your own API Queue Processor you must create a class which implements a Global Interface called 'IAPIQueueProcessor' and an associated Custom Metadata record on the 'API_Queue_Processor' object.

The 'IAPIQueueProcessor' requires three methods. Ensure that the class and each method is marked as global, otherwise the API Queue will not be able to be run by the managed package.

build: Used to build the API Queue with the appropriate fields populated, such as custom lookup fields.

additionalFieldsForQuery: Any additional related parent fields you need to query and use in your API Queue Processor.

execute: The method which performs the API callout.

Feel free to use the example provided as a starting point.


Create an API Queue Record

To create an API Queue record you can either manually create a record and insert it or use the available package helper method.

insert SmarterPay.APIQueueHelper.generateAPIQueueRecords(yourNewRecords, yourOldRecords, 'Insert/Update/Retrieve', 'Your Defined Type');

This helper method will call your implantation of the 'build' method in your Processor Class.

It accepts new and old versions of your triggering records (the latter available if in a trigger), the event (which can be used to determine which API Call to use) and the API Queue Type (which determines which API Queue Processor Class to call).


The API Queue Custom Metadata

So the API Queue knows which class to run for an API Queue Processor Class you must create an API Queue Custom Metadata record.

Active: You can temporarily disable an API Queue Processor using this field. This can be helpful if you require some time to debug a problem.

Class: The class that should be called when processing the API Queue record. This class must implement the 'IAPIQueueProcessor' interface.

Description: A free text area that you can use to be able to identify the record in the future.

Type: This should match the Type field on your API Queue record.


Run an API Queue Record

The API Queue will automatically run when it is inserted with the status of 'Ready for Processing'.


Additional Notes

Named Crednetials: If you are using a Named Credential to perform the callout to the external third party service you may need to define the specific user that is used to run the API Queue. By default the API Queue uses the 'Automated Process' user which does not have access to Named Credentials. We would recommend using the free API Only User or a dedicated user for automation tasks.

global class MyCustomAPIQueueProcessor implements IAPIQueueProcessor 
{
    global API_Queue__c build(sObject targetObject, sObject oldObject, String event)
    {
        API_Queue__c queue = new API_Queue__c(
            Record_Id__c = targetObject.Id,
            Event__c = event,
            Type__c = 'Your Defined Type',
            Record_JSON__c = JSON.serializePretty(targetObject),
            Previous_Record_JSON__c = JSON.serializePretty(oldObject)
        );

        return queue;
    }

    global Set<String> additionalFieldsForQuery()
    {
        return new Set<String>{'A_Lookup_Field__r.Some_Field__c'};
    }

    global List<SObject> execute(API_Queue__c queue)
    {        
        // You may need to populate your API Request with data from the source Salesforce record.
        My_Record__c myRecordSnapShot = (My_Record__c)JSON.deserialize(queue.Record_JSON__c, My_Record__c.class);
                        
        // Implement your API Callout here and handle the responses appropriately
        String responseJSON = MyCalloutHandler.createRecord();

        // It is recommended that you store the response from the endpoint in case of an error and subsequent debugging.
        queue.SmarterPay__Response__c = responseJSON; 

        MyResponseWrapper apiResponse = (MyResponseWrapper)JSON.deserialize(responseJSON, MyResponseWrapper.class);

        if(apiResponse.error)
        {
            /* 
                Handle any errors accordingly.

                Throw an Exception to make the Queue go into the "retry" mechanism or set it to Failed if you wish to skip this.
                throw new YourCustomException('A useful error message');
                queue.SmarterPay__Status__c = 'Failed'; 
            */
        }
        else
        {
            queue.SmarterPay__Status__c = 'Processed';

            // Map the response back to a record or list of records. These will be upserted by the queueing system.

            My_Record__c newRecord = new My_Record__c(Id = originalRecord.Id, 
                                                    My_External_Id__c = apiResponse.ThirdPartySystemId);
            return new List<sObject>{newRecord};               
        }

        return null;        
    }
}

Webhook Queue Processor


  • Last modified: 2025/07/22 14:48