Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Laravel Cashier (Paddle) - Subscription billing and payment processing
.claude/skills/microck-laravel-cashier-paddle/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 18% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 79% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 144% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 64% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 36% | 0% |
Comprehensive assistance with Laravel Cashier Paddle - an expressive, fluent interface to Paddle's subscription billing services for Laravel applications.
This skill should be triggered when:
phpuse Laravel\Paddle\Billable; class User extends Authenticatable { use Billable; public function paddleName(): string|null { return $this->name; } public function paddleEmail(): string|null { return $this->email; } }
php// Create checkout session $checkout = $user->checkout('pri_deluxe_album') ->returnTo(route('dashboard')); // Display checkout button <x-paddle-button :checkout="$checkout" class="px-8 py-4"> Subscribe </x-paddle-button>
php// Single subscription $checkout = $user->subscribe('price_basic_monthly', 'default') ->returnTo(route('home')); // Multi-product subscription $checkout = $user->subscribe([ 'price_monthly', 'price_chat' => 5 // with quantity ]);
phpuse Laravel\Paddle\Cashier; // Preview prices for country $prices = Cashier::previewPrices(['pri_123', 'pri_456'], [ 'address' => ['country_code' => 'BE', 'postal_code' => '1234'] ]); // Display in Blade @foreach ($prices as $price) <li>{{ $price->product['name'] }} - {{ $price->total() }}</li> <li>Subtotal: {{ $price->subtotal() }} + Tax: {{ $price->tax() }}</li> @endforeach
php// Check various subscription states if ($user->subscribed()) { } if ($user->subscribed('default')) { } if ($user->subscribedToProduct('pro_basic')) { } if ($user->subscription()->onTrial()) { } if ($user->subscription()->onGracePeriod()) { } if ($user->subscription()->canceled()) { } if ($user->subscription()->pastDue()) { }
php// Immediate swap with proration $user->subscription()->swap('pri_456'); // Swap and invoice immediately $user->subscription()->swapAndInvoice('pri_456'); // Swap without proration $user->subscription()->noProrate()->swap('pri_456');
php// Increment/decrement quantity $user->subscription()->incrementQuantity(); $user->subscription()->incrementQuantity(5); $user->subscription()->decrementQuantity(); // Set specific quantity $user->subscription()->updateQuantity(10); // Multi-product quantity $user->subscription()->incrementQuantity(1, 'price_chat');
php// Pause at period end $user->subscription()->pause(); // Pause immediately $user->subscription()->pauseNow(); // Pause until specific date $user->subscription()->pauseUntil(now()->addMonth()); // Resume paused subscription $user->subscription()->resume();
phpuse Laravel\Paddle\Events\WebhookReceived; use Laravel\Paddle\Events\TransactionCompleted; // Listen for specific events Event::listen(TransactionCompleted::class, function ($event) { $transaction = $event->transaction; // Process completed transaction }); // Handle custom webhook events public function handle(WebhookReceived $event): void { if ($event->payload['event_type'] === 'transaction.billed') { // Handle custom event } }
php// Retrieve transactions $transactions = $user->transactions; // Refund with specific items $response = $transaction->refund('Accidental charge', [ 'pri_123', 'pri_456' => 200 // partial refund amount ]); // Full refund $response = $transaction->refund('Customer request'); // Download invoice PDF return $transaction->redirectToInvoicePdf();
Cashier Paddle uses checkout sessions to initiate payments. Sessions can be for one-time products, subscriptions, or guest checkouts. They support both overlay and inline display modes.
Any Eloquent model can become "billable" by using the Billable trait. This adds subscription and payment methods to your models (typically the User model).
Subscriptions represent recurring billing arrangements. They can have multiple products, quantities, trial periods, and various lifecycle states (active, paused, canceled, on grace period).
Transactions represent completed payments. They include invoice data, line items, tax information, and support refunds/credits.
Paddle sends webhook events for important subscription and payment events. Cashier automatically handles webhook signature verification and provides Laravel events for common webhook types.
When swapping plans or changing quantities, Cashier can automatically calculate prorated amounts or you can disable proration using noProrate().
When subscriptions are paused or canceled, they remain active until the end of the current billing period. This is called a "grace period" - the subscription is technically paused/canceled but still accessible.
This skill includes comprehensive documentation in references/:
Use view to read the reference file when detailed information is needed.
references/other.md for complete API documentationswap(), pause(), or refund()phpnamespace App\Http\Middleware; class Subscribed { public function handle(Request $request, Closure $next): Response { if (!$request->user()?->subscribed()) { return redirect('/subscribe'); } return $next($request); } } Route::get('/dashboard', fn () => '...')->middleware([Subscribed::class]);
php// With payment method up front $checkout = $user->subscribe('pri_monthly') ->returnTo(route('home')); // Without payment method (generic trial) $user->createAsCustomer(['trial_ends_at' => now()->addDays(10)]); // Extend existing trial $user->subscription()->extendTrial(now()->addDays(5)); // Activate trial early $user->subscription()->activate();
phpuse Laravel\Paddle\Checkout; $checkout = Checkout::guest(['pri_34567']) ->returnTo(route('home'));
envPADDLE_CLIENT_SIDE_TOKEN=your-paddle-client-side-token PADDLE_API_KEY=your-paddle-api-key PADDLE_RETAIN_KEY=your-paddle-retain-key PADDLE_WEBHOOK_SECRET="your-paddle-webhook-secret" PADDLE_SANDBOX=true CASHIER_CURRENCY_LOCALE=nl_BE
CustomerUpdated - Customer information changedTransactionCompleted - Payment completed successfullyTransactionUpdated - Transaction details changedSubscriptionCreated - New subscription createdSubscriptionUpdated - Subscription modifiedSubscriptionPaused - Subscription pausedSubscriptionCanceled - Subscription canceledphp// Filter subscriptions by status Subscription::query()->valid(); Subscription::query()->onTrial(); Subscription::query()->active(); Subscription::query()->canceled(); Subscription::query()->paused(); Subscription::query()->onGracePeriod();
Organized documentation extracted from official sources containing:
Add helper scripts here for:
Add templates or examples:
To refresh this skill with updated documentation:
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 16,479 | 5,843 | -65% | 1 | 1 | 0% | 3,172 | 3,758 | +18% | 0 | 0 | — |
case-02 | fail→pass | 11,061 | 5,150 | -53% | 1 | 1 | 0% | 1,898 | 3,403 | +79% | 0 | 0 | — |
case-03 | pass→pass | 8,760 | 3,951 | -55% | 1 | 1 | 0% | 1,681 | 3,292 | +96% | 0 | 0 | — |
case-04 | fail→pass | 7,876 | 4,596 | -42% | 1 | 1 | 0% | 1,365 | 3,324 | +144% | 0 | 0 | — |
case-05 | fail→pass | 11,587 | 4,146 | -64% | 1 | 1 | 0% | 1,915 | 3,147 | +64% | 0 | 0 | — |
case-06 | fail→pass | 14,768 | 3,324 | -77% | 1 | 1 | 0% | 2,259 | 3,078 | +36% | 0 | 0 | — |
case-07 | pass→pass | 4,609 | 1,936 | -58% | 1 | 1 | 0% | 827 | 2,807 | +239% | 0 | 0 | — |
case-08 | fail→pass | 26,916 | 4,068 | -85% | 1 | 1 | 0% | 2,443 | 3,252 | +33% | 0 | 0 | — |
case-09 | pass→pass | 9,279 | 2,971 | -68% | 1 | 1 | 0% | 1,604 | 2,955 | +84% | 0 | 0 | — |
case-10 | pass→pass | 5,658 | 3,116 | -45% | 1 | 1 | 0% | 899 | 3,049 | +239% | 0 | 0 | — |
case-11 | fail→pass | 12,195 | 2,753 | -77% | 1 | 1 | 0% | 2,297 | 3,057 | +33% | 0 | 0 | — |
case-12 | fail→pass | 8,410 | 3,137 | -63% | 1 | 1 | 0% | 1,381 | 3,058 | +121% | 0 | 0 | — |
case-13 | fail→pass | 13,102 | 5,558 | -58% | 1 | 1 | 0% | 2,609 | 3,665 | +40% | 0 | 0 | — |
case-14 | pass→pass | 8,127 | 3,548 | -56% | 1 | 1 | 0% | 1,408 | 3,147 | +124% | 0 | 0 | — |
case-15 | pass→pass | 7,666 | 5,181 | -32% | 1 | 1 | 0% | 1,119 | 2,994 | +168% | 0 | 0 | — |
case-16 | fail→fail | 6,651 | 2,727 | -59% | 1 | 1 | 0% | 1,109 | 3,026 | +173% | 0 | 0 | — |
case-17 | pass→pass | 6,633 | 4,133 | -38% | 1 | 1 | 0% | 1,282 | 3,098 | +142% | 0 | 0 | — |
case-18 | pass→pass | 6,749 | 4,249 | -37% | 1 | 1 | 0% | 937 | 3,001 | +220% | 0 | 0 | — |
case-19 | fail→pass | 15,400 | 5,003 | -68% | 1 | 1 | 0% | 2,612 | 3,391 | +30% | 0 | 0 | — |
case-20 | fail→fail | 7,152 | 4,312 | -40% | 1 | 1 | 0% | 1,258 | 3,258 | +159% | 0 | 0 | — |
case-21 | pass→pass | 10,266 | 7,001 | -32% | 1 | 1 | 0% | 1,957 | 3,840 | +96% | 0 | 0 | — |
case-22 | pass→fail | 9,392 | 6,098 | -35% | 1 | 1 | 0% | 1,686 | 3,691 | +119% | 0 | 0 | — |
case-23 | pass→pass | 13,164 | 8,939 | -32% | 1 | 1 | 0% | 2,731 | 4,303 | +58% | 0 | 0 | — |
case-24 | pass→pass | 18,743 | 13,294 | -29% | 1 | 1 | 0% | 3,731 | 5,363 | +44% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 24 cases were attempted. The headline lift of +38 percentage points is the difference between those two pass rates over the 24 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.