3단계로 나누어 프로그램에 전자 서명 추가
69898 단어 webdevapijavascripttutorial
오늘날 PDF를 프로그래밍 방식으로 사용하는 것은 고통스러운 일이다.이것은 크고 복잡한 규범으로 라이브러리 지원이 매우 나쁘다.전자 서명은 복잡성만 증가시킬 뿐이다.
Dell은 앞으로 이러한 PDF 프로세스를 완벽하게 제어하면서 제품 통합에 많은 노력을 기울일 것입니다.Dell의 전자 서명 API 엔드포인트는 이러한 비전의 중요한 구성 요소로서 PDF 문서를 프로그래밍 방식으로 작성한 다음 작성된 PDF를 올바른 당사자에게 전송하여 서명할 수 있습니다.
본 논문에서, 나는 당신에게 전자 서명을 응용 프로그램에 신속하게 집적하는 방법을 보여 드리겠습니다.
목표
우리는 신입 사원들이 검토하고 서명할 수 있도록 인적 자원 서류 한 꾸러미를 보낼 것이다.우리의 예는 당신이 신속하게 시작하고 운행할 수 있도록 다음과 같은 개념을 포함할 것이다.
예시가 자바스크립트/노드node-anvil client library에서 사용되지만 플랫폼마다 개념이 같다.
node-anvil
신분 검증과 GraphQL 요청을 추상화했지만 통합의 핵심은 GraphQL 변체에 전달되는 변수로 이 변체는 어떠한 플랫폼에서도 작동할 수 있다.HR 서명 패키지 예
예제 HR 패키지에는 PDF 2개, IRS 테이블 W-4 1개, NDA 1개가 포함됩니다.두 사람이 서류에 서명해야 한다.
W-4
W-4에 서명해야 하는 직원만 있습니다.Dell은 시스템에 이미 직원의 정보가 있다고 가정하므로 서명을 위해 PDF를 보내기 전에 미리 PDF를 작성하고자 합니다.
비밀 협정
인적 자원 대표와 직원들은 모두 비밀 협정에 서명해야 한다.또한 직원 이름과 이메일, 고용주 정보 및 계약 날짜와 같은 일부 정보를 NDA PDF에 미리 채워야 합니다.
서명 과정의 작업 원리
먼저 두 PDF가 포함된 서명 패키지를 만듭니다.작성 프로세스의 일부로 PDF를 직원 데이터로 미리 채운 다음 새 패키지를 보내서 서명하도록 하겠습니다.
간단하게 보기 위해서, 우리는 패키지 기본값을 사용할 것입니다.이러한 기본 설정을 사용하면 Anvil은 이메일을 통해 모든 서명 요청 알림을 관리합니다.
포괄적인 프로세스는 다음과 같습니다.
코드 개요
코드의 측면에서 볼 때 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
라는 변수 대상을 구축하고 이를 createEtchPacket
GraphQL 변형에 보낼 것이다.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.이 프레젠테이션 프로그램은 서명 과정을 이해하는 데 도움을 줄 수 있을 것입니다.그것은 많은 중요한 개념의 코드를 포함하는데, 특히 삽입식 서명자가 그렇다.그런 다음 다음 다음 에셋을 확인합니다.
Customize the signature page 색상과 로고가 포함되어 있습니다.
Encrypt data PDF를 작성할 때
Reference
이 문제에 관하여(3단계로 나누어 프로그램에 전자 서명 추가), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/useanvil/add-e-signatures-to-your-app-in-3-steps-62c텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)