PHPackages                             paulo-hortelan/signum - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. paulo-hortelan/signum

ActiveLibrary

paulo-hortelan/signum
=====================

This is my package signum

v1.1.0(2mo ago)18MITPHP ^8.1

Since Oct 14Compare

[ Source](https://github.com/paulo-hortelan/signum)[ Packagist](https://packagist.org/packages/paulo-hortelan/signum)[ Docs](https://github.com/paulo-hortelan/signum)[ GitHub Sponsors](https://github.com/paulo-hortelan)[ RSS](/packages/paulo-hortelan-signum/feed)WikiDiscussions Synced 3w ago

READMEChangelog (2)Dependencies (15)Versions (6)Used By (0)

Signum
======

[](#signum)

[![Latest Version on Packagist](https://camo.githubusercontent.com/1dcbef9fdb315c5032d6e57cefb1fd5990565bcde8e92ed1b65cfec52d304d59/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7061756c6f2d686f7274656c616e2f7369676e756d2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/paulo-hortelan/signum)[![Tests](https://camo.githubusercontent.com/3306714edf690d4f6dc732b482428f756836bcea4041fb88065212ff34c23b8e/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f7061756c6f2d686f7274656c616e2f7369676e756d2f72756e2d74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/paulo-hortelan/signum/actions?query=workflow%3Arun-tests+branch%3Amain)[![Code Style](https://camo.githubusercontent.com/01cb699c8b1df97db78b2dbc50a53135edc76eb99912925f2309e127b799e5fc/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f7061756c6f2d686f7274656c616e2f7369676e756d2f6669782d7068702d636f64652d7374796c652d6973737565732e796d6c3f6272616e63683d6d61696e266c6162656c3d636f64652532307374796c65267374796c653d666c61742d737175617265)](https://github.com/paulo-hortelan/signum/actions?query=workflow%3A%22Fix+PHP+code+style+issues%22+branch%3Amain)[![Total Downloads](https://camo.githubusercontent.com/7c59c9a190678395564c3d7f8b1bd76ceb92d8e5bcd5c1210f2f94f8ec3aa5b0/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f7061756c6f2d686f7274656c616e2f7369676e756d2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/paulo-hortelan/signum)

Signum is a Laravel package to generate, sign, display, download, and validate course certificates.

It includes:

- digital signature support with RSA private/public keys
- certificate preview and PDF download routes
- browser-friendly validation page and JSON API validation response
- multi-page certificate support (course content appendices)
- i18n support (`en` and `pt_BR`)
- signature rendering as either text or image

Requirements
------------

[](#requirements)

- PHP `^8.1`
- Laravel `10`, `11`, or `12`

Installation
------------

[](#installation)

```
composer require paulo-hortelan/signum
```

Publish package files:

```
php artisan vendor:publish --tag=signum-config
php artisan vendor:publish --tag=signum-views
php artisan vendor:publish --tag=signum-translations
php artisan vendor:publish --tag=signum-assets
php artisan vendor:publish --tag=signum-migrations
```

Run migrations:

```
php artisan migrate
```

Quick Start
-----------

[](#quick-start)

### 1) Configure keys

[](#1-configure-keys)

Generate keys:

```
openssl genpkey -algorithm RSA -out private.pem -pkeyopt rsa_keygen_bits:2048
openssl rsa -pubout -in private.pem -out public.pem
```

Set `.env`:

```
SIGNUM_PRIVATE_KEY_PATH=/absolute/path/private.pem
SIGNUM_PUBLIC_KEY_PATH=/absolute/path/public.pem
SIGNUM_VALIDATION_URL=https://your-domain.com/signum/certificates/validate
```

Docker note:

- Paths must exist inside the container (for example `/run/secrets/signum_private.pem`).
- The PHP process user inside the container must have read permission.
- If mounting key files is inconvenient, you can provide inline keys with `SIGNUM_PRIVATE_KEY` and `SIGNUM_PUBLIC_KEY`.

### 2) Generate a certificate

[](#2-generate-a-certificate)

```
use PauloHortelan\Signum\Facades\Signum;

$certificate = Signum::generateCertificate([
    'recipient_name' => 'Jane Doe',
    'course_name' => 'Advanced Laravel',
    'locale' => 'en',
    'meta' => [
        'content_sections' => [
            [
                'title' => 'Module 1 - Fundamentals',
                'items' => ['Service Container', 'Events', 'Queues'],
            ],
            [
                'title' => 'Module 2 - Delivery',
                'items' => ['Testing', 'CI/CD'],
            ],
        ],
    ],
    'signature_display' => [
        'type' => 'text',
        'text' => 'Jane Instructor',
    ],
]);
```

### 3) Access routes

[](#3-access-routes)

By default:

- `GET /signum/certificates/{code}`
- `GET /signum/certificates/{code}/download`
- `GET /signum/certificates/validate?code={code}`

Development-only route (enabled in `local`/`testing` by default):

- `GET /signum/certificates/demo`

Production recommendation:

```
SIGNUM_DEMO_ROUTE_ENABLED=false
```

Validation Endpoint (Web + API)
-------------------------------

[](#validation-endpoint-web--api)

The same endpoint supports both browser and API consumers:

- `Accept: text/html` -&gt; renders a styled validation page
- `Accept: application/json` -&gt; returns JSON

Example:

```
curl -H "Accept: application/json" \
  "https://your-domain.com/signum/certificates/validate?code=01H..."
```

Signature Display Options
-------------------------

[](#signature-display-options)

Text signature:

```
'signature_display' => [
    'type' => 'text',
    'text' => 'Jane Instructor',
]
```

Uploaded image signature:

```
'signature_display' => [
    'type' => 'image',
    'image_upload' => $request->file('signature'),
]
```

Pre-existing image path:

```
'signature_display' => [
    'type' => 'image',
    'image_path' => storage_path('app/public/signatures/director.png'),
]
```

Localization
------------

[](#localization)

Supported locales:

- `en` (default)
- `pt_BR`

You can set locale per certificate (`locale` field) or globally (`SIGNUM_DEFAULT_LOCALE`).

Customization Guide
-------------------

[](#customization-guide)

After publishing files, you can customize:

- `config/signum.php`: route prefix, default locale, validation URL, storage disk, default views
- `resources/views/vendor/signum/certificate.blade.php`: certificate and appendix layout
- `resources/views/vendor/signum/validation.blade.php`: browser validation page layout
- `lang/vendor/signum/{locale}/signum.php`: labels and copy
- `public/vendor/signum/images/*`: logo/background/signature assets

Useful config entries:

- `certificate.view`
- `certificate.pdf_view`
- `certificate.validation_view`
- `certificate.layout.print_width`
- `certificate.layout.print_height`
- `certificate.images`
- `certificate.text_overrides`
- `certificate.custom_html`
- `certificate.signature_upload`
- `demo_route_enabled`

Local Package Development
-------------------------

[](#local-package-development)

This repository is a package (no root `artisan`).

Run local testbench server:

```
composer run serve
```

List package routes:

```
composer run routes
```

Quality Checks
--------------

[](#quality-checks)

```
composer test
php vendor/bin/pint --test
php vendor/bin/phpstan analyse
```

Changelog
---------

[](#changelog)

See [CHANGELOG.md](CHANGELOG.md).

License
-------

[](#license)

MIT. See [LICENSE.md](LICENSE.md).

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance85

Actively maintained with recent releases

Popularity8

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity49

Maturing project, gaining track record

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1 days

Total

2

Last Release

79d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/135706260?v=4)[Paulo Hortelan Ribeiro](/maintainers/paulo-hortelan)[@paulo-hortelan](https://github.com/paulo-hortelan)

---

Tags

laravelPaulo Hortelansignum

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/paulo-hortelan-signum/health.svg)

```
[![Health](https://phpackages.com/badges/paulo-hortelan-signum/health.svg)](https://phpackages.com/packages/paulo-hortelan-signum)
```

###  Alternatives

[spatie/laravel-pdf

Create PDFs in Laravel apps

1.0k4.8M48](/packages/spatie-laravel-pdf)[rawilk/profile-filament-plugin

Profile &amp; MFA starter kit for filament.

3914.8k](/packages/rawilk-profile-filament-plugin)[harris21/laravel-fuse

Circuit breaker for Laravel queue jobs. Protect your workers from cascading failures.

45955.7k](/packages/harris21-laravel-fuse)[vormkracht10/laravel-mails

Laravel Mails can collect everything you might want to track about the mails that has been sent by your Laravel app.

24957.5k](/packages/vormkracht10-laravel-mails)[lettermint/lettermint-laravel

Official Lettermint driver for Laravel

1190.2k1](/packages/lettermint-lettermint-laravel)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
