Laravel MPP: Charge AI Agents for API Access with 402 Payment Required
Laravel AI #Laravel #AI Agents #Middleware #Payments #Machine Payments Protocol #API

Laravel MPP: Charge AI Agents for API Access with 402 Payment Required

3 min read Mohamed Said Mohamed Said

What Is Laravel MPP?

Laravel MPP (square1/laravel-mpp) is a middleware package that implements the Machine Payments Protocol (MPP). Instead of blocking unauthorized requests with a 401 or 403, it returns an HTTP 402 Payment Required response containing an HMAC-signed challenge. An AI agent that understands MPP fulfills the challenge over a supported payment rail and retries the request — no human in the loop required.

The package is currently at v1.1.0, MIT licensed, and both MPP and the Stripe SPT APIs it relies on are still in preview.

Gating a Route

Attaching the mpp middleware to any route is all it takes to enable payment enforcement:

Route::get('/resource', MyPaidResource::class)
    ->middleware('mpp:0.50,USD');

You can also declare pricing declaratively with the RequiresPayment PHP attribute on a controller method and enable automatic enforcement via an environment variable:

#[RequiresPayment(amount: '5.00', currency: 'USD', grants: 10)]
public function report()
{
    // ...
}

Route::get('/report', ReportController::class)->middleware('mpp');

Set MPP_ATTRIBUTES_ENABLED=true in your .env and the middleware reads the attribute automatically.

Metered Sessions

When grants is greater than one, a single payment covers multiple accesses. The successful response includes a Payment-Session header:

Payment-Session: id="sess_...", remaining="9", scope="report.basic", expiresAt="..."

Subsequent requests replay the session ID instead of paying again:

curl -si https://your-host/report \
  -H 'Authorization: Payment method="stripe", session="sess_..."'

Sessions default to the cache driver but can be persisted to the database:

MPP_SESSION_DRIVER=database
MPP_SESSION_CACHE_STORE=redis

Run php artisan vendor:publish --tag=mpp-migrations && php artisan migrate when using the database driver.

Preconditions

Preconditions are named checks that run before the payment gate, so you can reject ineligible requests without asking an agent to pay first. Register them in config/mpp.php:

'preconditions' => [
    'checks' => [
        'postexists' => [\App\Mpp\Checks\PostExists::class, 'check'],
    ],
    'global' => ['usernotblocked'],
],

A check returns null to pass or a Response to short-circuit:

public function check(Request $request, PaymentSpec $spec): ?Response
{
    return Post::find($request->route('post'))
        ? null
        : response()->json(['error' => 'No such post.'], 404);
}

Attach a precondition per route with the middleware parameter:

Route::get('/posts/{post}', ShowPost::class)
    ->middleware('mpp:1.00,USD,preconditions=postexists');

Payment Rails

The package ships with two built-in rails:

  • Stripe — uses Shared Payment Tokens (SPTs); configure STRIPE_SECRET_KEY, STRIPE_NETWORK_ID, and STRIPE_API_VERSION.
  • Tempo — settles in pathUSD on-chain; select it per route with method=tempo.

You can accept multiple rails on one route (methods=stripe|acme) and register a custom rail by implementing the Verifier interface.

Installation

composer require square1/laravel-mpp
php artisan vendor:publish --tag=mpp-config

Key Takeaways

  • Attach mpp middleware to any route to gate it behind an HTTP 402 payment challenge.
  • Supports Stripe SPTs and Tempo pathUSD out of the box; custom rails are possible via the Verifier interface.
  • Metered sessions let one payment cover multiple requests, tracked atomically in cache or database.
  • Preconditions let you reject ineligible requests before the payment gate runs.
  • Pricing can be declared inline in the middleware string or via the RequiresPayment PHP attribute.
  • The package is in preview (v1.1.0, MIT); the underlying Stripe SPT API may change.

Source: Laravel News — Laravel MPP: Charge AI Agents for API Access with 402 Payment Required

Found this useful?

Frequently Asked Questions

3 questions
Q01 What payment methods does Laravel MPP support out of the box?
Laravel MPP ships with two payment rails: Stripe Shared Payment Tokens (SPTs) and Tempo pathUSD (on-chain). You can also register a custom rail by implementing the package's Verifier interface, and multiple rails can be accepted on a single route.
Q02 How do metered sessions work in Laravel MPP?
When a payment specifies a `grants` value greater than one, a single payment covers that many accesses. The server returns a `Payment-Session` header with the session ID and remaining balance. The agent includes that session ID in subsequent requests instead of paying again. Sessions are stored in the cache by default, or in the database for persistence.
Q03 What are preconditions and why would I use them?
Preconditions are named checks that run before the payment gate. They let you reject ineligible requests — for example, a missing resource or a blocked user — before an agent is asked to pay, avoiding unnecessary payment challenges for requests that would fail anyway.

Continue reading

More Articles

View all