docusign / code-examples-php Goto Github PK
View Code? Open in Web Editor NEWDocusign PHP code examples and launcher
Home Page: https://developers.docusign.com/
License: MIT License
Docusign PHP code examples and launcher
Home Page: https://developers.docusign.com/
License: MIT License
Hi,
Kindly let us know the alternative for embedded signing in the part-11 module enabled docusign
kindly let us know we need to get sign from two signers for single document
Hi,
We have added the custom field check box in the template in docusign admin panel and on user end if the user is checked the check box we are not able to find the value,kindly tell me how to achieve it
in api php we are using below code
$envelopeEvents = ['customFields','recipients','tabs','form_data'];
$event_data1 = new \DocuSign\eSign\Model\ConnectEventData([
'include_data' =>$envelopeEvents
]);
$recipient_event1 = new \DocuSign\eSign\Model\RecipientEvent([
'recipient_event_status_code' => "Sent"
]);
$recipient_events1 = [$recipient_event1];
$envelope_event1 = new \DocuSign\eSign\Model\EnvelopeEvent([
'envelope_event_status_code' => "Completed"
]);
$envelope_events1 = [$envelope_event1];
$event_notification1 = new \DocuSign\eSign\Model\EventNotification([
'envelope_events' => $envelope_events1,
'event_data' => $event_data1,
'include_envelope_void_reason' => "true",
'logging_enabled' => "true",
'recipient_events' => $recipient_events1,
'require_acknowledgment' => "true",
'url' => "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
]);
$envelope_definition->setEventNotification($event_notification1);
kindly help me to get the envelope form field values in webhook using php
<?php
/**
* Created by PhpStorm.
* User: larry.kluger
* Date: 11/21/18
* Time: 8:46 PM
*/
require_once __DIR__ . '/../vendor/autoload.php';
require_once __DIR__ . '/../vendor/src/ObjectSerializer.php';
require_once __DIR__ . '/../ds_config.php';
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
$GLOBALS['app_url'] = $GLOBALS['DS_CONFIG']['app_url'] . '/';
$loader = new Twig_Loader_Filesystem(__DIR__ .'/../templates');
$twig = new Twig_Environment($loader);
$twig->addGlobal('app_url', $GLOBALS['app_url']);
$twig->addGlobal('session', $_SESSION);
$twig_function = new Twig_Function('get_flash', function () {
if (! isset($_SESSION['flash'])) {$_SESSION['flash'] = [];}
$msgs = $_SESSION['flash'];
$_SESSION['flash'] = [];
return $msgs;
});
$twig->addFunction($twig_function);
# Add csrf_token func. See https://stackoverflow.com/a/31683058/64904
$twig_function = new Twig_Function('csrf_token', function($lock_to = null) {
if (empty($_SESSION['csrf_token'])) {$_SESSION['csrf_token'] = bin2hex(random_bytes(32));}
if (empty($_SESSION['csrf_token2'])) {$_SESSION['csrf_token2'] = random_bytes(32);}
if (empty($lock_to)) {return $_SESSION['csrf_token'];}
return hash_hmac('sha256', $lock_to, $_SESSION['csrf_token2']);
});
$twig->addFunction($twig_function);
$GLOBALS['twig'] = $twig;
function flash($msg) {
if (! isset($_SESSION['flash'])) {$_SESSION['flash'] = [];}
array_push($_SESSION['flash'], $msg);
}
function router() {
$routes = [
'ds_return' => 'DsReturn',
'must_authenticate' => 'MustAuthenticate',
'eg001' => 'EG001EmbeddedSigning',
'eg002' => 'EG002SigningViaEmail',
'eg003' => 'EG003ListEnvelopes',
'eg004' => 'EG004EnvelopeInfo',
'eg005' => 'EG005EnvelopeRecipients',
'eg006' => 'EG006EnvelopeDocs',
'eg007' => 'EG007EnvelopeGetDoc',
'eg008' => 'EG008CreateTemplate',
'eg009' => 'EG009UseTemplate',
'eg010' => 'EG010SendBinaryDocs',
'eg011' => 'EG011EmbeddedSending',
'eg012' => 'EG012EmbeddedConsole',
'eg013' => 'EG013AddDocToTemplate',
'eg014' => 'EG014CollectPayment',
'eg015' => 'EG015EnvelopeTabData',
'eg016' => 'EG016SetTabValues',
'eg017' => 'EG017SetTemplateTabValues',
'eg018' => 'EG018EnvelopeCustomFieldData',
];
if (! isset($_GET['page'])) {
$controller = 'Example\Home';
} elseif ($_GET['page'] == 'ds_login') {
ds_login(); // See below in oauth section
exit();
} elseif ($_GET['page'] == 'ds_callback') {
ds_callback(); // See below in oauth section
exit();
} elseif ($_GET['page'] == 'ds_logout') {
ds_logout(); // See below in oauth section
exit();
} else {
$page = $_GET['page'];
$controller = 'Example\\' . $routes[$page];
}
$c = new $controller();
$c->controller();
}
/**
* Check that the csrf token is present and correct.
* If not, return to home page.
* See https://stackoverflow.com/a/31683058/64904
*/
function check_csrf(){
if ( ! (isset($_POST['csrf_token']) &&
hash_equals($_SESSION['csrf_token'], $_POST['csrf_token']))) {
# trouble!
flash('CSRF token problem!');
header('Location: ' . $GLOBALS['app_url']);
exit;
}
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//
// OAuth support
// Using the https://github.com/thephpleague/oauth2-client with a locally
// stored DocuSign provider
//
/**
* @param int $buffer_min buffer time needed in minutes
* @return boolean $ok true iff the user has an access token that will be good for another buffer min
*/
function ds_token_ok($buffer_min=60)
{
$ok = isset($_SESSION['ds_access_token']) && isset($_SESSION['ds_expiration']);
$ok = $ok && (($_SESSION['ds_expiration'] - ($buffer_min * 60)) > time());
return $ok;
}
function get_oauth_provider()
{
$provider = new \DocuSign\OAuth2\Client\Provider\DocuSign([
'clientId' => $GLOBALS['DS_CONFIG']['ds_client_id'],
'clientSecret' => $GLOBALS['DS_CONFIG']['ds_client_secret'],
'redirectUri' => $GLOBALS['DS_CONFIG']['app_url'] . '/index.php?page=ds_callback',
'authorizationServer' => $GLOBALS['DS_CONFIG']['authorization_server'],
'allowSilentAuth' => $GLOBALS['DS_CONFIG']['allow_silent_authentication']
]);
return $provider;
}
function ds_login()
{
$provider = get_oauth_provider();
$authorizationUrl = $provider->getAuthorizationUrl();
// Get the state generated for you and store it to the session.
$_SESSION['oauth2state'] = $provider->getState();
// Redirect the user to the authorization URL.
header('Location: ' . $authorizationUrl);
exit;
}
/*
* Called via a redirect from DocuSign authentication service
*/
function ds_callback()
{
# Save the redirect eg if present
$redirect_url = false;
if (isset($_SESSION['eg'])) {
$redirect_url = $_SESSION['eg'];
}
# reset the session
ds_logout_internal();
$provider = get_oauth_provider();
// Check given state against previously stored one to mitigate CSRF attack
if (empty($_GET['state']) || (isset($_SESSION['oauth2state']) && $_GET['state'] !== $_SESSION['oauth2state'])) {
if (isset($_SESSION['oauth2state'])) {
unset($_SESSION['oauth2state']);
}
exit('Invalid OAuth state');
} else {
try {
// Try to get an access token using the authorization code grant.
$accessToken = $provider->getAccessToken('authorization_code', [
'code' => $_GET['code']
]);
flash('You have authenticated with DocuSign.');
// We have an access token, which we may use in authenticated
// requests against the service provider's API.
$_SESSION['ds_access_token'] = $accessToken->getToken();
$_SESSION['ds_refresh_token'] = $accessToken->getRefreshToken();
$_SESSION['ds_expiration'] = $accessToken->getExpires(); # expiration time.
// Using the access token, we may look up details about the
// resource owner.
$user = $provider->getResourceOwner($accessToken);
$_SESSION['ds_user_name'] = $user->getName();
$_SESSION['ds_user_email'] = $user->getEmail();
$account_info = $user->getAccountInfo();
$base_uri_suffix = '/restapi';
$_SESSION['ds_account_id'] = $account_info["account_id"];
$_SESSION['ds_account_name'] = $account_info["account_name"];
$_SESSION['ds_base_path'] = $account_info["base_uri"] . $base_uri_suffix;
} catch (\League\OAuth2\Client\Provider\Exception\IdentityProviderException $e) {
// Failed to get the access token or user details.
exit($e->getMessage());
}
if (! $redirect_url) {
$redirect_url = $GLOBALS['app_url'];
}
header('Location: ' . $redirect_url);
exit;
}
}
/**
* ds_logout
*/
function ds_logout()
{
ds_logout_internal();
flash('You have logged out from DocuSign.');
header('Location: ' . $GLOBALS['app_url']);
exit;
}
/**
* Unset all items from the session
*/
function ds_logout_internal()
{
if (isset($_SESSION['ds_access_token' ])) {unset($_SESSION['ds_access_token' ]);}
if (isset($_SESSION['ds_refresh_token' ])) {unset($_SESSION['ds_refresh_token' ]);}
if (isset($_SESSION['ds_user_email' ])) {unset($_SESSION['ds_user_email' ]);}
if (isset($_SESSION['ds_user_name' ])) {unset($_SESSION['ds_user_name' ]);}
if (isset($_SESSION['ds_expiration' ])) {unset($_SESSION['ds_expiration' ]);}
if (isset($_SESSION['ds_account_id' ])) {unset($_SESSION['ds_account_id' ]);}
if (isset($_SESSION['ds_account_name' ])) {unset($_SESSION['ds_account_name' ]);}
if (isset($_SESSION['ds_base_path' ])) {unset($_SESSION['ds_base_path' ]);}
if (isset($_SESSION['envelope_id' ])) {unset($_SESSION['envelope_id' ]);}
if (isset($_SESSION['eg' ])) {unset($_SESSION['eg' ]);}
if (isset($_SESSION['envelope_documents'])) {unset($_SESSION['envelope_documents']);}
if (isset($_SESSION['template_id' ])) {unset($_SESSION['template_id' ]);}
}
router();
Hi We are getting Error on Envelope Creation
We are getting Error as "USER_AUTHENTICATION_FAILED","message":"One or both of Username and Password are invalid. Invalid access token"
Kindly let us know changes to fix the issue
I am trying to run this code on IIS server but not working it shows me
Uncaught Error: Class '\Example\Controllers\Examples\eSignature\Home' not found.
I am running PHP 7.3 and IIS 10.0
I'm trying to find a code example for how to authenticate without needing a user to do something in a browser. I want a backend system to be able to create an envelope with contents using a template and pushing data in via tabs. All I see is oauth stuff that talks about users and browser and redirects, etc. I don't have a person doing something in a browser, I need this to happen with 100% no user interaction. Is that possible?
Hi,
We need to configure notification url for the each envelope in docusign api php
Kindly let us know how to achieve it i have tried as
$envelopeEvents = ['customFields','recipients'];
$event_data = new ConnectEventData(['format' => 'xml', 'include_data' =>$envelopeEvents]) ;
$eventNotification = new EventNotification(['event_data' => $event_data ]);
$eventNotification->setUrl('https://stagingapi.medneon.com/MedNeonServices/econsent/DocusignWebhookI/');
$eventNotification->setLoggingEnabled('true');
$eventNotification->setRequireAcknowledgment('true');
$envelope_definition->setEventNotification($eventNotification);
I'm new to the DocuSign API. Trying the sample code, I have it running on my localhost, and when I try to authenticate:
And then the callback gives me a 500 error:
When I check my PHP server logs, I get this:
Next GuzzleHttp\Exception\ConnectException: Connection refused for URI https://account-d.docusign.com/oauth/token in C:\MAMP\htdocs\docusign\vendor\guzzlehttp\guzzle\src\Handler\StreamHandler.php:72
Has anyone encountered the same thing? Or any ideas?
How can we implement multiple signers with in same document using template id after enabling part-11 module
Hi,
I have created template in docusign admin panel with two persons and added the signature for the person1 and two signature for the person2 and added the radio buttons for the second person
I need to access the logic in example 32 and 33,but i am not able to get using templateid by
$envelope_definition = new EnvelopeDefinition([
'status' => "sent",
'template_id' => '1ecda85e-c502-4d2f-9bb7-e784277e5032'
]);
$envelope_definition->setWorkflow($workflow);
$envelope_definition->setTemplateRoles([$signer1, $signer2]);
Please help me to achieve
Hi I am using the template ID with embedded sign using the example 32 and envelope update for the 33
Kindly help me to resolve the issue
this is for the envelope Update
namespace Example\Controllers\Examples\eSignature;
use DocuSign\eSign\Api\EnvelopesApi\UpdateOptions;
use DocuSign\eSign\Client\ApiException;
use DocuSign\eSign\Model\EnvelopeDefinition;
use DocuSign\eSign\Model\Workflow;
use DocuSign\eSign\Model\Recipients;
use DocuSign\eSign\Model\Signer;
use DocuSign\eSign\Model\RecipientViewRequest;
use Example\Controllers\eSignBaseController;
use Example\Services\SignatureClientService;
use Example\Services\RouterService;
class EG033UnpauseSignatureWorkflow extends eSignBaseController
{
/** signatureClientService */
private $clientService;
/** RouterService */
private $routerService;
/** Specific template arguments */
private $args;
private $eg = "eg033"; # Reference (and URL) for this example
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->args = $this->getTemplateArgs();
$this->clientService = new SignatureClientService($this->args);
$this->routerService = new RouterService();
parent::controller($this->eg, $this->routerService, basename(__FILE__));
}
/**
* 1. Check the token
* 2. Call the worker method
*
* @return void
* @throws ApiException for API problems and perhaps file access \Exception, too
*/
public function createController(): void
{
$minimum_buffer_min = 3;
if ($this->routerService->ds_token_ok($minimum_buffer_min)) {
# 1. Call the worker method
# More data validation would be a good idea here
# Strip anything other than characters listed
$results = $this->worker($this->args);
if ($results) {
$_SESSION['pause_envelope_id'] = false;
# Redirect the user to the embedded signing
# Don't use an iFrame!
# State can be stored/recovered using the framework's session or a
# query parameter on the returnUrl (see the make recipient_view_request method)
header('Location: ' . $results["redirect_url"]);
exit;
} else {
$this->clientService->needToReAuth($this->eg);
}
}
public function worker($args): array
{
$envelope_api = $this->clientService->getEnvelopeApi();
$env = new EnvelopeDefinition([
'workflow' => new Workflow(['workflow_status' => 'in_progress']
),
]);
$envelope_option = new UpdateOptions();
$envelope_option -> setAdvancedUpdate('true');
$envelope_option -> setResendEnvelope('true');
$signer1 = new Signer([ # The signer1
'email' => ' '#### ',
'name' => 'GH',
'recipient_id' => "1",
'routing_order' => "1",
'role_name' => 'd',
'client_user_id' => '#### ',
]);
$signer2 = new Signer([ # The signer2
'email' => '#### ',
'name' => 'MH',
'recipient_id' => "2",
'routing_order' => "2",
'role_name' => 'p',
'client_user_id' => '#### ',
]);
$recipients = new Recipients([
'signers' => [$signer1, $signer2, ],
]) ;
$env -> setTemplateId( '#### ');
$env->setTemplateRoles([$signer1, $signer2]);
$authentication_method = 'None';
$recipient_view_request = $this->clientService->getRecipientViewRequest(
$authentication_method,
$args['receipent_arguments']);
$envelope = $envelope_api->update(
$args['account_id'],
$args['pause_envelope_id'],
$envelope=$env,
$options=$envelope_option
);
$envelope_id = $envelope['envelope_id'];
$results = $this->clientService->getRecipientView($args['account_id'], $envelope_id,
$recipient_view_request);
return ['envelope_id' => $envelope_id, 'redirect_url' => $results['url']];
}
/**
* Get specific template arguments
*
* @return array
*/
private function getTemplateArgs(): array
{
$signer2_name = preg_replace('/([^\w \-\@\.\,])+/', '', $_SESSION['signer2_name']);
$signer2_email = preg_replace('/([^\w \-\@\.\,])+/', '', $_SESSION['signer2_email']);
$receipent_arguments =[
'signer_email' => '#### ',
'signer_name' => 'MH',
'signer_client_id' => '#### ',,
'ds_return_url' => $GLOBALS['app_url'] . 'index.php?page=ds_return',
'recipient_id' => '2',
'routing_order' => '2',
'role_name' => 'p',
];
$args = [
'account_id' => $_SESSION['ds_account_id'],
'base_path' => $_SESSION['ds_base_path'],
'ds_access_token' => $_SESSION['ds_access_token'],
'pause_envelope_id' => '#### ',
'receipent_arguments' => $receipent_arguments,
];
return $args;
}
}
Hi ,
My need to add the custom fields like two text fields and i will pass value to api it should be hidden in the signer view,but it should be visible to the webhhook
kindly how to implement in php
After JWT Authetication i am not able to call any API in list. It is redirecting to base URL.
Please help..
On using Must authenticate, with JWT method,
I get this error,
Deprecated: Non-static method Example\Controllers\Auth\DocuSign::getDefaultScopes() should not be called statically in C:\xampp\htdocs\docusign\code-examples-php-master\src\Services\JWTService.php on line 67
jb65ebbd0-f472-41d0-b25f-d05d36437685
Fatal error: Uncaught DocuSign\eSign\Client\ApiException: Error while requesting server, received a non successful HTTP code [400] with response Body: O:8:"stdClass":1:{s:5:"error";s:15:"invalid_request";} in C:\xampp\htdocs\docusign\code-examples-php-master\vendor\docusign\esign-client\src\Client\ApiClient.php:344 Stack trace: #0 C:\xampp\htdocs\docusign\code-examples-php-master\vendor\docusign\esign-client\src\Client\ApiClient.php(597): DocuSign\eSign\Client\ApiClient->callApi('/oauth/token', 'POST', Array, 'assertion=eyJ0e...', Array, NULL, NULL, true) #1 C:\xampp\htdocs\docusign\code-examples-php-master\src\Services\JWTService.php(76): DocuSign\eSign\Client\ApiClient->requestJWTUserToken('03ff0533-b1e8-4...', 'jb65ebbd0-f472-...', '-----BEGIN RSA ...', 'signature imper...') #2 C:\xampp\htdocs\docusign\code-examples-php-master\src\Services\JWTService.php(44): Example\Services\JWTService->configureJwtAuthorizationFlowByKey() #3 C:\xampp\htdocs\docusign\code-examples-php-master\src\Services\RouterService.php(310): Examp in C:\xampp\htdocs\docusign\code-examples-php-master\vendor\docusign\esign-client\src\Client\ApiClient.php on line 344
And when I open the url, in new tab, I am already authenticated.
Is this the recommended behaviour.
https://www.loom.com/share/15e589d870d749428a201ebdf6e08863
Also, I would like to know, The Jwt will be performed only once, or everytime. What If I just want to create an API on my server to send Envelope by post fields,
Hi, I successfully integrated the repository here (https://github.com/docusign/eg-01-php-jwt) along with the repository (https://github.com/docusign/eg-03-php-auth-code-grant) a few months back. Recently I tried the application and got invalid_grant errors. When I went to research the issue, I see that both repositories have been closed and point to this one. Having tried for days to integrate with the new examples, I can't find any related documents to be able to open a url with data to automatically send an envelop like before. There's also no documentation on migrating from one to another. Can you please help me replace the following:
include_once 'example_base.php';
class SendEnvelope extends ExampleBase {
Where can I find the equivalent code? Thanks!
There are plenty of errors in the published code.
For example:
everywhere:
$envelope_api = new \DocuSign\eSign\Api\EnvelopesApi($api_client);
should be:
$envelope_api = new \DocuSign\eSign\Client\Api\EnvelopesApi($api_client);
Hi ,
Can we add the radio button with some logics in the the unpausing the signatue flow with docusign php
is it possible can we tell me how to do it in php
Got error while trying to run composer install: "The url supplied for the path (C:\Users\robert.knight\src\DPE\robert-knight\SDKs\docusign-admin-php-client-master) repository does not exist"
Hi ,
I am trying to change the Example 32 to change to Embeded signing and i am getting the error
INVALID_EMAIL_ADDRESS_FOR_RECIPIENT: The email address for the recipient is invalid. The recipient Id follows. Envelope definition is missing an email address for recipientId: 1
Kindly help me resolve the issue
Hello,
When running "docker compose up -d" I get the following error during STEP 4/13
=> ERROR [php-fpm stage-1 4/13] RUN pecl install imagick xdebug
27.69 configure: error: rtnetlink.h is required, install the linux-headers package: apk add --update linux-headers
27.71 ERROR: `/tmp/pear/temp/xdebug/configure --with-php-config=/usr/local/bin/php-config' failed
Adding "RUN apk add --update linux-headers" to the Dockerfile fixes this issue.
Hi, I want to set a specified owner or brand_id when I create a new template, so I'm adding these specified values to the EnveloppeTemplate definiton but that actually not work, data are setted, but when the template is created without errors, brand_id is null and the owner is still the default DS account.
($userInfo data is retrieve from the getUsersApi()->callList() method)
$owner = new UserInfo();
$owner->setEmail($userInfo->getEmail());
$owner->setUserId($userInfo->getUserId());
$owner->setUserName($userInfo->getUserName());
$template_request = new EnvelopeTemplate([
'documents' => [$document], 'email_subject' => "Please sign this document",
'envelope_template_definition' => $envelope_template_definition,
'recipients' => new Recipients([
'signers' => [$signer], 'carbon_copies' => [$cc]]),
'status' => "created",
'description' => "Example template created via the API",
'name' => $this->template_name,
'shared' => "false",
'brand_id' => "my_other_brand_id",
'owner' => $owner
]);
If you have any ideas about this mistake. Thanks.
I see that the examples retrieve, but do not make use of the Refresh Token.
I understand that their use may be out of scope for this example.
However, it might be helpful to put a pointer to their SDK usage in the README. There are references to other information sources that are also out of scope, so I feel like it isn't unreasonable to request such a reference here.
If their absence from the documentation is because they are absent from the SDK, a note to the effect that they are non-functional would be helpful. At least I could stop looking for a feature that isn't yet production-ready.
Hi,
Can we get three signers sign to docusign using embedded signing
As of now we are using below code
$signer1 = new Signer([
'email' => $envelope_args['signer1_email'],'name' => $envelope_args['signer1_name'],
'role_name' => "d", 'recipient_id' => "1",
'routing_order' => "0",
'client_user_id' => ################################
]);
$signer2 = new Signer([
'email' => $envelope_args['signer2_email'],
'name' => $envelope_args['signer2_name'],
'recipient_id' => "1",
'routing_order' => "0",
'role_name' => 'p',
'client_user_id' => @@@@@@@@@@@@@@@@@@@@@@@@@@@
]);
$envelope_definition->setTemplateRoles([$signer1, $signer2
]);
can we add one more member for signing
In JWTService, $_SESSION['ds_expiration']
is set like this:
$_SESSION['ds_expiration'] = time() + (self::$access_token->getExpiresIn() * 1000); # expiration time.
PHP's time()
returns the current unix epoch in seconds:
>>> time()
=> 1613082946
>>> time()
=> 1613082948
OAuthToken's getExpiresIn()
property appears to be in seconds too:
>>> $token = $auth->generateToken();
=> DocuSign\eSign\Client\Auth\OAuthToken {#5236}
>>> $token->getExpiresIn();
=> "3600"
The DocuSign documentation specifies that expires_in
is in seconds:
Name | Description |
---|---|
expires_in | The number of seconds before the access token expires. When your access token expires, your application should generate a new JWT with your credentials and request a new access token. |
If the "3600" value was treated as seconds, it would be 60 minutes and the correct code may be $_SESSION['ds_expiration'] = time() + self::$access_token->getExpiresIn()
. The current code enacts an expiration time of 60 * 1000
minutes = about 41 days
I'm new to Docker (not to PHP) so apologies if I'm missing something obvious.
Steps:
docker-compose up
[wait for it to complete]Fatal error: require_once(): Failed opening required '/var/www/html/public/../vendor/autoload.php' (include_path='.:/usr/local/lib/php') in /var/www/html/public/index.php on line 9
docker-compose build
before the docker-compose up
but that gave the same result.I was expecting to see the quickstart. Am I doing something wrong?
Any assistance greatly appreciated.
Hi,
How can we send email to two signers using the template kindly let us know the changes to do
args = $this->getTemplateArgs(); $this->clientService = new SignatureClientService($this->args); $this->routerService = new RouterService(); parent::controller($this->eg, $this->routerService, basename(__FILE__)); } /** * 1. Check the token * 2. Call the worker method * * @return void * @throws ApiException for API problems and perhaps file access \Exception, too */ public function createController(): void { $minimum_buffer_min = 3; if ($this->routerService->ds_token_ok($minimum_buffer_min)) { # 1. Call the worker method # More data validation would be a good idea here # Strip anything other than characters listed $envelope_id = $this->worker($this->args); if ($envelope_id) { $_SESSION["pause_envelope_id"] = $envelope_id; $nextExampleUrl = "/public/index.php?page=eg033"; $this->clientService->showDoneTemplate( "Envelope sent", "Envelope sent", "The envelope has been created and sent!To resume a workflow after the first recipient signs
the envelope use example 33.
"
);
}
} else {
$this->clientService->needToReAuth($this->eg);
}
}
/**
* Do the work of the example
* 1. Create the envelope request object
* 2. Send the envelope
*
* @param $args array
* @return string
* @throws ApiException for API problems and perhaps file access \Exception, too
*/
public function worker($args): string
{
# Step 3-1 Start
$envelope_args = $args['envelope_args'];
$envelope_api = $this->clientService->getEnvelopeApi();
$envelope_definition = $this->make_envelope($envelope_args);
# Step 3-1 End
# Step 4 Start
$envelope = $envelope_api->createEnvelope($args["account_id"], $envelope_definition);
$envelope_id = $envelope["envelope_id"];
# Step 4 End
return $envelope_id;
}
/**
* Creates envelope definition
* Parameters for the envelope: signer_email, signer_name, signer_client_id
*
* @param $envelope_args array
* @return EnvelopeDefinition -- returns an envelope definition
*/
# Step 3-2 start
private function make_envelope($envelope_args)
{
# The envelope has two recipients
# Recipient 1 - signer1
# Recipient 2 - signer2
# The envelope will be sent first to the signer1
# After it is signed, a signature workflow will be paused
# After resuming (unpause) the signature workflow will send to the second recipient
# Create the top-level envelope definition
$envelope_definition = new EnvelopeDefinition([
'email_subject' => "EnvelopeWorkflowTest",
]);
# Create the signer recipient models
# routing_order (lower means earlier) determines the order of deliveries
# to the recipients.
$signer1 = new Signer([ # The signer1
'email' => $envelope_args['signer1_email'],
'name' => $envelope_args['signer1_name'],
'recipient_id' => "1",
'routing_order' => "1",
]);
$signer2 = new Signer([ # The signer2
'email' => $envelope_args['signer2_email'],
'name' => $envelope_args['signer2_name'],
'recipient_id' => "2",
'routing_order' => "2",
]);
# Create SignHere fields (also known as tabs) on the documents.
$sign_here1 = new SignHere([
'document_id' => "1",
'page_number' => "1",
'tab_label' => "Sign Here",
'x_position' => "200",
'y_position' => "200",
]);
$sign_here2 = new SignHere([
'document_id' => "1",
'page_number' => "1",
'tab_label' => "Sign Here",
'x_position' => "300",
'y_position' => "200",
]);
# Add the tabs model (including the sign_here tabs) to the signer
# The Tabs object takes arrays of the different field/tab types
$signer1->setTabs(
new Tabs([
'sign_here_tabs' => [$sign_here1, ],
])
);
$signer2->setTabs(
new Tabs([
'sign_here_tabs' => [$sign_here2, ],
])
);
# Add the recipients to the envelope object
$recipients = new Recipients([
'signers' => [$signer1, $signer2, ],
]) ;
$envelope_definition->setRecipients($recipients);
# Create a workflow model
# Signature workflow will be paused after it is signed by the first signer
$workflow_step = new WorkflowStep([
'action' => "pause_before",
'trigger_on_item' => "routing_order",
'item_id' => "2",
]);
$workflow = new Workflow([
'workflow_steps' => [$workflow_step, ],
]);
# Add the workflow to the envelope object
$envelope_definition->setWorkflow($workflow);
# Request that the envelope be sent by setting |status| to "sent"
# To request that the envelope be created as a draft, set to "created"
$envelope_definition->setStatus($envelope_args['status']);
return $envelope_definition;
}
# Step 3-2 End
/**
* Get specific template arguments
*
* @return array
*/
public function getTemplateArgs(): array
{
$signer1_name = preg_replace('/([^\w \-\@\.\,])+/', '', $_POST['signer1_name']);
$signer1_email = preg_replace('/([^\w +\-\@\.\,])+/', '', $_POST['signer1_email']);
$signer2_name = preg_replace('/([^\w \-\@\.\,])+/', '', $_POST['signer2_name']);
$signer2_email = preg_replace('/([^\w +\-\@\.\,])+/', '', $_POST['signer2_email']);
$envelope_args = [
'signer1_email' => $signer1_email,
'signer1_name' => $signer1_name,
'signer2_email' => $signer2_email,
'signer2_name' => $signer2_name,
'status' => "Sent",
];
$args = [
'account_id' => $_SESSION['ds_account_id'],
'base_path' => $_SESSION['ds_base_path'],
'ds_access_token' => $_SESSION['ds_access_token'],
'envelope_args' => $envelope_args
];
return $args;
}
}
I am trying to download the document from the envelope created using following code:
$tempFile = $envelopeApi->getDocument($config['accountId'], 'combined',$config['envelopeId']);
file_put_contents('combined.pdf', file_get_contents($tempFile->getPathName()));
$tempFile = $envelopeApi->getDocument($config['accountId'], '1',$config['envelopeId']);
file_put_contents('sample.pdf', file_get_contents($tempFile->getPathName()));
In both the case , the file being saved is of zero bytes, which means empty.
Even that happens in this example Code, which belongs to the Code Here
Any help would be appreciated,
Thanks
Hi,
I have tried the example 32 and 32 using the template id for the receiving the signature of the first and second signer
I am getting error
UNSPECIFIED_ERROR: Object reference not set to an instance of an object.
i have checked that it is due to on updating the envelope it is causing issue
can you help me to resolve this issue
I have tried like that
<?php
namespace Example\Controllers\Examples\eSignature;
use DocuSign\eSign\Api\EnvelopesApi\UpdateOptions;
use DocuSign\eSign\Client\ApiException;
use DocuSign\eSign\Model\EnvelopeDefinition;
use DocuSign\eSign\Model\Workflow;
use DocuSign\eSign\Model\Recipients;
use DocuSign\eSign\Model\Signer;
use DocuSign\eSign\Model\SignHere;
use DocuSign\eSign\Model\Tabs;
use DocuSign\eSign\Model\RecipientViewRequest;
use Example\Controllers\eSignBaseController;
use Example\Services\SignatureClientService;
use Example\Services\RouterService;
use DocuSign\eSign\Model\TemplateRole;
class EG033UnpauseSignatureWorkflow extends eSignBaseController
{
/** signatureClientService */
private $clientService;
/** RouterService */
private $routerService;
/** Specific template arguments */
private $args;
private $eg = "eg033"; # Reference (and URL) for this example
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->args = $this->getTemplateArgs();
$this->clientService = new SignatureClientService($this->args);
$this->routerService = new RouterService();
parent::controller($this->eg, $this->routerService, basename(__FILE__));
}
/**
* 1. Check the token
* 2. Call the worker method
*
* @return void
* @throws ApiException for API problems and perhaps file access \Exception, too
*/
public function createController(): void
{
$minimum_buffer_min = 3;
if ($this->routerService->ds_token_ok($minimum_buffer_min)) {
# 1. Call the worker method
# More data validation would be a good idea here
# Strip anything other than characters listed
// $envelope_id = $this->worker($this->args);
$results = $this->worker($this->args);
if ($results) {
$_SESSION['pause_envelope_id'] = false;
# Redirect the user to the embedded signing
# Don't use an iFrame!
# State can be stored/recovered using the framework's session or a
# query parameter on the returnUrl (see the make recipient_view_request method)
header('Location: ' . $results["redirect_url"]);
exit;
}
// if ($envelope_id) {
// $_SESSION['pause_envelope_id'] = false;
// $this->clientService->showDoneTemplate(
// "Envelope unpaused",
// "Envelope unpaused",
// "The envelope workflow has been resumed and the envelope
// has been sent to a second recipient!<br/>
// Envelope ID {$envelope_id}."
// );
// }
} else {
$this->clientService->needToReAuth($this->eg);
}
}
/**
* Do the work of the example
* 1. Create the envelope request object
* 2. Send the envelope
*
* @param $args array
* @return string
* @throws ApiException for API problems and perhaps file access \Exception, too
*/
public function worker($args): array
{
// echo '<pre>';
# Step 3 Start
# Update resend envelope parameter
try {
$env = new EnvelopeDefinition([
'workflow' => new Workflow(['workflow_status' => 'in_progress']
),
//'status' => "sent"
]);
$envelope_api = $this->clientService->getEnvelopeApi();
$envelope_option = new UpdateOptions();
$envelope_option -> setAdvancedUpdate('true');
// $envelope_option -> setResendEnvelope('true');
# Step 3 End
# Step 4 Start
# Call Envelopes::update API method to unpause signature workflow
// $env->setStatus("sent");
$signer1 = new Signer([ # The signer1
'email' => 'xxxx',
'name' => 'GH',
'recipient_id' => "1",
'routing_order' => "1",
'role_name' => 'signer1',
'client_user_id' => 'xxx'
]);
$signer2 = new Signer([ # The signer2
'email' => 'xx',
'name' => 'xx',
'recipient_id' => "2",
'routing_order' => "2",
'role_name' => 'signer2',
'client_user_id' => 'xxx'
]);
$sign_here1 = new SignHere([
'document_id' => "1",
'page_number' => "1",
'tab_label' => "Sign Here",
'x_position' => "200",
'y_position' => "200",
]);
$sign_here2 = new SignHere([
'document_id' => "1",
'page_number' => "1",
'tab_label' => "Sign Here",
'x_position' => "300",
'y_position' => "200",
]);
# Add the tabs model (including the sign_here tabs) to the signer
# The Tabs object takes arrays of the different field/tab types
$signer1->setTabs(
new Tabs([
'sign_here_tabs' => [$sign_here1, ],
])
);
$signer2->setTabs(
new Tabs([
'sign_here_tabs' => [$sign_here2, ],
])
);
$recipients = new Recipients([
'signers' => [$signer1, $signer2, ],
]) ;
$env->setRecipients($recipients);
// $env->setTemplateRoles([$signer1, $signer2]);
$authentication_method = 'None';
$recipient_view_request = $this->clientService->getRecipientViewRequest(
$authentication_method,
$args['receipent_arguments']);
$envelope = $envelope_api->update(
$args['account_id'],
$args['pause_envelope_id'],
$envelope=$env,
$options=$envelope_option
);
$envelope_id = $envelope['envelope_id'];
// $results = $this->clientService->getRecipientView($args['account_id'], $envelope_id,
// $recipient_view_request);
// return ['envelope_id' => $envelope_id,'ServiceStatus' =>'Success', 'redirect_url' => $results['url']];
# 4. Obtain the recipient_view_url for the embedded signing
# Exceptions will be caught by the calling function
// $results = $this->clientService->getRecipientView($args['account_id'], $envelope_id, $recipient_view_request);
$results = $this->clientService->getRecipientView($args['account_id'], $envelope_id,
$recipient_view_request);
return ['envelope_id' => $envelope_id, 'redirect_url' => $results['url']];
} catch (ApiException $e) {
$this->clientService->showErrorTemplate($e);
exit;
}
// $results = $envelope_api->createRecipientView($args['account_id'], $envelope_id,
// $recipient_view_request);
// return ['envelope_id' => $envelope_id,'ServiceStatus' =>'Success', 'redirect_url' => $results['url']];
# 4. Obtain the recipient_view_url for the embedded signing
# Exceptions will be caught by the calling function
// $results = $this->clientService->getRecipientView($args['account_id'], $envelope_id, $recipient_view_request);
// return ['envelope_id' => $envelope_id, 'redirect_url' => $results['url']];
// } catch (ApiException $e) {
// $this->clientService->showErrorTemplate($e);
// exit;
// }
}
/**
* Get specific template arguments
*
* @return array
*/
private function getTemplateArgs(): array
{
$signer2_name = preg_replace('/([^\w \-\@\.\,])+/', '', $_SESSION['signer2_name']);
$signer2_email = preg_replace('/([^\w \-\@\.\,])+/', '', $_SESSION['signer2_email']);
$receipent_arguments =[
'signer_email' => 'xxx',
'signer_name' => 'xxx',
'signer_client_id' =>'xxxx',
'ds_return_url' => $GLOBALS['app_url'] . 'index.php?page=ds_return',
'recipient_id' => '2',
'routing_order' => '2',
'role_name' => 'signer2',
];
$args = [
'account_id' => $_SESSION['ds_account_id'],
'base_path' => $_SESSION['ds_base_path'],
'ds_access_token' => $_SESSION['ds_access_token'],
'pause_envelope_id' => 'xxx',
'receipent_arguments' => $receipent_arguments,
];
return $args;
}
}
Hi,
I have added some logics like adding radio button in the Admin template page
Can we access the logics and UI in the api level using client id and template id
Hi ,
I have added 3 checkboxes in the page
$check1 = new Checkbox(['document_id' => '1', 'page_number' => '7',
'x_position' => '150', 'y_position' => '420', 'tab_label' => 'ckAuthorization']);
$check2 = new Checkbox(['document_id' => '1', 'page_number' => '7',
'x_position' => '150', 'y_position' => '460', 'tab_label' => 'ckAuthentication']);
$check3 = new Checkbox(['document_id' => '1', 'page_number' => '7',
'x_position' => '150', 'y_position' => '500', 'tab_label' => 'ckAgreement']);
I need logic that if one and two selected then the 3rd check box must be hidden
and if the 3rd checkbox is checked then the 1 and 2 must be hidden
Kindly help me how to add it
Hi,
We have added the custom field check box in the template in docusign admin panel and on user end if the user is checked the check box we are not able to find the value,kindly tell me how to achieve it
Hi,
I have added the custom fields in the envelope as
$custom_field1 = new TextCustomField([
'field_id' => '10574617715',
'name' => 'track_text_d',
'required' => 'false',
'show' => 'false', # Yes, include in the CoC
'value' => '1234567']);
$custom_field2 = new TextCustomField([
'field_id' => '10574617714',
'name' => 'track_text',
'required' => 'false',
'show' => 'false', # Yes, include in the CoC
'value' => 'welcome']);
$custom_fields = new CustomFields([
'text_custom_fields' => [$custom_field1,$custom_field2]]);
$envelope_definition->setCustomFields($custom_fields);
$envelope_definition->setWorkflow($workflow);
$envelope_definition->setTemplateRoles([$signer1, $signer2]);
can u tell me the how to call the webhook url locally in php script and get the custom variable
Hi,
I have tried the example 32 and 32 using the template id for the receiving the signature of the first and second signer
I am getting error
UNSPECIFIED_ERROR: Object reference not set to an instance of an object.
i have checked that it is due to on updating the envelope it is causing issue
can you help me to resolve this issue
The comment says:
Try to get an access token using the authorization code grant.
This was most likely copied from the CodeGrantService.php code and not updated to say JWT. I was initially very confused as to why you would try to get a code grant token in the JWT service but then realized it was just an incorrect comment.
Hi ,
Kindly let us know the code in php for the scenario
We have 2 signers using the template id for signing and one user is signed and other is not signd
We need to send email to user who is not signed the document
Hi,
We are using embeded signing and we are are creating redirect url and sent to the user for signing
But can not find the redirect url is expired or not we found that the redirect url expired time is 120 mins
kindly help us how to find the redirect url is expired in webhook url
We are using below code for creating redirect url
$recipient_view_request = $this->clientService->getRecipientViewRequest(
$authentication_method,
$args['patient_arguments']
);
$results = $envelope_api->createRecipientView($args['account_id'], $envelope_id,
$recipient_view_request);
$all_details['patient'] =['envelope_id' => $envelope_id, 'redirect_url' => $results['url']];
I have downloaded the QuickStart example and set the configs.
What am I missing?
I am able to authenticate using ACG, but not JWT.
Here the error
PHP Fatal error: Uncaught Error: Call to a member function getAccessToken() on null in /sources/docusign/src/Services/JWTService.php:52
Stack trace:
#0 /sources/docusign/src/Services/RouterService.php(391): Example\\Services\\JWTService->login()
#1 /sources/docusign/src/Services/RouterService.php(275): Example\\Services\\RouterService->ds_login()
#2 /sources/docusign/public/index.php(42): Example\\Services\\RouterService->router()
#3 {main}
thrown in /sources/docusign/src/Services/JWTService.php on line 52,
referer: http://localhost/docusign/index.php?page=must_authenticate
Firstly, this may come across as opinion or personal taste. Please see it as feedback on how to improve the usability and ease of integration of the API in existing web apps.
The API documentation often references code from the quick start app. While this is fine for new applications, reference the quick start app's code introduces barriers for anyone trying to integrate DocuSign's API into an existing application that possibly doesn't adhere to the quickstart app's code structure and methodology. Therefore, this requires existing app developers to untangle the quickstart app's code to find the core of the DocuSign API's usage.
A suggestion on API documentation, let the calls and processes code be minimal and only for the purpose of demonstrating how to make or use the call without any additional code which isn't necessary for the demonstration. On this page (https://developers.docusign.com/docs/esign-rest-api/sdk-tools/php/auth/), the code examples display a snippet of the quickstart code and a link to it to Github. But, the dev must then dive through controllers and interfaces before actually getting to the code that uses DocuSign's API. This is an example of the quickstart application's code getting in the way of the API's documentation.
A good example of API documentation and examples, in my opinion, is Stripe: https://stripe.com/docs/api?lang=php . It displays simplistic, stand-alone code snippets demonstrating all the different methods with an explanation of what it's used for, response, and parameters.
Example EG008CreateTemplate.php here
# Create top two objects
$envelope_template_definition = new EnvelopeTemplateDefinition([
'description' => "Example template created via the API",
'name' => $this->template_name,
'shared' => "false"
]);
# Top object:
$template_request = new EnvelopeTemplate([
'documents' => [$document], 'email_subject' => "Please sign this document",
'envelope_template_definition' => $envelope_template_definition,
'recipients' => new Recipients([
'signers' => [$signer], 'carbon_copies' => [$cc]]),
'status' => "created"
]);
this declaration :
'envelope_template_definition' => $envelope_template_definition,
does not match anything in the EnvelopeTemplate model definition => here so it does not work...
Can you check the mistake please, thanks!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.