{"id":49158,"date":"2025-04-25T06:23:10","date_gmt":"2025-04-25T06:23:10","guid":{"rendered":"https:\/\/www.devopsschool.com\/blog\/?p=49158"},"modified":"2025-04-25T06:23:10","modified_gmt":"2025-04-25T06:23:10","slug":"best-alternative-of-laravel-spark-with-stripe-paddle","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/blog\/best-alternative-of-laravel-spark-with-stripe-paddle\/","title":{"rendered":"Best Alternative of Laravel Spark with Stripe\/Paddle"},"content":{"rendered":"\n<p>You want the <strong>control centre<\/strong> of your subscription logic (plans, user status, features, invoicing rules) to be inside your core Laravel application, using PayPal and Paytm purely as external <strong>payment processors<\/strong>.<\/p>\n\n\n\n<p>This is a valid approach, often chosen for greater flexibility or when dealing with payment gateways not supported by tools like Cashier\/Spark. However, it does mean you&#8217;ll be responsible for building more of the logic yourself.<\/p>\n\n\n\n<p>Laravel Spark is <strong>not<\/strong> suitable for this, as its primary value comes from its tight integration with Cashier (Stripe\/Paddle) and handling much of the billing logic via those providers.<\/p>\n\n\n\n<p>Here\u2019s a suggested approach using Laravel libraries to speed up development while keeping core logic in-house:<\/p>\n\n\n\n<p><strong>1. Core Subscription Management (In-House Logic)<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Goal:<\/strong> Manage plans, features, user subscription status, trial periods, and renewals within your application&#8217;s database and logic.<\/li>\n\n\n\n<li><strong>Approach:<\/strong> You&#8217;ll need Eloquent models for <code>Plan<\/code>, <code>Feature<\/code>, <code>Subscription<\/code> (linking User to Plan, storing status, trial end, next billing date, etc.), maybe <code>SubscriptionUsage<\/code> for metered billing.<\/li>\n\n\n\n<li><strong>Libraries to Help:<\/strong>\n<ul class=\"wp-block-list\">\n<li><strong><code>webaune\/laravel-subscriptions<\/code><\/strong>: This package looks like a strong candidate. Its description explicitly states <strong>&#8220;Payments are out of scope for this package&#8221;<\/strong>. It focuses on providing the database structure (migrations) and Eloquent models\/traits for managing plans, features, and subscriptions within your Laravel application itself. This aligns perfectly with your goal of keeping the core logic internal.<\/li>\n\n\n\n<li><strong>Custom Build:<\/strong> You can always build these models and the associated logic (checking <code>isActive()<\/code>, <code>isOnTrial()<\/code>, <code>canUseFeature()<\/code>, handling renewals) yourself using standard Laravel practices. <code>webaune\/laravel-subscriptions<\/code> just gives you a head start.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p><strong>2. Invoice Generation (In-House Logic)<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Goal:<\/strong> Generate PDF invoices based on your internal subscription data when a payment is confirmed or a billing cycle renews. Store or allow download of these PDFs.<\/li>\n\n\n\n<li><strong>Approach:<\/strong> Use a dedicated Laravel PDF generation package combined with your internal subscription data.<\/li>\n\n\n\n<li><strong>Libraries to Help:<\/strong>\n<ul class=\"wp-block-list\">\n<li><strong><code>laraveldaily\/laravel-invoices<\/code><\/strong>: A popular and robust package specifically for creating customizable PDF invoices. You feed it data (buyer info, items, prices, taxes from <em>your<\/em> models), and it generates the PDF.<\/li>\n\n\n\n<li><strong><code>elegantly\/laravel-invoices<\/code><\/strong>: A newer, well-regarded alternative that also focuses on generating PDFs from Eloquent data and includes database storage for invoice records.<\/li>\n\n\n\n<li><strong>Base PDF Packages:<\/strong> You could use lower-level packages like <code>barryvdh\/laravel-dompdf<\/code> or <code>spatie\/laravel-pdf<\/code> and create the HTML invoice template yourself, but the dedicated invoice packages provide more structure.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p><strong>3. PayPal Integration (Payment Processing Only)<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Goal:<\/strong> Initiate payments (one-time or recurring setup), securely handle redirects\/callbacks, and listen for webhook notifications (e.g., <code>PAYMENT.SALE.COMPLETED<\/code>, <code>BILLING.SUBSCRIPTION.ACTIVATED<\/code>, <code>PAYMENT.CAPTURE.COMPLETED<\/code>).<\/li>\n\n\n\n<li><strong>Approach:<\/strong> Use a reliable PayPal SDK wrapper for Laravel.<\/li>\n\n\n\n<li><strong>Libraries to Help:<\/strong>\n<ul class=\"wp-block-list\">\n<li><strong><code>srmklive\/paypal<\/code><\/strong>: This is a widely used and generally well-maintained package for integrating PayPal into Laravel. It simplifies interacting with the PayPal REST API (getting tokens, creating orders, capturing payments, setting up subscriptions) and handling IPN\/Webhooks compared to using the raw PayPal PHP SDK directly. This is likely your best option for accelerating PayPal integration.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p><strong>4. Paytm Integration (Payment Processing Only)<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Goal:<\/strong> Initiate payments (supporting methods like UPI, cards, NetBanking, including recurring mandates like UPI Autopay\/eNACH), handle callbacks, and process webhook notifications.<\/li>\n\n\n\n<li><strong>Approach:<\/strong> Use the official Paytm SDK or a trusted Laravel wrapper.<\/li>\n\n\n\n<li><strong>Libraries to Help:<\/strong>\n<ul class=\"wp-block-list\">\n<li><strong>Official <code>paytm\/paytm-pg<\/code> SDK<\/strong>: Use the official SDK provided by Paytm. This gives you the most direct control but requires more manual setup within your Laravel app.<\/li>\n\n\n\n<li><strong><code>anandsiddharth\/laravel-paytm-wallet<\/code><\/strong>: This third-party package was specifically mentioned in a tutorial regarding Paytm subscriptions in Laravel. You&#8217;ll need to assess its current maintenance status and compatibility with the latest Laravel versions and Paytm APIs. If it&#8217;s up-to-date, it could save significant time. <em>Evaluate this first<\/em>.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p><strong>Putting It All Together (The Workflow):<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Define Plans\/Features:<\/strong> Use your internal models (possibly assisted by <code>webaune\/laravel-subscriptions<\/code>) to define subscription plans and their associated features in your database.<\/li>\n\n\n\n<li><strong>User Subscribes:<\/strong>\n<ul class=\"wp-block-list\">\n<li>User selects a plan in your UI.<\/li>\n\n\n\n<li>Create a <code>Subscription<\/code> record in your database (using your internal models\/package) with a status like <code>pending<\/code> or <code>initiating<\/code>.<\/li>\n\n\n\n<li>Based on the user&#8217;s chosen gateway (PayPal\/Paytm), call the appropriate package (<code>srmklive\/paypal<\/code> or Paytm package) to initiate the payment\/subscription setup on the gateway&#8217;s side.<\/li>\n\n\n\n<li>Redirect the user to PayPal\/Paytm to authorize the payment\/mandate.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Handle Gateway Callbacks\/Redirects:<\/strong> User returns to your site. Show a pending\/success\/failure message. The real confirmation often comes via webhook.<\/li>\n\n\n\n<li><strong>Handle Gateway Webhooks:<\/strong>\n<ul class=\"wp-block-list\">\n<li>Create dedicated webhook controllers\/routes for PayPal and Paytm.<\/li>\n\n\n\n<li>Verify the incoming webhook authenticity.<\/li>\n\n\n\n<li>When a successful payment\/activation webhook arrives:\n<ul class=\"wp-block-list\">\n<li>Find the corresponding internal <code>Subscription<\/code> record.<\/li>\n\n\n\n<li>Update its status to <code>active<\/code>.<\/li>\n\n\n\n<li>Set the <code>trial_ends_at<\/code>, <code>starts_at<\/code>, <code>ends_at<\/code> (next billing date) based on the plan and payment confirmation.<\/li>\n\n\n\n<li>Store relevant gateway subscription IDs (e.g., PayPal Subscription ID) on your internal <code>Subscription<\/code> model for reference (e.g., for cancellations).<\/li>\n\n\n\n<li>Trigger invoice generation using your chosen invoicing package (<code>laraveldaily\/laravel-invoices<\/code> or <code>elegantly\/laravel-invoices<\/code>), feeding it data from your internal <code>Subscription<\/code> and <code>Plan<\/code> models. Save\/store the invoice.<\/li>\n\n\n\n<li>Grant the user access to features based on the active subscription.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>When a renewal payment webhook arrives, update the <code>ends_at<\/code> date and generate a new invoice.<\/li>\n\n\n\n<li>Handle failure\/cancellation webhooks by updating the internal <code>Subscription<\/code> status accordingly (e.g., <code>past_due<\/code>, <code>cancelled<\/code>) and potentially revoking feature access after any grace period.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Manage Subscription Changes (Cancel, Swap):<\/strong>\n<ul class=\"wp-block-list\">\n<li>Provide UI for users to manage their subscriptions.<\/li>\n\n\n\n<li>When a user cancels: Update the internal <code>Subscription<\/code> status (e.g., set <code>ends_at<\/code> to the end of the current paid period, mark as <code>cancelling<\/code>). Call the gateway API (via <code>srmklive\/paypal<\/code> or Paytm package) to cancel the recurring payment on their end.<\/li>\n\n\n\n<li>Swapping plans involves more complex logic: potentially cancelling the old gateway subscription, creating a new one, calculating proration (if needed &#8211; this logic would be <em>yours<\/em> to implement), and updating the internal <code>Subscription<\/code> record.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p><strong>Summary of Suggested Libraries:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Core Subscriptions:<\/strong> <code>webaune\/laravel-subscriptions<\/code> (or custom Eloquent models)<\/li>\n\n\n\n<li><strong>Invoicing:<\/strong> <code>laraveldaily\/laravel-invoices<\/code> or <code>elegantly\/laravel-invoices<\/code><\/li>\n\n\n\n<li><strong>PayPal:<\/strong> <code>srmklive\/paypal<\/code><\/li>\n\n\n\n<li><strong>Paytm:<\/strong> <code>anandsiddharth\/laravel-paytm-wallet<\/code> (evaluate first) or official <code>paytm\/paytm-pg<\/code> SDK<\/li>\n<\/ul>\n\n\n\n<p>This approach gives you the desired control over the core logic while leveraging specialized packages to handle the complex and time-consuming parts of PDF generation and payment gateway API interactions. It requires more development effort than Spark but precisely meets your requirement of keeping the subscription business logic &#8220;in-house&#8221;.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>You want the control centre of your subscription logic (plans, user status, features, invoicing rules) to be inside your core Laravel application, using PayPal and Paytm purely as external payment&#8230; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"_joinchat":[],"footnotes":""},"categories":[2],"tags":[],"class_list":["post-49158","post","type-post","status-publish","format-standard","hentry","category-uncategorised"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/49158","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/comments?post=49158"}],"version-history":[{"count":1,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/49158\/revisions"}],"predecessor-version":[{"id":49159,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/49158\/revisions\/49159"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media?parent=49158"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/categories?post=49158"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/tags?post=49158"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}