Quick Start: Signature Appliance SOAP API

The DocuSign Signature Appliance SOAP API provides signing and user management functions for the signingt appliance. It can be used with any development stack.

Introduction

The SOAP API enables developers to enhance their applications with digital signatures without requiring previous experience using public-key cryptography. The DocuSign Signature Appliance SOAP API is an XML/SOAP network API via HTTPS. It can be used from any client, with any operating system.

The SOAP API includes functions for signing files, verifying signatures, and managing signers.

This API is also known as the SAPI Web Services API.

Getting Started

Obtain a developer account

Sign up for a free DocuSign Signature Appliance Developer Sandbox account.

Check that your signing account was created by using the Developer Web App to sign a PDF.

Make a jpg scan of your signature and use the Developer Web App to upload it to the signing appliance. Click on your name (upper right corner of the web screen) to upload your graphical signature.

WSDL Files

The API's WSDL files describe the API's methods. The files are available both on-line from your DocuSign Signature Appliance and off-line. To use your server's files, it should have a dns name within your network, but it does not have to be visible on the internet.

The files are also available in the SDK's sapiws folder.

The API uses two WSDL files:

SAPIWS-DSS.wsdl

This WSDL file provides method definitions for signing and verifying documents and data.

URL: https://<signing_appliance.example.com>:8080/sapiws/dss.asmx?WSDL

URL for the developer account server: https://prime.cosigntrial.com:8080/sapiws/dss.asmx?WSDL

SAPIWS-SPML.wsdl

This WSDL file provides method definitions for management of the signing appliance's users.

URL: https://<signing_appliance.example.com>:8080/sapiws/spml.asmx?WSDL

The user management methods are not available from the developer sandbox server.

Using SOAP Methods

A key idea of SOAP and Web Services is that client systems can automatically create the stub functions for the programmer. Then the programmer can use function calls rather than having to deal with a networking layer.

On some platforms, a separate build step is used to create stub methods. Other platforms link your app's methods to SOAP calls at runtime.

Many developers use their platform SOAP libraries to handle SOAP calls. Others ignore the SOAP layer; they create and parse the XML/SOAP messages in their own software rather than using their platform's SOAP infrastructure.

Creating the SOAP functions in different platforms

PHP

The PHP Soap Client library builds the SOAP calls at runtime.

The WSDL URL from the signing appliance is used when instantiating the PHP SOAP Client library. Example:


$wsdlUrl = 'https://prime.cosigntrial.com:8080/sapiws/dss.asmx?WSDL';
 
// Initiate SOAP client
$client = new SoapClient(
	$wsdlUrl,
	array(
		'stream_context'=>stream_context_create(array(
			'ssl' => array(
				'verify_peer' => true,
				'cafile' => __DIR__ . '/cacert.pem',
				'CN_match' => 'prime.cosigntrial.com'
			)
		)
	)
));
 
// Send the request
$output = $client->DssSign($signRequest);

Java

Java uses a separate build step to create stub methods for the API. Using the API with the Java JAX-WS and JAXB environment:

  1. Download and install the latest Java Development Kit
    • Download the JDK from Oracle
    • Add the bin folder of the Java SDK to the PATH system variable and set the JAVA_HOME system variable. Example for Windows:
      PATH += jdk-install-path\jdk1.7.0_05\bin, JAVA_HOME = jdk-install-path\jdk1.7.0_05
  2. Generate the client side stub Java classes
    • Create a working folder for your project
    • Download and unzip the DocuSign Signing Appliance SDK.
    • Copy the SAPIWS-DSS.wsdl and SAPIWS-SPML.wsdl files from the SDK’s sapiws folder to your working directory
    • Use the wsimport JDK utility to generate the stubs for the Cosign web services:
      wsimport -keep -extension SAPIWS-DSS.wsdl

    Notes

    • ‘-keep’ don’t delete the generated java files(by default, only the .class files are kept)
    • ‘-extension’ -allow vendor (SAPI) extensions

C#

This example shows how to use Visual Studio 2008 to add a SOAP WSDL file to a Windows Forms .net 2.0 application and automatically build the client-side stub functions.

When you press ‘Add Reference,’ Visual Studio will generate the client side stubs for your project.

To add the WSDL files and build the client-side stubs:

Step 1

Right click the project in Visual Studio and chose ‘Add Web reference …’:

Step 2

Next, enter the WSDL location (URL) and click ‘Add Reference’:

Step 3

Repeat step 2 to add the WSDL for signing and verifying files at https://prime.cosigntrial.com:8080/SAPIWS/dss.asmx

Verifying the Signing Server’s Identity via its SSL Certificate

SSL should always be used to communicate from your app to the signing appliance. SSL protects the session but does not guarentee the identity of the endpoint. To verify the identity of the endpoint, best practice is to confirm it by examining its SSL certificate.

First, download the signing appliance’s CA certificate.

Some runtime systems verify the SSL certificate automatically, others require an explicit step in the client code. See below for more information for some popular runtime platforms.

PHP

SSL certificate verification is not required in PHP, although it can be accomplished quite easily with the SoapClient library. Download the signing appliance’s CA cert and use the SSL stream_context option:

$wsdlUrl = 'https://prime.cosigntrial.com:8080/sapiws/dss.asmx?WSDL';
 
// Initiate SOAP client
$client = new SoapClient(
	$wsdlUrl,
	array(
		'stream_context'=>stream_context_create(array(
			'ssl' => array(
				'verify_peer' => true,
				'cafile' => __DIR__ . '/cacert.pem',
				'CN_match' => 'prime.cosigntrial.com'
			)
		)
	)
));
 
// Send the request
$output = $client->DssSign($signRequest);

 

Java

The Java Runtime Environment requires Hostname and certificate verification. It is handled automatically by the Java Runtime System for HTTPS connections. The SSL certificate of the remote server is verified against the Java Trust Store. Therefore, you must install the signing appliance’s CA cert in the Java Trust Store to enable successful verification.

Adding the signing appliance’s CA cert to the Java Trust Store

Use the Java keytool utility:

keytool -import -keystore "jre-path\lib\security\cacerts" \
    -file certs\COMODOHigh-AssuranceSecureServerCA.crt -alias COMODOHigh-AssuranceSecureServerCA \
    -keypass changeit -storepass changeit

Note: You may have multiple Java Runtime Environments (JREs) on your system. If this is the case, then be sure to install the signing appliance’s CA Cert into the JRE you will be using for your java client.

C#

Hostname and certificate verification is done automatically by the .NET framework on HTTPS connection. The certificate is verified against the Windows Certificate Store, requiring that the CoSign Server’s SSL CA cert be included in the Windows Certificate store for a successful verification.

Hello World: Signing a PDF

The Hello World example simply signs a PDF file based on set of fixed values.

Many other options and scenarios are available for signing including signing a previously defined blank digital signature field, providing the user with a WYSIWYG user interface for placing and sizing the signature, omitting the graphical representation of the digital signature, etc.

Hello World source on GitHub

Custom Values

First we define the custom parameters that will be used in this example.

// Custom Values
$filePath       = 'c:/temp/demo.pdf';   // File to sign
$fileMimeType   = 'application/pdf';    // File MIME type
$username       = 'John Miller';        // CoSign account username
$password       = '12345678';           // CoSign account password
$domain         = '';                   // CoSign account domain
$sigPageNum     = 1;                    // Create signature on the first page
$sigX           = 145;                  // Signature field X location
$sigY           = 125;                  // Signature field Y location
$sigWidth       = 160;                  // Signature field width
$sigHeight      = 45;                   // Signature field height
$timeFormat     = 'hh:mm:ss';           // The display format of the time
$dateFormat     = 'dd/MM/yyyy';         // The display format of the date
$appearanceMask = 11;                   // Elements to display on the signature field
                                        // (11 = Graphical image + Signer name + Time)
$signatureType  = 'http://arx.com/SAPIWS/DSS/1.0/signature-field-create-sign';  
    // The actual operation of the Sign Request function
$wsdlUrl        = 'https://prime.cosigntrial.com:8080/sapiws/dss.asmx?WSDL';    
    // URL to the WSDL file
# Custom Values
file_path       = 'c:/temp/demo.pdf';   # File to sign
file_mime_type  = 'application/pdf';    # File MIME type
username        = 'John Miller';        # CoSign account username
password        = '12345678';           # CoSign account password
domain          = '';                   # CoSign account domain
sig_page_num    = 1;                    # Create signature on the first page
sig_x           = 145;                  # Signature field X location
sig_y           = 125;                  # Signature field Y location
sig_width       = 160;                  # Signature field width
sig_height      = 45;                   # Signature field height
time_format     = 'hh:mm:ss';           # The display format of the time
date_format     = 'dd/MM/yyyy';         # The display format of the date
appearance_mask = 11;                   # Elements to display on the signature field 
                                        # (11 = Graphical image + Signer name + Time)
signature_type  = 'http://arx.com/SAPIWS/DSS/1.0/signature-field-create-sign';
    # The actual operation of the Sign Request function
wsdl_url        = 'https://prime.cosigntrial.com:8080/sapiws/dss.asmx?WSDL';
    # URL to the WSDL file
# Custom Values
file_path       = 'c:/temp/demo.pdf';   # File to sign
file_mime_type  = 'application/pdf';    # File MIME type
username        = 'John Miller';        # CoSign account username
password        = '12345678';           # CoSign account password
domain          = '';                   # CoSign account domain
sig_page_num    = 1;                    # Create signature on the first page
sig_x           = 145;                  # Signature field X location
sig_y           = 125;                  # Signature field Y location
sig_width       = 160;                  # Signature field width
sig_height      = 45;                   # Signature field height
time_format     = 'hh:mm:ss';           # The display format of the time
date_format     = 'dd/MM/yyyy';         # The display format of the date
appearance_mask = 11;                   # Elements to display on the signature field 
                                        # (11 = Graphical image + Signer name + Time)
signature_type  = 'http://arx.com/SAPIWS/DSS/1.0/signature-field-create-sign';  
    # The actual operation of the Sign Request function
wsdl_url        = 'https://prime.cosigntrial.com:8080/sapiws/dss.asmx?WSDL';
    # URL to the WSDL file
// Custom Values
String filePath      = "c:/temp/demo.pdf";  // File to sign
String fileMimeType  = "application/pdf";   // File MIME type
String username      = "John Miller";       // CoSign account username
String password      = "12345678";          // CoSign account password
String domain        = "";                  // CoSign account domain
int sigPageNum       = 1;                   // Create signature on the first page
int sigX             = 145;                 // Signature field X location
int sigY             = 125;                 // Signature field Y location
int sigWidth         = 160;                 // Signature field width
int sigHeight        = 45;                  // Signature field height
String timeFormat    = "hh:mm:ss";          // The display format of the time
String dateFormat    = "dd/MM/yyyy";        // The display format of the date
long appearanceMask  = 11;                  // Elements to display on the signature field 
                                            // (11 = Graphical image + Signer name + Time)
String signatureType = "http://arx.com/SAPIWS/DSS/1.0/signature-field-create-sign";
    // The actual operation of the Sign Request function
String wsdlUrl       = "https://prime.cosigntrial.com:8080/sapiws/dss.asmx?WSDL";
    // URL to the WSDL file
// Custom Values
string filePath      = "c:/temp/demo.pdf";  // File to sign
string fileMimeType  = "application/pdf";   // File MIME type
string username      = "John Miller";       // CoSign account username
string password      = "12345678";          // CoSign account password
string domain        = "";                  // CoSign account domain
int sigPageNum       = 1;                   // Create signature on the first page
int sigX             = 145;                 // Signature field X location
int sigY             = 125;                 // Signature field Y location
int sigWidth         = 160;                 // Signature field width
int sigHeight        = 45;                  // Signature field height
string timeFormat    = "hh:mm:ss";          // The display format of the time
string dateFormat    = "dd/MM/yyyy";        // The display format of the date
uint appearanceMask  = 11;                  // Elements to display on the signature field 
                                            // (11 = Graphical image + Signer name + Time)
string signatureType = "http://arx.com/SAPIWS/DSS/1.0/signature-field-create-sign";
    // The actual operation of the Sign Request function
string wsdlUrl       = "https://prime.cosigntrial.com:8080/sapiws/dss.asmx?WSDL";
    // URL to the WSDL file

 

Parameter Meaning
filePath Path to file
fileMimeType File MIME type
username User name for authenticating with the signing appliance. For the DevCenter server, use your email address
password The user’s password for CoSign
domain In an active directory environment, the name of the domain to which the user belongs. In directory independent or LDAP environments, this parameter is ignored and its value is NULL
sigPageNum PDF page number for the signature field
sigX X coordinate for the signature field rectangle
sigY Y coordinate for the signature field rectangle
sigWidth Width for the signature field rectangle
sigHeight Height for the signature field rectangle
timeFormat The display format of the time. See page 183 of the manual
dateFormat The display format of the date. See page 182 of the manual
appearanceMask Appearance Mask specifying which components (Date, Signer’s Title, Reason) will be included with the graphical representation of the digital signature. See page 197 of the manual
signatureType Determines the actual operation of the Sign Request. See 392 page of the manual
wsdlUrl SOAP API WSDL file’s URL

Sign Request Object

The sign operation of the SOAP API is composed of a Sign Request sent by the user to the server, and a Sign Response received back from the server. The Sign Request indicates the type of SAPI signature related operation that the server should perform and is consists of several parameters such as the user credentials, the signature field settings, and the document data.

// Read file contents
$contents = @file_get_contents($filePath);
if ($contents === False)
	throw new Exception('Cannot read file: ' . $filePath);
 
// Set file contents + MIME type (the SOAP library automatically base64 encodes the data)
$document = array(
	'Base64Data' => array(
		'_' => $contents,
		'MimeType' => $fileMimeType
	)
);
 
// Set user credentials. In case of Active Directory, the domain name should be defined 
// in the NameQualifier attribute
$claimedIdentidy = array(
	'Name' => array(
		'_' => $username,
		'NameQualifier' => $domain
	),
	'SupportingInfo' => array(
		'LogonPassword' => $password
	)
);
 
// Define signature field settings
$SAPISigFieldSettings = array(
	'Invisible' => false,
	'X' => $sigX,
	'Y' => $sigY,
	'Width' => $sigWidth,
	'Height' => $sigHeight,
	'Page' => $sigPageNum,
	'AppearanceMask' => $appearanceMask,
	'TimeFormat' => array(
		'ExtTimeFormat' => 'GMT',
		'DateFormat' => $dateFormat,
		'TimeFormat' => $timeFormat
	)
);
 
// Build complete request object
$signRequest = array(
	'SignRequest' => array(
		'OptionalInputs' => array(
			'ClaimedIdentity' => $claimedIdentidy,
			'SignatureType' => $signatureType,
			'SAPISigFieldSettings' => $SAPISigFieldSettings,
			'ReturnPDFTailOnly' => true		
                // Enable PDFTailOnly feature (Just the signature object is returned 
                // instead of the whole file)
		),
		'InputDocuments' => array(
			'Document' => $document
		)
	)
);
# Read file contents and convert to base64 string
base64_data = Base64.encode64(File.binread(file_path))
 
# Set file contents + MIME type
document = {
	Base64Data: base64_data,
	:attributes! => { Base64Data: { MimeType: file_mime_type } }
}
 
# Set user credentials. In case of Active Directory, the domain name should be defined 
# in the NameQualifier attribute
claimed_identidy = {
	Name: username,
	SupportingInfo: {
		LogonPassword: password,
		:attributes! => { LogonPassword: { xmlns: 'http://arx.com/SAPIWS/DSS/1.0' } }
	},
	:attributes! => { Name: { NameQualifier: domain } }
}
 
# Define signature field settings (inner elements)
sapi_sig_field_setings = {
	TimeFormat: '',
	:attributes! => {  
		TimeFormat: {
			ExtTimeFormat: 'GMT',
			DateFormat: date_format,
			TimeFormat: time_format
		}
	}
}
 
# Define signature field settings (attributes)
sapi_sig_field_setings_attributes = {
	Invisible: false,
	X: sig_x,
	Y: sig_y,
	Width: sig_width,
	Height: sig_height,
	Page: sig_page_num,
	AppearanceMask: appearance_mask,
	xmlns: 'http://arx.com/SAPIWS/DSS/1.0'
}
 
# Build complete request object
sign_request = {
	SignRequest: {
		OptionalInputs: {
			ClaimedIdentity: claimed_identidy,
			SignatureType: signature_type,
			SAPISigFieldSettings: sapi_sig_field_setings,
			ReturnPDFTailOnly: true,    # Enable PDFTailOnly feature (Signature object 
                                        # is returned instead of the whole file)
			:attributes! => {
				SAPISigFieldSettings: sapi_sig_field_setings_attributes,
				ReturnPDFTailOnly: { xmlns: 'http://arx.com/SAPIWS/DSS/1.0' }
			}
		},
		InputDocuments: {
			Document: document
		}
	},
	:attributes! => { SignRequest: { xmlns: 'urn:oasis:names:tc:dss:1.0:core:schema' } }
}
# Read file contents and convert to base64 string
base64_data = open(file_path, "rb").read().encode('base64')
 
# Set file contents (See "Fix SOAP Request" section below for how to define the 
# file MIME type)
document = {
	'Base64Data' : base64_data
}
 
# Set user credentials. In case of Active Directory, the domain name should be 
# defined in the NameQualifier attribute (See "Fix SOAP Request" section below)
claimed_identidy = {
	'Name' : username,
	'SupportingInfo' : {
		'LogonPassword' : password,
	}
}
 
# Define signature field settings
sapi_sig_field_setings = {
	'_Invisible' : 'false',
	'_X' : sig_x,
	'_Y' : sig_y,
	'_Width' : sig_width,
	'_Height' : sig_height,
	'_Page' : sig_page_num,
	'_AppearanceMask' : appearance_mask,
	'TimeFormat' : {
		'_ExtTimeFormat' : 'GMT',
		'_DateFormat' : date_format,
		'_TimeFormat' : time_format
	}
}
 
# Build complete request object
sign_request = {
	'OptionalInputs' : {
		'ClaimedIdentity' : claimed_identidy,
		'SignatureType' : signature_type,
		'SAPISigFieldSettings' : sapi_sig_field_setings,
		'ReturnPDFTailOnly' : 'true'    # Enable PDFTailOnly feature 
            #(Signature object is returned instead of the whole file)
	},
	'InputDocuments' : {
		'Document' : document
	}
}
// Read file contents
byte[] fileBuffer = Files.readAllBytes(Paths.get(filePath));
 
// Set file contents + MIME type (the SOAP library automatically base64 encodes the data)
DocumentType document = new DocumentType();
Base64Data base64Data = new Base64Data();
base64Data.setValue(fileBuffer);
base64Data.setMimeType(fileMimeType);
document.setBase64Data(base64Data);
 
// Set user credentials. In case of Active Directory, the domain name should be 
// defined in the NameQualifier attribute
ClaimedIdentity claimedIdentity = new ClaimedIdentity();
NameIdentifierType nameIdentifier = new NameIdentifierType();
nameIdentifier.setValue(username);
nameIdentifier.setNameQualifier(domain);
CoSignAuthDataType coSignAuthData = new CoSignAuthDataType();
coSignAuthData.setLogonPassword(password);
claimedIdentity.setName(nameIdentifier);
claimedIdentity.setSupportingInfo(coSignAuthData);
 
// Define signature field settings
SAPISigFieldSettingsType sigFieldSettings = new SAPISigFieldSettingsType();
sigFieldSettings.setInvisible(false);
sigFieldSettings.setX(sigX);
sigFieldSettings.setY(sigY);
sigFieldSettings.setWidth(sigWidth);
sigFieldSettings.setHeight(sigHeight);
sigFieldSettings.setPage(sigPageNum);
sigFieldSettings.setAppearanceMask(appearanceMask);
TimeDateFormatType timeDateFormat = new TimeDateFormatType();
timeDateFormat.setTimeFormat(timeFormat);
timeDateFormat.setDateFormat(dateFormat);
timeDateFormat.setExtTimeFormat(ExtendedTimeFormatEnum.GMT);
sigFieldSettings.setTimeFormat(timeDateFormat);
 
// Build complete request object
SignRequest signRequest = new SignRequest();
RequestBaseType.InputDocuments inputDocuments = new RequestBaseType.InputDocuments();
inputDocuments.getOtherOrDocumentHashOrTransformedData().add(document);
RequestBaseType.OptionalInputs optionalInputs = new RequestBaseType.OptionalInputs();
optionalInputs.setSignatureType(signatureType);
optionalInputs.setClaimedIdentity(claimedIdentity);
optionalInputs.setSAPISigFieldSettings(sigFieldSettings);
optionalInputs.setReturnPDFTailOnly(true);
signRequest.setOptionalInputs(optionalInputs);
signRequest.setInputDocuments(inputDocuments);
// Read file contents
byte[] fileBuffer = File.ReadAllBytes(filePath);
 
// Set file contents + MIME type (the SOAP library automatically base64 encodes the data)
DocumentType document = new DocumentType()
{
	Item = new DocumentTypeBase64Data()
	{
		Value = fileBuffer,
		MimeType = fileMimeType
	}
};
 
ClaimedIdentity claimedIdentity = new ClaimedIdentity()
{
	Name = new NameIdentifierType()
	{
		Value = username,
		NameQualifier = domain
	},
	SupportingInfo = new CoSignAuthDataType()
	{
		LogonPassword = password
	}
};
 
// Define signature field settings
SAPISigFieldSettingsType sigFieldSettings = new SAPISigFieldSettingsType()
{
	Invisible = false,
	InvisibleSpecified = true,
	X = sigX,
	XSpecified = true,
	Y = sigY,
	YSpecified = true,
	Width = sigWidth,
	WidthSpecified = true,
	Height = sigHeight,
	HeightSpecified = true,
	Page = sigPageNum,
	PageSpecified = true,
	AppearanceMask = appearanceMask,
	AppearanceMaskSpecified = true,
	TimeFormat = new TimeDateFormatType()
	{
		TimeFormat = timeFormat,
		DateFormat = dateFormat,
		ExtTimeFormat = ExtendedTimeFormatEnum.GMT,
		ExtTimeFormatSpecified = true
	}
};
 
// Build complete request object
SignRequest signRequest = new SignRequest()
{
	InputDocuments = new RequestBaseTypeInputDocuments()
	{
		Items = new DocumentType[] { document }
	},
	OptionalInputs = new RequestBaseTypeOptionalInputs()
	{
		SignatureType = signatureType,
		ClaimedIdentity = claimedIdentity,
		SAPISigFieldSettings = sigFieldSettings,
		ReturnPDFTailOnly = true,
		ReturnPDFTailOnlySpecified = true
	}
};

SOAP client initialization and request execution

As part of the client creation we need to provide the WSDL url, possibly with additional parameters depending on each client specifications. To invoke the request we call the DssSign function with the Sign Request object as its single parameter.

// Initiate SOAP client
$client = new SoapClient(
	$wsdlUrl,
	array(
		'stream_context'=>stream_context_create(array(
			'ssl' => array(
				'verify_peer' => true,
				'cafile' => __DIR__ . '/cacert.pem',
				'CN_match' => 'prime.cosigntrial.com'
			)
		)
	)
));
 
// Send the request
$output = $client->DssSign($signRequest);
# Initiate SOAP client (Savon)
client = Savon.client(
	wsdl: wsdl_url,
	convert_request_keys_to: :camelcase,
	element_form_default: :unqualified,
	ssl_ca_cert_file: 'cacert.pem',
	ssl_version: :TLSv1
)
 
# Send the request
response = client.call(:dss_sign, message: sign_request)
# Initiate SOAP client (SUDS)
client = Client(wsdl_url, plugins=[FixSOAPRequest()])
 
# Send the request
response = client.service.DssSign(sign_request)
// Initiate service client
DSS client = new DSS(new URL(wsdlUrl));
 
// Send the request
DssSignResult response = 
    client.getDSSSoap().dssSign(signRequest);
// Initiate service client
DSS client = new DSS() { Url = wsdlUrl };
 
// Send the request
DssSignResult response = client.DssSign(signRequest);

Appending the returned signature object to the PDF

The Sign Response that is returned from the server includes:

  • A result message indicating whether the sign operation completed successfully or not.
  • The output signature object (in case of success).

In the following code samples, in case of success, we append the signature object to the PDF document that was sent in the request. Otherwise, we raise an exception with the error message received in the Sign Response.

// Check response output
if ( $output->DssSignResult->Result->ResultMajor == 
    "urn:oasis:names:tc:dss:1.0:resultmajor:Success")
{
	// On success - append signature object to the source PDF document 
    // (the SOAP library automatically decodes the base64 encoded output)
	$value = $output->DssSignResult->SignatureObject->Base64Signature;
	file_put_contents($filePath, $value->_, FILE_APPEND);
}
else
{
	// On failure - raise exception with the result error message
	throw new Exception($output->DssSignResult->Result->ResultMessage->_);
}
# Check response output
response = response.body
if response[:dss_sign_response][:dss_sign_result][:result][:result_major] == 
    'urn:oasis:names:tc:dss:1.0:resultmajor:Success'
	# On success- append signature object to the source PDF document
	value = response[:dss_sign_response][:dss_sign_result][:signature_object][:base64_signature]
	File.binwrite(file_path, Base64.decode64(value), File.size(file_path), mode: 'a')
else
	# On failure- raise exception with the result error message
	raise response[:dss_sign_response][:dss_sign_result][:result][:result_message]
end
# Check response output
if response['Result']['ResultMajor'] == 
    'urn:oasis:names:tc:dss:1.0:resultmajor:Success':
	# On success - append signature object to the source PDF document
	value = response['SignatureObject']['Base64Signature']['value']
	open(file_path, "ab").write(value.decode('base64'))
else:
	# On failure - raise exception with the result error message
	raise Exception(response['Result']['ResultMajor'])
// Check response output
if ("urn:oasis:names:tc:dss:1.0:resultmajor:Success".equals(response.getResult().getResultMajor())) {
	// On success - append signature object to the source PDF document 
    // (the SOAP library automatically decodes the base64 encoded output)
	byte[] signatureObjectBuffer = response.getSignatureObject().getBase64Signature().getValue();
	Files.write(Paths.get(filePath), signatureObjectBuffer, StandardOpenOption.APPEND);
}
else
{
	// On failure- raise exception with the result error message
	throw new Exception(response.getResult().getResultMessage().getValue());
}
// Check response output
if ("urn:oasis:names:tc:dss:1.0:resultmajor:Success".Equals(response.Result.ResultMajor))
{
	// On success- append signature object to the source PDF document 
    // (the SOAP library automatically decodes the base64 encoded output)
	byte[] signatureObjectBuffer = 
        ((DssSignResultSignatureObjectBase64Signature)response.SignatureObject.Item).Value;
	using (var fileStream = new FileStream(filePath, FileMode.Append))
	{
		fileStream.Write(signatureObjectBuffer, 0, signatureObjectBuffer.Length);
	}
}
else
{
	// On failure- raise exception with the result error message
	throw new Exception(response.Result.ResultMessage.Value);
}