Skip to Content
Technical Articles

Electronic Contract Signing: Docusign Integration with SuccessFactors EC – Part 2

Hello Everyone,

This is the Part 2  of the blog “Electronic Contract Signing: Docusign Integration with SuccessFactors”. In this Part 2 we will focus on rest of step and final demo.

Step 4: Create oData service using CDS model and Cloud Platform Backend Service.

We need some storage which will store the data of all users who already got the contract so that if again some one try to trigger some change from SFEC Integration Center it will not send contract again and easiest way to do this is using SAP Cloud Platform Cloud Foundry Backend Service. Using CDS model we will create the oDATA service in the fly which will be used for storing user data and checking that user has already contract or not.

If you are very new to SAP Cloud Platform Backend Service, Please have a look at this series of tutorial.

In order to use the SAP Cloud Platform Backend Service, First we need to subscribe the Backend Service in Subscription.

Now Create the CDS Model File (docusign.cds), remember file extension should be .cds

service docusign {
	entity user {
	key	userID : String;
	sent: Boolean;
	}
}

Click on Create API

Upload the cds file and fill the all information and click on create API button to create the oData service.

 

Initially it will be in pending status then it ll be changed to Active.

Click on this API and explore the swagger API. If you want to use V2 oData you can check V2 also.

.

Step 5: Create XSUAA instance for Calling Backend Service API from Node.Js Application.

We can’t directly call Backend service API from outside , for that we need to create  XSUAA Instance

and configure the XSUAA with Backend Service.

 

In order to configure XSUAA for Backend Service follow this great blog.

In order to see how you can test Backend service API from outside in tools like Postman follow this

blog.

Step 6: Developing and Deploying Node.Js Application in Cloud Foundry which will handle the logic for sending Contract to Employee.

const express = require('express')
const bodyParser = require('body-parser')
const oauthClient = require('client-oauth2')
const request = require('request-promise')
const app = express()
const port = process.env.PORT || 3000
app.use(bodyParser.json())
app.post('/sendmail', (req, res) => {

 const email = req.body.email;
 const userid = req.body.userid;
 const fname = req.body.fname;
 const lname = req.body.lname;
 const full_name = fname + " " + lname;
 const contractCheck = function(email, userid, full_name, accessToken) {
  const userid1 = "'" + userid + "'";
  const serviceUrl = "https://backend-service-api.cfapps.eu10.hana.ondemand.com/odatav2/DEFAULT/DOCUSIGN;v=1/user(" + userid1 + ")";

  return new Promise(function(resolve, reject) {
   const options = {
    url: serviceUrl,
    resolveWithFullResponse: true,
    headers: {
     Authorization: 'Bearer ' + accessToken,
     Accept: 'application/json'
    }
   };

   request(options)
    .then(response => {
     if (response && response.statusCode == 200) {
      resolve(res.send('contract has been already sent'));
     }

    })
    .catch(error => {
     resolve(sendContract(email, full_name, userid, accessToken));

    });
  });


 }
 const gettingToken = function() {
  return new Promise((resolve, reject) => {
   const oautClient = new oauthClient({
    accessTokenUri: 'https://<your_sub_account>.authentication.eu10.hana.ondemand.com/oauth/token',
    clientId: '<xsuaa client id>',
    clientSecret: '<xsuaa client secret>',
    scopes: []
   });

   oautClient.owner.getToken('<your scp email>', '<your scp password>')
    .then(result => {
     resolve({
      accessToken: result.accessToken
     });
    })
    .catch(error => {
     reject({
      message: 'Error: failed to get access token.',
      error: error
     });
    });
  });
 }
 const sendContract = function(email, full_name, userid, accessToken) {
  var url = 'https://api.openconnectors.ext.hanatrial.ondemand.com/elements/api-v2/envelopes';
  var headers = {
   'authorization': 'User IXnG2ZC2lpg34sd6e2sNWCXTO098272XMAqldM=, Organization 927730555109ef5261b78359b8761, Element gg8vdijY0R0O7y0sBx09yK49mDCbhFzeMWiW/XJM50=',
   'accept': 'application/json',
   'content-type': 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW'
  };
  bodyJson = {
   "compositeTemplates": [{
    "compositeTemplateId": "1",
    "inlineTemplates": [{
     "recipients": {
      "carbonCopies": [{
       "email": "<email id of where you want copy>",
       "name": "Sudip Ghosh",
       "recipientId": "2"
      }],
      "signers": [{
       "email": email,
       "name": full_name,
       "recipientId": "1",
       "roleName": "Employee",
       "tabs": {
        "textTabs": []
       }
      }]
     },
     "sequence": "1"
    }],
    "serverTemplates": [{
     "sequence": "2",
     "templateId": "c7d72cca-3391-45d3-aee0-40d6558b037a"
    }]
   }],
   "emailSubject": "Employment Training Bond",
   "enableWetSign": "false",
   "status": "sent"
  }
  var options = {
   method: 'POST',
   url: url,
   headers: headers,
   formData: {
    envelope: JSON.stringify(bodyJson)
   }

  };
  request(options, function(error, response, body) {
   if (!error && response.statusCode == 200) {
    const backendAPIurl = 'https://backend-service-api.cfapps.eu10.hana.ondemand.com/odatav2/DEFAULT/DOCUSIGN;v=1/user';
    bodyData = {
     "userID": userid,
     "sent": true
    }

    var options = {
     'method': 'POST',
     'url': backendAPIurl,
     'headers': {
      'Authorization': 'Bearer ' + accessToken,
      'Content-Type': 'application/json'
     },
     body: JSON.stringify(bodyData)

    };
    request(options, function(error, response) {
     if (!error && response.statusCode == 201) {
      res.send('Contract has been sent');
     } else {
      res.send('Error Happened');
     }

     if (error) throw new Error(error);
     console.log(response.body);
    });

   } else {
    res.send('Error happened')
   }
  })

 }
 gettingToken()
  .then(result => {
   console.log('Successfully fetched OAuth access token: ' + result.accessToken.substring(0, 16));
   return contractCheck(email, userid, full_name, result.accessToken);
  })

  .catch(error => {
   console.log(error.message + ' Reason: ' + error.error);
   res.send(error.message + ' Reason: ' + error.error);
  });

})

app.listen(port, () => {
 console.log('Server is running on port ' + port)
})

On successful deployment you will be able to see the application running on SAP Cloud Platform Cloud Foundry like below

Step 7: Configure a Destination in Integration Center, which will call the node.js application and pass the recent change employee Data.

Login to SuccessFactors Employee Central and navigate to Integration center

Click on My Integration then create – > More Integration Types

Select Destination Type Rest, source type SuccessFactors

Give meaningful Integration name and Description in my case i have given Docusign

Choose user entity and select the fields you want to pass

Select the filter, in my cases i have selected time-based filter

Now this is the main part, configure the rest API URL, Select Method type POST

Below is the final configuration how it looks like.

Now we have done all the technical configuration required, Now it’s time to test this whole scenario.

Step 8: Testing the whole scenario (Demo)

 

I hope everyone will like this Blog, If you like this blog, Please don’t forget to like, comment and share. Again Happy new year, i wish this year brings lots of opportunity to everyone and make SAP Community more great.

 

 

4 Comments
You must be Logged on to comment or reply to a post.
  • Hi Sudip Ghosh,

    Thanks for sharing the information.

    Can you please confirm do we need separate licence for Docusign Sand Box Account?

    Because I can see while doing registration its dummy account and will get expire soon.

    Thanks.

     

    Best Regards,

    Sushil Maurya

     

     

    • Hello Sushil,

      I am not sure for sandbox, there shouldn’t be any such. For me its working for last 1 month. But definitely you need license to use productive version.

      Regards,

      Sudip