PHPackages                             l-mendes/laravel-aws-marketplace - 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. [API Development](/categories/api)
4. /
5. l-mendes/laravel-aws-marketplace

ActiveLibrary[API Development](/categories/api)

l-mendes/laravel-aws-marketplace
================================

AWS Marketplace integration for Laravel SaaS: customer resolution, contract entitlements, metered usage, and EventBridge lifecycle events.

00PHPCI passing

Since Jun 22Pushed todayCompare

[ Source](https://github.com/l-mendes/laravel-aws-marketplace)[ Packagist](https://packagist.org/packages/l-mendes/laravel-aws-marketplace)[ RSS](/packages/l-mendes-laravel-aws-marketplace/feed)WikiDiscussions main Synced today

READMEChangelogDependenciesVersions (1)Used By (0)

laravel-aws-marketplace
=======================

[](#laravel-aws-marketplace)

[![CI](https://github.com/l-mendes/laravel-aws-marketplace/actions/workflows/ci.yml/badge.svg)](https://github.com/l-mendes/laravel-aws-marketplace/actions/workflows/ci.yml)[![Latest Version on Packagist](https://camo.githubusercontent.com/3ba703f1b8757d8fa04e3225ddd3d3a660808b982abad56b9ca0c3bf5234f00e/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6c2d6d656e6465732f6c61726176656c2d6177732d6d61726b6574706c6163652e737667)](https://packagist.org/packages/l-mendes/laravel-aws-marketplace)[![Total Downloads](https://camo.githubusercontent.com/13283cf160e273171fa9ae00e613c5c463cea41646a5e7ebcf8b23466ccae83d/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6c2d6d656e6465732f6c61726176656c2d6177732d6d61726b6574706c6163652e737667)](https://packagist.org/packages/l-mendes/laravel-aws-marketplace)[![License: MIT](https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667)](LICENSE)

A standalone AWS Marketplace integration for Laravel SaaS products. It handles the post-subscribe registration handshake, contract entitlements, metered usage, and the EventBridge lifecycle webhook, and gives you typed domain events to react to: normalized, but never hiding the native AWS fields.

It targets the current AWS Marketplace model: EventBridge agreement and license events (source `aws.agreement-marketplace`) under Concurrent Agreements, the default for new SaaS listings since June 1, 2026. It does not use the legacy SNS subscription/entitlement topics, which cannot distinguish concurrent agreements because they do not carry the LicenseArn.

This README is the overview and quick start. For the complete, step-by-step integration guide (AWS-side setup, a worked example, renewals, metering windows, persistence, testing, and production), see [INTEGRATION.md](INTEGRATION.md).

What it does
------------

[](#what-it-does)

- Resolve the post-subscribe registration token (`x-amzn-marketplace-token`) into a `ResolvedCustomer`(LicenseArn, customer account id, customer identifier, product code).
- Entitlements: fetch a buyer's contract entitlements for a license (GetEntitlements, paginated).
- Metering: report metered usage (BatchMeterUsage), keyed by LicenseArn and customer account id.
- Lifecycle webhook: verify EventBridge deliveries with a shared-secret header, parse them, deduplicate retries, persist the subscription, and dispatch typed domain events.
- Client wiring: builds the Marketplace clients, optionally assuming a seller-account role via STS.

Use the parts your pricing model needs:

Product typeWhat you usePay-As-You-Go (usage)resolve + meter + lifecycle eventsContractresolve + entitlements + lifecycle eventsContract with consumptionresolve + entitlements + meter + lifecycle eventsIdentity model (important)
--------------------------

[](#identity-model-important)

Each AWS agreement is one subscription, keyed by its agreement id (`Subscription->id`), the identifier present on every lifecycle event. The LicenseArn (`Subscription->licenseArn`) is the operational handle for GetEntitlements and BatchMeterUsage; it is filled in from the License Updated event, so it may be null until then. The agreement id and the LicenseArn first appear together on that License Updated event, which is where you finalize the link between the tenant you bound at the landing and the canonical subscription.

Renewal and replacement mint a new agreement, with a new LicenseArn and therefore a new subscription. AWS exposes no pointer from it back to the prior agreement, so this library never guesses a link across agreements. You bind a subscription to your tenant at the landing step, and on a renewal you reconcile the new subscription to the existing customer using the buyer account id (which AWS does provide) against your own mapping.

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

[](#requirements)

- PHP `^8.3`
- Laravel `^12`

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

[](#installation)

```
composer require l-mendes/laravel-aws-marketplace
php artisan aws-marketplace:install
```

The service provider is auto-discovered. `aws-marketplace:install` publishes the config and migrations and runs them. To do it by hand:

```
php artisan vendor:publish --tag=aws-marketplace-config
php artisan vendor:publish --tag=aws-marketplace-migrations
php artisan migrate
```

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

[](#configuration)

```
# The Marketplace APIs are served from us-east-1; keep this as us-east-1 even if your app runs elsewhere.
AWS_MARKETPLACE_REGION=us-east-1

# Shared secret used to authenticate EventBridge webhook deliveries.
AWS_MARKETPLACE_EVENTBRIDGE_WEBHOOK_SECRET=change-me
AWS_MARKETPLACE_EVENTBRIDGE_WEBHOOK_HEADER=X-Marketplace-Webhook-Secret

# Optional: assume a seller-account role for the Marketplace APIs.
# Leave empty to use the default AWS credential chain (env, shared config, instance/task role).
AWS_MARKETPLACE_ROLE_ARN=
AWS_MARKETPLACE_ROLE_EXTERNAL_ID=
AWS_MARKETPLACE_ROLE_SESSION_NAME=laravel-aws-marketplace
```

The package registers two routes; point your AWS listing and EventBridge rule at them:

- Fulfillment URL (listing) -&gt; `https://app.example.com/marketplace/aws/landing`
- EventBridge API Destination -&gt; `https://app.example.com/marketplace/aws/webhook`, with a connection that adds the secret header matching `AWS_MARKETPLACE_EVENTBRIDGE_WEBHOOK_SECRET`.

Quick start
-----------

[](#quick-start)

### 1. Fulfillment (the landing handshake)

[](#1-fulfillment-the-landing-handshake)

Implement `FulfillmentHandler` and bind it. It receives the resolved buyer after they subscribe and owns onboarding plus the redirect. Bind your tenant to the LicenseArn here.

```
use App\Models\Tenant;
use LMendes\LaravelAwsMarketplace\Contracts\FulfillmentHandler;
use LMendes\LaravelAwsMarketplace\DTO\ResolvedCustomer;
use Symfony\Component\HttpFoundation\Response;

class MarketplaceFulfillment implements FulfillmentHandler
{
    public function fulfilled(ResolvedCustomer $customer): Response
    {
        // Key on the LicenseArn (unique to this agreement) so a replayed landing reuses the same tenant.
        $tenant = Tenant::firstOrCreate(
            ['aws_license_arn' => $customer->licenseArn],
            [
                'aws_customer_account_id' => $customer->customerAccountId,
                'aws_product_code' => $customer->productCode,
            ],
        );

        return redirect()->route('onboarding', $tenant);
    }

    public function failed(\Throwable $exception): Response
    {
        report($exception);

        return redirect()->route('subscribe.help');
    }
}
```

```
$this->app->bind(FulfillmentHandler::class, MarketplaceFulfillment::class);
```

The marketplace routes are stateless (the `api` middleware group), so start the buyer's session on a `web` route rather than in the handler. INTEGRATION.md shows the signed-redirect pattern that handles this and CSRF.

### 2. Lifecycle events

[](#2-lifecycle-events)

Listen for the typed events. Key on `$event->subscription->id` (the agreement id); every event also carries the normalized `$event->event` with the native AWS fields (`licenseArn`, `agreementId`, `intent`, `agreementStatus`, `customerAccountId`, `productCode`) and the raw payload.

```
use Illuminate\Support\Facades\Event;
use LMendes\LaravelAwsMarketplace\Events\SubscriptionUpdated;
use LMendes\LaravelAwsMarketplace\Events\SubscriptionRenewed;
use LMendes\LaravelAwsMarketplace\Events\SubscriptionCancelled;

Event::listen(SubscriptionUpdated::class, function (SubscriptionUpdated $e) {
    // Entitlements changed; re-fetch and re-sync.
});

Event::listen(SubscriptionRenewed::class, function (SubscriptionRenewed $e) {
    // New agreement (new id). Reconcile to your customer by the buyer account:
    $account = $e->event->customerAccountId;
    // ... attach $e->subscription->id to that customer's tenant.
});

Event::listen(SubscriptionCancelled::class, function (SubscriptionCancelled $e) {
    // $e->reason is Cancelled, Expired, Terminated, or Unknown.
});
```

The full set: `SubscriptionActivated`, `SubscriptionRenewed`, `SubscriptionReplaced`, `SubscriptionUpdated` (with a `changes` hint), `SubscriptionSuperseded` (the old agreement after a renewal or replacement, not a cancellation), `SubscriptionCancelled` (with a `reason`), plus the catch-all `AwsMarketplaceEventReceived` dispatched for every delivery.

### 3. Entitlements and metering

[](#3-entitlements-and-metering)

```
use LMendes\LaravelAwsMarketplace\Facades\AwsMarketplace;
use LMendes\LaravelAwsMarketplace\DTO\UsageRecord;

$entitlements = AwsMarketplace::entitlements($productCode, $licenseArn);

AwsMarketplace::meter($licenseArn, $customerAccountId, new UsageRecord(
    dimension: 'your_usage_dimension',
    quantity: 7,
));
```

Documentation
-------------

[](#documentation)

[INTEGRATION.md](INTEGRATION.md) is the full, end-to-end walkthrough:

- Install and configure, IAM, and the seller-account role
- The landing handshake, with sessions and CSRF handled
- Connecting AWS (EventBridge rule, API Destination, the shared secret, dead-letter queue)
- Reacting to lifecycle events with a worked provisioner and the tenant-to-agreement link
- Entitlements and metering (a scheduled reporter and the final-metering window)
- Renewals and replacements, persistence, local testing, a production checklist, and troubleshooting

Testing
-------

[](#testing)

```
composer install
vendor/bin/phpunit
```

License
-------

[](#license)

MIT

###  Health Score

21

—

LowBetter than 18% of packages

Maintenance65

Regular maintenance activity

Popularity0

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity11

Early-stage or recently created project

 Bus Factor1

Top contributor holds 50% 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.

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/53242625?v=4)[Lucas Mendes](/maintainers/l-mendes)[@l-mendes](https://github.com/l-mendes)

---

Top Contributors

[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (2 commits)")[![l-mendes](https://avatars.githubusercontent.com/u/53242625?v=4)](https://github.com/l-mendes "l-mendes (2 commits)")

### Embed Badge

![Health badge](/badges/l-mendes-laravel-aws-marketplace/health.svg)

```
[![Health](https://phpackages.com/badges/l-mendes-laravel-aws-marketplace/health.svg)](https://phpackages.com/packages/l-mendes-laravel-aws-marketplace)
```

###  Alternatives

[exsyst/swagger

A php library to manipulate Swagger specifications

35816.3M7](/packages/exsyst-swagger)[hubspot/api-client

Hubspot API client

24015.5M18](/packages/hubspot-api-client)[botman/driver-telegram

Telegram driver for BotMan

93452.6k6](/packages/botman-driver-telegram)

PHPackages © 2026

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