580
NOTE: This PDF is no longer being maintained. For the latest updates, please refer to our Community Portal . OneSpan Sign Integrator's Guide Date: January 28, 2020  Version: OneSpan Sign 7.2

OneSpan Sign Integrator's Guide › sites › default › files › ...Jan 28, 2020  · l Various other parameters (e.g., expiry date, auto-complete) A document contains: l A document's

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

  • NOTE: This PDF is no longer being maintained. For the latest updates, please refer to our Community Portal.

    OneSpan Sign Integrator's GuideDate: January 28, 2020

     

    Version: OneSpan Sign 7.2

    https://community.onespan.com/documentation/onespan-sign

  • Copyright Notices

    Copyright © 2019 OneSpan North America, Inc. All rights reserved.

    Trademarks

    OneSpan™, DIGIPASS® and CRONTO® are registered or unregistered trademarks of OneSpan North America Inc. and/or OneSpan International GmbH (collectively "OneSpan") in the U.S. and other countries.

    OneSpan reserves all rights to the trademarks, service marks and logos of OneSpan and its subsidiaries.

    All other trademarks or trade names are the property of their respective owners.

    Intellectual Property

    OneSpan Software, documents and related materials (“Materials”) contain proprietary and confidential information. All title, rights and interest in OneSpan Software and Materials, updates and upgrades thereof, including software rights, copyrights, patent rights, industrial design rights, trade secret rights, sui generis database rights, and all other intellectual and industrial property rights, vest exclusively in OneSpan or its licensors. No OneSpan Software or Materials may be downloaded, copied, transferred, disclosed, reproduced, redistributed, or transmitted in any form or by any means, elec-tronic, mechanical or otherwise, for any commercial or production purpose, except as otherwise marked or when expressly permitted by OneSpan in writing.

    Disclaimer

    OneSpan accepts no liability for the accuracy, completeness, or timeliness of content, or for the reliability of links to and content of external or third party websites or materials.

    OneSpan shall have no liability under any circumstances for any loss, damage, or expense incurred by you, your com-pany, or any third party arising from the use or inability to use OneSpan Software or Materials, or any third party mater-ial made available or downloadable. OneSpan will not be liable in relation to any loss/damage caused by modification of these Legal Notices or content.

    Reservation

    OneSpan reserves the right to modify these Notices and the content at any time. OneSpan likewise reserves the right to withdraw or revoke consent or otherwise prohibit use of the OneSpan Software or Materials if such use does not con-form to the terms of any written agreement between OneSpan and you, or other applicable terms that OneSpan pub-lishes from time to time.

    Contact us

    Phone: 1-855-MYESIGNe-Mail: [email protected] Support: https://www.esignlive.com/customer-supportResource center: https://www.esignlive.com/resource-centerCompany Website: https://www.onespan.com

    Date: January 28, 2020

    https://www.esignlive.com/customer-supporthttps://www.esignlive.com/resource-centerhttps://www.onespan.com/

  • CONTENTS

    1  Introduction 1

    1.1  Document Purpose 1

    1.2  Document Audience 2

    1.3  Document Organization 3

    2  Getting Started 5

    2.1  Overview of the Signing Process 6

    2.2  Connecting to OneSpan Sign Servers 7

    2.3  Anatomy of a Document Package 9

    3  System Requirements 10

    3.1  SSL Communication 11

    3.2  Integration Environment 12

    3.3  Java Diagnostics Application 13

    4  Environment URLs & IP Addresses 14

    4.1  US Instances on OneSpan Sign 15

    4.2  US Government Instances 16

    4.3  Canadian Instances 17

    4.4  Australian Instances 18

    4.5  European Instances 19

    Integrator's Guide

    iii

  • 5  External Signer Verification 20

    5.1  Sequence Diagram 21

    5.2  Sample Integration Code 25

    6  iFrame Best Practices 28

    6.1  Cross-Origin Resource Sharing 29

    6.2  Making an iFrame's Dimensions Dynamic 30

    6.3  Preventing Mobile Users from Scaling Content 32

    6.4  Adding Momentum-Based Scrolling CSS for iOS Devices 33

    6.5  Example that Incorporates the Above Tips 34

    7  SDKs 36

    7.1  Getting Started with SDKs 37

    7.2  Configuring Document Packages 40

    7.3  Managing Documents 58

    7.4  Managing Signers 103

    7.5  Preparing Documents 165

    7.6  Fast Track 213

    7.7  Signing Documents 219

    7.8  Managing Accounts and Groups 224

    7.9  Layouts and Templates 237

    7.10  Reports and Logging 257

    7.11  Customization 304

    7.12  OneSpan Sign Mobile SDKs 327

    Integrator's Guide

    iv

  • 8  REST API 357

    8.1  The API URLs 358

    8.2  API Versions 360

    8.3  Other Documentation 361

    8.4  Account Custom Fields 363

    8.5  Account Overview 369

    8.6  Accounts 371

    8.7  Approvals 384

    8.8  Authentication Tokens 399

    8.9  Designer 405

    8.10  Documents 409

    8.11  File Attachments 434

    8.12  Groups 438

    8.13  Layouts 450

    8.14  Notary e-Journal 464

    8.15  Packages 467

    8.16  Package Settings for Mortgages 498

    8.17  Package Settings for Digital Lending 502

    8.18  Reminders 506

    8.19  Reports 511

    8.20  Roles 516

    8.21  Signature Image Extraction 537

    8.22  Signing Ceremony Settings 540

    Integrator's Guide

    v

  • 8.23  Signing URL 543

    8.24  Templates 545

    8.25  Text Anchors 551

    8.26  User Custom Fields 558

    9  Event Notifier 565

    9.1  Starting the Event Notifier 566

    9.2  Interrupting OneSpan Sign’s Normal Activity 567

    9.3  Notification Event Types 568

    9  How to configure the Salesforce OAuth2 connector Using an API 572

    Integrator's Guide

    vi

  • 1 Introduction1.1  Document Purpose

    The product called OneSpan Sign provides a complete e-signature platform for the Web, including preparing, distributing, reviewing, signing, and downloading doc-uments.

    This guide tells developers how to integrate their Web application with OneSpan Sign using our REST Integration Model.

    After successful integration, an organization can invite people to sign documents instantly using their own Web application.

    1  IntroductionIntegrator's Guide

    1

  • 1.2  Document AudienceThis guide is intended for developers who are familiar with at least one of the fol-lowing:

     l The Java programming language and Java APIs

     l The C# programming language

     l REST APIs

    1  IntroductionIntegrator's Guide

    2

  • 1.3  Document OrganizationThe rest of this guide has the following chapters:

     l Getting Started on page 5 — An overview of concepts and procedures relevant to getting started with your integration

     l System Requirements on page 10 — A summary of the software requirements for integration

     l SDKs on page 36 — A description of our SDKs (Software Development Kits), which are built on our REST API

     l REST API on page 357 — A description of our REST API, which is the entry point for all external interactions with our product

     l Open API Specification — An interactive site from which you can download the YAML file for our REST API, search for specific endpoints in that API, and even try a few calls yourself.

     l Event Notifier on page 565 — A description of the Event Notifier, a component that can notify integrators when certain steps of the integration have been accomplished

     l External Signer Verification on page 20: A description of External Signer Veri-fication, which verifies the identity of a signer via their credentials with an external organization (e.g., DIGIPASS credentials).

     l iFrame Best Practices on page 28 — A description of certain best practices for using iFrames to integrate OneSpan Sign's Classic User Experience or New User Experience into a third-party application.

    NOTE: SDKs and the REST API are alternative ways of integrating your Web application.

    TIP: If you want to view all existing calls, see our interactive Open API Specification. From there you can download the YAML file for our REST API, search for specific endpoints in that API, and even try a few calls yourself. Additional information about the calls can be found on the Developer Community website.

    1  IntroductionIntegrator's Guide

    3

    https://docs.esignlive.com/api-docs/sandbox-us/https://docs.esignlive.com/api-docs/sandbox-us/https://docs.esignlive.com/api-docs/sandbox-us/https://developer.esignlive.com/

  • That site’s Feature Guides may be especially helpful when you’re building your solu-tion.

    1  IntroductionIntegrator's Guide

    4

    https://developer.esignlive.com/guides/feature-guides/

  • 2 Getting StartedThe following sections should help you to get started with your integration:

     l Overview of the Signing Process on page 6

     l Connecting to OneSpan Sign Servers on page 7

     l Anatomy of a Document Package on page 9

    2  Getting StartedIntegrator's Guide

    5

  • 2.1  Overview of the Signing ProcessThe following figure provides an overview of OneSpan Sign's signing process, includ-ing the interactions between the OneSpan Sign Application, your Web Application, and an end-user's browser.

    The above figure applies to the Java SDK, .NET SDK, and REST API.

    2  Getting StartedIntegrator's Guide

    6

  • 2.2  Connecting to OneSpan Sign ServersTo use the OneSpan Sign service, you must connect to a OneSpan Sign server. The following sections explain how to do so:

     l Environment URLs on page 7

     l API Key on page 7

    2.2.1  Environment URLsYou must provide the URL of a OneSpan Sign server.

    If you are exploring the system or performing tests, you can connect to our Sandbox environment. Alternatively, if you have completed your integration with our system and want to launch your product, you can connect to our Production environment.

    Sandbox Accounts are not equivalent to Production Accounts. To connect to the OneSpan Sign Production Environment, you must purchase a Production Account.

    For more information on which Environment URLs you should use to connect to, and which IP addresses need to be whitelisted to do so, see Environment URLs & IP Addresses on page 14.

    2.2.2  API KeyCustomers who wish to communicate with OneSpan Sign software can do it via REST API calls from within their own system. These communications are secured via an API key. Every call made to the REST API must provide this API key. If the key is not provided, the call will be refused.

    API calls are always specific to a User Account, and a caller cannot modify inform-ation unrelated to their account. The code enforces this via access-rights veri-fications.

    NOTE: All calls made to the REST API with an API key are deemed to have been done on behalf of the User Account for which the API key was created. Users should protect their API key as they would a password or an Authentication Certificate.

    2  Getting StartedIntegrator's Guide

    7

  • Users can retrieve their API key from their Account Information page. The key is a long string of encrypted data.

    Prerequisites

     l To view an account's API key, you must be the account owner.

     l If you are in a Production environment, you must have an Integration Pro-duction account.

    Action

    To view your account's API key:

     1. Go to your environment's Login page.

     2. Log in by entering your credentials.

    TIP: If you don't have an account, obtain a free Developer account by clicking Sign up on the Login page.

     3. Click your name near the top right, and from the drop-down menu that appears, select Admin. A new page appears.

     4. On the left pane, click Integration. The Integration page appears. The API Key field appears immediately below the title Integration. By default, that key is obfuscated.

     5. To reveal the value of your API key, click the little eye icon to the right of the obfuscated key.

    Once you have an Environment URL and an API key, you can instantiate your ESLClient object (as done by the code examples below). All tasks performed using your ESLClient will be done under the authority of your account.

    2  Getting StartedIntegrator's Guide

    8

  • 2.3  Anatomy of a Document PackageBefore you start issuing commands, take a moment to consider the hierarchy of classes that constitute the model of the OneSpan Sign SDKs. The model's top-level class is the DocumentPackage. It contains all the information required to fully specify an e-signature process. Specifically:

    A DocumentPackage contains:

     l A sender

     l A set of documents

     l A set of signers

     l Various other parameters (e.g., expiry date, auto-complete)

    A document contains:

     l A document's binary content

     l A set of signatures

     l Other additional settings

    A signature contains:

     l A set of fields

     l Data specific to a particular signature

    By combining all these classes, we can specify an entire DocumentPackage.

    2  Getting StartedIntegrator's Guide

    9

  • 3 System RequirementsThis section describes the following aspects of your system that are required for a successful integration:

     l SSL Communication on page 11

     l Integration Environment on page 12

     l Java Diagnostics Application on page 13

    3  System RequirementsIntegrator's Guide

    10

  • 3.1  SSL CommunicationIntegration with OneSpan Sign is secured via an SSL certificate issued by Glob-alSign. Thus that GlobalSign intermediate certificate must be installed in your integ-ration environment.

    3.1.1  Certificate Details

    Certificate serial#: 04 00 00 00 00 01 44 4e f0 3e 20 Thumbprint: 73 6a 4d c6 79 d6 82 da 32 15 63 64 7c 60 f6 99 f0 df c2 68

    Download link: https://secure.globalsign.com/cacert/gsdomainvalsha2g2r1.crt

    3.1.2  Installation

    Java

    To see if this certificate is already installed in your environment, run the following command:

    keytool -list -keystore | grep -i 73:6a:4d:c6:79:d6:82:da:32:15:63:64:7c:60:f6:99:f0:df:c2:68

    If the certificate is not installed, install it by running the following command:

    keytool -importcert -alias GlobalSignIntermediateCA -keystore -file gsdomainvalsha2g2r1.crt

    .NET

    To install the certificate, double-click the file gsdomainvalsha2g2r1.crt, and then select install certificate.

    3  System RequirementsIntegrator's Guide

    11

    https://secure.globalsign.com/cacert/gsdomainvalsha2g2r1.crt

  • 3.2  Integration EnvironmentIn light of the Logjam security vulnerability, OneSpan Sign has increased its DH SSL key from 1024 bits to 2048 bits.

    Older versions of Java and .NET will no longer be able to connect to OneSpan Sign, since they don't support the larger encryption key.

    3.2.1  Minimum Requirements

    Java

    Your JVM must be using Java 1.7.0_21 or higher.

    To identify the Java version installed on your system, run the following command:

    java -version

    .NET

    Your integration must use .NET framework 4.5 or higher.

    To identify the .NET framework installed on your system, follow the instructions in this link: https://msdn.microsoft.com/en-us/library/hh925568

    3  System RequirementsIntegrator's Guide

    12

    http://weakdh.org/https://msdn.microsoft.com/en-us/library/hh925568

  • 3.3  Java Diagnostics ApplicationIf you are using Java to integrate, we recommend that you download and run our Diagnostics Application. That application checks the compatibility of your JVM with OneSpan Sign's SSL security settings.

    You can download the Diagnostics Application here.

    To run the Diagnostics Application:

     1. Ensure that you are on the Production JVM, or on a testing JVM that is identical to the Production JVM.

     2. Run the following command:

    java -cp securityscanner.jar com.silanis.esl.Scanner

     3. If the test result is negative, an error message appears that begins: Your system is not compatible with eSignlive!

    3  System RequirementsIntegrator's Guide

    13

  • 4 Environment URLs & IP AddressesYou must provide the URL of a OneSpan Sign server.

    If you are exploring the system or performing tests, you can connect to our Sandbox environment. Alternatively, if you have completed your integration with our system and want to launch your product, you can connect to our Production environment.

    Sandbox Accounts are not equivalent to Production Accounts. To connect to the OneSpan Sign Production Environment, you must purchase a Production Account.

    NOTE: Your configuration settings depend on the URL into which you log. If you aren't sure which URL to use, in the email you received when you signed up, click Log into your account. In the Login screen that appears, your login URL will appear in your browser's address bar. Note that OneSpan Sign is in the process of removing the hyphen from its URLs.

    To ensure continuous service you must whitelist the appropriate IP addresses. See below for which IP addresses to whitelist, per environment.

    4  Environment URLs & IP AddressesIntegrator's Guide

    14

  • 4.1  US Instances on OneSpan SignBefore continuing, verify the domain that you are using for your OneSpan Sign instance. The following domains are available:

     l US 2 (esignlive.com) on page 15

     l US 1 (e-signlive.com) on page 15

    4.1.1  US 2 (esignlive.com)US instances that use US 2 (esignlive.com) as their domain must whitelist the fol-lowing IP addresses:

    Environment URLIncoming IP Address

    Outgoing IP Address

    US 2 OneSpan Sign Production

    apps.esignlive.com 52.4.146.88

    23.22.76.174

    52.38.114.149

    54.213.153.138

    52.200.120.227

    52.38.93.133

    US 2 Sandbox sandbox.esignlive.com 54.85.59.26

    54.164.84.186

    54.84.89.182

    4.1.2  US 1 (e-signlive.com)US instances that use US 1 (e-signlive.com) must whitelist the following IP addresses:

    Environment URLIncoming IP Address

    Outgoing IP Address

    US 1 OneSpan Sign Production

    apps.e-signlive.-com

    54.85.79.26

    54.85.78.62

    54.201.3.64

    54.200.10.69

    54.85.128.97

    54.201.188.127

    54.200.250.73

    US 1 Sandbox sandbox.e-signlive.-com

    54.84.132.241

    54.85.54.201

    54.84.89.182

    4  Environment URLs & IP AddressesIntegrator's Guide

    15

  • 4.2  US Government InstancesUS Government instances must whitelist the following IP addresses:

    Environment URLIncoming IP Address

    Outgoing IP Address

    OneSpan Sign Production for Government

    signer-gov-.esignlive.com

    23.97.15.51 52.227.164.112

    OneSpan Sign Sandbox for Government

    signer-sandbox-gov-.esignlive.com

    23.97.15.51 13.72.53.92

    4  Environment URLs & IP AddressesIntegrator's Guide

    16

  • 4.3  Canadian InstancesCanadian instances on esignlive.ca must whitelist the following IP addresses:

    Environment URLIncoming IP Address

    Outgoing IP Address

    PRDC Canada Pro-duction

    apps.e-signlive.ca 52.60.92.229

    52.60.122.173

    169.54.69.11

    169.54.69.14

    52.60.142.251

    52.60.143.116

    169.54.69.6

    169.54.69.10SBXC Canada Sand-box

    sandbox.e-signlive.ca

    52.60.105.234

    52.60.155.238

    158.85.81.52

    52.60.135.61

    52.60.146.3

    158.85.82.181

    158.85.82.182

    4  Environment URLs & IP AddressesIntegrator's Guide

    17

  • 4.4  Australian InstancesAustralian instances on esignlive.com.au must whitelist the following IP address:

    Environment URLIncoming IP Address

    Outgoing IP Address

    Australia Pro-duction

    apps.esignlive.com.au 52.62.209.65

    13.55.131.135

    168.1.38.249

    168.1.38.253

    168.1.69.165

    168.1.69.174

    168.1.38.251

    13.55.54.140

    52.62.192.176

    168.1.69.163

    168.1.69.169

    4  Environment URLs & IP AddressesIntegrator's Guide

    18

  • 4.5  European InstancesEuropean instances on esignlive.eu must whitelist the following IP address:

    Environment URLIncoming IP Address

    Outgoing IP Address

    Europe Production apps.esignlive.eu 18.196.249.213

    34.243.5.41

    34.243.143.168

    35.157.85.150

    18.197.87.157

    18.197.87.175

    52.215.67.32

    52.209.144.54

    4  Environment URLs & IP AddressesIntegrator's Guide

    19

  • 5 External Signer VerificationWhen a signer is trying to confirm their approval of a document within OneSpan Sign, it is sometimes desirable to verify their identity via their credentials with an external organization (e.g., DIGIPASS credentials).

    A new Java SDK enables this kind of "external signer verification" by integrating the OneSpan Sign Application Backend with an external organization’s Verification Server.

    The following sections explain how to use that "Integration SDK":

     l Sequence Diagram on page 21

     l Sample Integration Code on page 25

    NOTE: The intended audience for this information is any developer who has a good know-ledge of an External Verification Provider that they want to integrate with the OneSpan Sign Application Backend. The developer doesn't need any detailed knowledge of the com-munication protocol between the External Verification Server and the OneSpan Sign Application Backend.

    5  External Signer VerificationIntegrator's Guide

    20

  • 5.1  Sequence DiagramThis section discusses the following sequence diagram, which illustrates the pro-cess of External Signer Verification.

    TIP: A better view of this diagram is available here, and you can download that image by right-clicking here.

    5.1.1  Explanation of the DiagramThis section explains the following aspects of the sequence diagram:

     l Signer Verification Request on page 22

     l Signer Verification Response on page 23

    5  External Signer VerificationIntegrator's Guide

    21

  • Signer Verification Request

    When a signer tries to confirm their approval of a document, they will be redirected to the specified External Verification Provider via a URL of the following form:

    https://?verificationRequestToken=

    Here:

     l is the configured URL endpoint for a spe-cific External Verification Server.

     l is a Signer Verification Request Token gen-erated by the OneSpan Sign Application Backend. That token contains the fol-lowing information:

     l Document Identification Information — This contains data that identify the document and the signer. The External Verification Server needn’t do anything with this payload, except return it later as part of its verification response.

     l User Identity Information — This is used to identify the signer whom the External Verification Server must verify. That information was specified by the External Verification Provider (e.g., a bank) when it added the signer to the transaction. This data can have any format; it’s up to the external Veri-fication Server to extract the required information. The OneSpan Sign Application Backend does not interact with this information.

     l Callback URL — This URL is used by the External Verification Server to redirect the signer back to the Signing Ceremony after they have been suc-cessfully verified.

     l Transaction Information — This information is the transaction’s name and the document’s name. These items are provided in case the external Veri-fication Server Web Portal needs to display them.

     l Signer Information — This information is the signer’s first name, last name, and email address. These items are provided in case the external Veri-fication Server Web Portal needs to display them.

    The value of the verificationRequestToken query parameter will be extracted by the External Verification Server with the help of the SDK, which converts it into an

    5  External Signer VerificationIntegrator's Guide

    22

  • object that contains all the fields listed above. The External Verification Server can then parse the User Identity Information to determine which user to verify.

    At this point, the signer should be presented with an HTML form that prompts them to enter their credentials. Note that the Signer Verification Request Token is short‐lived and will expire in 30 seconds; therefore, the External Verification Server must consume it as soon as possible, and save the user data in a session.

    Signer Verification Response

    After the signer is successfully verified, the External Verification Server must com-municate the result to the OneSpan Sign Application Backend. It does so by redir-ecting the user back to the Signing Ceremony via a redirect URL of the following form:

    https://?verificationResponseToken=

    Here:

     l is the URL provided in the Signer Verification Request Token described above.

     l is a Signer Verification Response Token gen-erated by the External Verification Server. It contains the following information:

     l Verified — This Boolean parameter is set to true if the signer was suc-cessfully verified. Otherwise, it's set to false.

     l Document Identification Information — This is the data present in the Signer Verification Request Token. It must be sent back as part of the Signer Verification Response, so the OneSpan Sign Application Backend will confirm the right document for the right signer.

     l Confirmation Payload — This is a confirmation number provided by the external Verification Server upon successful user verification. It is optional. This string will be capped at 150 characters.

    The value of the verificationResponseToken query parameter will be extracted by the OneSpan Sign Application Backend with the help of the SDK, which converts it into an object that contains all the fields listed above. The OneSpan Sign Applic-ation Backend can now check if the signer was successfully verified, and parse the

    5  External Signer VerificationIntegrator's Guide

    23

  • Document Identification Information to ensure that the right document is con-firmed by the right signer.

    If the optional Confirmation Payload is provided by the External Verification Server, it can be put in OneSpan Sign’s Evidence Summary.

    5  External Signer VerificationIntegrator's Guide

    24

  • 5.2  Sample Integration CodeThe sample Java code discussed in this section illustrates how to use the Integ-ration SDK to integrate the OneSpan Sign Application Backend with an External Verification Server.

    Specifically, this section discusses:

     l Adding the SDK to Your Project on page 25

     l Sample Java Files on page 25

    5.2.1  Adding the SDK to Your ProjectTo add the Integration SDK to your project as a dependency, insert the following lines of code into your Maven POM file:

    com.eSignLive.com.esl esl-sdk-external-signer-verification 1.0.6

    To download the Integration SDK, refer to the online version of this help topic.

    CAUTION: If your version of the SDK is not 1.0.6, replace the "1.0.6" version number in the above code with your version number.

    5.2.2  Sample Java FilesThe following four files of sample Java code illustrate how to use various aspects of the Integration SDK:

    TIP: To download these files, refer to the online version of this help topic.

    5  External Signer VerificationIntegrator's Guide

    25

  •  1. VerificationRequestTokenConversion.java

     2. VerificationResponseTokenGeneration.java

     3. VerificationRequestTokenGeneration.java

     4. VerificationResponseTokenConversion.java

    Files 1 and 2 contain code for the external Verification Server. Files 3 and 4 contain code for the OneSpan Sign Application Backend.

    File 1: External Verification Server

    File 1 (VerificationRequestTokenConversion.java) illustrates how the external Verification Server converts an extracted Signer Verification Request Token into a SignerVerificationRequest object by calling the method Sign-erVerificationProcessor.toSignerVerificationRequest().

    File 2: External Verification Server

    File 2 (VerificationResponseTokenGeneration.java) illustrates how the external Verification Server generates a Signer Verification Response Token.

    It first retrieves the saved SignerVerificationRequest object, and then pulls the Docu-ment Identification Information as well as the Callback URL from it.

    It subsequently constructs a SignerVerificationResponse object with the Document Identification Information as the value of one of its fields.

    The SignerVerificationResponse object is then converted to a Signer Verification Response Token by calling the method Sign-erVerificationProcessor.toSignerVerificationResponsePayload().

    Finally, the result, along with the Callback URL, is used to build a redirect URL to send the user back to the Signing Ceremony.

    File 3: OneSpan Sign Application Backend

    File 3 (VerificationRequestTokenGeneration.java) illustrates how the OneSpan Sign Application Backend constructs a SignerVerificationRequest, which is then converted to a Signer Verification Request Token by calling the method Sign-erVerificationProcessor.toSignerVerificationRequestPayload().

    5  External Signer VerificationIntegrator's Guide

    26

  • The result is subsequently used to build a redirect URL to send the signer to the website of the External Verification Provider.

    File 4: OneSpan Sign Application Backend

    File 4 (VerificationResponseTokenConversion.java) illustrates how the OneSpan Sign Application Backend converts an extracted Signer Verification Response Token to a SignerVerificationResponse object by calling the method Sign-erVerificationProcessor.toSignerVerificationResponse().

    5  External Signer VerificationIntegrator's Guide

    27

  • 6 iFrame Best PracticesiFrames can be used to integrate OneSpan Sign's Classic User Experience or New User Experience into a third-party application.

    The following sections describe some best practices for developers who are per-forming such an integration:

     l Cross-Origin Resource Sharing on page 29

     l Making an iFrame's Dimensions Dynamic on page 30

     l Preventing Mobile Users from Scaling Content on page 32

     l Adding Momentum-Based Scrolling CSS for iOS Devices on page 33

     l Example that Incorporates the Above Tips on page 34

    6  iFrame Best PracticesIntegrator's Guide

    28

  • 6.1  Cross-Origin Resource SharingTo enhance performance and security, cross-origin communication is actively blocked by all "evergreen browsers" (i.e., browsers that are automatically upgraded to future versions).

    This poses various obstacles to Cross-Origin Resource Sharing (CORS), but the fol-lowing sections illustrate how some of those problems can be overcome:

     l Creating Session Cookies on page 29

     l Redirecting Outside an iFrame on page 29

    6.1.1  Creating Session CookiesTo create a session cookie on OneSpan Sign, you may need to:

     1. Create the session by opening the iFrame URL in a new window.

     2. Refresh your page with the iFrame.

    NOTE: You are more likely to need the above procedure if the session is on a mobile device.

    6.1.2  Redirecting Outside an iFrameIf you use OneSpan Sign inside an iFrame, and then redirect to another domain from within that iFrame, that domain must disable the X-Frame-Options header. If this isn't done, the page to which you redirect will be blank.

    TIP: To redirect outside the iFrame, consider using our Event Notifer.

    6  iFrame Best PracticesIntegrator's Guide

    29

  • 6.2  Making an iFrame's Dimensions DynamicFor the OneSpan Sign product, it's desirable to make an iFrame's height and width dynamic — i.e., to ensure that its dimensions are adjusted automatically so it's always in full view, and its sides are always visible.

    The following sections discuss three alternate ways of achieving a full view:

     l Using Viewport Units on page 30

     l Using Fixed Positioning on page 30

     l Using Fixed Dimensions on page 31

    6.2.1  Using Viewport UnitsTo ensure a full view, you might want to use viewport units and an online calculator.

    Code Sample

    body { margin: 0; /* Reset default margin */ } iframe { display: block; /* iframes are inline by default */ background: #000; border: none; /* Reset default border */ height: 100vh; /* Viewport-relative units */ width: 100vw; }

    6.2.2  Using Fixed PositioningThe safest way to ensure a full view is to use fixed positioning.

    Code Sample

    iframe { position: fixed; background: #000; border: none; top: 0; right: 0; bottom: 0; left: 0;

    6  iFrame Best PracticesIntegrator's Guide

    30

    https://caniuse.com/#feat=viewport-unitshttps://caniuse.com/#feat=calchttps://caniuse.com/#feat=calc

  • width: 100%; height: 100%; }

    6.2.3  Using Fixed DimensionsTo ensure a full view, you might want to use fixed dimensions by ensuring that the iFrame uses 100% of the screen.

    Code Sample

    html, body { height: 100%; margin: 0; /* Reset default margin on the body element */ } iframe { display: block; /* iframes are inline by default */ background: #000; border: none; /* Reset default border */ width: 100%; height: 100%; }

    6  iFrame Best PracticesIntegrator's Guide

    31

  • 6.3  Preventing Mobile Users from Scaling ContentThe following code illustrates how to prevent the users of mobile devices from scal-ing an iFrame's contents. If you don't do this, your iFrame may stop being in full view.

    Code Sample

    6  iFrame Best PracticesIntegrator's Guide

    32

  • 6.4  Adding Momentum-Based Scrolling CSS for iOS Devices

    Since you can't always control the dimensions of a iFrame, some content may not be accessible via scrolling. This is especially likely for iOS devices such as iPhones and iPads.

    To optimize usability for iOS Devices:

     1. Create a wrapper HTML element for your iFrame (e.g., create a div).

     2. Enable momentum-based scrolling CSS on the wrapper, as illustrated by the fol-lowing code:

    -webkit-overflow-scrolling: touch;

    NOTE: The above procedure ensures that if an iFrame's content is not scrollable, you can scroll the parent element.

    6  iFrame Best PracticesIntegrator's Guide

    33

  • 6.5  Example that Incorporates the Above TipsThe following code illustrates the best practices described above.

    Code Sample

    html, body { margin: 0; height: 100%; } body { position: relative; background: #EEE; } .frame_holder { position: absolute; top: 50px; bottom: 50px; left: 50px; right: 50px; background: #ffffff; overflow: hidden; } .my_frame { width: 100%; height: 100%; border: 1px solid #e0e0e0; }

  • class="my_frame" width="100%" height="100%" frameborder="0" scrolling="yes" allowTransparency="true" src="https://apps.esignlive.com/auth?target=https%3A%2F%2Fapps.esignlive.com%2Ftransaction%2FWghE2Df36wB1CGl6eODNkBn0HiA%3D%2Fsign&loginToken=YXY2R2pOV3pyRnhkcVlzdlNDYjlNZzVjRlZ6WTJVOFFIdFY1a3grSk5TdDZuWkNoZGZ4alFoOWVKcEhGN2VFbWR6RkpSZEN2cDZkMmNjdFlCdXJtS1dSbmFqVlVZbkpLTTJ0cFMzTlpXSGxWVW5OcmRGRkZXbEpQU1dwa1ZHd3hhVXBEZWt0cE1tdFpiV2xtYUV4d1ptNTVORFYxTWtWbVFuaE5PRFE1VjBsMXp5dUQyZmJ0YVZDZzdETjEzLzVBQ1pyalFsOTRBRmsxTWhncXZBN1gxQT09">

    TIP: The following sections illustrate two alternative ways of adapting the above code to access the OneSpan Sign service:

     l Authentication Tokens

     l Signing URL

    If you want to remove the logo and session bar from OneSpan Sign's Signing Ceremony, add iframe=true as a query argument in your target URL.

    6  iFrame Best PracticesIntegrator's Guide

    35

    https://docs.esignlive.com/content/c_integrator_s_guide/rest_api/authentication_tokens.htmhttps://docs.esignlive.com/content/c_integrator_s_guide/rest_api/signing_url.htm

  • 7 SDKsThe following sections collectively describe OneSpan Sign's SDKs:

     l Getting Started with SDKs on page 37

     l Configuring Document Packages on page 40

     l Managing Documents on page 58

     l Managing Signers on page 103

     l Preparing Documents on page 165

     l Fast Track on page 213

     l Signing Documents on page 219

     l Managing Accounts and Groups on page 224

     l Layouts and Templates on page 237

     l Reports and Logging on page 257

     l Customization on page 304

     l OneSpan Sign Mobile SDKs on page 327

    7  SDKsIntegrator's Guide

    36

  • 7.1  Getting Started with SDKsTo get started with the product's SDKs, you can download any of the following types of SDKs:

     l OneSpan Sign Java SDKs on page 37 — These SDKs enable integration with any application written in the Java programming language.

     l OneSpan Sign .NET SDKs on page 38 — These SDKs enable integration with any application written in the C# programming language.

     l OneSpan Sign Mobile SDKs on page 39 — These SDKs enable integration with Web applications on mobile phones and tablets.

     l OneSpan Sign APEX SDK on page 39 — This SDK enables integration with any application written for Salesforce or the Force.com platform.

    NOTE: OneSpan Sign Java SDKs and OneSpan Sign .NET SDKs offer alternate ways of doing the same thing through different programming languages. Most of this SDKs chapter describes those SDKs.

    7.1.1  OneSpan Sign Java SDKsIf you want to work with an OneSpan Sign Java SDK, download the 11 version.

    NOTE: To view Javadoc documentation for an OneSpan Sign Java SDK: (1) download the 11 version; (2) unzip the downloaded file; (3) run the file sdk--javadoc.

    NOTE: The OneSpan Sign Java SDKs support Java 1.7_21 and higher.

    For additional information, see the GitHub examples below.

    SDK 11

     l To download the OneSpan Sign Java SDK, see the online help.

    7  SDKsIntegrator's Guide

    37

    https://docs.esignlive.com/content/c_integrator_s_guide/sdk/a_introduction/getting_started_with_sdks.htm

  • Sample Java Code

     l Sample Java Code for Creating a Package

     l More Java Examples

    Maven Users

    If you are a Maven user, add to your pom file the appropriate one of following dependencies.

    For SDK 11:

    com.silanis.esl sdk 11.18

    NOTE: If you want the version of the SDK that bundles all dependencies, add jar-with-dependencies to the dependency.

    7.1.2  OneSpan Sign .NET SDKsIf you want to work with an OneSpan Sign .NET SDK, download the 11 version, and perform the extra configuration described below. For additional information, see the GitHub examples below.

    SDK 11

     l To download the OneSpan Sign .NET SDK, see the online help.

    Sample .NET Code

     l Sample .NET Code for Creating a Package

     l More .NET Examples

    Extra Configuration

    After you've downloaded an OneSpan Sign .NET SDK, and extracted the package into the directory of your Visual Studio project, add the following as references within Visual Studio:

    7  SDKsIntegrator's Guide

    38

    https://github.com/eSignLive/esl.sdk.java/blob/master/sdk/src/main/java/com/silanis/esl/sdk/examples/BasicPackageCreationExample.javahttps://github.com/esignlive/esl.sdk.java/tree/master/sdk/src/main/java/com/silanis/esl/sdk/exampleshttps://docs.esignlive.com/content/c_integrator_s_guide/sdk/a_introduction/getting_started_with_sdks.htmhttps://github.com/eSignLive/esl.sdk.net/blob/master/sdk/SDK.Examples/src/BasicPackageCreationExample.cshttps://github.com/esignlive/esl.sdk.net/tree/master/sdk/SDK.Examples/src

  • Newtonsoft.Json.dll Silanis.ESL.dll

    7.1.3  OneSpan Sign Mobile SDKsWhich Mobile SDK applies to you depends on your Operating System:

     l To learn how to download and integrate the iOS SDK, click here.

     l To learn how to download and integrate the Android SDK, click here.

    7.1.4  OneSpan Sign APEX SDKWritten in APEX, the OneSpan Sign APEX SDK for Salesforce enables developers to integrate e-signing functionality into their custom apps on either Salesforce or the Force.com platform.

     l To get started, please download the OneSpan Sign APEX SDK on GitHub.

     l You can also view numerous code snippets and examples.

     l If you have specific questions, check out our Developer Community.

    7  SDKsIntegrator's Guide

    39

    https://github.com/KadenceCollective/esignlive-apex-sdkhttps://github.com/KadenceCollective/esignlive-apex-sdk/wiki/SDK-Documentationhttps://developer.esignlive.com/

  • 7.2  Configuring Document PackagesThis following sections describe various ways of configuring a document package:

     l Customizing Sender Information on page 40

     l Setting a Reminder Schedule on page 41

     l Creating a Package with Custom Data on page 46

     l Modifying the Status of a Package on page 48

     l Adding Reasons for Opting Out or Declining to Sign on page 52

    7.2.1  Customizing Sender InformationIf your account is used by multiple senders, it is important to tailor a package's sender information to the relevant sender. By default, a new package identifies the Account Owner as the sender. This could confuse the package receiver, as they might not recognize the name of the Account Owner that appears in the email invit-ation. By configuring the package to use customized sender information, you will be able to accurately identify the sender to the package receiver.

    A "custom sender" must already be a member of the account. However, customized sender information is disregarded if the sender is one of the signers in the e-sig-nature process.

    The following code samples illustrate how to customize the sender information for a document package.

    Java Code

    PackageBuilder superDuperPackage = newPackageNamed("package")

    .withSenderInfo( SenderInfoBuilder.newSenderInfo("sender")

    .withName( "John", "Smith" )

    .withTitle( "CEO" )

    .withCompany( "Acme" ) );

    C# Code

    7  SDKsIntegrator's Guide

    40

  • DocumentPackageBuilder

    .WithSenderInfo( SenderInfoBuilder.NewSenderInfo()

    .WithName( "John", "Smith" )

    .WithTitle( "CEO" )

    .WithCompany( "Acme" ) );

    7.2.2  Setting a Reminder ScheduleBy configuring a Reminder Schedule, the sender can specify when and how often the system will remind a signer to sign. This doesn't affect the initial notification, which is issued the moment a package is sent for signing. Instead, after a cus-tomizable delay, an additional notification is sent to the signer (if their participation is still pending). Further reminders can also be configured, with the same specified interval between them.

    A Reminder Schedule can be set for a document package only after the package has been created, but before the package has been sent for signing. It is achieved using a separate SDK call. The package is identified by its package id.

    The Reminder Schedule for a package can be retrieved, given the package id. And once a package with a Reminder Schedule has been sent for signing, the schedule can be disabled, given the package id.

    The following code samples illustrate how to: (1) add a Reminder Schedule to a pack-age; (2) query the package for its Reminder Schedule ; (3) clear the Reminder Sched-ule.

    Java Code

    package com.eSignLive.com.esl.sdk.examples; import com.eSignLive.com.esl.sdk.DocumentPackage; import com.eSignLive.com.esl.sdk.DocumentType; import com.eSignLive.com.esl.sdk.ReminderSchedule; import com.eSignLive.com.esl.sdk.builder.ReminderScheduleBuilder; import java.io.InputStream; import java.text.SimpleDateFormat;

    7  SDKsIntegrator's Guide

    41

  • import java.util.Date; import java.util.Properties; import static com.eSignLive.com.esl.sdk.builder.DocumentBuilder.newDocumentWithName; import static com.eSignLive.com.esl.sdk.builder.PackageBuilder.newPackageNamed; import static com.eSignLive.com.esl.sdk.builder.SignatureBuilder.signatureFor; import static com.eSignLive.com.esl.sdk.builder.SignerBuilder.newSignerWithEmail; public class ReminderExample extends SDKSample { private String email1; private InputStream documentInputStream1; public ReminderSchedule reminderScheduleToCreate, reminderScheduleToUpdate; public ReminderSchedule createdReminderSchedule, updatedReminderSchedule, removedReminderSchedule; public static void main( String... args ) { new ReminderExample( Props.get() ).run(); } public ReminderExample( Properties props ) { this( props.getProperty( "api.key" ), props.getProperty( "api.url" ), props.getProperty( "1.email" ) ); } public ReminderExample( String apiKey, String apiUrl, String email1 ) { super( apiKey, apiUrl ); this.email1 = email1; documentInputStream1 = this.getClass().getClassLoader().getResourceAsStream( "document.pdf" ); } public void execute() { DocumentPackage superDuperPackage =

    7  SDKsIntegrator's Guide

    42

  • newPackageNamed( "ReminderExample Package " + new SimpleDateFormat( "HH:mm:ss" ).format( new Date() ) ) .withSigner( newSignerWithEmail( email1 ) .withFirstName( "Patty" ) .withLastName( "Galant" ) ) .withDocument( newDocumentWithName( "First Document" ) .fromStream( documentInputStream1, DocumentType.PDF ) .withSignature( signatureFor( email1 ) .onPage( 0 ) .atPosition( 100, 100 ) ) ) .build(); packageId = eslClient.createPackage( superDuperPackage ); reminderScheduleToCreate = ReminderScheduleBuilder.forPackageWithId( packageId ) .withDaysUntilFirstReminder( 2 ) .withDaysBetweenReminders( 1 ) .withNumberOfRepetitions( 5 ) .build(); eslClient.getReminderService().createReminderScheduleForPackage( reminderScheduleToCreate ); eslClient.sendPackage( packageId ); createdReminderSchedule = eslClient.getReminderService().getReminderScheduleForPackage(packageId); reminderScheduleToUpdate = ReminderScheduleBuilder.forPackageWithId( packageId ) .withDaysUntilFirstReminder( 3 ) .withDaysBetweenReminders( 2 ) .withNumberOfRepetitions( 10 ) .build(); eslClient.getReminderService().updateReminderScheduleForPackage( reminderScheduleToUpdate ); updatedReminderSchedule =

    7  SDKsIntegrator's Guide

    43

  • eslClient.getReminderService().getReminderScheduleForPackage(packageId); eslClient.getReminderService().clearReminderScheduleForPackage( packageId ); removedReminderSchedule = eslClient.getReminderService().getReminderScheduleForPackage(packageId); } }

    C# Code

    using System; using System.IO; using eSignLive.com.ESL.SDK; using eSignLive.com.ESL.SDK.Builder; namespace SDK.Examples { public class ReminderExample : SDKSample { public static void Main (string[] args) { new ReminderExample(Props.GetInstance()).Run(); } private string email1; private Stream fileStream1; public ReminderSchedule reminderScheduleToCreate, reminderScheduleToUpdate; public ReminderSchedule createdReminderSchedule, updatedReminderSchedule, removedReminderSchedule; public ReminderExample( Props props ) : this(props.Get("api.key"), props.Get("api.url"), props.Get("1.email")) { } public ReminderExample( string apiKey, string apiUrl, string email1 ) : base( apiKey, apiUrl ) { this.email1 = email1; this.fileStream1 = File.OpenRead(new FileInfo(Directory.GetCurrentDirectory() +

    7  SDKsIntegrator's Guide

    44

  • "/src/document.pdf").FullName); } override public void Execute() { DocumentPackage superDuperPackage = PackageBuilder.NewPackageNamed( "ReminderExample: " + DateTime.Now ) .WithSigner( SignerBuilder.NewSignerWithEmail( email1 ) .WithFirstName( "Patty" ) .WithLastName( "Galant" ) ) .WithDocument( DocumentBuilder.NewDocumentNamed( "First Document" ) .FromStream( fileStream1, DocumentType.PDF ) .WithSignature( SignatureBuilder.SignatureFor( email1 ) .OnPage( 0 ) .AtPosition( 100, 100 ) ) ) .Build(); packageId = eslClient.CreatePackage( superDuperPackage ); reminderScheduleToCreate = ReminderScheduleBuilder.ForPackageWithId(packageId) .WithDaysUntilFirstReminder(2) .WithDaysBetweenReminders(1) .WithNumberOfRepetitions(5) .Build(); eslClient.ReminderService.CreateReminderScheduleForPackage(reminderScheduleToCreate); eslClient.SendPackage( packageId ); createdReminderSchedule = eslClient.ReminderService.GetReminderScheduleForPackage(packageId); reminderScheduleToUpdate = ReminderScheduleBuilder.ForPackageWithId( packageId )

    7  SDKsIntegrator's Guide

    45

  • .WithDaysUntilFirstReminder( 3 ) .WithDaysBetweenReminders( 2 ) .WithNumberOfRepetitions( 10 ) .Build(); eslClient.ReminderService.UpdateReminderScheduleForPackage(reminderScheduleToUpdate); updatedReminderSchedule = eslClient.ReminderService.GetReminderScheduleForPackage(packageId); eslClient.ReminderService.ClearReminderScheduleForPackage(packageId); removedReminderSchedule = eslClient.ReminderService.GetReminderScheduleForPackage(packageId); } } }

    7.2.3  Creating a Package with Custom Data"Custom package data" is customized data related to a package. The data in this section of the package information is not interpreted by OneSpan Sign. The users of this data are free to store and interpret whatever data they want. The data is organ-ized as a map.

    The following code samples illustrate the simplest way of creating a package with customized package attributes. The samples illustrate how to create customized attributes with the keys First Name, Last Name, Language, and Signing Order. The customized attribute data is constructed as a map.

    CAUTION: The language that a signer sees is determined by the following somewhat complicated rules. (1) If the signer has a OneSpan Sign account, their language will be the one that the package sender last selected for themselves using OneSpan Sign’s User Inter-face. (2) If the signer does not have a OneSpan Sign account, their language can be spe-cified using the REST API or SDKs (e.g., using the method withLanguage in the following code examples). If this has not been done, the signer will inherit the package’s language. Thus the method withLanguage is effective only if the signer does not have a OneSpan Sign account. (3) If the sender has not specified a language for the package, the package

    7  SDKsIntegrator's Guide

    46

  • will use the language that the sender last selected for themselves using OneSpan Sign’s User Interface. (4) The language of the Consent Document is always the package’s lan-guage.

    Java Code

    DocumentPackage superDuperPackage1 = newPackageNamed( "Policy " + new SimpleDateFormat( "HH:mm:ss" ).format( new Date() ) ) .describedAs( "This is a package created using the eSignLive SDK" ) .expiresAt( new Date() ) .withEmailMessage( "This message should be delivered to all signers" ) .withSigner( newSignerWithEmail( "[email protected]" ) .withCustomId( "Client1" ) .withFirstName( "John" ) .withLastName( "Smith" ) .withLanguage( "English" ) .withTitle( "Managing Director" ) .withCompany( "Acme Inc." ) ) .withDocument( newDocumentWithName( "First Document" ) .fromStream( new java.io.FileInputStream(DOCUMENT_PATH), DocumentType.PDF ) .withSignature( signatureFor( "[email protected]" ) .onPage( 0 ) .withField( FieldBuilder.checkBox() .onPage( 0 ) .atPosition( 400, 200 ) .withValue( "x" ) ) .atPosition( 100, 100 ) ) ) .withAttributes(newDocumentPackageAttributes() .withAttribute( "First Name", "Bill" ) .withAttribute("Last Name", "Johnson") .withAttribute"Language", "English") .withAttribute("Signing Order", "1") .build()) .build(); PackageId packageId = eslClient.createPackage( superDuperPackage ); eslClient.sendPackage( packageId );

    C# Code

    7  SDKsIntegrator's Guide

    47

  • DocumentPackage superDuperPackage = PackageBuilder.NewPackageNamed( "Policy " + DateTime.Now ) .DescribedAs( "This is a package created using the eSignLive SDK" ) .ExpiresOn( DateTime.Now.AddMonths(1) ) .WithEmailMessage( "This message should be delivered to all signers" ) .WithSigner( SignerBuilder.NewSignerWithEmail( email1 ) .WithCustomId( "Client1" ) .WithFirstName( "John" ) .WithLastName( "Smith" ) .withLanguage( "English" ) .WithTitle( "Managing Director" ) .WithCompany( "Acme Inc." ) ) .WithDocument( DocumentBuilder.NewDocumentNamed( "First Document" ) .FromStream( fileStream1, DocumentType.PDF ) .WithSignature( SignatureBuilder.SignatureFor( email1 ) .OnPage( 0 ) .WithField( FieldBuilder.CheckBox() .OnPage( 0 ) .AtPosition( 400, 200 ) .WithValue( "x" ) ) .AtPosition( 100, 100 ) ) ) .WithAttributes(new DocumentPackageAttributesBuilder() .WithAttribute("First Name", "Bill") .WithAttribute("Last Name", "Johnson") .WithAttribute("Language", "English") .WithAttribute("Signing Order", "1") .Build()) .Build(); PackageId packageId = eslClient.CreatePackage( superDuperPackage ); eslClient.SendPackage( packageId );

    7.2.4  Modifying the Status of a PackageThe following code samples illustrate how to modify the status of a package.

    Java Code

    7  SDKsIntegrator's Guide

    48

  • package com.eSignLive.com.esl.sdk.examples; import com.eSignLive.com.esl.sdk.DocumentPackage; import com.eSignLive.com.esl.sdk.DocumentType; import java.io.InputStream; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Properties; import static com.eSignLive.com.esl.sdk.builder.DocumentBuilder.newDocumentWithName; import static com.eSignLive.com.esl.sdk.builder.PackageBuilder.newPackageNamed; import static com.eSignLive.com.esl.sdk.builder.SignatureBuilder.signatureFor; import static com.eSignLive.com.esl.sdk.builder.SignerBuilder.newSignerWithEmail; public class ChangePackageStatusExample extends SDKSample { private String email1; private InputStream documentInputStream1; public DocumentPackage sentPackage; public static void main( String... args ) { new ChangePackageStatusExample(Props.get()).run(); } public ChangePackageStatusExample( Properties props ) { this( props.getProperty( "api.key" ), props.getProperty( "api.url" ), props.getProperty( "1.email" )); } public ChangePackageStatusExample( String apiKey, String apiUrl, String email1 ) { super( apiKey, apiUrl ); this.email1 = email1; documentInputStream1 = this.getClass

    7  SDKsIntegrator's Guide

    49

  • ().getClassLoader().getResourceAsStream( "document.pdf" ); } public void execute() { DocumentPackage superDuperPackage = newPackageNamed("ChangePackageStatusExample " + new SimpleDateFormat("HH:mm:ss").format(new Date())) .describedAs("This is a package created using the eSignLive SDK") .withSigner(newSignerWithEmail(email1) .withFirstName("John1") .withLastName("Smith1")) .withDocument(newDocumentWithName("First Document") .fromStream(documentInputStream1, DocumentType.PDF) .withSignature(signatureFor(email1) .onPage(0) .atPosition(100, 100))) .build(); packageId = eslClient.createPackage( superDuperPackage ); eslClient.sendPackage( packageId ); sentPackage = eslClient.getPackage( packageId ); eslClient.changePackageStatusToDraft(packageId); retrievedPackage = eslClient.getPackage( packageId ); } }

    C# Code

    using System; using System.IO; using eSignLive.com.ESL.SDK; using eSignLive.com.ESL.SDK.Builder;

    7  SDKsIntegrator's Guide

    50

  • namespace SDK.Examples { public class ChangePackageStatusExample : SDKSample { public static void Main(string[] args) { new ChangePackageStatusExample(Props.GetInstance()).Run(); } private string email1; private Stream fileStream1; public DocumentPackage sentPackage; public readonly string DOCUMENT_NAME = "First Document"; public ChangePackageStatusExample(Props props) : this(props.Get("api.key"), props.Get("api.url"), props.Get("1.email")) { } public ChangePackageStatusExample(string apiKey, string apiUrl, string email1) : base(apiKey, apiUrl) { this.email1 = email1; this.fileStream1 = File.OpenRead(new FileInfo(Directory.GetCurrentDirectory() + "/src/document.pdf").FullName); } override public void Execute() { DocumentPackage superDuperPackage = PackageBuilder.NewPackageNamed("ChangePackageStatusExample: " + DateTime.Now) .WithSettings(DocumentPackageSettingsBuilder.NewDocumentPackageSettings().WithInPerson()) .WithSigner(SignerBuilder.NewSignerWithEmail(email1) .WithFirstName("John1") .WithLastName("Smith1"))

    7  SDKsIntegrator's Guide

    51

  • .WithDocument(DocumentBuilder.NewDocumentNamed(DOCUMENT_NAME) .FromStream(fileStream1, DocumentType.PDF) .WithSignature(SignatureBuilder.SignatureFor(email1) .OnPage(0) .AtPosition(100, 100))) .Build(); packageId = eslClient.CreatePackage(superDuperPackage); eslClient.SendPackage(packageId); sentPackage = eslClient.GetPackage(packageId); eslClient.ChangePackageStatusToDraft(packageId); retrievedPackage = eslClient.GetPackage( packageId ); } } }

    7.2.5  Adding Reasons for Opting Out or Declining to SignThe following code samples illustrate how to add reasons for "opting out" of signing a package electronically, or for "declining" to sign it altogether.

    Java Code

    package com.eSignLive.com.esl.sdk.examples; import com.eSignLive.com.esl.sdk.DocumentPackage; import com.eSignLive.com.esl.sdk.DocumentType; import java.io.InputStream; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Properties; import static com.eSignLive.com.esl.sdk.builder.CeremonyLayoutSettingsBuilder.newCeremonyLayoutSettings; import static com.eSignLive.com.esl.sdk.builder.DocumentBuilder.newDocumentWithName; import static

    7  SDKsIntegrator's Guide

    52

  • com.eSignLive.com.esl.sdk.builder.DocumentPackageSettingsBuilder.newDocumentPackageSettings; import static com.eSignLive.com.esl.sdk.builder.PackageBuilder.newPackageNamed; import static com.eSignLive.com.esl.sdk.builder.SignatureBuilder.signatureFor; import static com.eSignLive.com.esl.sdk.builder.SignerBuilder.newSignerWithEmail; public class DocumentPackageSettingsExample extends SDKSample { private String email1; private InputStream documentInputStream; public static final String DECLINE_REASON_1 = "Decline reason One"; public static final String DECLINE_REASON_2 = "Decline reason Two"; public static final String DECLINE_REASON_3 = "Decline reason Three"; public static final String OPT_OUT_REASON_1 = "Opt out reason One"; public static final String OPT_OUT_REASON_2 = "Opt out reason Two"; public static final String OPT_OUT_REASON_3 = "Opt out reason Three"; public static final String HAND_OVER_LINK_HREF = "http://www.google.ca"; public static final String HAND_OVER_LINK_TEXT = "click here"; public static final String HAND_OVER_LINK_TOOLTIP = "link tooltip"; public static void main( String... args ) { new DocumentPackageSettingsExample( Props.get() ).run(); } public DocumentPackageSettingsExample( Properties properties ) { this(properties.getProperty( "api.key" ), properties.getProperty( "api.url" ), properties.getProperty( "1.email" ) ); }

    7  SDKsIntegrator's Guide

    53

  • public DocumentPackageSettingsExample( String apiKey, String apiUrl, String email1 ) { super( apiKey, apiUrl ); this.email1 = email1; documentInputStream = this.getClass().getClassLoader().getResourceAsStream( "document.pdf" ); } @Override public void execute() { DocumentPackage superDuperPackage = newPackageNamed( "DocumentPackageSettingsExample " + new SimpleDateFormat( "HH:mm:ss" ).format( new Date() ) ) .withSettings( newDocumentPackageSettings() .withInPerson() .withoutLanguageDropDown() .hideOwnerInPersonDropDown() .disableFirstAffidavit() .disableSecondAffidavit() .withDecline() .withDeclineReason(DECLINE_REASON_1) .withDeclineReason(DECLINE_REASON_2) .withDeclineReason(DECLINE_REASON_3) .withOptOut() .withOptOutReason(OPT_OUT_REASON_1) .withOptOutReason(OPT_OUT_REASON_2) .withOptOutReason(OPT_OUT_REASON_3) .withHandOverLinkHref(HAND_OVER_LINK_HREF) .withHandOverLinkText(HAND_OVER_LINK_TEXT) .withHandOverLinkTooltip(HAND_OVER_LINK_TOOLTIP) .withDialogOnComplete() .withCeremonyLayoutSettings( newCeremonyLayoutSettings() .withoutGlobalConfirmButton() .withoutGlobalSaveAsLayoutButton() ) ) .withSigner( newSignerWithEmail( email1 ) .withFirstName( "John" ) .withLastName( "Smith" ) ) .withDocument( newDocumentWithName( "First

    7  SDKsIntegrator's Guide

    54

  • Document" ) .fromStream( documentInputStream, DocumentType.PDF ) .withSignature( signatureFor( email1 ) .onPage( 0 ) .atPosition( 100, 100 ) ) ) .build(); packageId = eslClient.createPackage( superDuperPackage ); eslClient.sendPackage( packageId ); retrievedPackage = eslClient.getPackage( packageId ); } }

    C# Code

    using System; using eSignLive.com.ESL.SDK; using eSignLive.com.ESL.SDK.Builder; using System.IO; namespace SDK.Examples { public class DocumentPackageSettingsExample : SDKSample { public static void Main (string[] args) { new DocumentPackageSettingsExample(Props.GetInstance()).Run(); } private string email1; private Stream fileStream1; public readonly string DECLINE_REASON_1 = "Decline reason One"; public readonly string DECLINE_REASON_2 = "Decline reason Two"; public readonly string DECLINE_REASON_3 = "Decline reason Three"; public readonly string OPT_OUT_REASON_1 = "OptOut reason One"; public readonly string OPT_OUT_REASON_2 =

    7  SDKsIntegrator's Guide

    55

  • "OptOut reason Two"; public readonly string OPT_OUT_REASON_3 = "OptOut reason Three"; public DocumentPackageSettingsExample( Props props ) : this(props.Get("api.key"), props.Get("api.url"), props.Get("1.email")) { } public DocumentPackageSettingsExample( String apiKey, String apiUrl, String email1 ) : base( apiKey, apiUrl ) { this.email1 = email1; this.fileStream1 = File.OpenRead(new FileInfo(Directory.GetCurrentDirectory() + "/src/document.pdf").FullName); } override public void Execute() { DocumentPackage superDuperPackage = PackageBuilder.NewPackageNamed("DocumentPackageSettingsExample " + DateTime.Now) .WithSettings(DocumentPackageSettingsBuilder.NewDocumentPackageSettings() .WithInPerson() .WithoutLanguageDropDown() .DisableFirstAffidavit() .DisableSecondAffidavit() .HideOwnerInPersonDropDown() .WithDecline() .WithOptOut() .WithDeclineReason(DECLINE_REASON_1) .WithDeclineReason(DECLINE_REASON_2) .WithDeclineReason(DECLINE_REASON_3) .WithOptOutReason(OPT_OUT_REASON_1) .WithOptOutReason(OPT_OUT_REASON_2) .WithOptOutReason(OPT_OUT_REASON_3) .WithHandOverLinkHref("http://www.google.ca") .WithHandOverLinkText("click here") .WithHandOverLinkTooltip("link tooltip") .WithCeremonyLayoutSettings(CeremonyLayoutSettingsBuilder.NewCeremonyLayoutSettings() .WithoutGlobalConfirmButton()

    7  SDKsIntegrator's Guide

    56

  • .WithoutGlobalDownloadButton() .WithoutGlobalSaveAsLayoutButton() ) ) .WithSigner(SignerBuilder.NewSignerWithEmail(email1) .WithFirstName("John") .WithLastName("Smith")) .WithDocument(DocumentBuilder.NewDocumentNamed("First Document") .FromStream(fileStream1, DocumentType.PDF) .WithSignature(SignatureBuilder.SignatureFor(email1) .OnPage(0) .AtPosition(100, 100))) .Build(); packageId = eslClient.CreateAndSendPackage(superDuperPackage); retrievedPackage = eslClient.GetPackage( packageId ); } } }

    7  SDKsIntegrator's Guide

    57

  • 7.3  Managing DocumentsThis section tells you how to upload and manage documents in the packages you create, and how to automatically position Signature Blocks and other fields in doc-uments. Specifically, this section discusses:

     l Uploading Documents

     l Document Workflow

     l Retrieving Documents

     l Managing Document Visibility

     l Field Injection

     l Extraction

    7.3.1  Uploading DocumentsTo add a new document to a document package, OneSpan Sign must upload the document's binary contents.

    You can enable that upload in two ways:

     l Uploading a Document from a File on page 59

     l Uploading a Document from a Stream on page 60

    NOTE: OneSpan Sign supports the following types of documents:

     l Adobe's Portable Document Format (*.pdf)

     l Microsoft Word (*.doc or *.docx)

     l Open Office (*.odt)

     l Text (.txt)

     l Rich Text Format (.rtf)

    7  SDKsIntegrator's Guide

    58

  • CAUTION: Please be aware of the following:

     l The maximum size of a single document is 16 MB. The only exceptions concern our Salesforce and Microsoft SharePoint connectors, whose maximum is 5 MB per doc-ument. Smaller documents yield better performance — we recommend under 5 MB per document.

     l If you enable email delivery while configuring a recipient, documents that are lar-ger than 5 MB will not be added as attachments to the email.

     l OneSpan will not provide Technical Support for a transaction or transaction tem-plate that has more than 10 documents.

     l Document file names should not contain any of the following comma-separated characters: *, /, \, :, , |, ?, ".

     l A document's name cannot contain the string esigned.

     l Uploading password-protected or corrupted documents will trigger an error.

     l PDFs added to a transaction must not have syntax errors. We strongly recommend that you scan a PDF for syntax errors before you add it to a transaction (e.g., by using Adobe's Preflight tool).

     l PDFs with the NeedAppearances flag set to true are not currently supported.

    Uploading a Document from a File

    If a document's binary contents are stored locally, you can tell the SDK to upload the relevant file from its location:

    Java Code

    DocumentBuilder.newDocumentWithName("First Document")

    .fromFile("src/main/Resources/document.pdf");

    C# Code

    DocumentBuilder.NewDocumentNamed("First Document")

    7  SDKsIntegrator's Guide

    59

  • .FromFile("src/main/Resources/document.pdf");

    NOTE: The document name should not contain any of the following comma-separated characters: *, /, \, :, , |, ?, ".

    Uploading a Document from a Stream

    If a document's binary contents are stored externally, you can tell the SDK to upload those contents directly from a stream:

    Java Code

    InputStream documentStream = .class.getResourceAsStream( "/document.pdf" ); DocumentBuilder.newDocumentWithName("First Document") .fromStream( documentStream, DocumentType.PDF );

    C# Code

    FileStream fileStream = new FileStream(@"/document.pdf", FileMode.Open); DocumentBuilder.NewDocumentNamed("First Document") .FromStream(fileStream, DocumentType.PDF);

    7.3.2  Document WorkflowDocument Workflow determines the order in which multiple documents are signed by a participant. By default, no Document Workflow is enforced, permitting a par-ticipant to freely browse all documents before signing them in any order.

    When a Document Workflow is enforced, the participant initially sees the unsigned document that has the lowest signing order. Once that document is processed, the participant sees the unsigned document that has the next lowest order. And so on. In general, a document of a given order can be viewed by the signer only after all documents of lower orders have been processed.

    This rest of this section discusses:

     l Creating a Document Workflow on page 61

     l Updating a Document Workflow on page 64

    7  SDKsIntegrator's Guide

    60

  •  l Combining Document and Signer Workflows on page 67

    Creating a Document Workflow

    In the following code samples, John is required to complete signing a first doc-ument before he's allowed to sign a second document.

    Java Code

    import static com.eSignLive.com.esl.sdk.builder.DocumentBuilder.newDocumentWithName; import static com.eSignLive.com.esl.sdk.builder.PackageBuilder.newPackageNamed; import static com.eSignLive.com.esl.sdk.builder.SignatureBuilder.signatureFor; import static com.eSignLive.com.esl.sdk.builder.SignerBuilder.newSignerWithEmail; import java.text.SimpleDateFormat; import java.util.Date; import com.eSignLive.com.esl.sdk.DocumentPackage; import com.eSignLive.com.esl.sdk.EslClient; import com.eSignLive.com.esl.sdk.PackageId; public class DocumentOrder { public static final String API_KEY = ""; public static final String API_URL = "https://sandbox.eSignLive.com/api"; // USE https://apps.eSignLive.com/api FOR PRODUCTION private static final SimpleDateFormat format = new SimpleDateFormat( "HH:mm:ss" ); public static void main( String... args ) { EslClient eslClient = new EslClient( API_KEY, API_URL ); DocumentPackage superDuperPackage = newPackageNamed("Policy " + format.format(new Date

    7  SDKsIntegrator's Guide

    61

  • ())) .describedAs("This is a package with a document workflow created using the eSignLive SDK") .withSigner(newSignerWithEmail("[email protected]") .withFirstName("John") .withLastName("Smith")) .withDocument(newDocumentWithName("Second Document") .fromFile("src/main/Resources/document.pdf") .atIndex(2) .withSignature(signatureFor("[email protected]") .onPage(0) .atPosition(100, 100))) .withDocument(newDocumentWithName("First Document") .fromFile("src/main/Resources/document.pdf") .atIndex(1) .withSignature(signatureFor("[email protected]") .onPage(0) .atPosition(100, 100))) .build(); PackageId packageId = eslClient.createPackage( superDuperPackage ); eslClient.sendPackage( packageId ); } }

    C# Code

    using System; using System.Globalization; using System.IO; using eSignLive.com.ESL.SDK; using eSignLive.com.ESL.SDK.Builder; using System.Collections.Generic; namespace SDK.Examples { public class DocumentWorkflow {

    7  SDKsIntegrator's Guide

    62

  • public static string API_KEY = ; public static string API_URL = ; public static void Main (string[] args) { test(); } public static void test() { EslClient eslClient = new EslClient( API_KEY, API_URL ); var usCulture = new CultureInfo("en-US"); var utcDate = DateTime.UtcNow; var gmt1Date = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(utcDate, "W. Europe Standard Time"); var str = gmt1Date.ToString("HH:mm:ss", usCulture); DocumentPackage superDuperPackage = PackageBuilder.NewPackageNamed("Policy " + str) .DescribedAs("This is a package with a document workflow created using the eSignLive SDK") .WithSigner(SignerBuilder.NewSignerWithEmail("[email protected]") .WithFirstName("John") .WithLastName("Smith")) .WithDocument(DocumentBuilder.NewDocumentNamed("Second Document") .FromFile("src/main/Resources/document.pdf") .AtIndex(2) .WithSignature(SignatureBuilder.SignatureFor("[email protected]") .OnPage(0) .AtPosition(100, 100))) .WithDocument(DocumentBuilder.NewDocumentNamed("First Document") .FromFile("src/main/Resources/document.pdf") .AtIndex(1) .WithSignature(SignatureBuilder.SignatureFor("[email protected]")

    7  SDKsIntegrator's Guide

    63

  • .OnPage(0) .AtPosition(100, 100))) .Build(); PackageId packageId = eslClient.CreatePackage( superDuperPackage ); eslClient.SendPackage( packageId ); } } }

    Updating a Document Workflow

    The following code samples illustrate how to update the Document Workflow after a package has been created. Each sample swaps the signing order of its two doc-uments.

    Java Code

    import static com.eSignLive.com.esl.sdk.builder.DocumentBuilder.newDocumentWithName; import static com.eSignLive.com.esl.sdk.builder.PackageBuilder.newPackageNamed; import static com.eSignLive.com.esl.sdk.builder.SignatureBuilder.signatureFor; import static com.eSignLive.com.esl.sdk.builder.SignerBuilder.newSignerWithEmail; import java.text.SimpleDateFormat; import java.util.Date; import com.eSignLive.com.esl.sdk.DocumentPackage; import com.eSignLive.com.esl.sdk.EslClient; import com.eSignLive.com.esl.sdk.PackageId; public class DocumentWorkflowExample { public static final String API_KEY = ""; public static final String API_URL = "https://sandbox.eSignLive.com/api"; // USE

    7  SDKsIntegrator's Guide

    64

  • https://apps.eSignLive.com/api FOR PRODUCTION private static final SimpleDateFormat format = new SimpleDateFormat( "HH:mm:ss" ); public static void main( String... args ) { EslClient eslClient = new EslClient( API_KEY, API_URL ); DocumentPackage superDuperPackage = newPackageNamed("DocumentWorkflowExample " + format.format(new Date())) .describedAs("This is a package with a document workflow created using the eSignLive SDK") .withSigner(newSignerWithEmail("[email protected]") .withFirstName("John") .withLastName("Smith")) .withDocument(newDocumentWithName("Second Document") .fromFile("src/main/Resources/document.pdf") .atIndex(2) .withSignature(signatureFor("[email protected]") .onPage(0) .atPosition(100, 100))) .withDocument(newDocumentWithName("First Document") .fromFile("src/main/Resources/document.pdf") .atIndex(1) .withSignature(signatureFor("[email protected]") .onPage(0) .atPosition(100, 100))) .build(); PackageId packageId = eslClient.createPackage( superDuperPackage ); // Reorder the documents: swap the order of the two documents DocumentPackage postOrderDocumentsPackage = eslClient.getPackage(packageId); postOrderDocumentsPackage.getDocument("First Document").setIndex(2); postOrderDocumentsPackage.getDocument("Second Document").setIndex(1);

    7  SDKsIntegrator's Guide

    65

  • eslClient.getPackageService().orderDocuments(postOrderDocumentsPackage); eslClient.sendPackage( packageId ); } }

    C# Code

    using System; using System.Globalization; using System.IO; using eSignLive.com.ESL.SDK; using eSignLive.com.ESL.SDK.Builder; using System.Collections.Generic; namespace SDK.Examples { public class DocumentWorkflowExample { public static string API_KEY = ; public static string API_URL = ; public static void Main (string[] args) { EslClient eslClient = new EslClient( API_KEY, API_URL ); var usCulture = new CultureInfo("en-US"); var utcDate = DateTime.UtcNow; var gmt1Date = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(utcDate, "W. Europe Standard Time"); var str = gmt1Date.ToString("HH:mm:ss", usCulture); DocumentPackage superDuperPackage = PackageBuilder.NewPackageNamed("DocumentWorkflowExample " + str) .DescribedAs("This is a package with a document workflow created using the eSignLive SDK") .WithSigner(SignerBuilder.NewSignerWithEmail("[email protected]") .WithFirstName("John")

    7  SDKsIntegrator's Guide

    66

  • .WithLastName("Smith")) .WithDocument(DocumentBuilder.NewDocumentNamed("Second Document") .FromFile("src/main/Resources/document.pdf") .AtIndex(2) .WithSignature(SignatureBuilder.SignatureFor("[email protected]") .OnPage(0) .AtPosition(100, 100))) .WithDocument(DocumentBuilder.NewDocumentNamed("First Document") .FromFile("src/main/Resources/document.pdf") .AtIndex(1) .WithSignature(SignatureBuilder.SignatureFor("[email protected]") .OnPage(0) .AtPosition(100, 100))) .Build(); PackageId packageId = eslClient.CreatePackage( superDuperPackage ); // Reorder the documents: swap the order of the two documents DocumentPackage savedPackage = eslClient.GetPackage(packageId); savedPackage.Documents["First Document"].Index = 2; savedPackage.Documents["Second Document"].Index = 1; eslClient.PackageService.OrderDocuments(savedPackage); eslClient.SendPackage( packageId ); } } }

    Combining Document and Signer Workflows

    If a Document Workflow and a Signer Workflow are both enforced:

    7  SDKsIntegrator's Guide

    67

  •  1. Signers are invited to participate according to the Signer Workflow.

     2. Documents are presented to a signer according to the Document Workflow.

    The following code samples invite two signers (signer1 and signer2) to sign two doc-uments (firstDocument and secondDocument). Signer1 must sign first, and must sign the firstDocument before the secondDocument. When signer1 has signed both documents, signer2 is invited to sign, the firstDocument first, and then the secondDocument.

    Java Code

    import static com.eSignLive.com.esl.sdk.builder.DocumentBuilder.newDocumentWithName; import static com.eSignLive.com.esl.sdk.builder.PackageBuilder.newPackageNamed; import static com.eSignLive.com.esl.sdk.builder.SignatureBuilder.signatureFor; import static com.eSignLive.com.esl.sdk.builder.SignerBuilder.newSignerWithEmail; import java.text.SimpleDateFormat; import java.util.Date; import com.eSignLive.com.esl.sdk.DocumentPackage; import com.eSignLive.com.esl.sdk.EslClient; import com.eSignLive.com.esl.sdk.PackageId; public class CombinedOrder { public static final String API_KEY = ""; public static final String API_URL = "https://sandbox.eSignLive.com/api"; // USE https://apps.eSignLive.com/api FOR PRODUCTION private static final SimpleDateFormat format = new SimpleDateFormat( "HH:mm:ss" ); public static void main( String... args ) { EslClient eslClient = new EslClient( API_KEY,

    7  SDKsIntegrator's Guide

    68

  • API_URL ); DocumentPackage superDuperPackage = newPackageNamed( "Policy " + format.format( new Date() ) ) .describedAs( "This is a package with a document workflow created using the eSignLive SDK" ) .withSigner( newSignerWithEmail( "[email protected]" ) .withFirstName( "FirstNameSigner1" ) .withLastName( "LastNameSigner1" ) .signingOrder( 1 ) ) .withSigner( newSignerWithEmail( "[email protected]" ) .withFirstName( "FirstNameSigner2" ) .withLastName( "LastNameSigner2" ) .signingOrder( 2 ) ) .withDocument( newDocumentWithName( "Second Document" ) .fromFile( "src/main/Resources/document.pdf" ) .atIndex( 2 ) .withSignature( signatureFor( "[email protected]" ) .onPage( 0 ) .atPosition( 100, 100 ) ) .withSignature( signatureFor( "[email protected]" ) .onPage( 0 ) .atPosition( 100, 200 ) ) ) .withDocument( newDocumentWithName( "First Document" ) .fromFile( "src/main/Resources/document.pdf" ) .atIndex( 1 ) .withSignature( signatureFor( "[email protected]" ) .onPage( 0 ) .atPosition( 100, 100 ) ) .withSignature( signatureFor( "[email protected]" ) .onPage( 0 ) .atPosition( 100, 200 ) ) ) .build();

    7  SDKsIntegrator's Guide

    69

  • PackageId packageId = eslClient.createPackage( superDuperPackage ); eslClient.sendPackage( packageId ); } }

    C# Code

    using System; using System.Globalization; using System.IO; using eSignLive.com.ESL.SDK; using eSignLive.com.ESL.SDK.Builder; using System.Collections.Generic; namespace SDK.Examples { public class CreatePackageWithBuilder { public static string API_KEY = ; public static string API_URL = ; public static void Main (string[] args) { test(); } public static void CombinedWorkflow() { EslClient eslClient = new EslClient(API_KEY, API_URL); var usCulture = new CultureInfo("en-US"); var utcDate = DateTime.UtcNow; var gmt1Date = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(utcDate, "W. Europe Standard Time"); var str = gmt1Date.ToString("HH:mm:ss", usCulture); DocumentPackage superDuperPackage = PackageBuilder.NewPackageNamed("Policy " + str) .DescribedAs("This is a package with a document workflow created using the eSignLive SDK") .WithSigner(SignerBuilder.NewSignerWithEmail("[email protected]") .WithFirstName("FirstNameSigner1")

    7  SDKsIntegrator's Guide

    70

  • .WithLastName("LastNameSigner1") .SigningOrder(1)) .WithSigner(SignerBuilder.NewSignerWithEmail("[email protected]") .WithFirstName("FirstNameSigner2") .WithLastName("LastNameSigner2") .SigningOrder(2)) .WithDocument(DocumentBuilder.NewDocumentNamed("Second Document") .FromFile("src/main/Resources/document.pdf") .AtIndex(2) .WithSignature(SignatureBuilder.SignatureFor("[email protected]") .OnPage(0) .AtPosition(100, 100)) .WithSignature(SignatureBuilder.SignatureFor("[email protected]") .OnPage(0) .AtPosition(100, 200))) .WithDocument(DocumentBuilder.NewDocumentNamed("First Document") .FromFile("src/main/Resources/document.pdf") .AtIndex(1) .WithSignature(SignatureBuilder.SignatureFor("[email protected]") .OnPage(0) .AtPosition(100, 100)) .WithSignature(SignatureBuilder.SignatureFor("[email protected]") .OnPage(0) .AtPosition(100, 200))) .Build(); PackageId packageId = eslClient.CreatePackage(superDuperPackage); eslClient.SendPackage(packageId); } } }

    7  SDKsIntegrator's Guide

    71

  • 7.3.3  Retrieving DocumentsAny documents uploaded when a document package is created can be downloaded later.

    NOTE: If you are using a Custom ID to identify a document, ensure that the ID contains only alphanumeric characters.

    The following methods can be used to retrieve documents:

     l The EslClient.downloadOriginalDocument() method can be called both before and after a package's completion. It retrieves the original document uploaded by the sender, without any signatures or fields.

     l The EslClient.downloadDocument() method can be called both before and after a package's completion. If called before, the documents will be flattened, removing all pending signatures and fields.

     l The EslClient.downloadZippedDocuments() method can be called only after all signing has been completed. Once called, the method will deliver an archive that contains all signed documents.

    NOTE: If you are testing in our Sandbox environment, there will be a watermark on all retrieved documents.

    The following code samples illustrate how to retrieve a document using field names.

    Java Code

    import com.google.common.io.Files; import com.eSignLive.com.esl.sdk.DocumentPackage; import com.eSignLive.com.esl.sdk.EslClient; import com.eSignLive.com.esl.sdk.PackageId; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Properties;

    7  SDKsIntegrator's Guide

    72

  • import static com.eSignLive.com.esl.sdk.builder.DocumentBuilder.newDocumentWithName; import static com.eSignLive.com.esl.sdk.builder.PackageBuilder.newPackageNamed; import static com.eSignLive.com.esl.sdk.builder.SignatureBuilder.signatureFor; import static com.eSignLive.com.esl.sdk.builder.SignerBuilder.newSignerWithEmail; public class DocumentRetrievalExample { public static final String API_KEY = ""; public static final String API_URL = "https://sandbox.eSignLive.com/api"; // USE https://apps.eSignLive.com/api FOR PRODUCTION private static final SimpleDateFormat format = new SimpleDateFormat( "HH:mm:ss" ); private static EslClient eslClient; private static PackageId packageId; private static String documentId = "myDocumentId"; public static void main( String... args ) throws IOException { eslClient = new EslClient( API_KEY, API_URL ); DocumentPackage superDuperPackage = newPackageNamed( "Policy " + format.format( new Date() ) ) .describedAs( "This is a package with a document workflow created using the eSignLive SDK" ) .withSigner( newSignerWithEmail( "[email protected]" ) .withFirstName( "John" ) .withLastName( "Smith" ) ) .withDocument( newDocumentWithName( "Second Document" )

    7  SDKsIntegrator's Guide

    73

  • .fromFile( "src/main/Resources/document.pdf" ) .withId( documentId ) .withSignature( signatureFor( "[email protected]" ) .onPage( 0 ) .atPosition( 100, 100 ) ) ) .build(); packageId = eslClient.createPackage( superDuperPackage ); eslClient.sendPackage( packageId ); // Retrieve the bytes of the document (with fields) byte[] pdfDocumentBytes = eslClient.downloadDocument(packageId, documentId); // Retrieve the bytes of the original document (without fields) byte[] originalPdfDocumentBytes = eslClient.downloadOriginalDocument(packageId, documentId); // Retrieve the bytes of the zipped file containing all the documents in the package byte[] zippedDocumentsBytes = eslClient.downloadZippedDocuments(packageId); } }

    C# Code

    using System; using eSignLive.com.ESL.SDK; using System.IO; using eSignLive.com.ESL.SDK.Builder; namespace SDK.Examples { public class DocumentRetrievalExample { public static string apiToken = "YOUR TOKEN HERE"; public static string baseUrl = "ENVIRONMENT URL

    7  SDKsIntegrator's Guide

    74

  • HERE"; private static EslClient eslClient; priv