PHPackages                             creem/laravel - 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. creem/laravel

ActiveLibrary[Payment Processing](/categories/payments)

creem/laravel
=============

Official Laravel package for CREEM - Accept payments globally with automatic tax handling

v1.0.0(2mo ago)432↓50%MITPHPPHP ^8.1CI passing

Since Feb 20Pushed 2mo agoCompare

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

READMEChangelogDependencies (8)Versions (2)Used By (0)

CREEM for Laravel
=================

[](#creem-for-laravel)

The official Laravel package for [CREEM](https://creem.io) — accept payments globally with automatic tax handling, subscription management, and license key distribution.

[![Latest Version on Packagist](https://camo.githubusercontent.com/ad18d0e88ae276d53bfb955a48a3fab149b1b48097f5aa2b9ac9cea57b48f1df/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f637265656d2f6c61726176656c2e737667)](https://packagist.org/packages/creem/laravel)[![Tests](https://github.com/Haniamin90/creem-laravel/actions/workflows/tests.yml/badge.svg)](https://github.com/Haniamin90/creem-laravel/actions/workflows/tests.yml)[![PHP](https://camo.githubusercontent.com/ea69ff8021a683c7b1ff683bfd909a5c960efd54004b1782ad84add19aecdac8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253345253344382e312d383839324246)](composer.json)[![Laravel](https://camo.githubusercontent.com/fb1a55c89eebe23b7ad42bc3a2d34de335288c0d532d2e73bd2a44c3ce42646e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c61726176656c2d31302532422d464632443230)](composer.json)[![License](https://camo.githubusercontent.com/f8df3091bbe1149f398a5369b2c39e896766f9f6efba3477c63e9b4aa940ef14/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e)](LICENSE)

Features
--------

[](#features)

- **Facade API** — `Creem::createCheckout()`, `Creem::getProduct()`, and 24 methods total
- **Webhook handling** — Automatic signature verification with typed Laravel events
- **Billable trait** — Add checkout, subscription, and billing portal to any Eloquent model
- **Artisan commands** — `creem:webhook-secret`, `creem:list-products`
- **Full API coverage** — Products, Checkouts, Subscriptions, Customers, Transactions, Licenses, Discounts
- **Auto sandbox detection** — Automatically routes to sandbox API when using test keys
- **Laravel 10, 11 &amp; 12** support with PHP 8.1+

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

[](#installation)

```
composer require creem/laravel
```

Publish the configuration file:

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

Add your API credentials to `.env`:

```
CREEM_API_KEY=creem_test_your_api_key_here
CREEM_WEBHOOK_SECRET=your_webhook_secret_here
```

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

[](#quick-start)

### Create a Checkout Session

[](#create-a-checkout-session)

```
use Creem\Laravel\Facades\Creem;

$checkout = Creem::createCheckout('prod_abc123', [
    'success_url' => route('checkout.success'),
    'customer' => ['email' => $user->email],
    'metadata' => ['user_id' => $user->id],
]);

return redirect($checkout['checkout_url']);
```

### Using the Billable Trait

[](#using-the-billable-trait)

Add the trait to your User model:

```
use Creem\Laravel\Traits\Billable;

class User extends Authenticatable
{
    use Billable;
}
```

Run the migration to add the `creem_customer_id` column:

```
php artisan vendor:publish --tag=creem-migrations
php artisan migrate
```

Now you can use billing methods directly on your User model:

```
// Create a checkout for this user
$checkout = $user->checkout('prod_abc123', [
    'success_url' => route('checkout.success'),
]);

// Get billing portal URL
$portal = $user->billingPortalUrl();

// Get all subscriptions
$subscriptions = $user->creemSubscriptions();

// Cancel a subscription
$user->cancelSubscription('sub_xyz', 'scheduled');
```

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

[](#api-reference)

### Checkouts

[](#checkouts)

```
// Create a checkout session
Creem::createCheckout('prod_123', [
    'success_url' => 'https://yourapp.com/success',
    'customer' => ['email' => 'customer@example.com'],
    'metadata' => ['key' => 'value'],
    'discount_code' => 'LAUNCH20',
    'request_id' => 'idempotency-key',
]);

// Retrieve a checkout session
Creem::getCheckout('chk_abc123');
```

### Products

[](#products)

```
// Create a product (price in cents)
Creem::createProduct([
    'name' => 'Pro Plan',
    'price' => 2999, // $29.99
    'currency' => 'USD',
    'billing_type' => 'recurring', // or 'onetime'
    'billing_period' => 'every-month',
    'tax_category' => 'saas',
]);

// Get a product
Creem::getProduct('prod_123');

// Search products
Creem::searchProducts(['limit' => 10]);
```

### Customers

[](#customers)

```
// Get customer by ID or email
Creem::getCustomer(['id' => 'cus_123']);
Creem::getCustomer(['email' => 'user@example.com']);

// List all customers
Creem::listCustomers(['limit' => 50]);

// Generate billing portal link
Creem::customerBillingPortal('cus_123');
```

### Subscriptions

[](#subscriptions)

```
// Get a subscription
Creem::getSubscription('sub_123');

// Search subscriptions
Creem::searchSubscriptions(['status' => 'active']);

// Update (seats, units, add-ons)
Creem::updateSubscription('sub_123', ['units' => 5]);

// Upgrade to different product
Creem::upgradeSubscription('sub_123', 'prod_pro');

// Cancel (immediate or at period end)
Creem::cancelSubscription('sub_123', 'scheduled');
Creem::cancelSubscription('sub_123', 'immediate');

// Pause & Resume
Creem::pauseSubscription('sub_123');
Creem::resumeSubscription('sub_123');
```

### Transactions

[](#transactions)

```
Creem::getTransaction('txn_123');
Creem::searchTransactions([
    'customer' => 'cus_123',
    'limit' => 20,
]);
```

### Licenses

[](#licenses)

```
// Activate a license on a device
$result = Creem::activateLicense('ABCD-1234-EFGH', 'MacBook Pro');
$instanceId = $result['instance_id'];

// Validate a license
Creem::validateLicense('ABCD-1234-EFGH', $instanceId);

// Deactivate
Creem::deactivateLicense('ABCD-1234-EFGH', $instanceId);
```

### Discounts

[](#discounts)

```
// Create a discount
Creem::createDiscount([
    'name' => 'Launch Sale',
    'code' => 'LAUNCH20',
    'type' => 'percentage', // or 'fixed'
    'percentage' => 20,
    'duration' => 'forever', // 'forever', 'once', or 'repeating'
    'applies_to_products' => ['prod_abc123'],
    'max_redemptions' => 100,
]);

// Get a discount
Creem::getDiscount(['code' => 'LAUNCH20']);

// Delete a discount
Creem::deleteDiscount('disc_123');
```

Webhooks
--------

[](#webhooks)

CREEM webhooks are handled automatically. The package registers a POST route at `/creem/webhook` (configurable) and verifies signatures using HMAC-SHA256.

### Setup

[](#setup)

1. Set your webhook secret in `.env`:

    ```
    CREEM_WEBHOOK_SECRET=your_webhook_secret
    ```
2. Register your webhook URL in the [CREEM dashboard](https://creem.io) under **Developers &gt; Webhook**:

    ```
    https://yourapp.com/creem/webhook

    ```

### Listening to Events

[](#listening-to-events)

Register listeners in your `EventServiceProvider` or use Laravel's event discovery:

```
use Creem\Laravel\Events\CheckoutCompleted;
use Creem\Laravel\Events\SubscriptionActive;
use Creem\Laravel\Events\SubscriptionCanceled;

class EventServiceProvider extends ServiceProvider
{
    protected $listen = [
        CheckoutCompleted::class => [
            GrantAccessListener::class,
        ],
        SubscriptionCanceled::class => [
            RevokeAccessListener::class,
        ],
    ];
}
```

Create a listener:

```
use Creem\Laravel\Events\CheckoutCompleted;

class GrantAccessListener
{
    public function handle(CheckoutCompleted $event): void
    {
        $data = $event->payload;

        // Grant access based on checkout data
        // $data contains customer, product, and transaction info
    }
}
```

### Available Events

[](#available-events)

Event ClassWebhook TypeDescription`CheckoutCompleted``checkout.completed`Payment successful, order created`SubscriptionActive``subscription.active`New subscription created`SubscriptionPaid``subscription.paid`Recurring payment processed`SubscriptionCanceled``subscription.canceled`Subscription ended`SubscriptionScheduledCancel``subscription.scheduled_cancel`Cancellation pending at period end`SubscriptionPastDue``subscription.past_due`Payment failed, retrying`SubscriptionExpired``subscription.expired`Period ended without payment`SubscriptionTrialing``subscription.trialing`Trial period started`SubscriptionPaused``subscription.paused`Subscription paused`SubscriptionUpdated``subscription.update`Subscription modified`RefundCreated``refund.created`Refund issued`DisputeCreated``dispute.created`Chargeback opened### Convenience Access Events

[](#convenience-access-events)

The package also dispatches `AccessGranted` and `AccessRevoked` events for simplified access management (inspired by the CREEM TypeScript SDK's `onGrantAccess`/`onRevokeAccess` pattern):

```
use Creem\Laravel\Events\AccessGranted;
use Creem\Laravel\Events\AccessRevoked;

// AccessGranted fires on: checkout.completed, subscription.active, subscription.paid
// AccessRevoked fires on: subscription.canceled, subscription.expired

class ManageUserAccess
{
    public function handleGrant(AccessGranted $event): void
    {
        // $event->reason — the original event type (e.g., 'checkout.completed')
        // $event->payload — the webhook object data
    }

    public function handleRevoke(AccessRevoked $event): void
    {
        // Revoke the user's access
    }
}
```

You can also listen to the generic `CreemWebhookReceived` event to catch all webhook types:

```
use Creem\Laravel\Events\CreemWebhookReceived;

class LogAllWebhooks
{
    public function handle(CreemWebhookReceived $event): void
    {
        logger()->info("CREEM webhook: {$event->eventType}", $event->payload);
    }
}
```

Artisan Commands
----------------

[](#artisan-commands)

### Generate Webhook Secret

[](#generate-webhook-secret)

```
# Generate a new webhook secret and add it to .env
php artisan creem:webhook-secret

# Show the current webhook secret
php artisan creem:webhook-secret --show

# Force overwrite an existing secret
php artisan creem:webhook-secret --force
```

### List Products

[](#list-products)

```
# List all products from your CREEM account
php artisan creem:list-products
```

Configuration
-------------

[](#configuration)

The config file (`config/creem.php`) supports these options:

OptionEnv VariableDefaultDescription`api_key``CREEM_API_KEY``''`Your CREEM API key`webhook_secret``CREEM_WEBHOOK_SECRET``''`Webhook signing secret`api_url``CREEM_API_URL`Auto-detectedOverride the API base URL`webhook_path``CREEM_WEBHOOK_PATH``creem/webhook`Webhook route path`currency``CREEM_CURRENCY``USD`Default currency`customer_model``CREEM_CUSTOMER_MODEL``App\Models\User`Billable model class### Sandbox vs Production

[](#sandbox-vs-production)

The package automatically detects sandbox mode based on your API key prefix:

- `creem_test_*` → Sandbox API (`https://test-api.creem.io`)
- `creem_*` → Production API (`https://api.creem.io`)

Error Handling
--------------

[](#error-handling)

The package throws typed exceptions for different error scenarios:

```
use Creem\Laravel\Exceptions\CreemApiException;
use Creem\Laravel\Exceptions\CreemAuthenticationException;
use Creem\Laravel\Exceptions\CreemRateLimitException;

try {
    $product = Creem::getProduct('prod_123');
} catch (CreemAuthenticationException $e) {
    // Missing or invalid API key (401/403)
} catch (CreemRateLimitException $e) {
    // Rate limited (429) - check $e->getRetryAfter() for seconds to wait
} catch (CreemApiException $e) {
    // Other API errors (400, 404, 500, etc.)
    $traceId = $e->getTraceId(); // For CREEM support debugging
}
```

Demo App
--------

[](#demo-app)

> **Live Demo:**  — see the package in action with real CREEM API integration.

A fully functional Docker-based demo app is included in [`examples/demo/`](examples/demo/). It demonstrates:

- Facade API calls (`Creem::searchProducts()`, `Creem::createProduct()`)
- Billable trait (`$user->checkout()`)
- Webhook event handling with live dashboard
- Sandbox/production auto-detection
- One-click sample product seeding via API

```
cd examples/demo
cp .env.example .env
# Add your CREEM API key and webhook secret to .env
docker compose up -d --build
# Visit http://localhost:8000
```

No products yet? Click **⚡ Create Sample Products** on the products page or run:

```
docker compose exec app php seed-products.php
```

See the [demo README](examples/demo/README.md) for full setup instructions.

Testing
-------

[](#testing)

```
composer test
```

Or run directly:

```
vendor/bin/phpunit
```

The package ships with 78 tests covering:

- API client HTTP handling &amp; error responses
- All 24 Facade methods (checkout, products, subscriptions, discounts, etc.)
- Webhook signature verification
- Event dispatching for all 12 webhook types + AccessGranted/AccessRevoked
- Service provider bindings &amp; configuration
- Artisan command registration &amp; behavior

Package Structure
-----------------

[](#package-structure)

```
creem-laravel/
├── config/
│   └── creem.php                 # Configuration file
├── database/
│   └── migrations/               # Billable migration
├── src/
│   ├── Api/                      # API endpoint classes
│   │   ├── CheckoutApi.php
│   │   ├── CustomerApi.php
│   │   ├── DiscountApi.php
│   │   ├── LicenseApi.php
│   │   ├── ProductApi.php
│   │   ├── SubscriptionApi.php
│   │   └── TransactionApi.php
│   ├── Commands/                 # Artisan commands
│   │   ├── SyncProductsCommand.php
│   │   └── WebhookSecretCommand.php
│   ├── Events/                   # Laravel events
│   │   ├── CheckoutCompleted.php
│   │   ├── CreemWebhookReceived.php
│   │   ├── SubscriptionActive.php
│   │   ├── AccessGranted.php
│   │   ├── AccessRevoked.php
│   │   └── ... (15 event classes total)
│   ├── Exceptions/               # Typed exceptions
│   ├── Facades/
│   │   └── Creem.php            # Facade with IDE hints
│   ├── Http/
│   │   ├── Controllers/
│   │   │   └── WebhookController.php
│   │   └── Middleware/
│   │       └── VerifyCreemWebhook.php
│   ├── Traits/
│   │   └── Billable.php         # Eloquent billing trait
│   ├── Creem.php                # Main service class
│   ├── CreemClient.php          # HTTP client
│   ├── CreemServiceProvider.php  # Service provider
│   └── WebhookEventType.php     # Event type constants
├── tests/
│   ├── Feature/                  # Integration tests
│   └── Unit/                     # Unit tests
├── composer.json
└── phpunit.xml

```

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

[](#requirements)

- PHP 8.1+
- Laravel 10, 11, or 12
- Guzzle HTTP 7.0+

License
-------

[](#license)

MIT License. See [LICENSE](LICENSE) for details.

Resources
---------

[](#resources)

- [CREEM Documentation](https://docs.creem.io)
- [CREEM Dashboard](https://creem.io)
- [API Reference](https://docs.creem.io/api-reference)

Author
------

[](#author)

Built by **Hani Amin** — [@HaniAmin90](https://x.com/HaniAmin90) · Discord: `xh90`

###  Health Score

38

—

LowBetter than 85% of packages

Maintenance83

Actively maintained with recent releases

Popularity14

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity42

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

Unknown

Total

1

Last Release

88d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/fe22226cf8ddd548150bfc93d6a8bbde5c40acc156437b8d01a69f70e483a8bf?d=identicon)[Haniamin90](/maintainers/Haniamin90)

---

Top Contributors

[![Haniamin90](https://avatars.githubusercontent.com/u/107732507?v=4)](https://github.com/Haniamin90 "Haniamin90 (12 commits)")

---

Tags

laravelbillingpaymentssubscriptionscreemmerchant-of-record

###  Code Quality

TestsPHPUnit

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/creem-laravel/health.svg)

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

###  Alternatives

[laravel/cashier-paddle

Cashier Paddle provides an expressive, fluent interface to Paddle's subscription billing services.

264778.4k3](/packages/laravel-cashier-paddle)[musahmusah/laravel-multipayment-gateways

A Laravel Package that makes implementation of multiple payment Gateways endpoints and webhooks seamless

852.2k1](/packages/musahmusah-laravel-multipayment-gateways)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

245.2k](/packages/aedart-athenaeum)[mmanos/laravel-billing

A billing package for Laravel 4.

451.3k](/packages/mmanos-laravel-billing)[asciisd/knet

Knet package is provides an expressive, fluent interface to KNet's payment services.

141.1k](/packages/asciisd-knet)

PHPackages © 2026

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