PHPackages                             qrid/codec - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Payment Processing](/categories/payments)
4. /
5. qrid/codec

ActiveLibrary[Payment Processing](/categories/payments)

qrid/codec
==========

Decode and encode MergeID electronic invoice QR codes

v1.1.0(2w ago)02MITPHPPHP &gt;=8.1CI passing

Since May 27Pushed 2w agoCompare

[ Source](https://github.com/Quality-XP-Development-SESSA/qrid-php)[ Packagist](https://packagist.org/packages/qrid/codec)[ Docs](https://github.com/Quality-XP-Development-SESSA/qrid-php)[ RSS](/packages/qrid-codec/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (2)Dependencies (3)Versions (4)Used By (0)

qrid/codec — PHP
================

[](#qridcodec--php)

PHP library for encoding and decoding **MergeID electronic invoice QR codes**.

MergeID QR codes embed invoice identity information (company, tax ID, contact, address) as a base64-encoded JSON payload. This library handles the encode/decode round-trip and, optionally, SVG QR image generation.

Typical usage flow
------------------

[](#typical-usage-flow)

 ```
sequenceDiagram
    actor Staff as Billing Staff
    participant ERP as Billing / ERP System
    participant Lib as qrid/codec
    participant QR as Invoice QR Code
    participant App as MergeID App

    Staff->>ERP: create invoice
    ERP->>Lib: Codec::encodeQRId(id, company, email, address, activityCode)
    Lib-->>ERP: SVG QR code
    ERP->>QR: print / embed on invoice

    Note over App,QR: later, at point of scan
    App->>QR: scan with camera
    QR-->>App: base64 payload string
    App->>Lib: Codec::decodeQRId(encoded)
    Lib-->>App: { v, id, company, email, address, activity_code }
    App-->>Staff: display verified invoice identity
```

      Loading Installation
------------

[](#installation)

```
# Decode only (no extra dependencies)
composer require qrid/codec

# Decode + encode SVG (adds QR generation library)
composer require qrid/codec chillerlan/php-qrcode
```

Usage
-----

[](#usage)

### Decode

[](#decode)

Pass the raw string value scanned from a QR code:

```
use QRId\Codec;

$payload = Codec::decodeQRId($encoded);

echo $payload['v'];             // Payload schema version (int, currently 1)
echo $payload['id'];            // Tax or company ID              (e.g. "3101679980")
echo $payload['company'];       // Company legal name
echo $payload['email'];         // Billing e-mail address
echo $payload['address'];       // Physical address
echo $payload['activity_code']; // Installation / activity code (e.g. "ACT-001"), or "" if blank
```

`decodeQRId` trims surrounding whitespace from the input before decoding, so strings copied with accidental padding are handled transparently.

**Exceptions thrown:**

ExceptionCause`InvalidArgumentException`Input is not valid base64`JsonException`Decoded bytes are not valid JSON```
use InvalidArgumentException;
use JsonException;
use QRId\Codec;

try {
    $payload = Codec::decodeQRId($raw);
} catch (InvalidArgumentException $e) {
    // QR data was not base64
} catch (JsonException $e) {
    // QR data decoded but was not the expected JSON structure
}
```

### Encode (requires `chillerlan/php-qrcode`)

[](#encode-requires-chillerlanphp-qrcode)

Produce an SVG QR code from invoice identity fields:

```
use QRId\Codec;

$svg = Codec::encodeQRId(
    id:           '3101679980',
    company:      'Acme Corp S.A.',
    email:        'billing@acme.example',
    address:      '123 Main St, San José, Costa Rica',
    activityCode: 'ACT-001',
);

// Serve inline
header('Content-Type: image/svg+xml');
echo $svg;

// Or embed in HTML
echo '';
```

`activityCode` is optional and defaults to `''` (blank). A blank activity code signals a consuming system to generate an electronic ticket instead of using an activity code.

**Exceptions thrown:**

ExceptionCause`RuntimeException``chillerlan/php-qrcode` is not installed`JsonException`JSON encoding of the payload failed (should not occur in practice)Payload format
--------------

[](#payload-format)

The QR code data is a UTF-8 JSON object encoded as standard base64 (no line-breaks):

```
{
  "v": 1,
  "id": "3101679980",
  "company": "Acme Corp S.A.",
  "email": "billing@acme.example",
  "address": "123 Main St, San José, Costa Rica",
  "activity_code": "ACT-001"
}
```

FieldTypeDescription`v``int`Payload schema version. Currently always `1`.`id``string`Tax / company registration ID.`company``string`Legal company name (UTF-8, including accented characters).`email``string`Primary billing or contact e-mail address.`address``string`Physical address of the company.`activity_code``string`Installation or activity code that links the QR to an internal record. May be blank (`""`), which signals a consuming system to generate an electronic ticket instead.Requirements
------------

[](#requirements)

DependencyVersionRequired forPHP`>= 8.1`Always`chillerlan/php-qrcode``^5.0``encodeQRId()` onlyRunning tests
-------------

[](#running-tests)

```
composer install
composer test
```

Tests cover field decoding, UTF-8 handling, whitespace trimming, error paths, and (when `chillerlan/php-qrcode` is available) the full encode-decode round-trip.

Publishing
----------

[](#publishing)

New versions reach [Packagist](https://packagist.org/packages/qrid/codec) automatically — there is no build/upload step:

1. Bump the version in the `VERSION` file (repo root) and merge to `main`.
2. [`release.yml`](.github/workflows/release.yml) runs on every push to `main`. It reads `VERSION`; if no `vX.Y.Z` tag already exists for it, it runs PHPUnit across PHP 8.2–8.4 (PHPUnit 11's minimum, even though the library itself supports PHP &gt;= 8.1) and creates that tag plus a GitHub Release.
3. Packagist's webhook on this repository picks up the new tag and republishes it within moments. Composer installs straight from the tagged GitHub source (via `dist`/zipball), so — unlike PyPI or npm — there's no artifact to build/upload and no OIDC/trusted-publisher concept to configure.

`composer.json` intentionally has no `version` field: Composer/Packagist derive the version purely from git tags, and a hardcoded field risks drifting out of sync with the actual tag. `VERSION` exists only so the release workflow has something to read.

Pushes to `main` that don't change `VERSION` are a no-op (the tag already exists), so unrelated commits (docs, CI tweaks) don't trigger a release.

License
-------

[](#license)

MIT

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance97

Actively maintained with recent releases

Popularity3

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity44

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~22 days

Total

3

Last Release

14d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/864648?v=4)[Valentin Secades Mendez](/maintainers/vsecades)[@vsecades](https://github.com/vsecades)

---

Top Contributors

[![vsecades](https://avatars.githubusercontent.com/u/864648?v=4)](https://github.com/vsecades "vsecades (7 commits)")

---

Tags

qrcodeqrinvoicedecodercodecmergeid

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/qrid-codec/health.svg)

```
[![Health](https://phpackages.com/badges/qrid-codec/health.svg)](https://phpackages.com/packages/qrid-codec)
```

###  Alternatives

[laraveldaily/laravel-invoices

Missing invoices for Laravel

1.6k1.5M5](/packages/laraveldaily-laravel-invoices)[horstoeko/zugferd

A library for creating and reading european electronic invoices

4295.8M31](/packages/horstoeko-zugferd)[atgp/factur-x

PHP library to manage your Factur-X / ZUGFeRD 2.0 PDF invoices files

153915.3k4](/packages/atgp-factur-x)[num-num/ubl-invoice

A modern object-oriented PHP library to create and read valid UBL and EN 16931/Peppol BIS 3.0 files

136923.4k](/packages/num-num-ubl-invoice)[josemmo/einvoicing

Library for reading and creating European-compliant electronic invoices (EN 16931)

177358.5k3](/packages/josemmo-einvoicing)[contributte/invoice

Library for easily and quickly creating invoices for customers.

98730.5k](/packages/contributte-invoice)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
