Installation
composer require bukashk0zzz/hellosign-bundle
Add to config/bundles.php (Symfony 4+):
return [
// ...
Bukashk0zzz\HelloSignBundle\HelloSignBundle::class => ['all' => true],
];
Configuration
Add to config/packages/hellosign.yaml:
hellosign:
api_key: '%env(HELLOSIGN_API_KEY)%'
webhook_secret: '%env(HELLOSIGN_WEBHOOK_SECRET)%'
First Use Case Send a basic signature request via a controller:
use Bukashk0zzz\HelloSignBundle\Service\HelloSignService;
class SignatureController extends AbstractController
{
public function sendSignature(HelloSignService $helloSign)
{
$request = $helloSign->createSignatureRequest(
'user@example.com',
'Sign this document',
['file.pdf'] // Array of file paths
);
return $this->redirect($request->getSigningUrl());
}
}
Signature Requests
$request = $helloSign->createSignatureRequest(
'recipient@example.com',
'Please sign this agreement',
['contract.pdf'],
['signer_name' => 'John Doe']
);
$request = $helloSign->createSignatureRequest(
null, // No default sender
'Team Approval',
['proposal.pdf'],
[
['email' => 'alice@example.com', 'role' => 'Approver'],
['email' => 'bob@example.com', 'role' => 'Reviewer']
]
);
Webhook Handling
config/routes.yaml:
hellosign_webhook:
path: /hellosign/webhook
controller: Bukashk0zzz\HelloSignBundle\Controller\WebhookController::handle
use Bukashk0zzz\HelloSignBundle\Event\WebhookEvent;
public function onWebhook(WebhookEvent $event)
{
if ($event->isValid()) {
$payload = $event->getPayload();
// Handle signature events (e.g., completed, declined)
}
}
Document Management
$documentId = $helloSign->uploadDocument('file.pdf');
$document = $helloSign->getDocument($documentId);
Templates
$template = $helloSign->createTemplate(
'Contract Template',
'contract.pdf',
['signer_name' => '{{signer_name}}']
);
$request = $helloSign->sendTemplate(
$templateId,
'recipient@example.com',
['signer_name' => 'Alice']
);
Laravel-Specific Adaptation
Replace Symfony’s HelloSignService with a Laravel service provider:
// app/Providers/HelloSignServiceProvider.php
public function register()
{
$this->app->singleton(HelloSignService::class, function ($app) {
return new HelloSignService(
$app['config']['hellosign.api_key'],
$app['config']['hellosign.webhook_secret']
);
});
}
Event Dispatching Extend the bundle’s events to trigger Laravel events:
// Listen to webhook events
$eventDispatcher->addListener(WebhookEvent::class, function (WebhookEvent $event) {
if ($event->isValid()) {
event(new HelloSignWebhookReceived($event->getPayload()));
}
});
Testing Use the SDK’s mock mode for unit tests:
$helloSign = new HelloSignService('test_key', 'test_secret');
$helloSign->setMockMode(true); // Enable mock responses
Deprecated SDK
guzzlehttp/guzzle to v7+).
composer require guzzlehttp/guzzle:^7.0
Webhook Validation
X-HelloSign-Signature header in production:
if (!$event->isValid()) {
throw new \RuntimeException('Invalid webhook signature');
}
Rate Limiting
$cacheKey = "hellosign_request_{$requestId}";
return Cache::remember($cacheKey, 300, function () use ($helloSign, $requestId) {
return $helloSign->getSignatureRequest($requestId);
});
File Handling
$fileContent = file_get_contents('file.pdf');
$documentId = $helloSign->uploadDocumentBase64(base64_encode($fileContent));
Enable SDK Logging
Add to config/services.yaml:
services:
HelloSign\Client:
arguments:
$logger: '@logger'
Check logs for API errors in storage/logs/laravel.log.
API Response Inspection Override the SDK’s HTTP client to log raw responses:
// In a service provider
$this->app->extend(HelloSign\Client::class, function ($client, $app) {
$client->setHttpClient(new \GuzzleHttp\Client([
'handler' => \GuzzleHttp\HandlerStack::create([
'debug' => function ($handler) {
return function ($request, $options) use ($handler) {
$response = $handler($request, $options);
\Log::debug('HelloSign API Response', [
'status' => $response->getStatusCode(),
'body' => (string) $response->getBody()
]);
return $response;
};
}
])
]));
return $client;
});
Webhook Testing Use HelloSign’s sandbox environment and test webhooks locally with:
ngrok http 8000 # Forward local webhook endpoint
Custom Events
Extend the bundle’s WebhookEvent to dispatch Laravel events:
// src/Events/HelloSignSignatureCompleted.php
class HelloSignSignatureCompleted
{
public function __construct(public string $signatureId) {}
}
Template Repository Create a repository pattern for templates:
class HelloSignTemplateRepository
{
public function __construct(private HelloSignService $helloSign) {}
public function findByName(string $name): ?array
{
$templates = $this->helloSign->listTemplates();
return collect($templates)->first(function ($template) use ($name) {
return $template['name'] === $name;
});
}
}
Document Storage Adapter Decouple file storage by implementing an adapter:
interface DocumentStorageAdapter
{
public function getFilePath(string $documentId): string;
}
// Usage:
$adapter = new S3DocumentAdapter();
$helloSign->setDocumentStorage($adapter);
How can I help you explore Laravel packages today?