Laravel Spark Paddle

1 view
Skip to first unread message

Florio Bessinger

unread,
Aug 3, 2024, 4:56:40 PM8/3/24
to meldmomobest

In the following documentation, we will discuss how to configure a Laravel Spark installation when using the Paddle payment provider. All of Spark's configuration options are housed in your application's config/spark.php configuration file.

Of course, to use Paddle as a payment provider for your Laravel Spark application you must have an active Paddle account. While you are developing your application, you may use the Paddle Sandbox.

Next, you should configure the application environment variables that will be needed by Spark in order to access your Paddle account. These variables should be placed in your application's .env environment file.

Of course, you should adjust the variable's values to correspond to your own Paddle account's credentials. In addition, you should set the PADDLE_SANDBOX variable to true if you are using Paddle's sandbox environment. Your Paddle API credentials and webhook secret are available in your Paddle account dashboard via the "Developer Tools" section's "Authentication" and "Notifications":

In addition, your Spark powered application will need to receive webhooks from Paddle in order to keep your application's billing and subscription data in sync with Paddle's. Within your Paddle dashboard's "Notifications" management panel, you should configure Paddle to send webhook alerts to your application's /paddle/webhook URI. You should enable webhook alerts for the following events:

For Paddle to be able to send your application webhooks during local development, you will need to expose your application via a site sharing service such as Ngrok or Expose. If you are developing your application locally using Laravel Sail, you may use Sail's site sharing command.

Spark allows you to define the type of billable model that your application will be managing. Most commonly, applications bill individual users for monthly and yearly subscription plans. However, your application may choose to bill some other type of model, such as a team, organization, band, etc. The Paddle edition of Spark currently only supports a single billable model (team, user, etc.) per application.

Before continuing, you should ensure that the model class that corresponds to your billable model is using the Spark\Billable trait. In addition, your billable model's primary key should be an integer column named id:

As you may have noticed, each entry in the billables configuration array is keyed by a "slug" that is a shortened form of the billable model class. This slug can be used when accessing the Spark customer billing portal, such as or

When you installed Laravel Spark, an App\Providers\SparkServiceProvider class was created for you. Within this service provider, you will find a callback that is used by Spark to resolve the billable model instance when accessing the Spark billing portal. By default, this callback simply returns the currently authenticated user, which is the desired behavior for most applications using Laravel Spark:

However, if your application is not billing individual users, you may need to adjust this callback. For example, if your application offers team billing instead of user billing, you might customize the callback like so:

Next, let's examine the authorization callbacks that Spark will use to determine if the currently authenticated user of your application is authorized to view the billing portal for a particular billable model.

When you installed Laravel Spark, an App\Providers\SparkServiceProvider class was created for you. Within this service provider, you will find the authorization callback definition used to determine if a given user is authorized to view the billing portal for the App\Models\User billable class. Of course, if your application is not billing users, you should update the billable class and authorization callback logic to fit your application's needs. By default, Spark will simply verify that the currently authenticated user can only manage its own billing settings:

If the authorization callback returns true, the currently authenticated user will be authorized to view the billing portal and manage the billing settings for the given $billable model. If the callback returns false, the request to access the billing portal will be denied.

You are free to customize the authorize callback based on your own application's needs. For example, if your application bills teams instead of individual users, you might update the callback like so:

By default, Spark will use your billable model's name and email attributes as the name and email address associated with the Paddle customer record it creates for the model. If you would like to specify another attribute that should be used instead, you may define a paddleName and paddleEmail method on your billable model:

As we previously discussed, Spark allows you to define the type of billable model that your application will be managing. This billable model is defined within the billables array of your application's config/spark.php configuration file:

The billable configuration within the billables array contains a plans array. Within this array you may configure each of the billing plans offered by your application to that particular billable type. The monthly_id and yearly_id identifiers should correspond to the plan identifiers associated with the subscription plan within your Paddle account dashboard:

If your subscription plan only offers a monthly billing cycle, you may omit the yearly_id identifier from your plan configuration. Likewise, if your plan only offers a yearly billing cycle, you may omit the monthly_id identifier.

Once you have configured your Spark installation, you may access your application's billing portal at the /billing URI. So, if your application is being served on localhost, you may access your application's billing portal at

Many applications display billing terms and conditions during checkout. Spark allows you to easily do the same within your application's billing portal. To get started, add a terms_url configuration value in your application's config/spark.php configuration file:

I have set up laravel spark next and jetsream with inertia as the base for authentication purposes. I have also acquired myself a paddle sandbox account to set up billing. I have successfully set up a subscription plan through paddle to test. After setting up the required env variables for paddle I proceeded to sign up to the service through the /billing endpoint. I enter the sandbox details in the payment gateway I enter the paddle interface as a subscriber so i know the api is working well. Unfortunately the subscription never applies to the user account. All it does is hangs at Subscription Pending.... After inspecting the network it appears that the billing url is stuck in an endless loop. I have followed everything to a tee. Is there something I am missing?

Getting the same error, I've dig further, and for me it was on the Paddle (payment gateway) side, using their Webhook simulator, it allows me to understand that they expect from your end to have a SSL Certificate that disclose the full chain.

Meaning that, depending on how you install your certificate on your website, you should provide your public certificate and the CA-bundle file (A file where there are many certificates on top of each other).

We use Stripe for for now but we consider switching to Paddle ( ). It has higher rates but, as opposed to Stripe, Paddle is a merchant of record. It means that it takes care of your taxes. You actually sell to Paddle, so you have one client and one invoice from accounting perspective, and Paddle sells to you clients.

PayPro Global! It is a leading payment processing company that offers a wide range of innovative payment solutions. From credit and debit card processing to e-commerce payments, global sales tax handling, invoicing and more, PayPro Global has you covered.

I am using the Laravel framework which offers spark first-party subscription solution for sass. They included the paddle in the new version of that package. I decided to give it a try when I was starting my new project.

c80f0f1006
Reply all
Reply to author
Forward
0 new messages