3단계로 나누어 프로그램에 전자 서명 추가

인적자원, 보험, 판매, 헬스케어, 금융서비스 분야의 공통된 주제는 산적한 PDF다.만약 당신이 그 중 한 업계에서 제품을 생산하려고 한다면, 의심할 여지없이 PDF 파일을 처리하고 서명해야 한다.
오늘날 PDF를 프로그래밍 방식으로 사용하는 것은 고통스러운 일이다.이것은 크고 복잡한 규범으로 라이브러리 지원이 매우 나쁘다.전자 서명은 복잡성만 증가시킬 뿐이다.
Dell은 앞으로 이러한 PDF 프로세스를 완벽하게 제어하면서 제품 통합에 많은 노력을 기울일 것입니다.Dell의 전자 서명 API 엔드포인트는 이러한 비전의 중요한 구성 요소로서 PDF 문서를 프로그래밍 방식으로 작성한 다음 작성된 PDF를 올바른 당사자에게 전송하여 서명할 수 있습니다.
본 논문에서, 나는 당신에게 전자 서명을 응용 프로그램에 신속하게 집적하는 방법을 보여 드리겠습니다.

목표


우리는 신입 사원들이 검토하고 서명할 수 있도록 인적 자원 서류 한 꾸러미를 보낼 것이다.우리의 예는 당신이 신속하게 시작하고 운행할 수 있도록 다음과 같은 개념을 포함할 것이다.
  • 여러 서명자의 서명 요청
  • 여러 PDF에 서명 요청
  • 서명을 요청하기 전에 PDF
  • 를 데이터로 미리 채웁니다.
  • 템플릿 PDF
  • 사용
  • 원본 PDF를 업로드하고 필드를 지정합니다
  • .
    예시가 자바스크립트/노드node-anvil client library에서 사용되지만 플랫폼마다 개념이 같다.node-anvil 신분 검증과 GraphQL 요청을 추상화했지만 통합의 핵심은 GraphQL 변체에 전달되는 변수로 이 변체는 어떠한 플랫폼에서도 작동할 수 있다.

    HR 서명 패키지 예


    예제 HR 패키지에는 PDF 2개, IRS 테이블 W-4 1개, NDA 1개가 포함됩니다.두 사람이 서류에 서명해야 한다.
  • 신입사원(W-4&NDA)
  • 인적 자원 담당자(NDA만 해당).
  • W-4



    W-4에 서명해야 하는 직원만 있습니다.Dell은 시스템에 이미 직원의 정보가 있다고 가정하므로 서명을 위해 PDF를 보내기 전에 미리 PDF를 작성하고자 합니다.

    비밀 협정



    인적 자원 대표와 직원들은 모두 비밀 협정에 서명해야 한다.또한 직원 이름과 이메일, 고용주 정보 및 계약 날짜와 같은 일부 정보를 NDA PDF에 미리 채워야 합니다.

    서명 과정의 작업 원리


    먼저 두 PDF가 포함된 서명 패키지를 만듭니다.작성 프로세스의 일부로 PDF를 직원 데이터로 미리 채운 다음 새 패키지를 보내서 서명하도록 하겠습니다.
    간단하게 보기 위해서, 우리는 패키지 기본값을 사용할 것입니다.이러한 기본 설정을 사용하면 Anvil은 이메일을 통해 모든 서명 요청 알림을 관리합니다.
    포괄적인 프로세스는 다음과 같습니다.
  • 팀은 API
  • 를 통해 패킷을 생성합니다.
  • 직원들은 서류에 서명할 것을 요구하는 이메일을 받을 것이다.이 사람에게 이 두 서류에 서명을 요구할 것이다.
  • 직원이 서류를 검토하고 서명하면 인적자원 대표는 이메일 한 통을 받아 서명한다.인적자원 대표는 이 두 서류를 보았지만 비밀 협정에 서명할 것을 요구받았다.
  • 인적 자원 담당자가 서명할 때 귀하의 팀은 모든 사람이 서명하고 절차가 완료되었음을 표시하는 이메일을 받을 것입니다.
  • 테스트 e-sign demo app를 통해 서명 과정을 신속하게 이해할 수 있습니다.

    코드 개요


    코드의 측면에서 볼 때 GraphQL 변이createEtchPacket를 사용하여 데이터 패키지를 만들고 문서를 미리 채우고 서명한 데이터 패키지를 보낼 것입니다.
    Anvil이 서명자 알림을 처리하기 때문에 변이 호출을 만들고 보내기만 하면 됩니다.대략적인 윤곽은 아래와 같다.
    import Anvil from '@anvilco/anvil'
    const apiKey = 'YOUR API KEY'
    const anvilClient = new Anvil({ apiKey })
    const packetVariables = {
      // Specify the files, signers, and data to fill the
      // PDFs here. The rest of this tutorial is dedicated to
      // fleshing these variables out!
    }
    const { data: result } = await anvilClient.createEtchPacket({
      variables: packetVariables
    })
    const { data, errors } = result
    
    // Provided there are no errors, the employee will have
    // been sent an email to sign their part
    console.log('Result', errors || data.createEtchPacket)
    
    // Your new EtchPacket ✨
    // {
    //   eid: 'Rb26TSuj5OxLfymG8tYv',
    //   name: 'HR Documents - Sally Employee',
    //   detailsURL: 'https://app.useanvil.com/org/your-org/etch/Rb26TSuj5OxLfymG8tYv',
    //   documentGroup: {
    //     eid: 'xXna1BmEFwBc32A3sGTe',
    //     status: 'sent',
    //     files: [ ... ],
    //     signers: [ ... ]
    //   }
    // }
    
    하면, 만약, 만약...박사님, 이 글에서 example script와 모든 코드를 보세요.

    시작하기 전: Anvil에 인증


    우선, signing up 이전에 계정의 API 키를 받아야 합니다.
    로그인하면 조직의 API 설정 페이지에서 API 키를 복사하라는 메시지가 표시됩니다.

    개발 키와 생산 키 사이에 약간의 차이가 있습니다.개발 키에 대한 호출은 항상 무료이지만, 생산 키보다 속도 제한이 엄격하고 PDF에 워터마크가 있습니다.
    이 강좌의 목적에서 개발 키를 복사하십시오.
    프로그램이 실행될 준비가 되었을 때, 생산 키로 전환하십시오.
    이 안내서에서, 우리는node anvil 클라이언트를 사용하지만, 원하는 플랫폼을 사용할 수 있습니다.인증에 대한 자세한 내용은 the docs를 참조하십시오.
    설치node-anvil 클라이언트:
    yarn add @anvilco/anvil
    # or
    npm install @anvilco/anvil
    
    그런 다음 가져오고 클라이언트 인스턴스를 만듭니다.
    import Anvil from '@anvilco/anvil'
    
    // The API key from your Anvil organization settings
    const apiKey = '7j2JuUWmN4fGjBxsCltWaybHOEy3UEtt'
    
    const anvilClient = new Anvil({ apiKey })
    

    1단계: 패키지 상세 정보 구성


    다음 세 단계에서 우리는 packetVariables라는 변수 대상을 구축하고 이를 createEtchPacketGraphQL 변형에 보낼 것이다.packetVariables의 첫 번째 변수는 패키지 자체를 설정합니다.패키지 설정의 다른 부분에서 다시 사용할 수 있도록 서명자의 이름과 전자메일을 정의할 것입니다.
    const employeeName = 'Sally Employee'
    const employeeEmail = '[email protected]'
    
    const employerName = 'Bill AcmeManager'
    const employerEmail = '[email protected]'
    
    const packetVariables = {
      // Indicate the packet is all ready to send to the
      // signers. An email will be sent to the first signer.
      isDraft: false,
    
      // Test packets will use development signatures and
      // not count toward your billed packets.
      isTest: true,
    
      // Specify the name of this packet in your dashboard.
      name: `HR Documents - ${employeeName}`,
    
      // Subject & body of the emails to signers
      signatureEmailSubject: 'HR Documents',
      signatureEmailBody: 'Please sign these HR documents....',
    
      // Only the beginning!
      ...otherVariables
    }
    

    2단계: PDF 설정


    더욱이const W-4와 NDA를 모두 사용하도록 지정하고 데이터를 사용하여 미리 채웁니다.

    W-4 상세 정보


    IRS 테이블 W-4는 이미 템플릿화되어 있으므로 필요하지 않습니다.PDF 템플릿 ID와 미리 채워진 데이터를 패키지에 지정합니다.
    이 슬라이드의 목표는 서명 패키지에서 PDF 템플릿을 사용하고 채우는 방법을 보여주는 것입니다.PDF 템플릿을 사용하는 것은 서명 패키지에 PDF를 포함하는 가장 일반적인 방법입니다.packetVariables 속성에 사용할 템플릿을 지정하고 files 속성에 데이터를 추가합니다.
    const packetVariables = {
      ...otherPacketVariables,
    
      files: [
        {
          // Our ID we will use to reference and fill
          // it with data. It can be any string you want!
          id: 'templatePdfIrsW4',
    
          // The id to the ready-made W-4 template.  
          //
          // You can upload and templatize your own PDFs from
          // the Anvil UI, then use them in the same way as
          // this W-4.
          // Anyone on your team can build PDF templates!
          castEid: 'XnuTZKVZg1Mljsu999od',
        }
      ],
    
      data: {
        payloads: {
          // 'templatePdfIrsW4' is the file ID specified above
          templatePdfIrsW4: {
            data: {
              // This data will fill the PDF before it's sent
              // to any signers. IDs here were set up on each
              // field while templatizing the PDF.
              name: employeeName,
              ssn: '111223333',
              address: {
                street1: '123 Main St #234',
                city: 'San Francisco',
                state: 'CA',
                zip: '94106',
                country: 'US',
              },
              filingStatus: 'Joint',
              employerEin: '897654321',
              employerAddress: {
                street1: '555 Market St',
                city: 'San Francisco',
                state: 'CA',
                zip: '94103',
                country: 'US',
              }
            }
          }
        }
      }
    }
    

    NDA 상세 정보


    이제 두 번째 파일인 NDA를 추가합니다.이 설명서에서는 NDA를 업로드하고 서명 패키지를 작성할 때 필드 위치를 지정합니다.다음 코드 세그먼트는 PDF에서 각 필드의 위치만 지정하는 것처럼 보입니다.
    W-4에서 설명한 것처럼 모든 PDF를 템플릿화하고 포함할 수 있습니다.그러나 템플릿 PDF 외에도 일회성 또는 동적 PDF가 필요할 수 있습니다.
    test-pdf-nda.pdf를 다운로드하여 로컬에 저장합니다.
    요청에 다음 코드를 추가합니다.
    const ndaFile = Anvil.prepareGraphQLFile('path/to/test-pdf-nda.pdf')
    const packetVariables = {
      ...otherPacketVariables,
    
      files: [
        // The NDA is included in addition to the W-4
        ...otherFiles,
        {
          // This is a file we will upload and specify the
          // fields ourselves
          id: 'fileUploadNDA',
          title: 'Demo NDA',
          file: ndaFile,
          fields: [
            // Define where the all the fields are for the
            // fresh PDF upload
            {
              id: 'effectiveDate',
              type: 'date',
              rect: { x: 326, y: 92, height: 12, width: 112 },
              format: 'MM/DD/YYYY',
              pageNum: 0,
            },
            {
              id: 'disclosingPartyName',
              type: 'fullName',
              rect: { x: 215, y: 107, height: 12, width: 140 },
              pageNum: 0,
            },
            {
              id: 'disclosingPartyEmail',
              type: 'email',
              rect: { x: 360, y: 107, height: 12, width: 166 },
              pageNum: 0,
            },
            {
              id: 'recipientName',
              type: 'fullName',
              rect: { x: 223, y: 120, height: 12, width: 140 },
              pageNum: 0,
            },
            {
              id: 'recipientEmail',
              type: 'email',
              rect: { x: 367, y: 120, height: 12, width: 166 },
              pageNum: 0,
            },
            {
              id: 'purposeOfBusiness',
              type: 'shortText',
              rect: { x: 314, y: 155, height: 12, width: 229 },
              pageNum: 0,
            },
            {
              id: 'recipientSignatureName',
              type: 'fullName',
              rect: { x: 107, y: 374, height: 22, width: 157 },
              pageNum: 1,
            },
            {
              id: 'recipientSignature',
              type: 'signature',
              rect: { x: 270, y: 374, height: 22, width: 142 },
              pageNum: 1,
            },
            {
              id: 'recipientSignatureDate',
              type: 'signatureDate',
              rect: { x: 419, y: 374, height: 22, width: 80 },
              pageNum: 1,
            },
            {
              id: 'disclosingPartySignatureName',
              type: 'fullName',
              rect: { x: 107, y: 416, height: 22, width: 159 },
              pageNum: 1,
            },
            {
              id: 'disclosingPartySignature',
              type: 'signature',
              rect: { x: 272, y: 415, height: 22, width: 138 },
              pageNum: 1,
            },
            {
              id: 'disclosingPartySignatureDate',
              type: 'signatureDate',
              rect: { x: 418, y: 414, height: 22, width: 82 },
              pageNum: 1,
            },
          ],
        },
      ],
    
      data: {
        payloads: {
          // Data to fill the NDA is included in addition
          // to the W-4's data
          ...otherPayloads,
    
          fileUploadNDA: {
            fontSize: 8,
            textColor: '#0000CC',
            data: {
              // The IDs here match the fields we created in
              // the files[].fields array above
              effectiveDate: '2024-01-30',
              recipientName: employeeName,
              recipientSignatureName: employeeName,
              recipientEmail: employeeEmail,
    
              disclosingPartyName: 'Acme Co.',
              disclosingPartySignatureName: employerName,
              disclosingPartyEmail: employerEmail,
    
              purposeOfBusiness: 'DEMO!!',
            },
          },
        }
      }
    }
    

    3단계: 서명자 설정


    우리가 해야 할 마지막 일은 서명자를 설정하는 것이다.모든 서명자는 최소한 한 필드와 연결되어야 로그인할 수 있습니다 data.payloads.
    그들이 서명할 차례가 되면, 모든 서명자는 두 개의 PDF 문서를 볼 수 있지만, 그들이 지정한 서명 상자를 클릭하도록 안내될 뿐이다.
    const packetVariables = {
      ...otherPacketVariables,
    
      signers: [
        // Signers will sign in the order they are specified
        // in this array. e.g. `employer` will sign after
        // `employee` has finished signing
        {
          // `employee` is the first signer
          id: 'employee',
          name: employeeName,
          email: employeeEmail,
    
          // These fields will be presented when this signer
          // signs. The signer will need to click through
          // the signatures in the order of this array.
          //
          // Each field referenced here must be of type
          // `signature`, `signatureDate`, or `initial`. You
          // can see in the NDA config above we specified two
          // `signature` fields and two `signatureDate` fields.
          // Here, we link them up!
          fields: [
            {
              fileId: 'templatePdfIrsW4',
              fieldId: 'employeeSignature',
            },
            {
              fileId: 'templatePdfIrsW4',
              fieldId: 'employeeSignatureDate',
            },
            {
              // The file ID we specified in the NDA section
              fileId: 'fileUploadNDA',
    
              // We specified this field ID the NDA section
              fieldId: 'recipientSignature',
            },
            {
              fileId: 'fileUploadNDA',
              fieldId: 'recipientSignatureDate',
            },
          ],
        },
        {
          // `employer` is the 2nd signer.
          id: 'employer',
          name: employerName,
          email: employerEmail,
          fields: [
            // The employer only signs the NDA, so we only
            // specify fields on the NDA
            {
              fileId: 'fileUploadNDA',
              fieldId: 'disclosingPartySignature',
            },
            {
              fileId: 'fileUploadNDA',
              fieldId: 'disclosingPartySignatureDate',
            },
          ],
        },
      ],
    }
    

    지금 같이


    성공했어!본문의 모든 코드를 포함하는runningexample script을 보십시오.
    import Anvil from '@anvilco/anvil'
    const apiKey = 'YOUR API KEY'
    const employeeName = 'Sally Employee'
    const employeeEmail = '[email protected]'
    
    const employerName = 'Bill AcmeManager'
    const employerEmail = '[email protected]'
    
    async function main () {
      const anvilClient = new Anvil({ apiKey })
      const ndaFile = Anvil.prepareGraphQLFile('path/to/test-pdf-nda.pdf')
      const packetVariables = getPacketVariables(ndaFile)
      const { data: result } = await anvilClient.createEtchPacket({
        variables: packetVariables
      })
      const { data, errors } = result
      console.log(errors || data.createEtchPacket)
    }
    
    function getPacketVariables (ndaFile) {
      return {
        isDraft: false,
        isTest: true,
        name: `HR Docs - ${employeeName}`,
        signatureEmailSubject: 'HR Documents ok',
        signatureEmailBody: 'Please sign these HR documents....',
        files: [
          {
            id: 'templatePdfIrsW4',
            // The id to the ready-made W-4 template
            castEid: 'XnuTZKVZg1Mljsu999od',
          },
          {
            // This is a file we will upload and specify the
            // fields ourselves
            id: 'fileUploadNDA',
            title: 'Demo NDA',
            file: ndaFile, // The file to be uploaded
            fields: [
              {
                id: 'effectiveDate',
                type: 'date',
                rect: { x: 326, y: 92, height: 12, width: 112 },
                format: 'MM/DD/YYYY',
                pageNum: 0,
              },
              {
                id: 'disclosingPartyName',
                type: 'fullName',
                rect: { x: 215, y: 107, height: 12, width: 140 },
                pageNum: 0,
              },
              {
                id: 'disclosingPartyEmail',
                type: 'email',
                rect: { x: 360, y: 107, height: 12, width: 166 },
                pageNum: 0,
              },
              {
                id: 'recipientName',
                type: 'fullName',
                rect: { x: 223, y: 120, height: 12, width: 140 },
                pageNum: 0,
              },
              {
                id: 'recipientEmail',
                type: 'email',
                rect: { x: 367, y: 120, height: 12, width: 166 },
                pageNum: 0,
              },
              {
                id: 'purposeOfBusiness',
                type: 'shortText',
                rect: { x: 314, y: 155, height: 12, width: 229 },
                pageNum: 0,
              },
              {
                id: 'recipientSignatureName',
                type: 'fullName',
                rect: { x: 107, y: 374, height: 22, width: 157 },
                pageNum: 1,
              },
              {
                id: 'recipientSignature',
                type: 'signature',
                rect: { x: 270, y: 374, height: 22, width: 142 },
                pageNum: 1,
              },
              {
                id: 'recipientSignatureDate',
                type: 'signatureDate',
                rect: { x: 419, y: 374, height: 22, width: 80 },
                pageNum: 1,
              },
              {
                id: 'disclosingPartySignatureName',
                type: 'fullName',
                rect: { x: 107, y: 416, height: 22, width: 159 },
                pageNum: 1,
              },
              {
                id: 'disclosingPartySignature',
                type: 'signature',
                rect: { x: 272, y: 415, height: 22, width: 138 },
                pageNum: 1,
              },
              {
                id: 'disclosingPartySignatureDate',
                type: 'signatureDate',
                rect: { x: 418, y: 414, height: 22, width: 82 },
                pageNum: 1,
              },
            ],
          },
        ],
    
        data: {
          // This data will fill the PDF before it's sent to
          // any signers.
          // IDs here were set up on each field while
          // templatizing the PDF.
          payloads: {
            templatePdfIrsW4: {
              data: {
                name: employeeName,
                ssn: '111223333',
                filingStatus: 'Joint',
                address: {
                  street1: '123 Main St #234',
                  city: 'San Francisco',
                  state: 'CA',
                  zip: '94106',
                  country: 'US',
                },
                employerEin: '897654321',
                employerAddress: {
                  street1: '555 Market St',
                  city: 'San Francisco',
                  state: 'CA',
                  zip: '94103',
                  country: 'US',
                },
              },
            },
            fileUploadNDA: {
              fontSize: 8,
              textColor: '#0000CC',
              data: {
                effectiveDate: '2024-01-30',
                recipientName: employeeName,
                recipientSignatureName: employeeName,
                recipientEmail: employeeEmail,
    
                disclosingPartyName: 'Acme Co.',
                disclosingPartySignatureName: employerName,
                disclosingPartyEmail: employerEmail,
    
                purposeOfBusiness: 'DEMO!!',
              },
            },
          },
        },
    
        signers: [
          {
            id: 'employee',
            name: employeeName,
            email: employeeEmail,
            fields: [
              {
                fileId: 'templatePdfIrsW4',
                fieldId: 'employeeSignature',
              },
              {
                fileId: 'templatePdfIrsW4',
                fieldId: 'employeeSignatureDate',
              },
              {
                fileId: 'fileUploadNDA',
                fieldId: 'recipientSignature',
              },
              {
                fileId: 'fileUploadNDA',
                fieldId: 'recipientSignatureDate',
              },
            ],
          },
          {
            id: 'employer',
            name: employerName,
            email: employerEmail,
            fields: [
              {
                fileId: 'fileUploadNDA',
                fieldId: 'disclosingPartySignature',
              },
              {
                fileId: 'fileUploadNDA',
                fieldId: 'disclosingPartySignatureDate',
              },
            ],
          },
        ],
      }
    }
    
    function run (fn) {
      fn().then(() => {
        process.exit(0)
      }).catch((err) => {
        console.log(err.stack || err.message)
        process.exit(1)
      })
    }
    
    run(main)
    

    한층 더


    만약 당신이 응용 프로그램에 더욱 깊이 있는 전자 서명을 집적하고 있다면, 여기에 깊이 연구하는 데 도움을 줄 수 있는 자원이 있습니다.
    우선, 시험live e-sign demo app 및 보기demo app's code.이 프레젠테이션 프로그램은 서명 과정을 이해하는 데 도움을 줄 수 있을 것입니다.그것은 많은 중요한 개념의 코드를 포함하는데, 특히 삽입식 서명자가 그렇다.그런 다음 다음 다음 에셋을 확인합니다.
  • 보기Postman collection 빠른 테스트 아이디어.
  • 서명자와 webhook notifications가 서명할 때 통지를 받는다.
  • 사용 embedded signers 서명자 알림을 제어하고 서명 사용자 인터페이스를 응용 프로그램에 삽입합니다.

  • Customize the signature page 색상과 로고가 포함되어 있습니다.

  • Encrypt data PDF를 작성할 때
  • 보기createEtchPacket reference docs.
  • 도움이 필요하십니까?전화[email protected]로 문의하십시오.

    좋은 웹페이지 즐겨찾기