aiarmada/vouchers

Flexible voucher and coupon system for Laravel with support for multiple redemption types, usage limits, expiry dates, and cart integration

Installs: 98

Dependents: 2

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

pkg:composer/aiarmada/vouchers

v1.2.6 2025-11-08 13:26 UTC

This package is auto-updated.

Last update: 2025-11-09 12:19:31 UTC


README

Professional voucher and coupon system for AIArmada Cart

Add powerful voucher functionality to your Laravel shopping cart with support for percentage discounts, fixed amounts, free shipping, usage limits, and advanced validation rules.

โœจ Features

  • ๐ŸŽซ Multiple Voucher Types - Percentage, fixed amount, free shipping
  • ๐Ÿ”’ Usage Limits - Global limits and per-user restrictions
  • ๐Ÿ“… Time-Based - Start and expiry dates for campaigns
  • ๐Ÿ’ผ Voucher Wallet - Save vouchers for later use with polymorphic owner support
  • ๐Ÿ’ฐ Smart Constraints - Minimum cart values, maximum discounts
  • ๐Ÿง‘โ€๐Ÿคโ€๐Ÿง‘ Multi-Owner Aware - Scope vouchers to the current tenant or merchant using a configurable resolver
  • ๐Ÿงพ Manual Redemption - Record offline usage with channels, metadata, and staff attribution
  • ๐Ÿ“Š Usage Tracking - Complete history of voucher applications
  • โšก Real-Time Validation - Instant feedback on voucher validity
  • ๐Ÿ” Secure - Built-in validation and fraud prevention

๐Ÿ“ฆ Installation

composer require aiarmada/cart-vouchers

Publish the configuration and migrations:

php artisan vendor:publish --tag=vouchers-config
php artisan vendor:publish --tag=vouchers-migrations

Run migrations:

php artisan migrate

JSON vs JSONB (PostgreSQL)

Migrations default to portable json columns. To opt into jsonb on a fresh install, set one of the following BEFORE running migrations:

COMMERCE_JSON_COLUMN_TYPE=jsonb
# or per-package override
VOUCHERS_JSON_COLUMN_TYPE=jsonb

Or run the interactive setup:

php artisan commerce:configure-database

When using PostgreSQL + jsonb, GIN indexes are created automatically on voucher JSON fields: applicable_products, excluded_products, applicable_categories, and metadata.

๐Ÿš€ Quick Start

Create a Voucher

use AIArmada\Vouchers\Facades\Voucher;
use AIArmada\Vouchers\Enums\VoucherType;

$voucher = Voucher::create([
    'code' => 'SUMMER2024',
    'name' => 'Summer Sale 2024',
    'description' => '20% off your entire order',
    'type' => VoucherType::Percentage,
    'value' => 20.00,
    'min_cart_value' => 50.00,
    'usage_limit' => 1000,
    'usage_limit_per_user' => 1,
    'starts_at' => now(),
    'expires_at' => now()->addMonths(3),
]);

Apply to Cart

use AIArmada\Cart\Facades\Cart;

try {
    Cart::applyVoucher('SUMMER2024');
    
    $total = Cart::getTotal();
    echo "Total with voucher: {$total->format()}";
    
} catch (\AIArmada\Vouchers\Exceptions\VoucherNotFoundException $e) {
    // Voucher doesn't exist
} catch (\AIArmada\Vouchers\Exceptions\VoucherExpiredException $e) {
    // Voucher has expired
}

Manual Redemption

Record offline usage for POS or concierge scenarios while keeping analytics accurate:

use AIArmada\Vouchers\Facades\Voucher;
use Akaunting\Money\Money;

Voucher::redeemManually(
    code: 'SUMMER2024',
    userIdentifier: 'order-1001',
    discountAmount: Money::USD(2500),
    reference: 'counter-19',
    metadata: ['source' => 'retail-pos'],
    notes: 'Awarded during in-store event'
);

Owner Scoping

Enable multi-tenant or multi-merchant scoping by registering a resolver that returns the current owner model:

// config/vouchers.php
'owner' => [
    'enabled' => true,
    'resolver' => App\Support\Vouchers\CurrentOwnerResolver::class,
],

When enabled, all lookups automatically constrain vouchers to the resolved owner while optionally including global vouchers. New vouchers created through the service are associated with the current owner for you.

Voucher Wallet

Allow users (or any model) to save vouchers for later use:

use AIArmada\Vouchers\Traits\HasVoucherWallet;

class User extends Model
{
    use HasVoucherWallet;
}

// Add voucher to wallet
$user->addVoucherToWallet('SUMMER2024');

// Check if voucher exists in wallet
if ($user->hasVoucherInWallet('SUMMER2024')) {
    // Voucher is saved
}

// Get available vouchers
$availableVouchers = $user->getAvailableVouchers();

// Get redeemed vouchers
$redeemedVouchers = $user->getRedeemedVouchers();

// Get expired vouchers
$expiredVouchers = $user->getExpiredVouchers();

// Mark as redeemed
$user->markVoucherAsRedeemed('SUMMER2024');

// Remove from wallet
$user->removeVoucherFromWallet('SUMMER2024');

The wallet system tracks claimed and redeemed status with timestamps and supports custom metadata for each entry.

๐Ÿ“š Documentation

๐Ÿงช Testing

composer test

๐Ÿ“ Requirements

  • PHP 8.2+
  • Laravel 12+
  • AIArmada Cart 2.0+

๐Ÿ“„ License

MIT License. See LICENSE for details.

๐Ÿค Contributing

Contributions are welcome! Please see CONTRIBUTING.md for details.

๐Ÿ”— Related Packages

๐Ÿ’ฌ Support