Paddle Setup

This guide explains how Laratic integrates with Paddle Billing via Laravel Cashier Paddle and how to configure your Paddle account, sandbox mode, and environment variables.

1. Create Paddle Sandbox Account

Sign up for a Paddle sandbox account complete all onboarding steps in the Paddle dashboard before continuing.

2. Enable Sandbox Mode

For development and testing, enable Sandbox mode in the Paddle dashboard > Developer Tools > Authentication. Create the following tokens:

  • API key
  • Client side token

These values should be stored in your .env file; see the example in the code snippet below.


PADDLE_SANDBOX=true # Do not add this to your production environment
PADDLE_CLIENT_SIDE_TOKEN=XXXXXXXXXXXXXXXXXXXXX
PADDLE_API_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
PADDLE_WEBHOOK_SECRET=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # After you create the webhook in the Paddle dashboard

After changing these values, clear and cache your configuration:

php artisan config:clear
php artisan config:cache

3. Add App URL to Checkout Overlay Tab

Laratic uses the Checkout Overlay feature to display the Paddle checkout overlay. You need to add your app URL to the Checkout Overlay tab in the Paddle dashboard > Checkout > Checkout Settings > General > Default Payment Linke. in developmene you can use https://127.0.0.1:8000.

See the dedicated Paddle Webhooks page for details on configuring and testing webhooks.

Webhooks

Webhooks are used to receive events from Paddle and keep your local database in sync. See the dedicated Paddle Webhooks page for details on configuring and testing webhooks.

Switching Between Sandbox & Production

When you are ready to go live:

  • Set PADDLE_SANDBOX=false.
  • Replace your sandbox credentials with live Paddle Vendor ID, auth code, and public key.
  • Verify that webhooks are configured for the live environment.

Always test new billing flows thoroughly in sandbox before switching your production credentials.

References

Category Path / Name Description
Model App\Models\Order Order model with Paddle transaction relationship
Model App\Models\Plan Subscription plan model with Paddle price ID
Model App\Models\Product One-time product model with Paddle price ID
Controller App\Http\Controllers\PlanController Handles subscription plan viewing and checkout
Controller App\Http\Controllers\ProductController Handles one-time product viewing and checkout
Controller App\Http\Controllers\OrderController Handles user order viewing and status checks
Controller App\Http\Controllers\TransactionController Handles user transaction viewing and invoice downloads
Controller App\Http\Controllers\SubscriptionController Handles subscription status and pending pages
Controller App\Http\Controllers\Admin\OrderController Admin controller for viewing orders and transactions
Livewire App\Livewire\Subscription\Manage Subscription management component (swap, cancel, update payment)
Livewire App\Livewire\Orders\OrdersTable User orders table with search and pagination
Livewire App\Livewire\Transactions\TransactionsTable User transactions table with pagination
Livewire App\Livewire\Admin\Subscription\CancelSubscription Admin component for canceling user subscriptions
Livewire App\Livewire\Admin\Transactions\TransactionsTable Admin transactions table component
Listener App\Listeners\PaddleEventListener Handles Paddle webhook events (price.created, price.updated, transaction.completed)
Helper app/Helpers/paddle_helpers.php Helper functions for processing Paddle webhook payloads
Command App\Console\Commands\DeleteOldIncompleteOrders Artisan command to clean up incomplete orders older than 24 hours
Migration create_orders_table Migration for orders table with paddle_id field
Migration create_plans_table Migration for plans table with paddle_id field
Migration create_products_table Migration for products table with paddle_id field
Migration create_subscriptions_table Laravel Cashier migration for subscriptions with paddle_id
Migration create_customers_table Laravel Cashier migration for customers with paddle_id
Migration create_transactions_table Laravel Cashier migration for transactions with paddle_id
Routes GET /plans/start (plans.start) Route to view available subscription plans
Routes GET /plans/{price_id} (plans.show) Route to initiate subscription checkout
Routes GET /products (products.index) Route to view available products
Routes GET /products/{product} (products.show) Route to initiate product checkout
Routes GET /orders (orders.index) Route to view user orders
Routes GET /orders/pending/{order_id} (orders.pending) Route to view order pending page after checkout
Routes GET /orders/status/{order_id} (orders.status) Route to check order status (returns JSON)
Routes GET /subscription/pending (subscription.pending) Route to view subscription pending page after checkout
Routes GET /subscription/status (subscription.status) Route to check subscription status (returns JSON)
Routes GET /subscription (subscription.manage) Route to manage subscription (requires subscribed middleware)
Routes GET /transactions (transactions.index) Route to view user transactions
Routes GET /admin/orders (admin.orders.index) Admin route to view all orders