PHPackages                             mortogo321/laravel-thai-promptpay - 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. mortogo321/laravel-thai-promptpay

ActiveLibrary[Payment Processing](/categories/payments)

mortogo321/laravel-thai-promptpay
=================================

Thai PromptPay QR Code Payment Generator for Laravel

v2.1.0(3mo ago)0347MITPHPPHP ^8.2

Since Oct 11Pushed 2mo agoCompare

[ Source](https://github.com/mortogo321/laravel-thai-promptpay)[ Packagist](https://packagist.org/packages/mortogo321/laravel-thai-promptpay)[ Docs](https://github.com/mortogo321/laravel-thai-promptpay)[ RSS](/packages/mortogo321-laravel-thai-promptpay/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (5)Versions (9)Used By (0)

Laravel Thai PromptPay
======================

[](#laravel-thai-promptpay)

[![Latest Version on Packagist](https://camo.githubusercontent.com/e7dc0dc19493103e3ecb22e4bb4091cb293e2df05ddd21275951e8ea1bd708d1/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6d6f72746f676f3332312f6c61726176656c2d746861692d70726f6d70747061792e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/mortogo321/laravel-thai-promptpay)[![Total Downloads](https://camo.githubusercontent.com/451500e90e839b1288961888997bd667237c1afc56bcda9d3a5ae290ba364f85/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6d6f72746f676f3332312f6c61726176656c2d746861692d70726f6d70747061792e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/mortogo321/laravel-thai-promptpay)[![GitHub License](https://camo.githubusercontent.com/3e68b1e059a1ca766629140fd9e74880c3b6226ff05b09234868f5ff0141fcc3/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6d6f72746f676f3332312f6c61726176656c2d746861692d70726f6d70747061792e7376673f7374796c653d666c61742d737175617265)](https://github.com/mortogo321/laravel-thai-promptpay/blob/main/LICENSE)[![PHP Version](https://camo.githubusercontent.com/9f3ca007b6376b1f305ccf5e0afcda8db0fcb98ce9899af79924f5f34b068162/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f6d6f72746f676f3332312f6c61726176656c2d746861692d70726f6d70747061792e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/mortogo321/laravel-thai-promptpay)[![Laravel Version](https://camo.githubusercontent.com/7d4658ae9e9ca795911f3e8d83e602174f812900fafc55642f8d858e355636d8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d31302e7825323025374325323031312e7825323025374325323031322e782d7265643f7374796c653d666c61742d737175617265)](https://laravel.com)[![Tests](https://camo.githubusercontent.com/b0f746223efc3815d1c392628d9b0a3f0b50eedbed51a4531da1f16af7e840f8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f54657374732d36382532307061737365642d627269676874677265656e3f7374796c653d666c61742d737175617265)](https://github.com/mortogo321/laravel-thai-promptpay)[![GitHub Stars](https://camo.githubusercontent.com/ad0e5548f4282002107e292c411c8ddcfb175c741f9c729211453041fe43320e/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f6d6f72746f676f3332312f6c61726176656c2d746861692d70726f6d70747061793f7374796c653d666c61742d737175617265)](https://github.com/mortogo321/laravel-thai-promptpay/stargazers)

A Laravel package for generating Thai PromptPay QR codes following the **BOT (Bank of Thailand) Thai QR Payment Standard**. Supports phone numbers, National ID, Tax ID, and e-Wallet with full validation.

Supported Formats
-----------------

[](#supported-formats)

TypeSupportedSub-tagFormatExampleMobile Phone✅0110 digits (06/08/09)`0812345678`National ID✅0213 digits`1234567890123`Tax ID✅0213 digits`0123456789012`e-Wallet✅0315 digits`123456789012345`Bank Account❌-NOT SUPPORTEDBOT spec: reserved> **Note:** Bank account numbers are NOT supported per BOT specification (marked as "reserved" - no Thai banks have implemented this).

Features
--------

[](#features)

- Generate PromptPay QR codes compliant with BOT Thai QR Payment Standard
- Support for phone numbers, National ID, Tax ID, and e-Wallet
- **Validation methods** for identifier and amount checking
- **Thai National ID checksum validation**
- **Payload CRC verification** for integrity checking
- Support for fixed amount and open amount payments
- Returns QR code as data URI or binary PNG
- Built-in AJAX/API endpoints with rate limiting
- Works with Axios, Fetch, Vue.js, React, and any frontend framework
- Laravel auto-discovery support
- **Full test suite** (68 tests, 151 assertions)

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

[](#requirements)

- PHP 8.2 - 8.5
- Laravel 10.x, 11.x, or 12.x

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

[](#installation)

```
composer require mortogo321/laravel-thai-promptpay
```

The package will automatically register its service provider.

### Publish Configuration (Optional)

[](#publish-configuration-optional)

```
php artisan vendor:publish --tag=promptpay-config
```

Basic Usage
-----------

[](#basic-usage)

### Using Facade

[](#using-facade)

```
use Mortogo321\LaravelThaiPromptPay\Facades\PromptPay;

// Generate QR code with phone number
$qrCode = PromptPay::generateQRCode('0812345678');

// Generate QR code with fixed amount
$qrCode = PromptPay::generateQRCode('0812345678', 100.50);

// Generate QR code with National ID
$qrCode = PromptPay::generateQRCode('1234567890123', 250.00);

// Generate QR code with custom size (default: 300px)
$qrCode = PromptPay::generateQRCode('0812345678', 100.00, 400);

// Generate payload string only
$payload = PromptPay::generatePayload('0812345678', 100.00);

// Generate QR code as binary PNG
$binary = PromptPay::generateQRCodeBinary('0812345678', 100.00);
```

### Using Dependency Injection

[](#using-dependency-injection)

```
use Mortogo321\LaravelThaiPromptPay\PromptPayQR;

class PaymentController extends Controller
{
    public function generateQR(PromptPayQR $promptpay)
    {
        $qrCode = $promptpay->generateQRCode('0812345678', 150.00);
        return view('payment', compact('qrCode'));
    }
}
```

Validation
----------

[](#validation)

### Validate Identifier

[](#validate-identifier)

```
use Mortogo321\LaravelThaiPromptPay\PromptPayQR;

$qr = new PromptPayQR();

// Validate without generating QR
$result = $qr->validate('0812345678');
// Returns: ['valid' => true, 'type' => 'mobile', 'formatted' => '0066812345678', 'error' => null]

$result = $qr->validate('invalid');
// Returns: ['valid' => false, 'type' => null, 'formatted' => null, 'error' => 'Invalid PromptPay ID format...']
```

### Validate Amount

[](#validate-amount)

```
$qr->validateAmount(100.50);       // ['valid' => true, 'error' => null]
$qr->validateAmount(-50);          // ['valid' => false, 'error' => 'Amount cannot be negative']
$qr->validateAmount(9999999999);   // ['valid' => false, 'error' => 'Amount exceeds maximum...']
$qr->validateAmount(100.123);      // ['valid' => false, 'error' => 'Amount must have at most 2 decimal places']
```

### Validate Payload Integrity

[](#validate-payload-integrity)

```
// Verify CRC checksum of a generated payload
$payload = $qr->generatePayload('0812345678', 100.00);
$isValid = $qr->validatePayload($payload);  // true

// Detect corrupted payload
$corrupted = substr($payload, 0, 10) . 'X' . substr($payload, 11);
$isValid = $qr->validatePayload($corrupted);  // false
```

### Type Detection

[](#type-detection)

```
// Get identifier type
$qr->getIdentifierType('0812345678');     // 'mobile'
$qr->getIdentifierType('1234567890123');  // 'tax_id'

// Specific type checks
$qr->isMobileNumber('0812345678');        // true (validates 06/08/09 prefix)
$qr->isMobileNumber('0212345678');        // false (02 is landline)
$qr->isNationalId('3320101323923');       // true (with checksum validation)
$qr->isTaxId('1234567890123');            // true
```

### Get Supported Formats

[](#get-supported-formats)

```
$formats = PromptPayQR::getSupportedFormats();
// Returns array with all supported formats, sub-tags, and examples
```

Display QR Code in Blade
------------------------

[](#display-qr-code-in-blade)

```

    Scan to Pay

    Amount: ฿{{ number_format($amount, 2) }}

```

AJAX/API Usage
--------------

[](#ajaxapi-usage)

### Available API Endpoints

[](#available-api-endpoints)

All endpoints are rate-limited to **60 requests per minute**.

#### Generate QR Code

[](#generate-qr-code)

**POST** `/promptpay/generate`

```
axios.post('/promptpay/generate', {
    identifier: '0812345678',  // Phone, National ID, or e-Wallet
    amount: 100.50,            // Optional (max 999,999,999.99, max 2 decimals)
    size: 300                  // Optional (100-1000, default: 300)
})
.then(response => {
    // response.data: { success, qr_code, identifier, type, amount }
    // type: 'mobile' | 'tax_id' | 'ewallet'
    document.getElementById('qr-image').src = response.data.qr_code;
});
```

#### Get Payload Only

[](#get-payload-only)

**POST** `/promptpay/payload`

```
axios.post('/promptpay/payload', {
    identifier: '0812345678',
    amount: 100.50
});
```

#### Download QR Code

[](#download-qr-code)

**POST** `/promptpay/download`

```
axios.post('/promptpay/download', {
    identifier: '0812345678',
    amount: 100.50
}, { responseType: 'blob' });
```

### API Response Format

[](#api-response-format)

**Success Response (200)**

```
{
    "success": true,
    "qr_code": "data:image/png;base64,...",
    "identifier": "0812345678",
    "type": "mobile",
    "amount": 100.50
}
```

**Error Response (422)**

```
{
    "success": false,
    "message": "Invalid PromptPay ID format..."
}
```

Identifier Format Details
-------------------------

[](#identifier-format-details)

### Phone Numbers

[](#phone-numbers)

- `0812345678` - Thai mobile (10 digits starting with 06/08/09)
- `812345678` - Without leading 0 (9 digits)
- `66812345678` - International format
- `0066812345678` - PromptPay format

### National ID / Tax ID

[](#national-id--tax-id)

- `1234567890123` - 13-digit number
- Includes checksum validation for National ID

### e-Wallet

[](#e-wallet)

- `123456789012345` - 15-digit e-Wallet ID

API Reference
-------------

[](#api-reference)

### `validate(string $identifier): array`

[](#validatestring-identifier-array)

Validate identifier without generating QR.

### `validateAmount(?float $amount): array`

[](#validateamountfloat-amount-array)

Validate payment amount (max 2 decimal places, max 999,999,999.99).

### `validatePayload(string $payload): bool`

[](#validatepayloadstring-payload-bool)

Verify CRC16-CCITT checksum of a complete payload.

### `getIdentifierType(string $identifier): ?string`

[](#getidentifiertypestring-identifier-string)

Get identifier type ('mobile', 'tax\_id', 'ewallet', or null).

### `isMobileNumber(string $identifier): bool`

[](#ismobilenumberstring-identifier-bool)

Check if valid Thai mobile number (06/08/09).

### `isNationalId(string $identifier): bool`

[](#isnationalidstring-identifier-bool)

Check if valid National ID with checksum validation.

### `isTaxId(string $identifier): bool`

[](#istaxidstring-identifier-bool)

Check if valid Tax ID (13 digits).

### `generatePayload(string $identifier, ?float $amount = null): string`

[](#generatepayloadstring-identifier-float-amount--null-string)

Generate PromptPay EMV QR code payload string.

### `generateQRCode(string $identifier, ?float $amount = null, int $size = 300): string`

[](#generateqrcodestring-identifier-float-amount--null-int-size--300-string)

Generate QR code image as data URI.

### `generateQRCodeBinary(string $identifier, ?float $amount = null, int $size = 300): string`

[](#generateqrcodebinarystring-identifier-float-amount--null-int-size--300-string)

Generate QR code as binary PNG data.

### `getSupportedFormats(): array`

[](#getsupportedformats-array)

Get list of all supported identifier formats.

Technical Specification
-----------------------

[](#technical-specification)

This package follows the **BOT (Bank of Thailand) Thai QR Payment Standard**:

- **AID:** `A000000677010111` (PromptPay Application ID)
- **Sub-tag 01:** Mobile phone number (`0066XXXXXXXXX` format)
- **Sub-tag 02:** National ID / Tax ID (13 digits)
- **Sub-tag 03:** e-Wallet ID (15 digits)
- **CRC:** CRC16-CCITT checksum (EMVCo standard)

Reference: [BOT Thai QR Payment Specification](https://www.bot.or.th/content/dam/bot/fipcs/documents/FPG/2562/ThaiPDF/25620084.pdf)

Testing
-------

[](#testing)

```
# Run all tests
composer test

# Run tests with coverage
composer test:coverage

# Run specific test suite
./vendor/bin/phpunit --testsuite=Unit
./vendor/bin/phpunit --testsuite=Feature
```

**Test Coverage:** 68 tests, 151 assertions

Code Quality
------------

[](#code-quality)

This package uses [Laravel Pint](https://laravel.com/docs/pint) for code style.

```
# Check code style
composer lint

# Fix code style
composer lint:fix
```

A pre-commit hook is included to automatically check code style before commits.

Contributing
------------

[](#contributing)

Contributions are welcome! Please feel free to submit a Pull Request.

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Run tests (`composer test`)
4. Run linting (`composer lint:fix`)
5. Commit your changes (`git commit -m 'Add amazing feature'`)
6. Push to the branch (`git push origin feature/amazing-feature`)
7. Open a Pull Request

License
-------

[](#license)

MIT License

Credits
-------

[](#credits)

- [Mor](https://github.com/mortogo321)
- Built with [endroid/qr-code](https://github.com/endroid/qr-code)

Support
-------

[](#support)

If you discover any issues, please create an issue on [GitHub](https://github.com/mortogo321/laravel-thai-promptpay/issues).

###  Health Score

41

—

FairBetter than 89% of packages

Maintenance83

Actively maintained with recent releases

Popularity13

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity53

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 ~16 days

Recently: every ~0 days

Total

8

Last Release

104d ago

Major Versions

v1.0.0 → v2.0.02026-02-02

PHP version history (2 changes)v1.0.0PHP ^8.1

v2.0.0PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/111abf5668131990b02e1b535794c862bf60dd94d688f6f99a2f3f8eaa9732e9?d=identicon)[mortogo321](/maintainers/mortogo321)

---

Top Contributors

[![mortogo321](https://avatars.githubusercontent.com/u/96430118?v=4)](https://github.com/mortogo321 "mortogo321 (17 commits)")

---

Tags

laravelpromptpaythaiqr codelaravelpaymentthailandPromptpay

###  Code Quality

TestsPHPUnit

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/mortogo321-laravel-thai-promptpay/health.svg)

```
[![Health](https://phpackages.com/badges/mortogo321-laravel-thai-promptpay/health.svg)](https://phpackages.com/packages/mortogo321-laravel-thai-promptpay)
```

###  Alternatives

[sebdesign/laravel-viva-payments

A Laravel package for integrating the Viva Payments gateway

4845.9k](/packages/sebdesign-laravel-viva-payments)[henryejemuta/laravel-monnify

A laravel package to seamlessly integrate monnify api within your laravel application

132.1k](/packages/henryejemuta-laravel-monnify)[dena-a/iran-payment

a Laravel package to handle Internet Payment Gateways for Iran Banking System

312.4k1](/packages/dena-a-iran-payment)

PHPackages © 2026

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