Writing Request PDFs to Salesforce

It may be needed for you to write Ironclad Clickwrap data back to Salesforce once a Contract has been signed or agreed to. While we currently don't have a native integration to do this, there are a few available options that may work for your use case and are below.

Before getting started, we recommend reading about the Ironclad Clickwrap for Salesforce components listed in the Salesforce Integration Components page.

Attaching Ironclad Clickwrap Request PDFs to Salesforce

There are a couple of ways that can accomplish this.

  1. Using Ironclad Clickwrap webhooks (not included in all plans) in combination with a service like Zapier.
  2. Using Salesforce Apex code to retrieve data from the Ironclad Clickwrap API.


Depending on the type of event you want to trigger the process (we normally see Request Complete or Agreed events), you'll need to make sure that you set this up in your Ironclad Clickwrap Site integrations page. Webhooks give you the ability to be notified when an acceptance has occurred and handle as needed. For example, using a platform like Zapier allows you to hook into Ironclad Clickwrap webhooks and update data within your Salesforce account as needed.

Webhooks are typically the easiest way to get data back to Salesforce when you may not have immediate Salesforce development resources. If you do have Salesforce help, the next section covers more advanced methods.

For more information on integrating Webhooks with Zapier, and writing back data to Salesforce using Zapier, visit our Integrating Ironclad Clickwrap with Zapier guide.

Salesforce Apex

The Ironclad Clickwrap for Salesforce managed package includes a couple of handy features that can assist in creating a workflow for writing back data. For example, any time Ironclad Clickwrap Contracts are sent from Salesforce and the signers have signed, the complete field on the PactSafeRequest__c custom object will be updated to true.

Knowing this, Apex triggers can be set up to handle what happens after the Ironclad Clickwrap Request is marked as complete. Additionally, our API provides a convenient route for retrieving the PDF record for a Request.


At an overview, you'll have to achieve this using a combination of Apex Classes that interface with the Ironclad Clickwrap API, the PactSafeRequest__c custom object, and an Apex trigger. The diagram below shows an example of what the flow looks like and is followed by code examples.


Example Data Flow

Example Apex Trigger

trigger PactSafeRequestCompleteTrigger on pactsafe1__PactSafeRequest__c (after update) {
  for (pactsafe1__PactSafeRequest__c r : Trigger.new) {
    // If the PactSafe Request is marked as true, handle appropriately.
    if (r.pactsafe1__Complete__c == true) {
      // The ID of the PactSafe Request will be available on the object.
      String requestId = r.pactsafe1__PactSafeRequestId__c;
      // Use related Opportunity as example for handling.
      String optyId = r.pactsafe1__Opportunity__c;
      // Handle using a static method.
      PSRequestCompleteTriggerHandlerExample.addRequestPdfToOpportunity(requestId, optyId);

Example Handler for Trigger

When using an Apex trigger, you'll need to utilize a static method that asynchronously handles what happens after the Apex Trigger has been called. The example below shows using the Ironclad Clickwrap Request ID and an Opportunity ID to grab the PDF using another Apex Class that interacts with the Ironclad Clickwrap API.

public with sharing class PSRequestCompleteTriggerHandlerExample {

  public static void addRequestPdfToOpportunity(String requestId, String optyId) {
    PSAPIExample psApi = new PSAPIExample();
    Blob pdfFile = psAPI.retrieveRequestPdf(requestId);
    Attachment attachment = new Attachment();
    attachment.ParentId = optyId;
    attachment.Name = requestId + '.pdf';
    attachment.Body = pdfFile;
    try {
      insert attachment;
    } catch(DmlException e) {
      System.debug('Issue updating object with error: ' + e);

Example Retrieve PDF Record with Ironclad Clickwrap API

public with sharing class PSAPIExample {

  // PDF File will be returned as a Blob
  public Blob retrieveRequestPdf(String requestId) {
    // You'll need your Ironclad Clickwrap API Key, which should be
    // stored elsewhere and retrieved securely.
    // See: https://developer.salesforce.com/wiki/secure_coding_storing_secrets#Apex_and_Visualforce_Applications
    String apiKey = '';

    // Create the URL
    String url = 'https://api.pactsafe.com/v1.1/requests/' + requestId + '/download';

    // Ensure URL is encoded
    String encodedUrl = EncodingUtil.urlDecode(url, 'UTF-8');

    // Create HTTP Request
    Http http = new Http();
    HttpRequest request = new HttpRequest();
    request.setHeader('Content-Type', 'application/pdf');
    request.setHeader('Authorization', 'Bearer ' + apiKey);
    HttpResponse response = http.send(request);
    if (response.getStatusCode() < 200 || response.getStatusCode() > 299) {
      System.debug('Error getting data from PactSafe API with status code: ' + response.getStatusCode());
      return null;
    } else {
      return response.getBodyAsBlob();