Install the Package:
composer require docusign/click-client
Ensure require_once('vendor/autoload.php') is in your Laravel autoloader (e.g., bootstrap/app.php).
Set Up OAuth Credentials:
https://your-app.test/docusign/callback).env:
DOCUSIGN_CLIENT_ID=your_client_id
DOCUSIGN_CLIENT_SECRET=your_client_secret
DOCUSIGN_REDIRECT_URI=https://your-app.test/docusign/callback
First Use Case: Send a Simple Envelope Use the Authorization Code Grant Launcher as a template. Example workflow:
// routes/web.php
Route::get('/docusign/auth', [DocuSignController::class, 'authenticate']);
Route::get('/docusign/callback', [DocuSignController::class, 'callback']);
// app/Http/Controllers/DocuSignController.php
use DocuSign\eSign\Model\Envelopes\EnvelopeDefinition;
use DocuSign\eSign\Model\Envelopes\Recipients\Signers\Signer;
use DocuSign\eSign\Model\Envelopes\Documents\Document;
use DocuSign\eSign\Api\EnvelopesApi;
class DocuSignController extends Controller {
public function authenticate() {
$authCodeUrl = $this->getAuthCodeUrl();
return redirect($authCodeUrl);
}
public function callback(Request $request) {
$accessToken = $this->getAccessToken($request->code);
$envelopeApi = new EnvelopesApi(new \DocuSign\eSign\ApiClient($accessToken));
// Create envelope
$envelopeDefinition = new EnvelopeDefinition([
'emailSubject' => 'Please sign this document',
'documents' => [new Document(['documentBase64' => base64_encode(file_get_contents('contract.pdf'))])],
'recipients' => [
'signers' => [new Signer(['email' => 'signer@example.com', 'name' => 'Signer Name', 'recipientId' => '1'])]
]
]);
$envelopeSummary = $envelopeApi->createEnvelope($accountId, $envelopeDefinition);
return redirect("/envelope/{$envelopeSummary->envelopeId}");
}
protected function getAuthCodeUrl() {
$authApi = new \DocuSign\eSign\Api\AuthApi(new \DocuSign\eSign\ApiClient());
return $authApi->getAuthorizationUrl(
config('docusign.client_id'),
config('docusign.redirect_uri'),
['scope' => 'signature', 'state' => 'some_state']
);
}
protected function getAccessToken($authCode) {
$authApi = new \DocuSign\eSign\Api\AuthApi(new \DocuSign\eSign\ApiClient());
return $authApi->requestAccessToken(
config('docusign.client_id'),
config('docusign.client_secret'),
config('docusign.redirect_uri'),
$authCode
)->accessToken;
}
}
Configure Laravel Services (Optional): Bind the SDK to Laravel’s container for reuse:
// config/app.php
'providers' => [
// ...
App\Providers\DocuSignServiceProvider::class,
],
// app/Providers/DocuSignServiceProvider.php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use DocuSign\eSign\ApiClient;
class DocuSignServiceProvider extends ServiceProvider {
public function register() {
$this->app->singleton('docusign.api.client', function ($app) {
return new ApiClient(config('docusign.access_token'));
});
}
}
Authorization Code Grant (Recommended):
Use the AuthApi to generate auth URLs and exchange codes for tokens.
$authApi = new \DocuSign\eSign\Api\AuthApi(new ApiClient());
$authUrl = $authApi->getAuthorizationUrl(
config('docusign.client_id'),
config('docusign.redirect_uri'),
['scope' => 'signature', 'state' => 'user_id_123']
);
Store the state to validate callback integrity.
JWT Grant (Server-to-Server): Ideal for background jobs or headless Laravel queues.
$jwtApi = new \DocuSign\eSign\Api\JWTApi(new ApiClient());
$jwtPayload = [
'iss' => config('docusign.jwt_issuer'),
'sub' => config('docusign.jwt_subject'),
'iat' => time(),
'exp' => time() + 3600,
'aud' => 'account-d.docusign.com',
'scope' => 'signature'
];
$jwt = \Firebase\JWT\JWT::encode($jwtPayload, config('docusign.jwt_private_key'), 'RS256');
$accessToken = $jwtApi->requestJWTUserToken(
config('docusign.jwt_issuer'),
$jwt,
config('docusign.jwt_private_key')
)->accessToken;
$envelopeApi = new EnvelopesApi(new ApiClient($accessToken));
$envelope = $envelopeApi->createEnvelope($accountId, $envelopeDefinition);
$envelopeApi->voidEnvelope($accountId, $envelopeId);
$envelopeSummary = $envelopeApi->getEnvelope($accountId, $envelopeId);
TemplateRole to bind dynamic data:
$templateRole = new \DocuSign\eSign\Model\Envelopes\TemplateRoles\TemplateRole([
'templateId' => '12345',
'templateRoles' => [
new \DocuSign\eSign\Model\Envelopes\TemplateRoles\TemplateSigner([
'email' => 'client@example.com',
'name' => 'Client Name',
'roleName' => 'signer'
])
],
'documents' => [new Document(['documentId' => '1', 'name' => 'Contract'})]
]);
$envelopeDefinition->setTemplateRoles([$templateRole]);
envelope_sent, signature_completed) to a configured webhook URL.// routes/web.php
Route::post('/docusign/webhook', [DocuSignWebhookController::class, 'handle']);
// app/Http/Controllers/DocuSignWebhookController.php
class DocuSignWebhookController extends Controller {
public function handle(Request $request) {
$payload = $request->json()->all();
$signature = $request->header('X-DocuSign-Signature');
// Verify webhook signature (DocuSign-specific)
if ($this->validateWebhookSignature($payload, $signature)) {
event(new \App\Events\DocuSignWebhookReceived($payload));
}
}
protected function validateWebhookSignature(array $payload, string $signature) {
// Implement signature validation logic
// See: https://developers.docusign.com/esign-rest-api/guides/webhooks
}
}
try {
$envelopeApi->createEnvelope($accountId, $envelopeDefinition);
} catch (\DocuSign\eSign\ApiException $e) {
\Log::error("DocuSign API Error: " . $e->getMessage());
return response()->json(['error' => 'Failed to send envelope'], 500);
}
Bind the SDK to Laravel’s container for dependency injection:
// app/Providers/AppServiceProvider.php
public function register() {
$this->app->bind(\DocuSign\eSign\Api\EnvelopesApi::class, function ($app) {
return new \DocuSign\eSign\Api\EnvelopesApi(
How can I help you explore Laravel packages today?