Pro 에디션
NextPDF Pro 빠른 시작
한눈에 보기
섹션 제목: “한눈에 보기”NextPDF Pro 라이선스 봉투를 가지고 있습니다. 이 튜토리얼은 이를 네 개의
짧은 단계로 검증된 첫 결과물로 바꿉니다. 비공개 저장소에서 nextpdf/pro를
설치하고, 라이선스를 활성화하고, 런타임이 해석한 엔타이틀먼트를 확인한
다음, 템플릿 기반 PDF를 렌더링하고 서명합니다. 각 단계는 확인해야 할 출력을 보여줍니다.
이 기능은 NextPDF Pro(nextpdf/pro)에 포함되며 Pro 등급 라이선스
봉투로 활성화됩니다. 해당 엔타이틀먼트가 없는 배포 환경은 이 기능의 클래스를 로드하지 않습니다.
에디션 비교 및 라이선스 구매.
사전 준비 사항
섹션 제목: “사전 준비 사항”- PHP 8.4 및 Composer 2. 프리미엄 패키지는 PHP
>=8.4 <9.0을 필요로 합니다. - 비공개 저장소 자격 증명. 포털에서 저장소 URL, 사용자 이름, 토큰을 발급합니다. 설정은 설치 및 인증에서 다룹니다.
- 라이선스 봉투. app.getnextpdf.com의 계정에 로그인하여, 라이선스 계약에 서명한 다음, 배포 환경에 맞는 서명된 봉투를 다운로드하세요. API 키처럼 취급하세요.
- ionCube Loader(인코딩된 빌드 전용). Pro 체험판과 유료 ionCube 인코딩 Pro 빌드는 PHP 8.4용 Loader가 필요합니다 — ionCube 설정을 참조하세요.
1. 설치 및 활성화
섹션 제목: “1. 설치 및 활성화”Composer가 비공개 저장소를 가리키도록 하고, 인증한 다음, 패키지를 require합니다:
composer config repositories.nextpdf composer https://repo.example.com/nextpdfcomposer config --auth http-basic.repo.example.com your-username your-tokencomposer require nextpdf/pro:^3포털에서 받은 저장소 URL과 자격 증명으로 대체하세요. 세 가지
인증 방법(프로젝트 auth.json, COMPOSER_AUTH, 전역 auth)은 모두
설치 및 인증에 설명되어 있습니다.
다음으로, 배포 환경이 로드하는 위치에 서명된 라이선스 봉투를 배치하되 구성 규칙을 따르고, 통합 환경의 활성화 단계를 실행하세요 — 대부분의 프레임워크는 이를 콘솔 명령으로 노출합니다. 내부적으로 온라인 활성화는 라이선싱 인터페이스에 대한 하나의 호출입니다:
public function activate(string $licenseJws, string $deploymentId, ?string $machineFingerprintHash = null, ?string $expectedLicenseId = null, ?string $clientNonce = null): StatusResponse다음 상황에서 예외를 던지거나 실패합니다: 전송 실패, 200이 아닌 상태,
또는 잘못 제공된 nonce에서 NextPDF\Enterprise\Licensing\LicenseClientException,
그리고 서명된 상태 검증이 실패하면
NextPDF\Accelerator\Exception\SpectrumAuthenticationException.
ionCube 채널에서는 라이선스가 주기적으로 온라인 검증도 수행하며,
signed-source 채널은 로컬에서 검증합니다 —
두 가지 전달 채널을 참조하세요.
2. 엔타이틀먼트 검증
섹션 제목: “2. 엔타이틀먼트 검증”엔타이틀먼트 평가기 — 라이선스 결정의 단일 권위 — 에게 여러분의
봉투가 무엇으로 해석되었는지 물어보세요. $license는 통합 환경의
라이선싱 부트스트랩이 노출하는 검증된
NextPDF\Enterprise\Licensing\LicenseKey이며, null은 fail-closed
방식의 라이선스 없음 결과를 나타냅니다.
use NextPDF\Enterprise\Licensing\EntitlementEvaluator;
$result = (new EntitlementEvaluator())->evaluate($license);
printf("status: %s\n", $result->status->value);printf("edition: %s\n", $result->edition?->value ?? '(none)');printf("channel: %s\n", $result->channel->value);printf("branding: %s\n", $result->brandingMode->value);printf("runtime: %s\n", $result->runtimeAllowed ? 'allowed' : 'disabled');그 뒤에 있는 메서드(예외를 던지지 않습니다):
public function evaluate(?LicenseKey $license, ?DateTimeImmutable $now = null): EntitlementResult활성 유료 Pro 라이선스가 있으면 다음을 예상하세요:
status: activeedition: prochannel: paidbranding: noneruntime: allowed체험판이나 평가판 부여에서는 대신 channel: evaluation과
branding: evaluation을 예상하세요. 모든 Pro 기능은 여전히 실행되며,
렌더링된 출력에는 의도적으로 눈에 보이는 평가판 워터마크가 포함됩니다.
유료 라이선스는 코드 변경 없이 이를 제거합니다 —
체험 및 평가판 브랜딩을 참조하세요.
3. 첫 결과물
섹션 제목: “3. 첫 결과물”이제 재미있는 부분입니다: JSON 템플릿을 파싱하고, 타입을 인식하는
서식으로 데이터를 바인딩하고, 바인딩된 값을 렌더링한 다음, 문서에
서명합니다. 이것을 vendor/ 디렉터리 옆에 quickstart.php로
저장하고 php quickstart.php를 실행하세요.
PKCS#12 파일(signing-cert.p12) 형태의 서명 인증서가 필요하며, 이
튜토리얼에서는 자체 서명된 인증서로도 괜찮습니다. 프로덕션 서명에는
적절히 보호된 개인 키, 실제 인증서 체인, 그리고 수신자가 수락하는 신뢰 정책이 필요합니다 — 자체 서명된 서명은 신뢰된 수신자 워크플로에 적합하지 않습니다.
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;use NextPDF\Pro\Template\TemplateDataBinder;use NextPDF\Pro\Template\TemplateParser;use NextPDF\Security\Signature\CertificateInfo;use NextPDF\Security\Signature\SignatureLevel;
// Parse a JSON template: one A4 page, three positioned placeholders.$template = (new TemplateParser())->parse(<<<'JSON'{ "name": "welcome-letter", "pageSize": "A4", "orientation": "P", "placeholders": [ {"name": "customer", "type": "text", "x": 25, "y": 60, "width": 160, "height": 10}, {"name": "issued", "type": "date", "x": 25, "y": 72, "width": 80, "height": 10}, {"name": "total", "type": "currency", "x": 25, "y": 84, "width": 80, "height": 10, "format": "EUR "} ]}JSON);
// Bind data. Keys match placeholder names case-insensitively.$binding = (new TemplateDataBinder())->bind($template, [ 'customer' => 'Aurora Paper Co.', 'issued' => '2026-07-03', 'total' => 1249.5,]);
printf( "Bound %d of %d placeholders (%d missing, %d warnings)\n", $binding->count(), count($template->placeholders), count($binding->missingFields), count($binding->warnings),);
// Render the bound values with the Core document API.$doc = Document::createStandalone();$doc->setTitle('Welcome letter');$doc->addPage();$doc->setFont('helvetica', '', 12);
foreach ($binding->bindings as $bound) { $doc->text($bound->placeholder->x, $bound->placeholder->y, $bound->formattedValue);}
// Apply a PAdES B-B baseline signature, then save once.$doc->setSignature( CertificateInfo::fromPkcs12(__DIR__ . '/signing-cert.p12', (string) getenv('NEXTPDF_P12_PASSWORD')), SignatureLevel::PAdES_B_B,);
$doc->save(__DIR__ . '/welcome-letter-signed.pdf');
echo "Created: welcome-letter-signed.pdf\n";예상 출력:
Bound 3 of 3 placeholders (0 missing, 0 warnings)Created: welcome-letter-signed.pdfPDF 리더에서 welcome-letter-signed.pdf를 여세요: 세 개의 바인딩된
값이 템플릿 위치에 나타나고(issued는 Y-m-d로 서식 지정되고, total은
EUR 1,249.50으로), 리더의 서명 패널에 하나의 서명이 표시됩니다. 방출된
구조는 PAdES 베이스라인 B-B 프로필을 따릅니다. NextPDF는 이를 인증이
아니라 기능으로 문서화합니다 — 범위와 준수 태세는
PAdES 레벨 페이지에 있습니다. 템플릿 JSON이
잘못된 형식이면, TemplateParser::parse()는 Template validation failed:
접두사가 붙은 메시지와 함께 InvalidArgumentException을 던집니다.
방금 사용한 핵심 시그니처, 그대로:
public function parse(string $json): TemplateDefinitionpublic function bind(TemplateDefinition $template, array $data): BindingResultpublic static function fromPkcs12(string $p12Path, #[SensitiveParameter] string $password = ''): selfpublic function setSignature(CertificateInfo $certInfo, SignatureLevel $level = SignatureLevel::PAdES_B_B, ?TsaClient $tsaClient = null, ?ClientInterface $httpClient = null): staticpublic function save(string $path): void다음 상황에서 예외를 던지거나 실패합니다: parse() — JSON이
유효하지 않거나 예상 구조에 맞지 않을 때 InvalidArgumentException;
fromPkcs12() — 파일을 읽거나 파싱할 수 없을 때
NextPDF\Exception\SignatureException; setSignature() — 선형화가
이미 활성화되어 있을 때 NextPDF\Exception\InvalidConfigException(PAdES와
Fast Web View는 상호 배타적입니다); save() — 파일을 쓸 수 없을 때
NextPDF\Exception\InvalidConfigException,
NextPDF\Exception\PageLayoutException, 또는
NextPDF\Exception\CompressionException.
bind()는 예외를 던지지 않고, 대신 missingFields와 warnings를 보고합니다.
4. 무언가 실패할 때
섹션 제목: “4. 무언가 실패할 때”Composer가 nextpdf/pro를 찾거나 가져올 수 없음
섹션 제목: “Composer가 nextpdf/pro를 찾거나 가져올 수 없음”composer require 도중의 401/403, 또는 “could not be found”는
비공개 저장소 또는 그 자격 증명이 이 프로젝트에 대해 구성되지 않았음을
의미합니다. auth.json의 호스트 키는 저장소 URL의 호스트와 정확히
일치해야 합니다. 설치 및 인증을
따라 진행하세요.
런타임이 라이선스 없음을 보고함
섹션 제목: “런타임이 라이선스 없음을 보고함”2단계는 status: no_license, runtime: disabled, 그리고 평가기의
경고를 출력합니다 — 원시 프리미엄 런타임 메시지(두 에디션이 공유)는
다음과 같습니다: No license configured. Enterprise runtime is disabled. Install a license or purchase one at https://nextpdf.dev/pricing. 프리미엄 기능은
검증된 봉투 없이는 fail closed됩니다. 존재하지만 손상된 봉투 파일은
결코 없는 것으로 취급되지 않습니다 — 이는
License file is present but unreadable: ... 또는 License file is present but empty: ...와 같은 메시지와 함께
NextPDF\Enterprise\Licensing\Storage\LicenseStorageException을
발생시킵니다. 구성된 경로에 봉투를 배치하고 PHP 프로세스 사용자가
읽을 수 있도록 만드세요.
서명 인증서가 로드되지 않음
섹션 제목: “서명 인증서가 로드되지 않음”CertificateInfo::fromPkcs12()는 .p12 파일을 읽거나 파싱할 수 없을
때 NextPDF\Exception\SignatureException을 던집니다. 일반적인 원인은
잘못된 경로, 잘못된 비밀번호(NEXTPDF_P12_PASSWORD 확인), 또는 실제로
PKCS#12가 아닌 파일입니다.
openssl pkcs12 -info -in signing-cert.p12 -noout으로 검증하세요.
다음으로 갈 곳
섹션 제목: “다음으로 갈 곳”- Template — 전체 템플릿 정의 및 바인딩 레퍼런스.
- PAdES B-B로 PDF에 서명한 다음 PAdES B-T로 확장 — 서명에 RFC 3161 타임스탬프를 추가합니다.
- NextPDF Pro 기능 — Pro 라이선스에 포함된 모든 것.
- 두 가지 전달 채널 — ionCube 온라인 리스 대 완전 오프라인 signed source.
- 체험 및 평가판 브랜딩 — 평가판 워터마크가 어떻게 보이는지와 유료 라이선스가 이를 제거하는 방법.