Partage
  • Partager sur Facebook
  • Partager sur Twitter

Utulisation de l'API Yousing avec Symfony

    27 avril 2024 à 18:08:13

    Bonjour à tous, je voudrai utiliser l'api yousing sur Synfony. Pour cela je me suis aider de la doc de Yousing et du tuto de YoanDev qui est trés pédagogue.

    Voici les liens:


    https://developers.yousign.com/docs/symfony-new

    https://www.youtube.com/watch?v=k9ZA8BoNFik

    Mais l'ai donc une erreur de 404 pour l'envoie des mes infos à Yousing!

    No routes found for "/api_public/v3/signature_requests/1/documents".

    Cette route doit être pourtant générer dans mes paramètres.

    Donc j'ai générer ma clef api que j'ai mis sur mon .env

    Le http_client.yaml, qui est fourni par la doc yousing:

    framework:
      http_client:
        scoped_clients:
          yousign.client:
            base_uri: 'https://api-sandbox.yousign.app/v3/'
            headers:
              Accept: 'application/json'
              Authorization: 'Bearer %env(YOUSIGN_SANDBOX_API_KEY)%'


    Je pense que le probleme vient du yaml, pourtant il faut juste faire un copier coller. La route https://api-sandbox.yousign.app/v3/ ce transforme en /api_public/.

    Ma bibliothèque Yousing :

    <?php
    
    namespace App\Controller\YousignService;
    
    use Symfony\Contracts\HttpClient\HttpClientInterface;
    use Symfony\Component\Mime\Part\DataPart;
    
    use Symfony\Component\Mime\Part\Multipart\FormDataPart;
    
    class YousignService
    {
    
    
        // ">Addsigner
    
        public function __construct(
            private HttpClientInterface $yousignClient,
        ) {
        }
    
        public function createSignatureRequest(): array
        {
            $response = $this->yousignClient->request(
                'POST',
                'signature_requests',
                [
                    'body' => <<<JSON
                              {
                                "name": "The name of your Signature Request",
                                "delivery_mode": "none",
                                "timezone": "Europe/Paris"
                              }
                              JSON,
                    'headers' => [
                        'Content-Type' => 'application/json',
                    ],
                ]
            );
    
            $StatusCode =  $response->getStatusCode();
    
            if ($StatusCode != 201) {
                throw new Exception('Invalid strength passed ');
            }
    
            return $response->toArray();
        }
     
    
        public function addDocumentToSignatureRequest(string $signatureRequestId, string $filename,): string
        {
            // $signatureRequestId = 'c3fd4243-de20-48b3-849a-ca1012ed2b59';
     
            $homepage = file_get_contents('pdf/contract_teste.pdf');
    
            $signatureRequestId = '1';
     
    
            $formFields = [
                'nature' => 'signable_document',
                'file' => $homepage,
            ];
    
            $formData = new FormDataPart($formFields);
            $headers = $formData->getPreparedHeaders()->toArray();
    
            $response = $this->yousignClient->request(
                'POST', 
                 sprintf('signature_requests/%s/documents', $signatureRequestId), 
                 [
                   'headers' => $headers,
                   'body' => $formData->bodyToIterable(),
                 ]
            );
    
       
            return $response->getContent();
        }
    
    
    
    
        public function addSignerToSignatureRequest(  $signatureRequestId, $documentId, $nom, $prenom, $email): string
        {
            
             
    
            $response = $this->yousignClient->request(
                'POST',
                sprintf('signature_requests/%s/signers', $signatureRequestId),
                [
                    'body' => <<<JSON
                               {
                                   "info":{
                                      "first_name": $nom,
                                      "last_name":$prenom,
                                      "email": $email,
                                      "locale":"fr"
                                   },
                                   "fields":[
                                      {
                                         "type":"signature",
                                         "document_id": $documentId,
                                         "page":1,
                                         "x":77,
                                         "y":581
                                      }
                                   ],
                                   "signature_level":"electronic_signature",
                                   "signature_authentication_mode":"no_otp"
                               }
                               JSON,
                    'headers' => [
                        'Content-Type' => 'application/json',
                    ],
                ]
            );
    
    
            $StatusCode =  $response->setStatusCode();
    
     
    
    
            if ($StatusCode != 201) {
                throw new Exception('Invalid strength passed ');
            }
    
            return $response->toArray();
        }
    
    
        public function activateSignatureRequest(string $signatureRequestId): string
        {
            //  $signatureRequestId = 'c3fd4243-de20-48b3-849a-ca1012ed2b59';
    
            $response = $this->yousignClient->request(
                'POST',
                sprintf('signature_requests/%s/activate', $signatureRequestId)
            );
    
            $StatusCode =  $response->setStatusCode();
    
            if ($StatusCode != 201) {
                throw new Exception('Invalid strength passed ');
            }
    
            return $response->toArray();
        }
    }
    

    et la fonction du contrôler pour l'envoie:

        #[Route('/signature/{id}', name: 'app_contracts_signature', methods: ['GET'])]
        public function signature(Contracts $contract, ManagerRegistry $doctrine, ContractsRepository $contractsRepository, YousignService $YousignService, $id): Response
        {
    
    
    
            $entityManager = $doctrine->getManager();
            // recuperation de 'id de l'annonce
           
            $userRepo = $entityManager->getRepository(Contracts::class);
            $id = $userRepo->findOneBy(["id" => $id]);
    
            // créaton de la demande de signature 
            $YousignServiceRequest = $YousignService->createSignatureRequest();
            $contract->SetSignatureId($YousignServiceRequest['id']);
            $contractsRepository->save($contract, true);
    
            
    
            // uplload du document 
            $UploadDocument = $YousignService->addDocumentToSignatureRequest(1,1);
     
            $contract->SetDocumentId($UploadDocument['id']);
            $contractsRepository->save($contract, true);
    
            $signatureRequestId = '067b25ba-cefc-4008-92eb-d35f16d70acb'; 
            
            // ajout des signataie
            $SignerId = $YousignService->addSignerToSignatureRequest(
                $signatureRequestId,
                $contract->GetSignatureId(),
                $contract->GetNom(),
                $contract->GetPrenom(),
                $contract->GetEmail(),
            );
            $contract->SetSignerId($SignerId['id']);
            $contractsRepository->save($contract, true);
    
    
            // envoie de la demande de signature 
            $YousignServiceRequest->activateSignatureRequest($contract->GetSignatureId());
    
    
    
            return $this->render('contracts/index.html.twig', [
                'contracts' => $contractsRepository->findAll(),
            ]);
        }
    
    
    
    

    Merci par avence!


    -
    Edité par Frédouze 28 avril 2024 à 0:23:37

    • Partager sur Facebook
    • Partager sur Twitter
      28 avril 2024 à 0:21:19

      Salut

      A mon sens, l'ID de demande de signature 1 n'est pas bon, je pense qu'il te faut enregistrer le retour de la demande de signature, il devrait y avoir un identifiant quelconque dedans, et je m'attendrais à ce qu'il ait la forme 89120884-d29a-4b1a-ac7b-a9e73a872795. Cette valeur est à enregistrer de ton côté et à utiliser à la place de l'ID interne à Symfony pour converser avec l'API — parce qu'autrement, il faut que tu saches à l'avance l'ID que tu vas avoir pour l'envoyer à l'API… cela ne fonctionne probablement pas ainsi.

      • Partager sur Facebook
      • Partager sur Twitter
        28 avril 2024 à 0:55:11

        Effectivement, j'ai remplacer l'id de synfony par un ide que yousing m'as générer, mais maintenant j'ai  l'erreur

        You have some invalid params in your payload.

        Ca à l'aire de venir d'une erreur 400. Mon formulaire est pas bon apparemment. 

        -
        Edité par Frédouze 28 avril 2024 à 1:01:14

        • Partager sur Facebook
        • Partager sur Twitter
          28 avril 2024 à 10:10:56

          Je note tout de même que les deux vidéos que tu suis datent d'environ un an, il faudrait pouvoir s'assurer que ce qu'elles montrent est encore à jour. Sinon, il faudra t'intéresser à la documentation technique de l'API afin de t'affranchir des codes fournis et ainsi créer le tien qui puisse être correct.

          Si j'en crois ladite documentation, tu devrais avoir des détails en plus de ce message général, non ? Qu'y est-il dit ?

          Si jamais, mettre des liens vers des vidéos de plus de 30 minutes et espérer qu'elles seront regardées pour comprendre ton problème, désolé mais c'est un peu illusoire en ce qui me concerne.

          • Partager sur Facebook
          • Partager sur Twitter
            28 avril 2024 à 23:43:41

            J'ai put régler mon problème de ma dernière intervention, l'erreur venait de la ligne 59 de la biblique yousingservice 

            j'ai donc remplacer

            $formFields = [
                        'nature' => 'signable_document',
                        'file' => $homepage,
                    ];
             

            par

             $formFields = [
                        'nature' => 'signable_document',
                        'file' => DataPart::fromPath($filePath, $fileName, 'application/pdf'),
                    ];

            mais je retombe sur l'erreur

            No routes found for "/api_public/v3/signature_requests/%22e8edc480-f3a1-4e9c-a8ca-2c7f0478e8a1%22/signers".

            je suis à la fonction  addSignerToSignatureRequest de la bibliothèque yousing, donc à l'avent dernière étape. L'id vient pourtant de  l'api yousing que j'ai du convertir en json.

             $signatureRequestId =  json_encode($signatureRequestId);



            J'ai mis la vidéo aussi pour ceux qui serait intéresser à utiliser yousing. 

            Cordialement. 


            • Partager sur Facebook
            • Partager sur Twitter
              29 avril 2024 à 10:18:41

              Tu sembles avoir enregistré les guillemets avec l'ID (les %22 que l'on voit dans ton URL en résultent), ce n'est pas nécessaire.

              • Partager sur Facebook
              • Partager sur Twitter
                29 avril 2024 à 15:36:14

                Oui, je sait mais cela vient de ma conversion json.

                $signatureRequestId =  json_encode($signatureRequestId);

                Si je ne fait pas cette transformation, j'ai une erreur comme quoi la réponse de la fonction addSignerToSignatureRequest n'est pas de type json.

                En faisant un écho de la variable $signatureRequestId l'id est bien entourer de guillemets.



                • Partager sur Facebook
                • Partager sur Twitter
                  29 avril 2024 à 16:43:02

                  Le truc, c'est que tu transformes en JSON une chaîne de caractères, ce qui n'est pas vraiment nécessaire et qui va justement ajouter des guillemets à la valeur alors que tu devrais pouvoir l'enregistrer et l'utiliser telle-quelle. L'erreur que tu mentionnes doit provenir d'autre chose, plus probablement que le retour de l'appel ne s'est pas bien passé, mais tu n'as pas d'erreur 404 qui viendrait si tu utilisais les guillemets.

                  -
                  Edité par Ymox 29 avril 2024 à 16:45:13

                  • Partager sur Facebook
                  • Partager sur Twitter
                    29 avril 2024 à 18:15:49

                    J'ai bien vu que c'est un problème, mais si j’enlève la conversion json , j'ai l'erreur  

                    Invalid json message received

                    -
                    Edité par Frédouze 29 avril 2024 à 18:37:53

                    • Partager sur Facebook
                    • Partager sur Twitter
                      30 avril 2024 à 8:54:43

                      Mais ce n'est plus un souci dans l'URL pour le coup (cela te retournerait une 404 comme précédemment), c'est un souci dans les données JSON que tu envoies. Je pense que c'est notamment dû au fait que plutôt que d'utiliser json_encode() sur des tableaux, tu construis le JSON sous forme de chaîne de caractères avec <<<JSON … JSON, et sous cette forme, il faut effectivement les guillemets autour de la valeur vu que c'est une chaîne. Soit tu changes la manière de générer le JSON, soit tu ajoutes à cet endroit les guillemets manquants.

                      • Partager sur Facebook
                      • Partager sur Twitter
                        30 avril 2024 à 16:41:24

                        Merci  de ton aide!

                        Je suis arriver  à la dernière dernière étape  de mon formulaire Yousin qui m'affiche l'erreur

                        Signature request "ffc822f2-5df8-461a-a4d9-73c3795660c1" does not have any recipient, thus it cannot be sent.

                        Je n'ai pas totalement configuré mon compte yousing bien que j'ai envoyer une adresse mail valide dans le formulaire. Mais je ne doit plus avoir de problème coté code.

                        Je met à disposition mon code

                        Ma bibliothèque YousingServices

                        <?php
                        
                        namespace App\Controller\YousignService;
                        
                        use Symfony\Contracts\HttpClient\HttpClientInterface;
                        use Symfony\Component\Mime\Part\DataPart;
                        
                        use Symfony\Component\Mime\Part\Multipart\FormDataPart;
                        
                        class YousignService
                        {
                        
                        
                            // ">Addsigner
                        
                            public function __construct(
                                private HttpClientInterface $yousignClient,
                            ) {
                            }
                        
                            public function createSignatureRequest()
                            {
                                $response = $this->yousignClient->request(
                                    'POST',
                                    'signature_requests',
                                    [
                                        'body' => <<<JSON
                                                  {
                                                    "name": "The name of your Signature Request",
                                                    "delivery_mode": "none",
                                                    "timezone": "Europe/Paris"
                                                  }
                                                  JSON,
                                        'headers' => [
                                            'Content-Type' => 'application/json',
                                        ],
                                    ]
                                );
                        
                                $StatusCode =  $response->getStatusCode();
                        
                                if ($StatusCode != 201) {
                                    throw new Exception('Invalid strength passed ');
                                }
                        
                                return $response->toArray();
                            }
                        
                        
                            public function addDocumentToSignatureRequest(string $signatureRequestId, string $filename,): string
                            {
                                // $signatureRequestId = 'c3fd4243-de20-48b3-849a-ca1012ed2b59';
                        
                        
                        
                                $homepage = file_get_contents('pdf/' . $filename);
                                $filePath = 'pdf/' . $filename;
                                $fileName = $filename;
                        
                                $formFields = [
                                    'nature' => 'signable_document',
                                    'file' => DataPart::fromPath($filePath, $fileName, 'application/pdf'),
                                ];
                        
                                $formData = new FormDataPart($formFields);
                                $headers = $formData->getPreparedHeaders()->toArray();
                        
                        
                        
                                $response = $this->yousignClient->request(
                                    'POST',
                                    sprintf('signature_requests/%s/documents', $signatureRequestId),
                                    [
                                        'headers' => $headers,
                                        'body' => $formData->bodyToIterable(),
                                    ]
                                );
                        
                        
                                return $response->getContent();
                            }
                        
                        
                            public function addSigner(
                                string $signatureRequestId,
                                string $documentId,
                                string $nom,
                                string $prenom,
                                string $email
                            ): string {
                        
                                $signatureRequestId =  json_encode($signatureRequestId);
                        
                                $curl = curl_init();
                        
                                $data = <<<JSON
                                {
                                  "info": {
                                    "first_name": "John",
                                    "last_name": "Doe",
                                    "email": $email,
                                    "phone_number": "+33700000000",
                                    "locale": "fr"
                                  },
                                  "signature_authentication_mode": "no_otp",
                                  "signature_level": "electronic_signature",
                                  "fields": [
                                    {
                                      "document_id": "{$documentId}",
                                      "type": "signature",
                                      "height": 37,
                                      "width": 85,
                                      "page": 1,
                                      "x": 0,
                                      "y": 0
                                    }
                                  ]
                                }
                                JSON;
                        
                                curl_setopt_array($curl, [
                                    CURLOPT_URL => sprintf('signature_requests/%s/signers', $signatureRequestId),
                                    CURLOPT_RETURNTRANSFER => true,
                                    CURLOPT_CUSTOMREQUEST => 'POST',
                                    CURLOPT_POSTFIELDS => $data,
                        
                                ]);
                        
                                return $data;
                            }
                        
                        
                            public function activateSignatureRequest(string $signatureRequestId): string
                            {
                        
                                $response = $this->yousignClient->request(
                                    'POST',
                                    sprintf('signature_requests/%s/activate', $signatureRequestId)
                                );
                        
                                $StatusCode =  $response->setStatusCode();
                        
                                if ($StatusCode != 201) {
                                    throw new Exception('Invalid strength passed ');
                                }
                        
                                return $response->toArray();
                            }
                        }
                        

                        Et la fonction du contrôleur qui execute la bibliothèque:

                            #[Route('/signature/{id}', name: 'app_contracts_signature', methods: ['GET'])]
                            public function signature(Contracts $contract, ManagerRegistry $doctrine, ContractsRepository $contractsRepository, YousignService $YousignService, $id): Response
                            {
                        
                        
                        
                                $entityManager = $doctrine->getManager();
                                // recuperation de 'id de l'annonce
                        
                                $userRepo = $entityManager->getRepository(Contracts::class);
                                $id = $userRepo->findOneBy(["id" => $id]);
                                $filename = $id->getPdf();
                        
                        
                                // créaton de la demande de signature 
                                $YousignServiceRequest = $YousignService->createSignatureRequest();
                                $contract->SetSignatureId($YousignServiceRequest['id']);
                        
                        
                                $userRepo = $entityManager->getRepository(Contracts::class);
                        
                        
                                $signatureRequestId = $YousignServiceRequest['id'];
                                $message = $userRepo->find($id);
                                $message->setSignatureId($signatureRequestId);
                                $entityManager->flush();
                        
                        
                        
                                // uplload du document 
                                $UploadDocument = $YousignService->addDocumentToSignatureRequest($signatureRequestId, $filename);
                        
                        
                        
                                // onextrait l'id de la rempnse. 
                                $pieces = explode('":"', $UploadDocument);
                        
                                $rest = substr($pieces[1], 0, -11);
                        
                        
                                $message = $userRepo->find($id);
                                $message->SetDocumentId($rest);
                                $entityManager->flush();
                        
                        
                        
                        
                                // ajout des signataie
                                $SignerId = $YousignService->addSigner(
                                    $signatureRequestId,
                                    $contract->GetSignatureId(),
                                    $contract->GetNom(),
                                    $contract->GetPrenom(),
                                    $contract->GetEmail(),
                                );
                        
                        
                                // envoie de la demande de signature  
                        
                                $YousignService = $YousignService->activateSignatureRequest($signatureRequestId);
                        
                        
                                return $this->render('contracts/index.html.twig', [
                                    'contracts' => $contractsRepository->findAll(),
                                ]);
                            }
                        
                        
                        
                        
                        




                        • Partager sur Facebook
                        • Partager sur Twitter
                          30 avril 2024 à 22:54:48

                          Je dirais que quand tu créés la demande de signature, tu dois aussi envoyer des adresses représentant ceux qui devront signer le document, A moins que l'erreur ne soit à cette étape, qui est la seconde ?

                          <php
                          // …
                          $signatureRequestId =  json_encode($signatureRequestId);
                          // …
                          "document_id": "{$signatureRequestId}",
                          // …

                          Pour moi, il y a encore un souci de guillemets en trop là, et si ça marche, à moi la peur de ce service "Yousing". SI je prends un exemple :

                          <php
                          // $signatureRequestId vaut pwet
                          $signatureRequestId =  json_encode($signatureRequestId);
                          // $signatureRequestId vaut maintenant "pwet"
                          $data = <<<JSON
                          // … 
                          "document_id": "{$signatureRequestId}",
                          // $data contient donc "document_id": ""pwet"",

                          -
                          Edité par Ymox 1 mai 2024 à 16:31:34

                          • Partager sur Facebook
                          • Partager sur Twitter
                            1 mai 2024 à 15:23:10

                            Yousing est français, comme Tousanticovid ou France travail, ce donc c'est forcement  sérieux! Bon je ne ferait pas de polémique .

                            Finalement j'ai enlever purement est simplement cette conversion Json,

                            $signatureRequestId =  json_encode($signatureRequestId);

                            J'ai la même erreur. J'ai inverser les variable  $signatureRequestId avec $documentId, j'ai l'erreur que le document est pas trouver! donc c'est normal. j'ai fait un écho de l'adresse mail, qui est la mienne dans la fonction addSigner elle apparait bien. J'ai enlever la fonction

                            activateSignatureRequest mais donc la il n'y aura pas d'activation du service. Aucune erreur. Je pense qu'il faut que je regarde la doc il y a peut-être une adresse mail à renseigner pour l’application. 

                            J'ai toujours l'erreur

                            Signature request "96a97858-5a96-4ebe-9ccf-29b2684a4d48" does not have any recipient, thus it cannot be sent.

                            • Partager sur Facebook
                            • Partager sur Twitter
                              1 mai 2024 à 16:30:45

                              En fait, l'erreur pourrait très bien venir du même genre de problème de guillemets, à savoir qu'avec la ligne "email": $email,, qui fait partie d'une chaîne de caractères déclarée avec la "syntaxe Heredoc", l'adresse est directement dans la chaîne, donc ce que reçoit le serveur est "email": tartempion@example.com, au lieu de "email": "tartempion@example.com",.

                              • Partager sur Facebook
                              • Partager sur Twitter
                                1 mai 2024 à 17:27:59

                                J'ai envoyer une demande à yousing pour leur expliquer le  problème. J'ai fait un écho du data le la fonction addSigner avec et sans guillemets ça ne change rien.

                                 J'ai fait aussi avec ma vrais adresse, avec une adresse sans @ afin de recevoir un message adresse non valide, j'ai toujours la même erreur. 


                                { "info": { "first_name": "John", "last_name": "Doe", "email": "tartempion@example.com", "phone_number": "+33700000000", "locale": "fr" }, "signature_authentication_mode": "no_otp", "signature_level": "electronic_signature", "fields": [ { "document_id": "83d1f39d-4e1a-4fb4-a47d-aa366158900e", "type": "signature", "height": 37, "width": 85, "page": 1, "x": 0, "y": 0 } ] }


                                { "info": { "first_name": "John", "last_name": "Doe", "email": tartempion@example.com, "phone_number": "+33700000000", "locale": "fr" }, "signature_authentication_mode": "no_otp", "signature_level": "electronic_signature", "fields": [ { "document_id": "803330df-61ff-473b-98df-e84bba7a1d0b", "type": "signature", "height": 37, "width": 85, "page": 1, "x": 0, "y": 0 } ] }

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  2 mai 2024 à 8:45:49

                                  De toute manière, la seconde version n'est pas du JSON valide.

                                  Est-ce que c'est là la demande de création de requête ? Du coup, est-ce qu'il ne manque pas une étape dans ton processus pour ajouter les informations sur ceux qui doivent signer le document ?

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    2 mai 2024 à 16:46:51

                                    J'ai suivi la doc de yousing et la vidéo de Yohandev. Dans la vidéo le fonction addSignerToSignatureRequest et devenu addSigner et elle m'a posé des difficulté. En mettant un écho, elle retourne bien le tableau. Si j’enlève la fonction activateSignatureRequest, qui est la dernière étape je n'ai pas d'erreur mais la validation du formulaire ne ce fait pas. J'ai envoyer un ticket à yousing j’attends leur réponse.
                                    • Partager sur Facebook
                                    • Partager sur Twitter

                                    Utulisation de l'API Yousing avec Symfony

                                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                    • Editeur
                                    • Markdown