Laravel Cashier (Paddle): React Implementation Not Storing Transactions & Subscriptions
I. Introduction
Laravel Cashier is a billing and subscription management solution built on top of Laravel, a popular PHP web application framework. Cashier integrates with various payment gateways, including Paddle, to handle recurring billing and manage subscriptions. In this response, we will discuss how to implement Laravel Cashier with Paddle in a React application and address the issue of missing transactions and subscriptions.
II. Setting up Laravel Cashier with Paddle
To set up Laravel Cashier with Paddle, follow these steps:
- Install Laravel and Cashier: Ensure you have Laravel installed on your server. After that, install Cashier using Composer:
composer require laravel/cashier
-
Configure Cashier: Update your
.env
file with your Stripe or Mollie credentials if you're using Stripe or Mollie as your payment gateway. For Paddle, you don't need to provide any credentials since Cashier doesn't support Paddle directly. Instead, you'll use Paddle's webhooks to sync transactions and subscriptions with Laravel. -
Install Laravel Sanctum: Laravel Sanctum is an authentication system that will help secure your application's routes. Install it using Composer:
composer require laravel/sanctum
- Configure Laravel Sanctum: Update your
.env
file with the following settings:
SANCTUM_STATEFUL_DOMAINS=localhost:3000,your-app-domain.com
-
Set up Paddle: Create an account on Paddle (https://paddle.com/) and create a new product. Make sure to note down the product ID.
-
Create a route in Laravel: Create a new route in Laravel to handle Paddle's webhooks. This route will be responsible for receiving webhook events and storing them in your database.
// routes/web.php
Route::post('/paddle/webhook', 'App\Http\Controllers\WebhookController@handlePaddleWebhook')->name('paddle.webhook');
- Create a controller: Create a new controller named
WebhookController
and implement thehandlePaddleWebhook
method:
// app/Http/Controllers/WebhookController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class WebhookController extends Controller
{
public function handlePaddleWebhook(Request $request)
{
// Validate the signature
$paddleSignature = $request->header('X-Paddle-Signature');
$webhookSecret = env('PADDLE_WEBHOOK_SECRET');
if (!hash_equals(sha1($request->getContent()), $paddleSignature)) {
abort(401);
}
// Process the webhook event
$event = json_decode($request->getContent());
// Store the event in your database
// ...
return response()->json(['status' => 'success']);
}
}
Make sure to set the PADDLE_WEBHOOK_SECRET
environment variable with your Paddle webhook secret.
- Set up Laravel Cashier with Paddle: Since Laravel Cashier doesn't support Paddle directly, you'll need to use a package like
laravel-cashier-paddle
to interact with Paddle's API. Install the package using Composer:
composer require spatie/laravel-cashier-paddle
- Configure the package: Update your
.env
file with your Paddle API key:
PADDLE_API_KEY=your_paddle_api_key
- Register the service provider: Register the
Spatie\Cashier\CashierServiceProvider
in yourapp/Providers/AppServiceProvider.php
file:
// app/Providers/AppServiceProvider.php
namespace App\Providers;
use Spatie\Cashier\CashierServiceProvider;
class AppServiceProvider extends CashierServiceProvider
{
// ...
}
-
Create a User model: Laravel Cashier requires a User model to manage subscriptions and transactions. Make sure you have a User model in your Laravel application.
-
Set up the User model: Update the User model to use Laravel Cashier:
// app/Models/User.php
namespace App\Models;
use Laravel\Cashier\Billable;
use Spatie\Cashier\Contracts\Billable as CashierBillable;
class User implements CashierBillable
{
use Billable;
// ...
}
III. Implementing Paddle in React
To implement Paddle in a React application, you can use the react-paddle-checkout
package. Follow these steps:
- Install the package: Install the
react-paddle-checkout
package using npm or yarn:
npm install react-paddle-checkout
or
yarn add react-paddle-checkout
- Import the package: Import the
Checkout
component fromreact-paddle-checkout
in your React component:
import Checkout from 'react-paddle-checkout';
- Set up the Checkout component: Use the
Checkout
component to create a checkout form:
function CheckoutPage() {
const productId = 'your_product_id';
const priceId = 'your_price_id';
return (
<Checkout
productId={productId}
priceId={priceId}
onSuccess={(order) => {
// Handle successful checkout
}}
onError={(error) => {
// Handle checkout error
}}
>
{({ openCheckout }) => (
<button onClick={openCheckout}>Buy Now</button>
)}
</Checkout>
);
}
Replace your_product_id
and your_price_id
with your actual product and price IDs from Paddle.
IV. Syncing Transactions and Subscriptions
Since Laravel Cashier doesn't support Paddle directly, you'll need to use Laravel's webhooks to sync transactions and subscriptions between Laravel and Paddle. The webhook controller we created earlier will handle this.
When a user creates a new subscription or makes a payment through Paddle, Paddle will send a webhook event to your Laravel application. The webhook controller we created earlier will receive this event and store it in your database.
You can use Laravel's Eloquent ORM to query your database and fetch the latest transactions and subscriptions for a user.
V. Conclusion
In this response, we discussed how to implement Laravel Cashier with Paddle in a React application and addressed the issue of missing transactions and subscriptions. By following the steps outlined above, you should be able to set up a functional billing and subscription management system using Laravel Cashier, Paddle, and React.