How to add Signed Document to the Salesforce Record while working with APEX SDK
Monday, May 17, 2021 at 02:32amHi Team,
I am new to OneSpan and start working on the Apex SDK. I have gone through the SDK documentation but I am not able to find out how we can attach the signed document to the record or package can be assigned to the Parent record.
It will be really great if you can provide some documentation to achieve this functionality.
Regards,
Shashank Verma
Reply to: How to add Signed Document to the Salesforce Record while working with APEX SDK
Monday, May 17, 2021 at 05:15amHi Shashank Verma,
If you are looking for download capability, please refer to the Checking Transaction Status & Downloading Documents guide.
If you are looking for the callback mechanism to inform your application when the transaction has been completed, please refer to my blog series OAuth Event Notification for Salesforce Part 1 Part 2 and Part 3.
Duo
Reply to: Hi Shashank Verma, If…
Tuesday, May 18, 2021 at 06:06amHi Liang,
I am going through your OAuth Event Notification for Salesforce blogs and for the Part 2, I am getting error while doing Update OneSpan Sign Callback Service.
I am doing the exact steps which you have mentioned but while doing HTTP request for Post I am getting error i.e. Service not found at: /api/callback/connectors/salesforceOauth2.
Can you please let me know what is the reason I am getting this error.
Regards,
Shashank Verma
Reply to: Hi Liang, I am going…
Tuesday, May 18, 2021 at 08:22amHi Shashank Verma,
I am not able to reproduce the "Service not found at" error.
- Can you provide a screenshot of it? Is the error message returned in JSON or HTML format?
- Can you make a GET call and will the error consistent?
- Can you try invoking the API through Swagger?
Duo
Reply to: How to add Signed Document to the Salesforce Record while working with APEX SDK
Tuesday, May 18, 2021 at 10:11amHi Liang,
We tried the exact steps that mentioned inside the blog Part 2. Below are the POST request details
1. We are using POST Url : sandbox.esignlive.com/api/callback/connectors/salesforceOauth2
2. POST Header :
Content-Type: application/json
Accept: application/json
Authorization: Basic {My OneSpan API Key}
3. POST Body :
{
"url": "https://test123.my.salesforce.com/services/apexrest/oss/callback",
"events": ["DOCUMENT_SIGNED","EMAIL_BOUNCE","KBA_FAILURE","PACKAGE_ACTIVATE","PACKAGE_ARCHIVE","PACKAGE_ATTACHMENT","PACKAGE_COMPLETE","PACKAGE_CREATE","PACKAGE_DEACTIVATE","PACKAGE_DECLINE","PACKAGE_DELETE","PACKAGE_EXPIRE","PACKAGE_OPT_OUT","PACKAGE_READY_FOR_COMPLETE","PACKAGE_RESTORE","PACKAGE_TRASH","ROLE_REASSIGN","SIGNER_COMPLETE","SIGNER_LOCKED","TEMPLATE_CREATE"],
"key": "{Key Encrypted in Base64}"
}
While testing from PostMan we are getting following error
"Error: connect ETIMEDOUT 54.85.59.26:80"
Can you please let us know if the we are using the correct endpoint and let us know if the above steps are right.
Regards,
Shashank Verma
Reply to: Hi Liang, We tried the…
Tuesday, May 18, 2021 at 10:19amCan you also include the HTTPS schema "https://" in the URL path?
Duo
Reply to: How to add Signed Document to the Salesforce Record while working with APEX SDK
Wednesday, May 19, 2021 at 01:55amHi Liang,
We have added the HTTPS schema but now I am getting the below error in response body:
<html>
<head>
<title>400 Bad Request</title>
</head>
<body>
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx</center>
</body>
</html>
Can you please let me know if we are doing something wrong.
Regards,
Shashank Verma
Reply to: Hi Liang, We have added the…
Wednesday, May 19, 2021 at 05:14amHi Shashank Verma,
The easiest way to work around this is to use the Swagger instead of Postman.
In order to further investigate your issue, are you connecting through a proxy server? Can you open the Postman console (view > open postman console) and make a screenshot of request body in raw format (don't forget to hide the API key)?
Duo
Reply to: How to add Signed Document to the Salesforce Record while working with APEX SDK
Wednesday, May 19, 2021 at 06:07amHi Liang,
Below is the PostMan console log
POST https://sandbox.esignlive.com/api/callback/connectors/salesforceOauth2
400
1094 ms
POST /api/callback/connectors/salesforceOauth2 HTTP/1.1
Content-Type: application/json
Accept: application/json
Authorization: Basic { }
Postman-Token: { }
{
"url": "https://test123.lightning.force.com/services/apexrest/oss/callback",
"events": ["DOCUMENT_SIGNED","PACKAGE_READY_FOR_COMPLETE","PACKAGE_RESTORE","PACKAGE_TRASH","ROLE_REASSIGN","SIGNER_COMPLETE","SIGNER_LOCKED","TEMPLATE_CREATE"],
"key": " "
}
HTTP/1.1 400 Bad Request
Server: nginx
Date: Wed, 19 May 2021 06:50:36 GMT
Content-Type: text/html
Content-Length: 150
Connection: close
Allow: GET, POST, HEAD, PUT, PATCH, DELETE
<html>
<head><title>400 Bad Request</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx</center>
</body>
</html>
and also in the Swagger we are getting below error
{ "messageKey": "error.unauthorised.noSession", "message": "Failed to retrieve Session", "code": 401, "name": "Unauthorized" }
Regards,
Shashank Verma
Reply to: Hi Liang, Below is the…
Wednesday, May 19, 2021 at 08:33amI see.
For Swagger, click the "Authorize" button on top, then insert "Basic your_api_key" as ApiKeyAuth.
For your Postman settings, it seems your outbound request lacks two headers "Content-Length" and "Host". These two values should be auto-calculated by Postman (as per their documentation), make sure you didn't disable them.
Duo
Reply to: I see. For Swagger, click…
Wednesday, May 19, 2021 at 09:58amHi Liang,
Thank you for your quick response !!!
I have tried the above step and got the below response for POST
POST https://sandbox.esignlive.com/api/callback/connectors/salesforceOauth2
POST /api/callback/connectors/salesforceOauth2 HTTP/1.1
Content-Type: application/json
Accept: application/json
Authorization: Basic { }
Postman-Token: { }
Host: sandbox.esignlive.com
Content-Length: 799
{
"url": "https://test123.lightning.force.com/services/apexrest/oss/callback",
"events": ["DOCUMENT_SIGNED","EMAIL_BOUNCE","KBA_FAILURE","PACKAGE_ACTIVATE","PACKAGE_ARCHIVE","PACKAGE_ATTACHMENT","PACKAGE_COMPLETE","PACKAGE_CREATE","PACKAGE_DEACTIVATE","PACKAGE_DECLINE","PACKAGE_DELETE","PACKAGE_EXPIRE","PACKAGE_OPT_OUT","PACKAGE_READY_FOR_COMPLETE","PACKAGE_RESTORE","PACKAGE_TRASH","ROLE_REASSIGN","SIGNER_COMPLETE","SIGNER_LOCKED","TEMPLATE_CREATE"],
"key":"{ }"
}
HTTP/1.1 200 OK
Server: nginx
Date: Wed, 19 May 2021 14:11:41 GMT
Content-Type: application/json
Content-Length: 783
Connection: keep-alive
Expires: Wed, 19 May 2021 14:11:41 GMT
Cache-Control: no-cache, no-transform, max-age=0
Strict-Transport-Security: max-age=31536000; includeSubdomains;
Allow: GET, POST, HEAD, PUT, PATCH, DELETE
P3P: CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"
{"url":"https://test123.lightning.force.com/services/apexrest/oss/callback","events":["DOCUMENT_SIGNED","EMAIL_BOUNCE","KBA_FAILURE","PACKAGE_ACTIVATE","PACKAGE_ARCHIVE","PACKAGE_ATTACHMENT","PACKAGE_COMPLETE","PACKAGE_CREATE","PACKAGE_DEACTIVATE","PACKAGE_DECLINE","PACKAGE_DELETE","PACKAGE_EXPIRE","PACKAGE_OPT_OUT","PACKAGE_READY_FOR_COMPLETE","PACKAGE_RESTORE","PACKAGE_TRASH","ROLE_REASSIGN","SIGNER_COMPLETE","SIGNER_LOCKED","TEMPLATE_CREATE"],"key":"{ }"}
Also below is the GET response
GET https://sandbox.esignlive.com/api/callback/connectors/salesforceOauth2
GET /api/callback/connectors/salesforceOauth2 HTTP/1.1
Content-Type: application/json
Accept: application/json
Authorization: Basic { }
Postman-Token: { }
Host: sandbox.esignlive.com
HTTP/1.1 200 OK
Server: nginx
Date: Wed, 19 May 2021 14:14:01 GMT
Content-Type: application/json
Content-Length: 783
Connection: keep-alive
Expires: Wed, 19 May 2021 14:14:01 GMT
Cache-Control: no-cache, no-transform, max-age=0
Strict-Transport-Security: max-age=31536000; includeSubdomains;
Allow: GET, POST, HEAD, PUT, PATCH, DELETE
P3P: CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"
{"url":"https://test123.lightning.force.com/services/apexrest/oss/callback","key":"{ }","events":["DOCUMENT_SIGNED","EMAIL_BOUNCE","KBA_FAILURE","PACKAGE_ACTIVATE","PACKAGE_ARCHIVE","PACKAGE_ATTACHMENT","PACKAGE_COMPLETE","PACKAGE_CREATE","PACKAGE_DEACTIVATE","PACKAGE_DECLINE","PACKAGE_DELETE","PACKAGE_EXPIRE","PACKAGE_OPT_OUT","PACKAGE_READY_FOR_COMPLETE","PACKAGE_RESTORE","PACKAGE_TRASH","ROLE_REASSIGN","SIGNER_COMPLETE","SIGNER_LOCKED","TEMPLATE_CREATE"]}
For the next step we have implemented the Part 3 blog mentioned steps. But as mentioned in the blog we didn't get any debug logs and as well files not created inside the folder.
Can you please let me know if we are doing something wrong.
Regards,
Shashank Verma
Reply to: Hi Liang, Thank you for…
Wednesday, May 19, 2021 at 10:13amHi Shashank Verma,
Try to test your exposed service separately:
(1)manually generate an access token for your connected app
(2)in Postman, make below call and stimulate the callback notification:
POST https://test123.lightning.force.com/services/apexrest/oss/callback
with header: Authorization: Bearer generated_access_token
with payload: {"@class":"com.silanis.esl.packages.event.ESLProcessEvent","name":"PACKAGE_COMPLETE","sessionUser":"18EZDL44xgsX","packageId":"jYLxykyNOHoZ6c7YY2p7BfANpeg=","message":null,"documentId":null,"createdDate":"2018-07-18T18:19:19.356Z"}
You can replace the packageId with a real one.
(3)check if above call succeeds, and if there's any income request in SFDC console.
If it turns out that the connected app is configured correctly and the code works, can you share your actual payload to [email protected] and let me have a further investigate?
Duo
Reply to: Hi Shashank Verma, Try…
Thursday, May 20, 2021 at 02:00amHi Liang,
We have tried the above step and getting the below error:
GET https://test123.my.salesforce.com/services/apexrest/oss/callback
GET /services/apexrest/oss/callback HTTP/1.1
Accept: application/json
Postman-Token: { }
Cookie: BrowserId= {Browser Id}
Referer: https://test123.lightning.force.com/services/apexrest/oss/callback
Host: test123.my.salesforce.com
{"@class":"com.silanis.esl.packages.event.ESLProcessEvent","name":"PACKAGE_COMPLETE","sessionUser":"18EZDL44xgsX","packageId":"{ }","message":null,"documentId":null,"createdDate":"2018-07-18T18:19:19.356Z"}
HTTP/1.1 401 Unauthorized
Date: Thu, 20 May 2021 06:35:38 GMT
Strict-Transport-Security: max-age=31536002; includeSubDomains
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
X-Robots-Tag: none
Cache-Control: no-cache,must-revalidate,max-age=0,no-store,private
WWW-Authenticate: Token
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
[{"message":"Session expired or invalid","errorCode":"INVALID_SESSION_ID"}]
Can you please let us know what will be the issue and also we are not sure about the sessionUser you have mentioned in the payload.
Regards,
Shashank Verma
Reply to: Hi Liang, We have tried…
Thursday, May 20, 2021 at 08:36amHi Shashank Verma,
Few things I've noticed:
(1)When an event of interest get triggered, OneSpan Sign sends a POST call to your callback endpoint. Therefore you also need to expose a POST function. (It seems that you were testing with a GET function)
(2)Have you manually generated a SFDC access token via below call? - It seems there's no Bearer header in your testing call.
Duo
Reply to: Hi Shashank Verma, Few…
Thursday, May 20, 2021 at 10:42amHi Liang,
I have did the same steps you have mentioned and sends the POST call but with the POST request I also got the GET response. Below, are the POST call details
POST / HTTP/1.1
Content-Type: application/json
Accept: application/json
Authorization: Bearer { }
Postman-Token: { }
Host: test123.lightning.force.com
Content-Length: 231
Cookie: BrowserId={ }
HTTP/1.1 302
Date: Thu, 20 May 2021 15:37:10 GMT
Strict-Transport-Security: max-age=31536001; includeSubDomains
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Content-Security-Policy: upgrade-insecure-requests
X-Robots-Tag: none
Cache-Control: no-cache,must-revalidate,max-age=0,no-store,private
Location: https://test123.my.salesforce.com/services/apexrest/oss/callback
Content-Length: 0
GET response
GET /services/apexrest/oss/callback HTTP/1.1
Accept: application/json
Postman-Token: { }
Cookie: BrowserId={ }
Referer: https://test123.force.com/services/apexrest/oss/callback
Host: test123.my.salesforce.com
{"@class":"com.silanis.esl.packages.event.ESLProcessEvent","name":"PACKAGE_COMPLETE","sessionUser":"18EZDL44xgsX","packageId":"{ }=","message":null,"documentId":null,"createdDate":"2018-07-18T18:19:19.356Z"}
HTTP/1.1 401 Unauthorized
Date: Thu, 20 May 2021 15:37:11 GMT
Strict-Transport-Security: max-age=31536002; includeSubDomains
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
X-Robots-Tag: none
Cache-Control: no-cache,must-revalidate,max-age=0,no-store,private
WWW-Authenticate: Token
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
[{"message":"Session expired or invalid","errorCode":"INVALID_SESSION_ID"}]
Can you please check what will be the issue.
Regards,
Shashank Verma
Reply to: Hi Liang, I have did the…
Thursday, May 20, 2021 at 11:14amHi Shashank Verma,
The response code is 302 which means to redirect to "Location" header, that's why you saw a second GET call. Because it's a GET call (not POST) and doesn't carry the Bearer header, hence yield the 401 error.
The first line appears like "POST / HTTP/1.1", are you aware why it's not something like "POST /services/apexrest/oss/callback HTTP/1.1"?
For your reference, this is an example from my postman console:
POST /services/apexrest/oss/callback HTTP/1.1
Authorization: Bearer 00D0b000000CxxxxxxxxyD82g.vuyHOsxNO
Content-Type: application/json
User-Agent: PostmanRuntime/7.26.10
Accept: */*
Cache-Control: no-cache
Postman-Token: c135a07a-2f07-40ab-894d-9ecc66941878
Host: mydomain-dev-ed.my.salesforce.com
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 239
Cookie: BrowserId=3wr9yblvEeuwTxl2UA4Wog
{
"@class": "com.silanis.esl.packages.event.ESLProcessEvent",
"name": "PACKAGE_COMPLETE",
"sessionUser": "0787be84-f095-44c7-ba00-787093df86fc",
"packageId": "WKZ0PV6yjLegSUjmt3kxQBDx5wU=",
"message": null,
"documentId": null
}
Duo
Reply to: How to add Signed Document to the Salesforce Record while working with APEX SDK
Friday, May 21, 2021 at 01:51amHi Duo,
We have exactly did the same steps what you have mentioned but we are not sure why we are getting GET response.
Also, can you please confirm about the sessionUser which you have used in pay load.
Let me know if you have any solution. So, we can move forward.
Regards,
Shashank Verma
Reply to: How to add Signed Document to the Salesforce Record while working with APEX SDK
Monday, May 24, 2021 at 06:12pmHi Duo,
We tried the steps which you have mentioned in the post on "Wednesday, May 19, 2021 at 10:13am". We are able to see the callback request coming to Salesforce. So I believe this means our Connected App configuration is proper.
However, the OneSpan is not notifying the callback listener (in Salesforce) whenever the events we have registered is triggered.
We have followed all the steps in your 3-part blog to register our callback with our OneSpan sandbox account ([email protected]).
Thanks,
John Wesly
Reply to: How to add Signed Document to the Salesforce Record while working with APEX SDK
Monday, May 24, 2021 at 06:44pmHi Duo,
Finally figured out the issue! :)
As per your blog post (part-2), the POST URL which we need to use to register the callback is "/api/callback/connectors/salesforceOauth2". When we used this, we were NOT getting any event notifications.
We did the following changes:
Can you tell us why the "/api/callback/connectors/salesforceOauth2" endpoint didn't work in our case?
Thanks,
John Wesly
Reply to: Hi Duo, Finally figured out…
Tuesday, May 25, 2021 at 06:34amHi John,
I believe specifying "origin" as "OSS" does the trick.
For the callback service endpoint, it's defined in the swagger, hence I won't think it's a problem here.
For the origin attribute, it was also highlighted in my blog:
Take current version (11.40) for example, if a transaction is created from sender portal or equivalently carries “data” > “origin” : “OSS” in transaction JSON, once an event of interest triggers, the callback framework will deliver the notification to the Salesforce listener, which is registered as “salesforceOauth2”.
Duo
Reply to: Hi John, I believe…
Thursday, May 27, 2021 at 10:21amHey Duo,
We are able to get the callback in Salesforce but now we are trying to get the callback from the different OneSpan account. While doing that we are getting the below error on the registered user account email:
Failed to communicate with the callback server.
URL: https://test123.my.salesforce.com/services/apexrest/oss/callback
Payload: {"@class":"com.silanis.esl.packages.event.ESLProcessEvent","name":"SIGNER_COMPLETE","sessionUser":"{ }","packageId":"{ }" ,"message":null,"documentId":null,"createdDate":"2021-05-27T13:30:12.920Z"}
Reason(s): status code: 401, reason phrase: 401: Unauthorized
Can you please let us know what will be the issue.
Regards,
Shashank Verma
Reply to: Hey Duo, We are able to…
Friday, May 28, 2021 at 08:15amHi Shashank,
Glad to hear it partially works for you. Have you updated the OneSpan Sign Callback Service API (POST /api/callback/connectors/salesforceOauth2)? Did you send the package with the package data "origin" : "OSS"?
Duo
Reply to: Hi Shashank, Glad to…
Tuesday, June 1, 2021 at 06:14amHey Duo,
As we mentioned before OneSpan Sign Callback Service API (POST /api/callback/connectors/salesforceOauth2) is not working.
We did the following changes:
then we are able to get the callback. But when we have changed the Salesforce org and used the same setting then again we are not getting callback in the system.
Also, we are getting below error
Failed to communicate with the callback server.
URL: http://localhost:11567/connectors/callback/salesforceOauth2
Payload: {"type":"PACKAGE_CREATE","origin":"salesforceOauth2","packageId":"{ }","packageOwnerUid":"{ }","sessionUser":"{ }","documentId":null,"accountOwnerUid":"{ }","connectorInfo":"{ }"}
Reason(s): HttpResponseException: 503: IOException: Authenticate request was not successful (http code: 400, response body: {"error":"invalid_grant","error_description":"expired access/refresh token"})
We have created new refresh token as well but again we are getting above error.
Can you please let us know if we doing something wrong.
Shashank Verma
Reply to: Hey Duo, As we mentioned…
Tuesday, June 1, 2021 at 07:48amHi Shashank,
As the error message suggested "http code: 400, response body: {"error":"invalid_grant","error_description":"expired access/refresh token"}", can you double check if the refresh token you supplied is still valid?
Duo
Reply to: Hi Shashank, As the…
Tuesday, June 1, 2021 at 08:20amHey Duo,
I have generated the new refresh token and tried with that only.
Regards,
Shashank Verma
Reply to: Hey Duo, I have…
Thursday, June 3, 2021 at 10:12amHi Duo,
We are now getting following errors in callback via mail:
Failed to communicate with the callback server.
URL: https://testDomain.my.salesforce.com/services/apexrest/oss/callback
Payload: {"@class":"com.silanis.esl.packages.event.ESLProcessEvent","name":"PACKAGE_CREATE","sessionUser":"{ }","packageId":"{ }","message":null,"documentId":null,"createdDate":"2021-06-03T14:40:11.518Z"}
Reason(s): status code: 401, reason phrase: 401: Unauthorized
Failed to communicate with the callback server.
URL: http://localhost:11567/connectors/callback/salesforceOauth2
Payload: {"type":"PACKAGE_CREATE","origin":"salesforceOauth2","packageId":"{ }","packageOwnerUid":"{ }","sessionUser":"{ }","documentId":null,"accountOwnerUid":"{ }","connectorInfo":"BASE64"}
Reason(s): HttpResponseException: status code: 503, reason phrase: 503: IOException: Unexpected response code for CONNECT: 503
In BASE64 Callback URL we are getting older salesforce org URL which we had registered earlier. But, OneSpan sanbox showing the updated Event Notification.
Please let us know how to reset all the Callback URL's.
Regards,
Shashank Verma
Reply to: Hi Duo, We are now…
Thursday, June 3, 2021 at 03:45pmThese two callbacks are sent by different callback services, you can tell the difference from the payload -
The top one comes from the normal callback service with Basic authentication. When you are engaging Salesforce (OAuth2) callback service, you don't need to register the normal callback service, and it won't work. You can cancel the registration from sender portal (e.g. https://sandbox.esignlive.com/a/login) > Admin > Event Notification > scroll down to the bottom and select "Clear".
The bottom one is the callback service you registered via "POST /api/callback/connectors/salesforceOauth2" endpoint. You won't be able to view the configuration through UI portal and the only way to check is through a GET call "GET /api/callback/connectors/salesforceOauth2".
I understood that you were experiencing problem pinging the endpoint using Postman. But you can always utilize the Swagger page.
Duo
Reply to: These two callbacks are sent…
Monday, June 7, 2021 at 07:18amThank You Duo, Appreciate for your support.