Cómo Firmar PDFs Usando Certificados Digitales en Laravel/PHP/Symfony
Introducción
En esta guía, te guiaremos a través del proceso de firmar PDFs digitalmente utilizando un entorno PHP y Laravel. Cubriremos cómo lograr esto utilizando código PHP dentro de tu aplicación Laravel. Utilizaremos un servicio externo gratuito llamado pdfsignify.com, que simplifica el proceso de firma digital y permite una fácil personalización de las firmas.
Las firmas digitales aseguran la autenticidad e integridad de tus PDFs. Para firmar un PDF, necesitarás un certificado digital en forma de un archivo .pfx o .p12, que contiene tu clave privada y certificado. Además, necesitarás la contraseña asociada con tu archivo de certificado.
Cubriremos todo, desde la configuración del entorno Laravel hasta la realización de solicitudes API para firmar PDFs, para que puedas integrar las firmas digitales de manera fluida en tus aplicaciones. ¡Comencemos!
Parte 1: Configuración de una Aplicación Laravel
En este paso, configuraremos una nueva aplicación Laravel que se encargará de generar y firmar PDFs. Laravel ofrece un marco de trabajo potente y elegante para agilizar el proceso de desarrollo. Usaremos GuzzleHTTP para realizar solicitudes API para firmar los PDFs y el sistema de almacenamiento de archivos en Laravel para leer y manipular el contenido de un archivo PDF.
Si ya tienes tu proyecto Laravel configurado y solo necesitas la funcionalidad de firma de PDFs, puedes omitir esta parte.
Primero, asegúrate de que Composer esté instalado en tu máquina, ya que Laravel depende de él para gestionar las dependencias. Luego, abre tu terminal y crea un nuevo proyecto Laravel:
composer create-project --prefer-dist laravel/laravel pdf-signing-app
Este comando creará un nuevo proyecto Laravel en un directorio llamado pdf-signing-app
.
Paso 1: Configurar el Entorno de Laravel
cd pdf-signing-app
Luego, configura tu archivo de entorno. Laravel proporciona un archivo .env.example, que puedes copiar para crear tu archivo .env:
cp .env.example .env
Genera la clave de la aplicación para asegurar que tus sesiones y otros datos cifrados permanezcan seguros:
php artisan key:generate
Ahora, tu entorno de Laravel está configurado y listo para el desarrollo posterior.
Paso 2: Configurar Laravel
Es hora de configurar tu aplicación Laravel. Primero, actualizaremos el archivo .env para configurar la conexión a tu base de datos. En este ejemplo, utilizaremos el controlador MySQL.
Abre el archivo .env en el directorio de tu proyecto Laravel. Busca la siguiente sección, que está relacionada con la configuración de la base de datos:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=nombre_de_tu_base_de_datos
DB_USERNAME=nombre_de_usuario_de_tu_base_de_datos
DB_PASSWORD=contraseña_de_tu_base_de_datos
Paso 3: Migrar la Base de Datos
Una vez que tu conexión a la base de datos esté configurada y funcionando, ejecuta las migraciones de Laravel para configurar el esquema de tu base de datos:
php artisan migrate
Este comando creará las tablas necesarias en tu base de datos MySQL.
Ahora, tu aplicación Laravel está configurada y conectada a la base de datos MySQL. ¡Puedes continuar con la construcción de tu aplicación!
Parte 2: Configuración de PDF Signify
Ahora que nuestro servidor Laravel está en funcionamiento, es momento de configurar PDF Signify para firmar nuestros PDFs. PDF Signify es un servicio gratuito que nos permite agregar fácilmente firmas digitales a nuestros archivos PDF. En esta sección, te guiaremos a través del proceso de crear una cuenta y preparar el servicio para su uso.
Paso 1: Crear una Cuenta o Iniciar Sesión
- Visita el sitio web de PDFSignify: Dirígete al sitio web de PDFSignify en pdfsignify.com.

2. Registrar una Cuenta o Iniciar Sesión: Si aún no tienes una cuenta, haz clic en el botón “Registrar”.
Tienes la opción de registrarte utilizando una cuenta de Google o Microsoft para un proceso de registro rápido. Si prefieres registrarte manualmente, completa tus detalles (correo electrónico, contraseña, etc.) y termina el proceso de registro.

Paso 2: Verificar tu Correo Electrónico
Después de registrarte, necesitarás verificar tu dirección de correo electrónico para activar tu cuenta:
- Revisa tu Bandeja de Entrada: Poco después de registrarte, recibirás un correo electrónico de verificación de PDFSignify.

2. Haz clic en el Botón de Verificación: Abre el correo electrónico y haz clic en el botón o enlace de verificación proporcionado para confirmar tu dirección de correo electrónico.

3. ¿No Recibiste el Correo Electrónico?: Si no recibes el correo en unos minutos, revisa tu carpeta de spam o correo no deseado. Si aún no lo encuentras, regresa al panel de control de PDFSignify y solicita un nuevo correo de verificación.

Paso 3: Crear un Nuevo Proyecto en PDFSignify
Ahora que has verificado tu correo electrónico y accedido al panel de control de PDFSignify, es momento de crear un nuevo proyecto para comenzar a trabajar con el servicio. Esto te permitirá generar claves API, rastrear el uso y gestionar tus firmas digitales.
- Selecciona un Plan: Al crear un nuevo proyecto, se te pedirá que elijas un plan de precios. Para nuestros propósitos, utilizaremos el Plan Gratuito, que tiene algunas limitaciones, pero es suficiente para pruebas y uso básico.
El Plan Gratuito típicamente incluye un número limitado de solicitudes API por mes, así que ten esto en cuenta durante el desarrollo.

2. Configuración del Proyecto: Después de seleccionar el plan de precios, haz clic en Siguiente y asigna un nombre a tu proyecto.

Paso 4: Explorar el Panel de Administración
Con tu proyecto creado, ahora puedes ver el Panel de Administración. Aquí es donde encontrarás información importante y controles relacionados con tu proyecto:
- Uso de la API: El panel mostrará detalles sobre el uso de tu API, incluyendo la cantidad de solicitudes API que has realizado y tu cuota restante.
- Límites: También podrás ver las limitaciones de tu plan, como el número máximo de solicitudes API y cualquier otra restricción asociada con el Plan Gratuito.
- Claves API: En el panel, encontrarás tus claves API, que son esenciales para autenticar tus solicitudes desde el servidor Laravel o PHP. Copia esta clave y guárdala de forma segura, ya que la necesitarás en los siguientes pasos.

Parte 3: Crear Credenciales API
Ahora que tu proyecto está configurado en PDF Signify, el siguiente paso es crear las credenciales API. Estas credenciales son esenciales para autenticar tus solicitudes a la API de PDF Signify desde tu servidor Laravel o PHP. Sigue los pasos a continuación para crear y gestionar tus credenciales API.
Paso 1: Navegar a la Sección de Credenciales API
Ubica y haz clic en la opción “API Credentials” en la barra lateral. Aquí es donde podrás crear y gestionar tus claves API.

Paso 2: Crear Nuevas Credenciales API
En la sección de Credenciales API, verás un botón “Create Credentials”. Haz clic en este botón para generar un nuevo conjunto de credenciales API.
Después de hacer clic en el botón, aparecerá un popup mostrando tus nuevas credenciales API. Estas incluyen:
- API Key: Se utiliza para autenticar tus solicitudes API.
- Secret Key: Se utiliza para firmar tus solicitudes de manera segura.
La Secret Key solo se mostrará una vez, así que asegúrate de copiarla y guardarla en un lugar seguro. Si la pierdes, necesitarás regenerar un nuevo conjunto de credenciales.

Parte 4: Programando la Aplicación Laravel/PHP/Symphony
Ahora que tenemos nuestras credenciales API de PDF Signify, es momento de integrarlas en nuestra aplicación Laravel y PHP. Para este ejemplo, usaremos un PDF ya creado para ahorrar tiempo.
Si necesitas generar un PDF primero, puedes usar una librería como Dompdf o TCPDF. Sin embargo, una vez que el PDF esté generado, podrás enviar directamente su contenido a PDF Signify sin necesidad de guardarlo ni leer el archivo nuevamente.
Paso 1: Guardar el PDF Ya Creado
Antes de proceder a firmar el PDF, guardemos el archivo PDF con el que estarás trabajando. Este archivo se almacenará en el directorio storage/app/ de tu proyecto Laravel.
- Obtener el Archivo PDF: Asegúrate de tener el archivo PDF que deseas firmar. Si lo has generado en otro lugar, asegúrate de que esté listo.
- Guardar el PDF en el Directorio storage/app/: Mueve o copia tu archivo PDF al directorio storage/app/ de tu proyecto Laravel. Renombra el archivo como filepdf.pdf.
Por ejemplo, la estructura de tu directorio del proyecto debería verse algo así:
laravel-project/
│
├── app/
├── bootstrap/
├── config/
├── database/
├── public/
├── resources/
├── routes/
├── storage/
│ └── app/
│ └── filepdf.pdf
├── tests/
└── artisan
Paso 2: Crear una Nueva Ruta para Firmar PDFs
A continuación, crearemos una nueva ruta web para manejar la firma de nuestros PDFs. También editaremos nuestro controlador para agregar la lógica de firma de los PDFs.
Definir la Ruta: Abre el archivo routes/web.php
en tu proyecto Laravel. Agrega una nueva ruta que apunte a un método del controlador responsable de firmar los PDFs.
Por ejemplo, puedes agregar una ruta como esta:
use App\Http\Controllers\PDFSignController;
Route::get('/sign-pdf', [PDFSignController::class, 'signPDF'])->name('sign.pdf');
2. Editar el Controlador: Abre o crea el archivo PdfSignController.php en el directorio app/Http/Controllers/. Agrega un método llamado signPdf que se encargará de la lógica para firmar el PDF.
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Storage; // USED TO READ THE FILES
use CURLFile; // USED FOR THE multiplatform/request
class PDFSignController extends Controller
{
public function signPDF()
{
dd("Sign pdf");
}
}
Con esta ruta y método del controlador en su lugar, al navegar a /sign-pdf en tu navegador se activará el proceso de firma del PDF almacenado en storage/app/filepdf.pdf.
Paso 3: Configurar tu Certificado de Firma y Contraseña
Para firmar PDFs utilizando un certificado digital, necesitas tener un archivo de certificado válido y su contraseña asociada. En este paso, colocarás tu certificado en el directorio storage/app/ de tu proyecto Laravel y configurarás tu aplicación para usarlo.
- Obtener tu Certificado Digital: Asegúrate de tener tu archivo de certificado digital listo. Este podría estar en formato .pfx o .p12.
- Colocar el Certificado en el Directorio storage/app/: Mueve o copia tu archivo de certificado al directorio storage/app/ de tu proyecto Laravel. Renombra el archivo como certificate.pfx o certificate.p12.
Ahora, la estructura de tu directorio del proyecto debería verse algo como esto:
laravel-project/
│
├── app/
├── bootstrap/
├── config/
├── database/
├── public/
├── resources/
├── routes/
├── storage/
│ └── app/
│ ├── filepdf.pdf
│ └── certificate.pfx // or certificate.p12
├── tests/
└── artisan
Paso 4: Leer los Archivos Necesarios en el Código
Para finalizar la configuración, necesitas asegurarte de que tu código lea correctamente los archivos PDF y el certificado, además de manejar de forma segura la contraseña del certificado.
En tu ruta /sign-pdf, puedes leer los archivos PDF y el certificado utilizando el componente Storage de Laravel. Aquí te muestro cómo integrarlos en tu función existente:
$certPath = Storage::path('certificate.pfx');
$pdfPath = Storage::path('filepdf.pdf');
$password = "YOUR_CERTIFICATE_PASSWORD";
Paso 5: Crear los Datos del Formulario para Preparar la Solicitud
Para enviar una solicitud de tipo multipart/form-data para firmar un PDF en PHP, necesitas preparar correctamente los datos del formulario. Esto implica crear la solicitud que incluirá el archivo de certificado, la contraseña del certificado y el archivo PDF que se firmará. En PHP, puedes usar la librería cURL o el cliente GuzzleHTTP para lograr esto.
// Define the form data to send
$postFields = [
'certificate' => new CURLFile($certPath, 'application/x-pkcs12', 'certificate.pfx'),
'certificatePassword' => $password,
'pdf' => new CURLFile($pdfPath, 'application/pdf', 'filepdf.pdf')
];
Paso 6: Ejecutar la Solicitud y Manejar el Resultado
Ahora que hemos configurado correctamente los datos del formulario y añadido los campos necesarios, es hora de ejecutar la solicitud para firmar el PDF. Vamos a utilizar cURL para hacer la solicitud POST a la API de PDFSignify y manejar la respuesta.
Añade esto en la ruta:
// Prepare the cURL request
$ch = curl_init();
// Set the URL for the PDF Signify API endpoint
curl_setopt($ch, CURLOPT_URL, 'https://api.pdfsignify.com/api/v1/sign-pdf');
// Set the cURL options
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Set the headers
$headers = [
'Content-Type: multipart/form-data',
'AccessKey: ' . "MY_ACCESS_KEY",
'SecretKey: ' . "MY_SECRET_KEY"
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
// Execute the request
$response = curl_exec($ch);
// Get the HTTP status code
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
// Close the cURL session
curl_close($ch);
// Check for errors if the response code is NOT OK
if ($statusCode != 200) {
return response()->json(['response' => $response], 500);
}
// Return the signed PDF as a response
return response($response, 200)
->header('Content-Type', 'application/pdf')
->header('Content-Disposition', 'attachment; filename="signed_filepdf.pdf"');
IMPORTANTE: En los encabezados de la solicitud, reemplaza MY_ACCESS_KEY con la clave de acceso que generaste en el sitio de PDFSignify y reemplaza MY_SECRET_KEY con la clave secreta generada en tus credenciales.
Ahora, tu archivo app/Http/Controllers/PDFSignController.php
debería verse así:
<?php
namespace App\Http\Controllers;
use CURLFile;
use Illuminate\Support\Facades\Storage;
class PDFSignController extends Controller
{
public function signPDF()
{
$certPath = Storage::path('certificate.pfx');
$pdfPath = Storage::path('filepdf.pdf');
$password = "YOUR_CERTIFICATE_PASSWORD";
// Define the form data to send
$postFields = [
'certificate' => new CURLFile($certPath, 'application/x-pkcs12', 'certificate.pfx'),
'certificatePassword' => $password,
'pdf' => new CURLFile($pdfPath, 'application/pdf', 'filepdf.pdf')
];
// Prepare the cURL request
$ch = curl_init();
// Set the URL for the PDF Signify API endpoint
curl_setopt($ch, CURLOPT_URL, 'https://api.pdfsignify.com/api/v1/sign-pdf');
// Set the cURL options
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Set the headers
$headers = [
'Content-Type: multipart/form-data',
'AccessKey: ' . "MY_ACCESS_KEY",
'SecretKey: ' . "MY_SECRET_KEY"
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
// Execute the request
$response = curl_exec($ch);
// Get the HTTP status code
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
// Close the cURL session
curl_close($ch);
// Check for errors if the response code is NOT OK
if ($statusCode != 200) {
return response()->json(['response' => $response], 500);
}
// Return the signed PDF as a response
return response($response, 200)
->header('Content-Type', 'application/pdf')
->header('Content-Disposition', 'attachment; filename="signed_filepdf.pdf"');
}
}
Paso 7: Reinicia el servidor y prueba la ruta de sign
Ahora es el momento de probar tu implementación. Reinicia el servidor si es necesario utilizando el comando php artisan serve. Abre tu navegador web y navega a la ruta de sign-pdf ingresando la siguiente URL: http://localhost:8000/sign-pdf
Parte 5: Verifica los resultados
Respuesta de error
Si encuentras un error, verás un mensaje indicando el problema y su causa. Los errores comunes incluyen:
- El PDF no se guarda con el nombre correcto: Asegúrate de que el nombre del archivo coincida con el formato requerido.
- El certificado no se guarda con el nombre correcto: Verifica que tanto el nombre del archivo como la extensión sean correctos.
- Contraseña incorrecta del certificado: Verifica que la contraseña que ingresaste sea correcta.
- Credenciales de la API incorrectas: Revisa tus credenciales de la API y regenéralas si es necesario.
Respuesta de éxito
Una vez que se abra la ruta, verás el PDF firmado. Sin embargo, las firmas pueden no aparecer en el navegador.
Para ver las firmas, descarga el PDF y ábrelo con un visor de PDF en tu sistema operativo. En Windows y macOS, puedes usar Adobe Reader, mientras que en Linux, puedes usar el visor de documentos predeterminado.
La firma será visible en las coordenadas (0,0), que se encuentran en la esquina inferior izquierda de la página.

Parte 6: Personaliza la firma
Pdfsignify ofrece una amplia gama de características para personalizar tu firma. En esta sección, exploraremos muchas de las opciones de personalización disponibles.
Para obtener una lista completa de características y opciones, puedes consultar la documentación aquí.
Paso 1: Personalización de la imagen de fondo:
Para personalizar la imagen de fondo, se requiere una cuenta de pago. Una vez que tengas una cuenta de pago, puedes establecer tu logo como la imagen de fondo utilizando el parámetro signatureBackgroundImage.
Esto implica enviar la imagen utilizando CurlFile para la personalización:
$certPath = Storage::path('certificate.pfx');
$pdfPath = Storage::path('filepdf.pdf');
$password = "YOUR_CERTIFICATE_PASSWORD";
$signatureBackgroundImage = Storage::path('backgroundImage.png');
// Define the form data to send
$postFields = [
'certificate' => new CURLFile($certPath, 'application/x-pkcs12', 'certificate.pfx'),
'certificatePassword' => $password,
'pdf' => new CURLFile($pdfPath, 'application/pdf', 'filepdf.pdf'),
'signatureBackgroundImage' => new CURLFile($signatureBackgroundImage, 'image/png', 'logo.png'),
];
Paso 2: Imagen cerca de la firma:
Si no tienes una cuenta de pago, aún puedes mostrar tu logo utilizando el parámetro signatureImage. Esto te permite colocar una imagen cerca de la firma.
$signatureImage = Storage::path('signatureImage.png');
// Define the form data to send
$postFields = [
'certificate' => new CURLFile($certPath, 'application/x-pkcs12', 'certificate.pfx'),
'certificatePassword' => $password,
'pdf' => new CURLFile($pdfPath, 'application/pdf', 'filepdf.pdf'),
'signatureImage' => new CURLFile($signatureImage, 'image/png', 'logo.png'),
];
Paso 3: Parámetros de la firma
En la documentación, puedes encontrar varios parámetros para personalizar la visualización de la firma y sus valores:
- timezone: Zona horaria para la marca de tiempo de la firma en formato PHP. El valor predeterminado es UTC. Consulta la lista de todas las zonas horarias disponibles.
- signatureFieldName: Nombre único del campo para la firma (el valor predeterminado asigna un nombre único automáticamente).
- signatureXPosition: Establece la posición X de la firma en píxeles en relación con el borde izquierdo del PDF. Un valor de 0 corresponde al extremo izquierdo. (El valor predeterminado es 0).
- signatureYPosition: Establece la posición Y de la firma en píxeles en relación con la parte inferior del PDF. El valor de 0 corresponde a la parte inferior del PDF. (El valor predeterminado es 0).
- signatureWidth: Ancho en píxeles de la firma (el valor predeterminado es 100).
- signatureHeight: Altura en píxeles de la firma (el valor predeterminado es 50).
- signatureMessage: Mensaje visual de la firma (el valor predeterminado es ‘Firmado digitalmente’).
- signaturePageAppearance: Página(s) en la que aparecerá la firma. Puede ser un número entero para especificar una sola página, un arreglo de números enteros para varias páginas, o -1 para indicar todas las páginas. El valor predeterminado es 1.
- signatureDateLabel: Etiqueta para la fecha de la firma (el valor predeterminado es ‘Fecha:’).
- signatureDateFormat: Formato para la fecha de la firma en formato PHP (el valor predeterminado es ‘d-m-Y H:i’).
- signatureReasonLabel: Etiqueta para el motivo de la firma (el valor predeterminado es ‘Motivo:’).
- signatureReason: Motivo de la firma (el valor predeterminado es nulo).
- signatureLocation: Ubicación de la firma (el valor predeterminado es nulo).
- signatureContactInfo: Información de contacto para la firma (el valor predeterminado es nulo).
- signatureShowDistinguishedName: Muestra el Nombre Distinguido (DN) en la firma, incluyendo el nombre propietario y toda la información relacionada con la firma (valor predeterminado: falso).
Puedes encontrar algunos ejemplos en el siguiente código:
// Customize signature appearance and position
$postFields['signaturePageAppearance'] = -1; // Page number for signature (-1 for all pages or specify an array of pages)
$postFields['timezone'] = 'UTC'; // Timezone for signature date and time
$postFields['signatureMessage'] = 'Digitally signed by the user'; // Reason/message for the signature
$postFields['signatureDateLabel'] = ''; // Label for the signature date (empty string for no label)
$postFields['signatureDateFormat'] = 'Y-m-d H:i:s'; // Format for the signature date
$postFields['signatureHeight'] = 100; // Signature height in pixels
$postFields['signatureWidth'] = 150; // Signature width in pixels
$postFields['signatureYPosition'] = 100; // Y position of the signature relative to the bottom of the page
$postFields['signatureXPosition'] = 180; // X position of the signature relative to the left of the page
Paso 4: Metadatos del PDF
Cuando firmas un PDF, PDF Signify también te permite modificar los metadatos. Los siguientes parámetros están disponibles para este propósito:
- pdfMetadataTitle: Título del documento PDF
- pdfMetadataSubject: Asunto del documento PDF
- pdfMetadataAuthor: Autor del documento PDF
- pdfMetadataKeywords: Palabras clave asociadas con el documento PDF
- pdfMetadataCreator: Aplicación creadora del documento PDF
- pdfMetadataProducer: Aplicación productora del documento PDF
- pdfMetadataCreationDate: Fecha de creación del documento PDF en formato ISO 8601 (por ejemplo, 2024–01–01 10:00:00)
- pdfMetadataModificationDate: Fecha de última modificación del documento PDF en formato ISO 8601 (por ejemplo, 2024–01–01 10:00:00)
// Optional: Modify PDF metadata
$postFields['pdfMetadataAuthor'] = 'AUTHOR'; // PDF author
$postFields['pdfMetadataKeywords'] = 'keywords,keyword2'; // PDF keywords
$postFields['pdfMetadataTitle'] = 'MY DOCUMENT'; // PDF title
$postFields['pdfMetadataSubject'] = 'EXAMPLE DOCUMENT'; // PDF subject
$postFields['pdfMetadataCreator'] = 'PDFSIGNIFY'; // PDF creator software
$postFields['pdfMetadataProducer'] = 'PDFSIGNIFY'; // PDF producer software
// Get current date and time for metadata
$currentDateTime = (new \DateTime())->format('Y-m-d H:i:s'); // Format as 'Y-m-d H:i:s'
// Assign creation and modification dates
$postFields['pdfMetadataCreationDate'] = $currentDateTime; // Creation date
$postFields['pdfMetadataModificationDate'] = $currentDateTime; // Modification date
IMPORTANTE: También puedes utilizar el endpoint /api/v1/set-pdf-metadata con los mismos parámetros para cambiar los metadatos del PDF sin necesidad de firmar el documento. Puedes encontrar más información aquí.
<?php
namespace App\Http\Controllers;
use CURLFile;
use Illuminate\Support\Facades\Storage;
class PDFSignController extends Controller
{
public function signPDF()
{
$certPath = Storage::path('certificate.pfx');
$pdfPath = Storage::path('filepdf.pdf');
$password = "password";
$signatureBackgroundImage = Storage::path('backgroundImage.png'); // Append the custom background image to the form data (optional)
//$signatureImage = Storage::path('signatureImage.png'); // Append the custom image near the signature (optional)
// Define the form data to send
$postFields = [
'certificate' => new CURLFile($certPath, 'application/x-pkcs12', 'certificate.pfx'),
'certificatePassword' => $password,
'pdf' => new CURLFile($pdfPath, 'application/pdf', 'filepdf.pdf'),
'signatureBackgroundImage' => new CURLFile($signatureBackgroundImage, 'image/png', 'logo.png'),
//'signatureImage' => new CURLFile($signatureImage, 'image/png', 'logo.png'),
];
// Customize signature appearance and position
$postFields['signaturePageAppearance'] = -1; // Page number for signature (-1 for all pages or specify an array of pages)
$postFields['timezone'] = 'UTC'; // Timezone for signature date and time
$postFields['signatureMessage'] = 'Digitally signed by the user'; // Reason/message for the signature
$postFields['signatureDateLabel'] = ''; // Label for the signature date (empty string for no label)
$postFields['signatureDateFormat'] = 'Y-m-d H:i:s'; // Format for the signature date
$postFields['signatureHeight'] = 100; // Signature height in pixels
$postFields['signatureWidth'] = 150; // Signature width in pixels
$postFields['signatureYPosition'] = 100; // Y position of the signature relative to the bottom of the page
$postFields['signatureXPosition'] = 180; // X position of the signature relative to the left of the page
// Optional: Modify PDF metadata
$postFields['pdfMetadataAuthor'] = 'AUTHOR'; // PDF author
$postFields['pdfMetadataKeywords'] = 'keywords,keyword2'; // PDF keywords
$postFields['pdfMetadataTitle'] = 'MY DOCUMENT'; // PDF title
$postFields['pdfMetadataSubject'] = 'EXAMPLE DOCUMENT'; // PDF subject
$postFields['pdfMetadataCreator'] = 'PDFSIGNIFY'; // PDF creator software
$postFields['pdfMetadataProducer'] = 'PDFSIGNIFY'; // PDF producer software
// Get current date and time for metadata
$currentDateTime = (new \DateTime())->format('Y-m-d H:i:s'); // Format as 'Y-m-d H:i:s'
// Assign creation and modification dates
$postFields['pdfMetadataCreationDate'] = $currentDateTime; // Creation date
$postFields['pdfMetadataModificationDate'] = $currentDateTime; // Modification date
// Prepare the cURL request
$ch = curl_init();
// Set the URL for the PDF Signify API endpoint
curl_setopt($ch, CURLOPT_URL, 'https://api.pdfsignify.com/api/v1/sign-pdf');
// Set the cURL options
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Set the headers
$headers = [
'Content-Type: multipart/form-data',
'AccessKey: ' . "MY_ACCESS_KEY",
'SecretKey: ' . "MY_SECRET_KEY"
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
// Execute the request
$response = curl_exec($ch);
// Get the HTTP status code
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
// Close the cURL session
curl_close($ch);
// Check for errors if the response code is NOT OK
if ($statusCode != 200) {
return response()->json(['response' => $response], 500);
}
// Return the signed PDF as a response
return response($response, 200)
->header('Content-Type', 'application/pdf')
->header('Content-Disposition', 'attachment; filename="signed_filepdf.pdf"');
}
}
Paso 5: Verificar la validez del certificado y la coincidencia de la contraseña
PDF Signify también te permite verificar si un certificado es válido y si la contraseña coincide.
Para realizar esta comprobación, utiliza el endpoint /api/v1/check-certificate-password. Puedes encontrar más información aquí.
Este método solo utiliza dos parámetros: el certificado (certificate), como se utilizó anteriormente, y la contraseña del certificado (certificatePassword).
Puedes usar el siguiente ejemplo agregando el endpoint /check-certificate en el archivo routes/web.php:
Route::get('/check-certificate', [PDFSignController::class, 'checkCertificate'])->name('check.certificate');
Y agregar la función checkCertificate en el archivo PDFSignController.php:
public function checkCertificate(){
$certPath = Storage::path('certificate.pfx');
$password = "password";
$postFields = [
'certificate' => new CURLFile($certPath, 'application/x-pkcs12', 'certificate.pfx'),
'certificatePassword' => $password,
];
$ch = curl_init();
// Establecer la URL para el endpoint de la API de PDF Signify
curl_setopt($ch, CURLOPT_URL, 'https://api.pdfsignify.com/api/v1/check-certificate-password');
// Establecer las opciones de cURL
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Establecer los encabezados
$headers = [
'Content-Type: multipart/form-data',
'AccessKey: ' . "MI_CLAVE_DE_ACCESO",
'SecretKey: ' . "MI_CLAVE_SECRETA"
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
// Ejecutar la solicitud
$response = curl_exec($ch);
return response()->json(['response' => $response]);
}
En este caso, la respuesta estará en formato application/json y puede indicar éxito de la siguiente manera:
{"success":true,"message":"¡La contraseña del certificado es correcta!","errors":[],"data":{},"auth":true}
Alternativamente, la respuesta puede indicar que el certificado o la contraseña no son válidos, como se muestra a continuación:
{"success":false,"message":"¡La contraseña del certificado no es correcta!","errors":["certificatePassword"],"data":{},"auth":true}
Parte 7: Conclusiones
En conclusión, hemos explorado un ejemplo completo de cómo firmar PDFs utilizando Laravel, Simphony o PHP, y la aplicación PDF Signify. Hemos visto cómo este servicio puede ayudar a firmar cualquier documento PDF, establecer metadatos de PDF o verificar un certificado con facilidad, y puede integrarse con diversas tecnologías.
Para obtener más información, puedes visitar los siguientes recursos:
- Documentación de la API: https://api.pdfsignify.com/api/documentation#/
- Ejemplos: https://pdfsignify.com/#examples
- Sitio web: https://pdfsignify.com/
Si tienes más preguntas, puedes contactar al soporte de PDF Signify por correo electrónico.