Une librairie PHP pour utiliser les services de Universign
Tribune Glob'codeurGLOBALIS publie un kit d'utilisation de signature électronique sans dépendance à un framework
La signature électronique apporte une dimension juridique à un document électronique en fournissant des garanties en termes de valeur légale et d’authenticité des signataires. Ce mécanisme a beau avoir une dizaine d’années d’existence, elle reste aujourd’hui relativement méconnue du grand public mais aussi de la plupart des professionnels.
Il semble toutefois que le mouvement d’adoption massif est désormais initié et les procédures de signature en ligne se multiplient dans la plupart des secteurs.
Globalis est régulièrement sollicitée par ses clients pour la mise en place de procédures dématérialisées. Nous avons donc étudié le marché et rencontré la plupart des acteurs. Récemment, nous avons utilisé les services de la société Universign sur deux plateformes distinctes:
- Pour une assurance mutualiste, nous avons mis en place une procédure d’adhésion en ligne et un espace client. Le plateforme permet la signature des documents contractuels et le paiement en ligne.
- Pour un organisme collecteur du domaine culturel, nous avons conçu et développé un portail qui permet la déclaration et le règlement de cotisations.
Pourquoi avoir choisi Universign ? C’est le prestataire français qui combinait le mieux à la fois la simplicité d’intégration et le strict respect des aspects réglementaires eIDAS n°910/2014 du 23 juillet 2014.
Universign se distingue en particulier dans le secteur des assurances, des mutuelles, de l’épargne et de la gestion de patrimoine ou plus largement sur les domaines où la demande mise en place de souscription en ligne est forte. Ce prestataire de services de confiance annonce plus de 1 000 000 de signatures électroniques et 4 000 000 de jetons d'horodatage par mois. Ses clients ont pour nom AXA, MAIF, SWissLife, Financière de l'Echiquier, Alticemedia, Total, LesEchos, OuestFrance, Ingénico, etc.
Si nous avons beaucoup apprécié les services de cet acteur, nous avons regretté l'absence de librairies PHP, hors Symfony, permettant d’accélérer l’intégration de leurs API.
Le premier projet, que notre agence a développé avec WordPress, comme le second basé sur Puppet-Skilled (issu de CodeIgniter), ne pouvaientt utiliser directement la librairie Universign à disposition. Nous avons donc décidé d'implémenter une nouvelle qui couvre l'ensemble des fonctionnalités du service de signature fourni par Universign et sans aucune dépendance à un framework (framework-agnostic).
Après des journées de lecture de la documentation des spécifications techniques de la plateforme (elle fait tout même 30 pages), et un développement quant à lui à un peu plus long, nous sommes fiers de vous présenter notre librairie "globalis/universign-service". Vous pouvez l'installer en téléchargeant les sources ou via packagist:
composer require globalis/universign-service
Cette librairie permet d’interroger les services proposés par universign. Il est donc possible de faire de la signature électronique simple, un seul document à signer et une seule personne qui signe. Mais aussi des workflows plus complexes avec plusieurs signataires, plusieurs documents, des mandats de prélèvement SEPA… Il existe aussi plusieurs niveaux de signature électronique allant d’une confirmation via un code envoyé par sms ou mail, à une vérification complète de l’identité de la personne.
Avec globalis/universign-service:
L'intérêt principal de cette librairie est l’abstraction des appels aux services d'Universign. Elle construit l’ensemble de la requête XML-RPC que ce soit du typage des valeurs à l’envoi de la requête au service et retourne des wrappers qui décryptent automatiquement la réponse vers un format plus simple d’utilisation sous PHP. Voici un exemple d’envoi de requête pour une électronique:
<?php
// Signataire
$signer = new GlobalisUniversignRequestTransactionSigner();
$signer
->setFirstname('Jean')
->setLastname('Dupond')
->setPhoneNum('0999999999')
->setEmailAddress('jean.dupond@example.com')
->setSuccessURL('https://www.universign.eu/fr/sign/success/')
->setCancelURL('https://www.universign.eu/fr/sign/cancel/')
->setFailURL('https://www.universign.eu/fr/sign/failed/');
// Signature field
$signatureField = new GlobalisUniversignRequestDocSignatureField();
$signatureField->setPage(1)
->setX(100)
->setY(200)
->setSignerIndex(0);
// Document à signer
$doc = new GlobalisUniversignRequestTransactionDocument();
$doc->setPath('doc/Template_2.pdf')
->setSignatureFields([$signatureField]);
// Requête
$request = new GlobalisUniversignRequestTransactionRequest();
$request->addDocument($doc)
->setSigners([$signer])
->setFinalDocRequesterSent(true)
->setDescription("Demonstration de la signature Universign")
->setLanguage('fr');
// XmlRpc Client
$client = new PhpXmlRpcClient('https://url.to.universign/ws/');
$client->setCredentials(
'UNIVERSIGN_USER',
'UNIVERSIGN_PASSWORD'
);
// Interrogation du service
$requester = new GlobalisUniversignRequester($client);
$response = $req->requestTransaction($request);
$signatureUrl = $response->url;
$transactionId = $response->id;
Avec une librairie de gestion du protocole XML-RPC :
<?php
// Signataire
$signer = new PhpXmlRpcValue("Jean", "string"),
"lastname" => new PhpXmlRpcValue("Dupond", "string"),
"phoneNum" => new PhpXmlRpcValue("0612345678", "string"),
"emailAddress" => new PhpXmlRpcValue("jean.dupond@free.fr", "string"),
"successURLs" => new PhpXmlRpcValue("https://www.universign.eu/fr/sign/success/", "string"),
"cancelURLs" => new PhpXmlRpcValue("https://www.universign.eu/fr/sign/cancel/", "string"),
"failURLs" => new PhpXmlRpcValue("https://www.universign.eu/fr/sign/failed/", "string"),
], "struct");
// Signature field
$signatureField = new PhpXmlRpcValue([
"page" => new PhpXmlRpcValue(1, "int"),
"x" => new PhpXmlRpcValue(100, "int"),
"y" => new PhpXmlRpcValue(200, "int"),
"signerIndex" => new PhpXmlRpcValue(0, "int"),
], "struct");
// Document à signer
$docPath = "doc/Template_1.pdf";
$docContent = file_get_contents($docPath);
$doc = new PhpXmlRpcValue([
"content" => new PhpXmlRpcValue($docContent, "base64"),
"name" => new PhpXmlRpcValue($docPath, "string"),
"signatureFields" => new PhpXmlRpcValue([$signatureField], "array")
], "struct");
// Requête
$request = new PhpXmlRpcValue(
"documents" => new PhpXmlRpcValue([$doc], "array"),
"signers" => new PhpXmlRpcValue([$signer], "array"),
"finalDocRequesterSent" => new PhpXmlRpcValue(true, "boolean"),
"description" => new PhpXmlRpcValue("Demonstration de la signature Universign", "string"),
"language" => new PhpXmlRpcValue("fr", "string"),
], "struct");
// XmlRpc Client
$client = new PhpXmlRpcClient('https://url.to.universign/ws/');
$client->setCredentials(
'UNIVERSIGN_USER',
'UNIVERSIGN_PASSWORD'
);
// Interrogation du service
$response = $client->send(new PhpXmlRpcRequest(
'requester.requestTransaction',
$request
);
$responeValue = $response->value();
$signatureUrl = $responseValue['url']->scalarVal();
$transactionId = $responseValue['id']->scalarVal();