Laravel MPP — це middleware, що реалізує Machine Payments Protocol (MPP), дозволяючи стягувати плату з AI-агентів за доступ до захищених маршрутів. Пакет повертає HTTP-відповідь 402 Payment Required із підписаним челенджем (challenge). Агент, здатний здійснити оплату, виконує умови челенджа через підтримувану платіжну rail та повторює запит.
Основні можливості:
- Дві платіжні rails — Stripe Shared Payment Tokens (SPTs) та Tempo pathUSD.
- Гнучке ціноутворення — оплата за окремий запит або один платіж, що надає доступ до кількох звернень.
- HMAC-підписані челенджі — агенти отримують підписаний
402challenge для оплати та повторного запиту. - Сесії з лічильником (Metered sessions) — атомарні залишки кредитів із перевіркою scope, що зберігаються у cache або database.
- Preconditions — іменовані перевірки, які запускаються перед платіжним шлюзом, щоб вчасно відхилити невідповідні запити.
# Обмеження доступу до маршруту
Підключіть middleware mpp до маршруту, вказавши ціну та валюту. Запит без оплати отримає у відповідь 402 challenge:
Route::get('/resource', MyPaidResource::class)
->middleware('mpp:0.50,USD');
Ви також можете визначити параметри оплати за допомогою атрибута RequiresPayment у методі контролера. Middleware зчитає ці дані автоматично, якщо увімкнено опцію MPP_ATTRIBUTES_ENABLED=true:
#[RequiresPayment(amount: '5.00', currency: 'USD', grants: 10)]
public function report()
{
// ...
}
Route::get('/report', ReportController::class)->middleware('mpp');
# Сесії з лічильником
Якщо параметр grants перевищує одиницю, один платіж покриває кілька запитів. Успішна відповідь містить заголовок Payment-Session із залишком балансу та scope:
Payment-Session: id="sess_...", remaining="9", scope="report.basic", expiresAt="..."
Агент використовує ідентифікатор сесії в наступних запитах замість повторної оплати:
curl -si https://your-host/report \
-H 'Authorization: Payment method="stripe", session="sess_..."'
За замовчуванням сесії зберігаються у cache, але для надійності можна використовувати database:
MPP_SESSION_DRIVER=cache # Типово
MPP_SESSION_DRIVER=database # Зі зберіганням у БД; запустіть міграції
MPP_SESSION_CACHE_STORE=redis # Опціонально: власне сховище cache
# Preconditions
Preconditions — це перевірки, які виконуються до платіжного шлюзу. Це дозволяє відхилити некоректний запит ще до того, як ви попросите агента заплатити. Зареєструйте їх у config/mpp.php:
// config/mpp.php
'preconditions' => [
'checks' => [
'postexists' => [\App\Mpp\Checks\PostExists::class, 'check'],
],
'global' => ['usernotblocked'],
],
Перевірка має повернути null, щоб пропустити запит, або Response, щоб перервати його:
class PostExists
{
public function check(Request $request, PaymentSpec $spec): ?Response
{
return Post::find($request->route('post'))
? null
: response()->json(['error' => 'No such post.'], 404);
}
}
Route::get('/posts/{post}', ShowPost::class)
->middleware('mpp:1.00,USD,preconditions=postexists');
# Платіжні Rails
Пакет підтримує дві rails. Stripe використовує Shared Payment Tokens (SPTs), що налаштовуються через ключі Stripe та версію preview API:
STRIPE_SECRET_KEY=sk_test_...
STRIPE_NETWORK_ID=profile_...
STRIPE_API_VERSION=2026-05-27.preview
Tempo проводить розрахунки у pathUSD on-chain. Активуйте його для маршруту параметром method=tempo:
Route::get('/paid', fn () => response()->json(['data' => 'paid']))
->middleware('mpp:0.01,USD,method=tempo,scope=paid');
Ви можете приймати кілька варіантів оплати одночасно через methods=stripe|acme або додати власну rail, реалізувавши інтерфейс Verifier. Після успішної оплати відповідь містить заголовок Payment-Receipt.
# Встановлення
Встановіть пакет через Composer та опублікуйте конфігурацію:
composer require square1/laravel-mpp
php artisan vendor:publish --tag=mpp-config
Якщо ви використовуєте базу даних для сесій, опублікуйте та запустіть міграції:
php artisan vendor:publish --tag=mpp-migrations
php artisan migrate
Зверніть увагу: MPP та Stripe SPT API перебувають у стадії preview і можуть змінюватися. Поточна версія v1.1.0 розповсюджується під ліцензією MIT; вихідний код доступний на GitHub.