stability: Experimental
Generate GS1 Composite barcodes (CC-C carrier)
At a glance
Section titled “At a glance”Opt-in preview capability — default OFF. GS1 Composite support is an experimental, opt-in feature. The single shipped composite is CC-C (the full PDF417 carrier): Core registers the
barcode.gs1-composite-cc-ccapability and the Premium (nextpdf/pro) package gates the encoder behind it. With Core only, the capability is registered but its status isUnavailable, so nothing is emitted. CC-A and CC-B are not yet available: a request to encode either fails closed with a typed exception (UnsupportedBarcodeFeature).
A GS1 Composite symbol pairs a linear component (the primary item identifier) with a 2D composite component (extended data such as a batch or expiry). This recipe shows how the composite capability is registered and resolved, what Core provides, what Premium adds, and exactly where the support stops.
Install
Section titled “Install”composer require nextpdf/core:^3The CC-C composite encoder requires the Premium package:
composer require nextpdf/proConceptual overview
Section titled “Conceptual overview”NextPDF resolves a symbology through the capability registry, the same way the Barcode module resolves any encoder. One GS1 Composite capability is registered there:
barcode.gs1-composite-cc-cis registered inCapabilityRegistryin Core, under theProproduct tier. It is the full PDF417 carrier (ISO/IEC 15438) for the CC-C composite component. The Pro encoder routes the payload through the canonical core PDF417 encoder. The capability is registered always butAvailableonly when Premium is installed — with Core only its status isUnavailable, so it is registered yet inert (opt-in, default OFF).
No CC-A or CC-B capability is registered. A conformant CC-A/CC-B 2D component requires ISO/IEC 24723 Clause 5 base-928 high-level encodation plus a component-specific carrier, and this release does not implement that path, so advertising a CC-A/CC-B capability would name an encoder that cannot emit a decodable symbol.
Fail-closed boundary — what is not yet available
Section titled “Fail-closed boundary — what is not yet available”CC-A and CC-B are intentionally not shipped as usable symbologies:
- CC-A — a low-level base-928 radix primitive
(
Base928Converter, codewords only) and a Clause-5 binary-string builder exist internally, but the full ISO/IEC 24723 Clause 5 CC-A high-level encodation and the CC-A-specific carrier are not implemented, so no usable CC-A symbol is produced.CompositeComponentA::encode()always throws the typedUnsupportedBarcodeFeatureexception. - CC-B — the medium-capacity composite component is likewise not
implemented;
CompositeComponentB::encode()always throwsUnsupportedBarcodeFeature.
These fail closed: a request to encode either raises a typed exception rather than emitting a partial or wrong symbol. This is a deliberate scope line, not a defect.
The shipped CC-C path follows a codeword-golden discipline: its generated codewords are pinned against a golden and cross-checked with an independent decoder, so a CC-C codeword stream is verified, not merely produced. No end-to-end certification against the GS1 Composite standard is claimed.
API surface
Section titled “API surface”GS1 Composite symbols resolve through the capability registry rather than a new top-level facade method:
NextPDF\Support\CapabilityRegistry— the lookup that reports whetherbarcode.gs1-composite-cc-cisAvailablein the current edition. Useget('barcode.gs1-composite-cc-c')->statusfor the availability decision;has()only reports that the capability is registered (true even on Core-only installs), so it is not the availability gate.- The CC-C composite encoder is supplied by
nextpdf/proand registered behind the same encoder contract the Contracts / Barcode page documents. - There is no CC-A or CC-B encoder to call. The CC-A/CC-B component classes
fail closed on
encode().
Run composer docs:generate-api-php -- --module=Barcode for the generated
encoder table.
Code sample — Quick start
Section titled “Code sample — Quick start”Check that the CC-C carrier capability is available before you depend on it.
With Core only it is registered but Unavailable; with Premium installed it is
Available. Gate on the status, not on has() — has() is true on a Core-only
install too, because the capability is always registered.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Support\CapabilityRegistry;use NextPDF\Support\CapabilityStatus;
$registry = CapabilityRegistry::getInstance();
$capability = $registry->get('barcode.gs1-composite-cc-c');
if ($capability->status === CapabilityStatus::Available) { echo "CC-C composite carrier is available (Premium present)\n";} else { echo "CC-C composite carrier needs nextpdf/pro\n";}Code sample — Production
Section titled “Code sample — Production”Gate on the capability status, and treat the unavailable components explicitly. A faithful CC-C symbol or a clear refusal — never a wrong composite.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Support\CapabilityRegistry;use NextPDF\Support\CapabilityStatus;
final readonly class CompositeLabelService{ public function __construct(private CapabilityRegistry $registry) {}
/** * Assert that the only shipped GS1 Composite (CC-C) is available before use. * * The capability is opt-in and default-OFF: on a Core-only install it is * registered but its status is Unavailable, so check the status — not has(). */ public function assertCompositeAvailable(): void { $status = $this->registry->get('barcode.gs1-composite-cc-c')->status;
if ($status !== CapabilityStatus::Available) { // Core-only install. The CC-C encoder needs Premium. Fail fast with // a clear upgrade message rather than emitting a degraded symbol. throw new \RuntimeException( 'GS1 Composite CC-C requires nextpdf/pro.', ); } }
// CC-A and CC-B are NOT yet available. Their component classes fail closed: // calling encode() always throws NextPDF\Pro\Barcode\Gs1Composite\ // UnsupportedBarcodeFeature. There is no runnable CC-A/CC-B encode path — // CC-C is the only shipped GS1 Composite symbology. Do not call encode() on // CC-A/CC-B expecting a symbol. public function note(): string { return 'CC-A and CC-B are not available; use CC-C.'; }}Edge cases & gotchas
Section titled “Edge cases & gotchas”- CC-C needs Premium to be available, and it is default-OFF. Core registers
the capability under the
Protier; the encoder behind it ships innextpdf/pro. On a Core-only install the capability is registered but its status isUnavailable. Gate onget(...)->status, not onhas()—has()is true even on Core-only because the entry is always registered. - There is no usable CC-A encoder. A low-level base-928 radix primitive exists internally, but the full ISO/IEC 24723 Clause 5 CC-A high-level encodation and CC-A-specific carrier are not implemented, so no CC-A symbol is produced.
- CC-A and CC-B fail closed. Their
encode()always throws the typedUnsupportedBarcodeFeatureexception rather than emitting a partial symbol. This is a documented scope boundary, on purpose. - GS1 application identifiers still apply. The linear component carries GS1-structured data with the FNC1 prefix, as in Generate 1D and 2D barcodes.
- Bound the payload. A larger composite payload yields a denser symbol. Bound payload length before encoding.
Performance
Section titled “Performance”Codeword generation is linear in payload length; carrier emission is linear in matrix area. There is no rasterization step — each module is a path operator — so memory stays flat regardless of symbol size. The recipe stays inside the 1500 ms / 64 MB budget.
Security notes
Section titled “Security notes”A composite symbol carries whatever payload you pass; treat the value as untrusted on the consuming side. The encoders encode bytes and do not authenticate them. Bound payload length before encoding to keep symbol size and work within budget.
Conformance
Section titled “Conformance”| Statement | Spec | Clause |
|---|---|---|
| The shipped CC-C composite component uses a PDF417 carrier. | ISO/IEC 15438 (PDF417) | §5 |
| CC-A’s base-928 high-level encodation is the Clause 5 method that this release does not implement. | ISO/IEC 24723 (GS1 Composite) | §5 |
This is an experimental, opt-in preview implementation. Core registers the
barcode.gs1-composite-cc-c capability under the Pro tier; the Premium
package gates the CC-C encoder, which is default-OFF on a Core-only install
(status Unavailable). CC-A and CC-B are not yet available — their encode()
fails closed with the typed UnsupportedBarcodeFeature exception. The shipped
CC-C codewords are pinned against a golden and cross-checked with an independent
decoder. No GA, conformance, or end-to-end certification against the GS1
Composite standard is claimed, and no standards text is reproduced.