PHPackages                             akashpoudelnp/nepali-payment-qr-generator - 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. akashpoudelnp/nepali-payment-qr-generator

ActiveLibrary[Payment Processing](/categories/payments)

akashpoudelnp/nepali-payment-qr-generator
=========================================

Generate and parse Nepali payment QR codes (Fonepay, eSewa, etc.)

1.0.0(1mo ago)00MITPHPPHP &gt;=8.1CI passing

Since Jul 12Pushed 1mo agoCompare

[ Source](https://github.com/akashpoudelnp/nepali-payment-qr-generator)[ Packagist](https://packagist.org/packages/akashpoudelnp/nepali-payment-qr-generator)[ Docs](https://github.com/akashpoudelnp/nepali-payment-qr-generator)[ RSS](/packages/akashpoudelnp-nepali-payment-qr-generator/feed)WikiDiscussions main Synced 1w ago

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

Nepali Payment QR Generator
===========================

[](#nepali-payment-qr-generator)

[![Latest Version](https://camo.githubusercontent.com/bb2527c56294429c34544986136388252b1d03b7d65951494f9c57231fd0334f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f616b617368706f7564656c6e702f6e6570616c692d7061796d656e742d71722d67656e657261746f723f7374796c653d666c61742d737175617265)](https://packagist.org/packages/akashpoudelnp/nepali-payment-qr-generator)[![Total Downloads](https://camo.githubusercontent.com/782c8dfcf63724c5a62ac2135977ea3d94c38ea85814e0073996df6344bf8ffc/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f616b617368706f7564656c6e702f6e6570616c692d7061796d656e742d71722d67656e657261746f723f7374796c653d666c61742d737175617265)](https://packagist.org/packages/akashpoudelnp/nepali-payment-qr-generator)[![PHP Version](https://camo.githubusercontent.com/7c2ad0bd6e2aadc5316b8884d8f8a5b00243f5a0a4bafdd3d8423205e3aff081/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f616b617368706f7564656c6e702f6e6570616c692d7061796d656e742d71722d67656e657261746f723f7374796c653d666c61742d737175617265)](https://packagist.org/packages/akashpoudelnp/nepali-payment-qr-generator)[![License](https://camo.githubusercontent.com/f7943b80ac7e52789048676e772895ecc6c85dd1bfd6e6db30bcc42402a3a7f2/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f616b617368706f7564656c6e702f6e6570616c692d7061796d656e742d71722d67656e657261746f723f7374796c653d666c61742d737175617265)](https://github.com/akashpoudelnp/nepali-payment-qr-generator/blob/main/LICENSE)[![GitHub Stars](https://camo.githubusercontent.com/2ed701733ac99b3a17f3cdbbc2a46504b4e0e7468ad5035d7ba65b553eccf741/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f616b617368706f7564656c6e702f6e6570616c692d7061796d656e742d71722d67656e657261746f723f7374796c653d666c61742d737175617265)](https://github.com/akashpoudelnp/nepali-payment-qr-generator)

Generate and parse Nepali payment QR codes (Fonepay, with more providers coming soon).

Produces **EMVCo-compliant QR strings** and renders them as **PNG images**. The parser can decode both EMVCo strings and QR images back into structured data.

Requirements
------------

[](#requirements)

- PHP &gt;= 8.1
- `ext-gd` (for PNG image output)
- `ext-mbstring`

Installation
------------

[](#installation)

```
composer require akashpoudelnp/nepali-payment-qr-generator
```

---

Quick Start
-----------

[](#quick-start)

```
use Akashpoudelnp\NepaliPaymentQrGenerator\PaymentQRGenerator;
use Akashpoudelnp\NepaliPaymentQrGenerator\Enums\PaymentQRType;

$output = PaymentQRGenerator::for(PaymentQRType::Fonepay, [
    'merchant_name' => 'Himalaya Tea Shop',
    'merchant_city' => 'Kathmandu',
    'fonepay_id'    => '2109020664',
    'terminal_id'   => '497140',
    'mcc'           => '5499',
    'country_code'  => 'NP',
])->generate(250.00, 'Order INV-2024-001');
```

### Output Methods

[](#output-methods)

```
$output->getQrString();             // "0002010102122639..."
$output->getTxnId();                // "TXN863412"
$output->getQrImage();              // Raw PNG binary string
$output->getQrImageAsBase64();      // Base64-encoded PNG
$output->getQrImageAsDataUri();     // "data:image/png;base64,..."
$output->getData();                 // PaymentQRData used to generate
$output->getType();                 // PaymentQRType::Fonepay
```

### Save to file

[](#save-to-file)

```
file_put_contents('payment-qr.png', $output->getQrImage());
```

### Embed directly in HTML

[](#embed-directly-in-html)

```
echo '';
```

---

How EMVCo QR Works
------------------

[](#how-emvco-qr-works)

The QR code does **not** contain a URL or image. It stores a **TLV (Tag-Length-Value)** string that payment apps parse to process the transaction.

### Structure

[](#structure)

```
00 02  01          → Payload Format Indicator (always "01")
01 02  12          → Point of Initiation Method ("12" = dynamic)
26 39  [data...]   → FonePay-specific data (see below)
52 04  8012        → Merchant Category Code (MCC)
53 03  524         → Currency (524 = NPR)
54 05  250.00      → Amount
58 02  NP          → Country Code
59 14  [name...]   → Merchant Name
60 09  [city...]   → Merchant City
62 24  [data...]   → Additional data (terminal ID, txn ID, remarks)
63 04  A1B2        → CRC16-CCITT checksum

```

Each tag is: **2 chars tag + 2 chars length (decimal) + N chars value**.

---

Fonepay Tag 26 — Two Formats
----------------------------

[](#fonepay-tag-26--two-formats)

The format is **auto-detected** — set `tag26_identifier` for format `07`, or omit it for default format `01_02`.

### Format `01_02` (default) — Separate IDs

[](#format-01_02-default--separate-ids)

Tag 26 contains sub-tags with individual Fonepay ID and Terminal ID.

```
PaymentQRGenerator::for(PaymentQRType::Fonepay, [
    'fonepay_id'   => '2109020664',
    'terminal_id'  => '497140',
]);
```

**Example generated QR string:**

```
000201010212
26 39  0011fonepay.com 01102109020664 0206497140
5204 5499
5303 524
5407 250.00
5802 NP
5911 Himalaya Tea
6009 Kathmandu
62 24  0706497140 0209TXN863412 0814Order INV-2024
6304 A1B2

```

Broken down:

```
Tag 26 length=39
├── 00 length=11 → "fonepay.com"       (FonePay URL)
├── 01 length=10 → "2109020664"        (FonePay merchant ID)
└── 02 length=06 → "497140"            (Terminal ID)

```

### Format `07` — Combined Identifier

[](#format-07--combined-identifier)

Tag 26 uses a single combined merchant identifier instead of separate sub-tags.

```
PaymentQRGenerator::for(PaymentQRType::Fonepay, [
    'tag26_identifier' => '2222020003108681',
    'terminal_id'      => '310871',
]);
```

**Example generated QR string:**

```
000201010212
26 35  0011fonepay.com 07162222020003108681
5204 5943
5303 524
5407 200.00
5802 NP
5930 Poudel Radio and Watch Service
6013 Ratnanagar MC
62 24  0706310871 0209TXN863586 0807Payment
6304 62FB

```

Broken down:

```
Tag 26 length=35
├── 00 length=11 → "fonepay.com"              (FonePay URL)
└── 07 length=16 → "2222020003108681"         (Combined identifier)

```

### How to Identify Which Format

[](#how-to-identify-which-format)

Criterion`01_02``07`Sub-tags inside tag 26`01` + `02``07` onlyQR string snippet`2639...0110...0206``2635...0011...0716`Typical identifier10-digit Fonepay ID + 6-digit terminal16-digit combined ID---

Parsing QR Data
---------------

[](#parsing-qr-data)

The parser reverses the EMVCo string back into structured data via `PaymentQROutput`.

### From an EMVCo String

[](#from-an-emvco-string)

```
$parsed = PaymentQRGenerator::parse('0002010102122635...');
```

### From a QR Image File

[](#from-a-qr-image-file)

```
$parsed = PaymentQRGenerator::parseFromImage('scan-me.png');
```

### From Raw Image Data (e.g., uploaded file)

[](#from-raw-image-data-eg-uploaded-file)

```
$parsed = PaymentQRGenerator::parseFromBlob($imageBinary);
```

### Parsed Output Example

[](#parsed-output-example)

Given a QR generated with:

```
$output = PaymentQRGenerator::for(PaymentQRType::Fonepay, [
    'merchant_name' => 'Himalaya Tea Shop',
    'merchant_city' => 'Kathmandu',
    'fonepay_id'    => '2109020664',
    'terminal_id'   => '497140',
    'mcc'           => '5499',
])->generate(250.00, 'Order INV-2024-001');
```

Parsing it back:

```
$parsed = PaymentQRGenerator::parse($output->getQrString());

$data = $parsed->getData();

$data->getAmount();                    // 250.0
$data->getRemarks();                   // "Order INV-2024-001"
$data->getMerchantName();             // "Himalaya Tea Shop"
$data->getMerchantCity();             // "Kathmandu"
$data->getFonepayId();                // "2109020664"
$data->getTerminalId();               // "497140"
$data->getMcc();                      // "5499"
$data->getCountryCode();              // "NP"
$data->getTag26Format();              // "01_02"
$data->getTag26Identifier();          // null (only set for "07" format)
$data->getMerchantPan();              // null (only set if present in QR)

$parsed->getTxnId();                  // "TXN863412" (from tag 62 sub-tag 02)
$parsed->getQrString();               // Original EMVCo string
$parsed->getType();                   // PaymentQRType::Fonepay
```

### Parse → Modify → Re-generate

[](#parse--modify--re-generate)

```
// Parse an existing QR
$parsed = PaymentQRGenerator::parseFromImage('existing-qr.png');
$data = $parsed->getData();

// Change amount and re-generate
$data->setAmount(500.00);
$data->setRemarks('Partial payment');

$newOutput = PaymentQRGenerator::for(PaymentQRType::Fonepay)->generate($data);
file_put_contents('updated-qr.png', $newOutput->getQrImage());
```

---

Using the DTO Directly
----------------------

[](#using-the-dto-directly)

`PaymentQRData` uses a fluent builder pattern. Every field has a sensible default — you only need to override what matters.

```
use Akashpoudelnp\NepaliPaymentQrGenerator\DTO\PaymentQRData;

$data = PaymentQRData::new()
    ->setAmount(500.00)
    ->setRemarks('Gift')
    ->setMerchantName('Mountain Books')
    ->setMerchantCity('Pokhara')
    ->setFonepayId('2109020664')
    ->setTerminalId('123456')
    ->setMcc('5942');

$output = PaymentQRGenerator::for(PaymentQRType::Fonepay)->generate($data);
```

---

Full End-to-End Example
-----------------------

[](#full-end-to-end-example)

```
