CINXE.COM
Laravel Cashier (Paddle) - Laravel 11.x - The PHP Framework For Web Artisans
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Laravel Cashier (Paddle) - Laravel 11.x - The PHP Framework For Web Artisans</title> <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"> <link rel="canonical" href="https://laravel.com/docs/11.x/cashier-paddle"> <!-- Primary Meta Tags --> <meta name="title" content="Laravel - The PHP Framework For Web Artisans"> <meta name="description" content="Laravel is a PHP web application framework with expressive, elegant syntax. We’ve already laid the foundation — freeing you to create without sweating the small things."> <!-- Open Graph / Facebook --> <meta property="og:type" content="website"> <meta property="og:url" content="https://laravel.com/"> <meta property="og:title" content="Laravel - The PHP Framework For Web Artisans"> <meta property="og:description" content="Laravel is a PHP web application framework with expressive, elegant syntax. We’ve already laid the foundation — freeing you to create without sweating the small things."> <meta property="og:image" content="https://laravel.com/img/og-image.jpg"> <!-- Twitter --> <meta property="twitter:card" content="summary_large_image"> <meta property="twitter:url" content="https://laravel.com/"> <meta property="twitter:title" content="Laravel - The PHP Framework For Web Artisans"> <meta property="twitter:description" content="Laravel is a PHP web application framework with expressive, elegant syntax. We’ve already laid the foundation — freeing you to create without sweating the small things."> <meta property="twitter:image" content="https://laravel.com/img/og-image.jpg"> <!-- Favicon --> <link rel="apple-touch-icon" sizes="180x180" href="/img/favicon/apple-touch-icon.png"> <link rel="icon" type="image/png" sizes="32x32" href="/img/favicon/favicon-32x32.png"> <link rel="icon" type="image/png" sizes="16x16" href="/img/favicon/favicon-16x16.png"> <link rel="manifest" href="/img/favicon/site.webmanifest"> <link rel="mask-icon" href="/img/favicon/safari-pinned-tab.svg" color="#ff2d20"> <link rel="shortcut icon" href="/img/favicon/favicon.ico"> <meta name="msapplication-TileColor" content="#ff2d20"> <meta name="msapplication-config" content="/img/favicon/browserconfig.xml"> <meta name="theme-color" content="#ffffff"> <meta name="color-scheme" content="light"> <link rel="preconnect" href="https://E3MIRNPJH5-dsn.algolia.net" crossorigin /> <link rel="stylesheet" href="https://use.typekit.net/ins2wgm.css"> <link rel="preload" as="style" href="https://laravel.com/build/assets/app-dc063eeb.css" /><link rel="modulepreload" href="https://laravel.com/build/assets/app-70a5a3a6.js" /><link rel="modulepreload" href="https://laravel.com/build/assets/docs-45166933.js" /><link rel="stylesheet" href="https://laravel.com/build/assets/app-dc063eeb.css" /><script type="module" src="https://laravel.com/build/assets/app-70a5a3a6.js"></script><script type="module" src="https://laravel.com/build/assets/docs-45166933.js"></script> <!-- Fathom - beautiful, simple website analytics --> <script src="https://cdn.usefathom.com/script.js" data-site="DVMEKBYF" defer></script> <!-- / Fathom --> <!-- Clearbit --> <script async src="https://tag.clearbitscripts.com/v1/pk_97d2bf69f817feb07be42fcda1460119/tags.js" referrerpolicy="strict-origin-when-cross-origin"></script> <script> const alwaysLightMode = false; </script> <script> function updateTheme() { if (!('theme' in localStorage)) { localStorage.theme = 'system'; } switch (localStorage.theme) { case 'system': if (window.matchMedia('(prefers-color-scheme: dark)').matches) { document.documentElement.classList.add('dark'); document.documentElement.setAttribute('data-theme', 'dark'); } else { document.documentElement.classList.remove('dark'); document.documentElement.setAttribute('data-theme', 'light'); } document.documentElement.setAttribute('color-theme', 'system'); break; case 'dark': document.documentElement.classList.add('dark'); document.documentElement.setAttribute('color-theme', 'dark'); document.documentElement.setAttribute('data-theme', 'dark'); break; case 'light': document.documentElement.classList.remove('dark'); document.documentElement.setAttribute('color-theme', 'light'); document.documentElement.setAttribute('data-theme', 'light'); break; } updateThemeAndSchemeColor(); } function updateThemeAndSchemeColor() { if (! alwaysLightMode) { if (document.documentElement.classList.contains('dark')) { document.querySelector('meta[name="color-scheme"]').setAttribute('content', 'dark'); document.querySelector('meta[name="theme-color"]').setAttribute('content', '#171923'); return; } document.querySelector('meta[name="color-scheme"]').setAttribute('content', 'light'); document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff'); } } updateTheme(); </script> </head> <body x-data="{ navIsOpen: false, }" class="w-full h-full font-sans antialiased text-gray-900 language-php" data-instant-intensity="0" > <a id="skip-to-content-link" href="#main-content" class="absolute bg-gray-100 px-4 py-2 top-3 left-3 text-gray-700 shadow-xl" > Skip to content </a> <div class="items-center justify-center bg-gradient-to-b from-red-500 to-red-600 p-2 text-center text-white text-sm h-9"> <template id="news-herd"> <div> <svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 text-white" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" stroke-linecap="round" fill="none" stroke-linejoin="round"> <path stroke="none" d="M0 0h24v24H0z" fill="none"/> <path d="M3 4m0 1a1 1 0 0 1 1 -1h16a1 1 0 0 1 1 1v14a1 1 0 0 1 -1 1h-16a1 1 0 0 1 -1 -1z" /> <path d="M7 8v1" /> <path d="M17 8v1" /> <path d="M12.5 4c-.654 1.486 -1.26 3.443 -1.5 9h2.5c-.19 2.867 .094 5.024 .5 7" /> <path d="M7 15.5c3.667 2 6.333 2 10 0" /> </svg> </div> <div class="mt-px ml-1"> Get started with PHP and Laravel faster than ever using <a href="https://herd.laravel.com" class="underline">Laravel Herd</a>. </div> </template> <template id="news-laracon"> <div><svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3.055 11H5a2 2 0 012 2v1a2 2 0 002 2 2 2 0 012 2v2.945M8 3.935V5.5A2.5 2.5 0 0010.5 8h.5a2 2 0 012 2 2 2 0 104 0 2 2 0 012-2h1.064M15 20.488V18a2 2 0 012-2h3.064M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg></div> <div class="mt-px ml-1"> Join us in Dallas, TX! Tickets are now available for <a href="https://laracon.us" class="underline">Laracon US</a>. </div> </template> <template id="news-laracon-in"> <div><svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3.055 11H5a2 2 0 012 2v1a2 2 0 002 2 2 2 0 012 2v2.945M8 3.935V5.5A2.5 2.5 0 0010.5 8h.5a2 2 0 012 2 2 2 0 104 0 2 2 0 012-2h1.064M15 20.488V18a2 2 0 012-2h3.064M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg></div> <div class="mt-px ml-1"> Let's go to India! Tickets are now available for <a href="https://laracon.in" class="underline">Laracon IN</a>. </div> </template> <template id="news-laracon-eu"> <div><svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3.055 11H5a2 2 0 012 2v1a2 2 0 002 2 2 2 0 012 2v2.945M8 3.935V5.5A2.5 2.5 0 0010.5 8h.5a2 2 0 012 2 2 2 0 104 0 2 2 0 012-2h1.064M15 20.488V18a2 2 0 012-2h3.064M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg></div> <div class="mt-px ml-1"> Let's go to Europe! Tickets are now available for <a href="https://laracon.eu" class="underline">Laracon EU</a>. </div> </template> <template id="news-laracon-au"> <div><svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3.055 11H5a2 2 0 012 2v1a2 2 0 002 2 2 2 0 012 2v2.945M8 3.935V5.5A2.5 2.5 0 0010.5 8h.5a2 2 0 012 2 2 2 0 104 0 2 2 0 012-2h1.064M15 20.488V18a2 2 0 012-2h3.064M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg></div> <div class="mt-px ml-1"> Let's go down under! Tickets are now available for <a href="https://laracon.au" class="underline">Laracon AU</a>. </div> </template> <template id="news-forge"> <div><svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"></path></svg></div> <div class="mt-px ml-1"> Servers with PHP 8.3 are now available for provisioning via <a href="https://forge.laravel.com" class="underline">Laravel Forge</a>. </div> </template> <template id="news-vapor"> <div><svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 15a4 4 0 004 4h9a5 5 0 10-.1-9.999 5.002 5.002 0 10-9.78 2.096A4.001 4.001 0 003 15z"></path></svg></div> <div class="mt-px ml-1"> Deploy Laravel with the infinite scale of serverless using <a href="https://vapor.laravel.com" class="underline">Laravel Vapor</a>. </div> </template> <template id="news-cloud"> <div class="mt-px ml-1"> Join the waitlist for <a href="https://cloud.laravel.com" class="underline">Laravel Cloud</a><span class="hidden md:inline">, the future of shipping</span>. </div> </template> <template id="news-nightwatch"> <div class="mt-px ml-1"> Join the waitlist for <a href="https://nightwatch.laravel.com" class="underline">Laravel Nightwatch</a><span class="hidden md:inline">, first-class monitoring designed for Laravel</span>. </div> </template> <template id="news-pulse"> <div><svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 15a4 4 0 004 4h9a5 5 0 10-.1-9.999 5.002 5.002 0 10-9.78 2.096A4.001 4.001 0 003 15z"></path></svg></div> <div class="mt-px ml-1"> How's your health? Check your application's vital signs using <a href="https://pulse.laravel.com" class="underline">Laravel Pulse</a>. </div> </template> <template id="news-reverb"> <div> <svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 text-white" width="44" height="44" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"> <path stroke="none" d="M0 0h24v24H0z" fill="none"/> <path d="M3.707 6.293l2.586 -2.586a1 1 0 0 1 1.414 0l5.586 5.586a1 1 0 0 1 0 1.414l-2.586 2.586a1 1 0 0 1 -1.414 0l-5.586 -5.586a1 1 0 0 1 0 -1.414z" /> <path d="M6 10l-3 3l3 3l3 -3" /> <path d="M10 6l3 -3l3 3l-3 3" /> <path d="M12 12l1.5 1.5" /> <path d="M14.5 17a2.5 2.5 0 0 0 2.5 -2.5" /> <path d="M15 21a6 6 0 0 0 6 -6" /> </svg> </div> <div class="mt-px ml-1"> Incoming transmission received. <a href="https://reverb.laravel.com" class="underline">Laravel Reverb</a> is now available! </div> </template> <template id="news-nova"> <div> <svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"> <path stroke-linecap="round" stroke-linejoin="round" d="M15.59 14.37a6 6 0 01-5.84 7.38v-4.8m5.84-2.58a14.98 14.98 0 006.16-12.12A14.98 14.98 0 009.631 8.41m5.96 5.96a14.926 14.926 0 01-5.841 2.58m-.119-8.54a6 6 0 00-7.381 5.84h4.8m2.581-5.84a14.927 14.927 0 00-2.58 5.84m2.699 2.7c-.103.021-.207.041-.311.06a15.09 15.09 0 01-2.448-2.448 14.9 14.9 0 01.06-.312m-2.24 2.39a4.493 4.493 0 00-1.757 4.306 4.493 4.493 0 004.306-1.758M16.5 9a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0z"></path> </svg> </div> <div class="mt-px ml-1"> Take your administration backend to another dimension with <a href="https://nova.laravel.com" class="underline">Laravel Nova</a>. </div> </template> <template id="news-careers"> <div> <svg class="w-5 h-5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"> <path stroke-linecap="round" stroke-linejoin="round" d="M20.25 14.15v4.25c0 1.094-.787 2.036-1.872 2.18-2.087.277-4.216.42-6.378.42s-4.291-.143-6.378-.42c-1.085-.144-1.872-1.086-1.872-2.18v-4.25m16.5 0a2.18 2.18 0 0 0 .75-1.661V8.706c0-1.081-.768-2.015-1.837-2.175a48.114 48.114 0 0 0-3.413-.387m4.5 8.006c-.194.165-.42.295-.673.38A23.978 23.978 0 0 1 12 15.75c-2.648 0-5.195-.429-7.577-1.22a2.016 2.016 0 0 1-.673-.38m0 0A2.18 2.18 0 0 1 3 12.489V8.706c0-1.081.768-2.015 1.837-2.175a48.111 48.111 0 0 1 3.413-.387m7.5 0V5.25A2.25 2.25 0 0 0 13.5 3h-3a2.25 2.25 0 0 0-2.25 2.25v.894m7.5 0a48.667 48.667 0 0 0-7.5 0M12 12.75h.008v.008H12v-.008Z" /> </svg> </div> <div class="mt-px ml-1"> Laravel is hiring! <a href="https://laravel.com/careers" class="underline">Help us build the future of Laravel</a>. </div> </template> </div> <script> const activeNewsTemplate = document.getElementById( 'news-'+JSON.parse('[\u0022cloud\u0022,\u0022nightwatch\u0022]')[Math.floor(Math.random() * 2)] ) activeNewsTemplate.replaceWith(activeNewsTemplate.content) </script> <div class="relative dark:bg-dark-700" id="docsScreen"> <div class="relative lg:flex lg:items-start"> <aside class="hidden fixed top-0 bottom-0 left-0 z-20 w-16 bg-gradient-to-b from-gray-100 to-white transition-all duration-300 lg:sticky lg:w-80 lg:shrink-0 lg:flex lg:flex-col lg:justify-end lg:items-end 2xl:max-w-lg 2xl:w-full dark:from-dark-800 dark:to-dark-700"> <div class="relative max-h-screen overflow-auto flex-1 flex flex-col xl:w-80"> <a href="/" class="flex items-center py-8 px-4 lg:px-8 xl:px-16"> <img class="w-8 h-8 shrink-0 transition-all duration-300 lg:w-12 lg:h-12" src="/img/logomark.min.svg" alt="Laravel" width="50" height="52" > <img src="/img/logotype.min.svg" alt="Laravel" class="hidden ml-4 lg:block" width="114" height="29" > </a> <div class="px-4 pb-10 lg:px-8 xl:px-16"> <nav id="indexed-nav" class="hidden lg:block lg:mt-4"> <div class="docs_sidebar"> <ul> <li> <h2>Prologue</h2> <ul> <li> <a href="/docs/11.x/releases">Release Notes</a> </li> <li> <a href="/docs/11.x/upgrade">Upgrade Guide</a> </li> <li> <a href="/docs/11.x/contributions">Contribution Guide</a> </li> </ul> </li> <li> <h2>Getting Started</h2> <ul> <li> <a href="/docs/11.x/installation">Installation</a> </li> <li> <a href="/docs/11.x/configuration">Configuration</a> </li> <li> <a href="/docs/11.x/structure">Directory Structure</a> </li> <li> <a href="/docs/11.x/frontend">Frontend</a> </li> <li> <a href="/docs/11.x/starter-kits">Starter Kits</a> </li> <li> <a href="/docs/11.x/deployment">Deployment</a> </li> </ul> </li> <li> <h2>Architecture Concepts</h2> <ul> <li> <a href="/docs/11.x/lifecycle">Request Lifecycle</a> </li> <li> <a href="/docs/11.x/container">Service Container</a> </li> <li> <a href="/docs/11.x/providers">Service Providers</a> </li> <li> <a href="/docs/11.x/facades">Facades</a> </li> </ul> </li> <li> <h2>The Basics</h2> <ul> <li> <a href="/docs/11.x/routing">Routing</a> </li> <li> <a href="/docs/11.x/middleware">Middleware</a> </li> <li> <a href="/docs/11.x/csrf">CSRF Protection</a> </li> <li> <a href="/docs/11.x/controllers">Controllers</a> </li> <li> <a href="/docs/11.x/requests">Requests</a> </li> <li> <a href="/docs/11.x/responses">Responses</a> </li> <li> <a href="/docs/11.x/views">Views</a> </li> <li> <a href="/docs/11.x/blade">Blade Templates</a> </li> <li> <a href="/docs/11.x/vite">Asset Bundling</a> </li> <li> <a href="/docs/11.x/urls">URL Generation</a> </li> <li> <a href="/docs/11.x/session">Session</a> </li> <li> <a href="/docs/11.x/validation">Validation</a> </li> <li> <a href="/docs/11.x/errors">Error Handling</a> </li> <li> <a href="/docs/11.x/logging">Logging</a> </li> </ul> </li> <li> <h2>Digging Deeper</h2> <ul> <li> <a href="/docs/11.x/artisan">Artisan Console</a> </li> <li> <a href="/docs/11.x/broadcasting">Broadcasting</a> </li> <li> <a href="/docs/11.x/cache">Cache</a> </li> <li> <a href="/docs/11.x/collections">Collections</a> </li> <li> <a href="/docs/11.x/concurrency">Concurrency</a> </li> <li> <a href="/docs/11.x/context">Context</a> </li> <li> <a href="/docs/11.x/contracts">Contracts</a> </li> <li> <a href="/docs/11.x/events">Events</a> </li> <li> <a href="/docs/11.x/filesystem">File Storage</a> </li> <li> <a href="/docs/11.x/helpers">Helpers</a> </li> <li> <a href="/docs/11.x/http-client">HTTP Client</a> </li> <li> <a href="/docs/11.x/localization">Localization</a> </li> <li> <a href="/docs/11.x/mail">Mail</a> </li> <li> <a href="/docs/11.x/notifications">Notifications</a> </li> <li> <a href="/docs/11.x/packages">Package Development</a> </li> <li> <a href="/docs/11.x/processes">Processes</a> </li> <li> <a href="/docs/11.x/queues">Queues</a> </li> <li> <a href="/docs/11.x/rate-limiting">Rate Limiting</a> </li> <li> <a href="/docs/11.x/strings">Strings</a> </li> <li> <a href="/docs/11.x/scheduling">Task Scheduling</a> </li> </ul> </li> <li> <h2>Security</h2> <ul> <li> <a href="/docs/11.x/authentication">Authentication</a> </li> <li> <a href="/docs/11.x/authorization">Authorization</a> </li> <li> <a href="/docs/11.x/verification">Email Verification</a> </li> <li> <a href="/docs/11.x/encryption">Encryption</a> </li> <li> <a href="/docs/11.x/hashing">Hashing</a> </li> <li> <a href="/docs/11.x/passwords">Password Reset</a> </li> </ul> </li> <li> <h2>Database</h2> <ul> <li> <a href="/docs/11.x/database">Getting Started</a> </li> <li> <a href="/docs/11.x/queries">Query Builder</a> </li> <li> <a href="/docs/11.x/pagination">Pagination</a> </li> <li> <a href="/docs/11.x/migrations">Migrations</a> </li> <li> <a href="/docs/11.x/seeding">Seeding</a> </li> <li> <a href="/docs/11.x/redis">Redis</a> </li> <li> <a href="/docs/11.x/mongodb">MongoDB</a> </li> </ul> </li> <li> <h2>Eloquent ORM</h2> <ul> <li> <a href="/docs/11.x/eloquent">Getting Started</a> </li> <li> <a href="/docs/11.x/eloquent-relationships">Relationships</a> </li> <li> <a href="/docs/11.x/eloquent-collections">Collections</a> </li> <li> <a href="/docs/11.x/eloquent-mutators">Mutators / Casts</a> </li> <li> <a href="/docs/11.x/eloquent-resources">API Resources</a> </li> <li> <a href="/docs/11.x/eloquent-serialization">Serialization</a> </li> <li> <a href="/docs/11.x/eloquent-factories">Factories</a> </li> </ul> </li> <li> <h2>Testing</h2> <ul> <li> <a href="/docs/11.x/testing">Getting Started</a> </li> <li> <a href="/docs/11.x/http-tests">HTTP Tests</a> </li> <li> <a href="/docs/11.x/console-tests">Console Tests</a> </li> <li> <a href="/docs/11.x/dusk">Browser Tests</a> </li> <li> <a href="/docs/11.x/database-testing">Database</a> </li> <li> <a href="/docs/11.x/mocking">Mocking</a> </li> </ul> </li> <li class="sub--on"> <h2>Packages</h2> <ul> <li> <a href="/docs/11.x/starter-kits#laravel-breeze">Breeze</a> </li> <li> <a href="/docs/11.x/billing">Cashier (Stripe)</a> </li> <li class="active"> <a href="/docs/11.x/cashier-paddle">Cashier (Paddle)</a> </li> <li> <a href="/docs/11.x/dusk">Dusk</a> </li> <li> <a href="/docs/11.x/envoy">Envoy</a> </li> <li> <a href="/docs/11.x/fortify">Fortify</a> </li> <li> <a href="/docs/11.x/folio">Folio</a> </li> <li> <a href="/docs/11.x/homestead">Homestead</a> </li> <li> <a href="/docs/11.x/horizon">Horizon</a> </li> <li> <a href="https://jetstream.laravel.com">Jetstream</a> </li> <li> <a href="/docs/11.x/mix">Mix</a> </li> <li> <a href="/docs/11.x/octane">Octane</a> </li> <li> <a href="/docs/11.x/passport">Passport</a> </li> <li> <a href="/docs/11.x/pennant">Pennant</a> </li> <li> <a href="/docs/11.x/pint">Pint</a> </li> <li> <a href="/docs/11.x/precognition">Precognition</a> </li> <li> <a href="/docs/11.x/prompts">Prompts</a> </li> <li> <a href="/docs/11.x/pulse">Pulse</a> </li> <li> <a href="/docs/11.x/reverb">Reverb</a> </li> <li> <a href="/docs/11.x/sail">Sail</a> </li> <li> <a href="/docs/11.x/sanctum">Sanctum</a> </li> <li> <a href="/docs/11.x/scout">Scout</a> </li> <li> <a href="/docs/11.x/socialite">Socialite</a> </li> <li> <a href="/docs/11.x/telescope">Telescope</a> </li> <li> <a href="/docs/11.x/valet">Valet</a> </li> </ul> </li> <li> <a href="/api/11.x">API Documentation</a> </li> </ul> </div> </nav> <template id="promote-forge"> <div class="mt-4 px-3 py-2 border-dashed border-gray-200 border rounded-lg text-xs leading-loose text-gray-700 lg:block dark:border-gray-400 dark:text-gray-200"> <span class="font-medium">Laravel Forge:</span> create and manage PHP 8 servers. Deploy your Laravel applications in seconds. <a class="underline text-red-600" href="https://forge.laravel.com">Sign up now!</a>. </div> </template> <template id="promote-vapor"> <div class="mt-4 px-3 py-2 border-dashed border-gray-200 border rounded-lg text-xs leading-loose text-gray-700 lg:block dark:border-gray-400 dark:text-gray-200"> <span class="font-medium">Laravel Vapor:</span> experience extreme scale on a dedicated serverless platform for Laravel. <a class="underline text-red-600" href="https://vapor.laravel.com">Sign up now!</a>. </div> </template> <template id="promote-nova"> <div class="mt-4 px-3 py-2 border-dashed border-gray-200 border rounded-lg text-xs leading-loose text-gray-700 lg:block dark:border-gray-400 dark:text-gray-200"> <span class="font-medium">Laravel Nova:</span> The next generation of Nova is <a class="underline text-red-600" href="https://nova.laravel.com">now available</a>. </div> </template> <template id="promote-pulse"> <div class="mt-4 px-3 py-2 border-dashed border-gray-200 border rounded-lg text-xs leading-loose text-gray-700 lg:block dark:border-gray-400 dark:text-gray-200"> <span class="font-medium">Laravel Pulse:</span> How's your health? Check your application's vital signs using <a href="https://pulse.laravel.com" class="underline text-red-600">Laravel Pulse</a>. </div> </template> <template id="promote-reverb"> <div class="mt-4 px-3 py-2 border-dashed border-gray-200 border rounded-lg text-xs leading-loose text-gray-700 lg:block dark:border-gray-400 dark:text-gray-200"> <span class="font-medium">Laravel Reverb:</span> You can easily build dynamic, real-time Laravel applications using WebSockets. <a href="https://reverb.laravel.com" class="underline text-red-600">Laravel Reverb</a> is now available! </div> </template> <script> const activePromotionTemplate = document.getElementById( 'promote-'+JSON.parse('[\u0022forge\u0022,\u0022vapor\u0022,\u0022nova\u0022,\u0022pulse\u0022,\u0022reverb\u0022]')[Math.floor(Math.random() * 5)] ) activePromotionTemplate.replaceWith(activePromotionTemplate.content) </script> </div> </div> </aside> <header class="lg:hidden" @keydown.window.escape="navIsOpen = false" @click.away="navIsOpen = false" > <div class="relative mx-auto w-full py-10 bg-white transition duration-200 dark:bg-dark-700"> <div class="mx-auto px-8 sm:px-16 flex items-center justify-between"> <a href="/" class="flex items-center"> <img class="" src="/img/logomark.min.svg" alt="Laravel" width="50" height="52"> <img class="hidden ml-5 sm:block" src="/img/logotype.min.svg" alt="Laravel" width="114" height="29"> </a> <div class="flex-1 flex items-center justify-end"> <button id="header__sun" onclick="toSystemMode()" title="Switch to system theme" class="relative w-10 h-10 focus:outline-none focus:shadow-outline text-gray-500"> <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-sun" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"> <path stroke="none" d="M0 0h24v24H0z" fill="none"></path> <circle cx="12" cy="12" r="4"></circle> <path d="M3 12h1m8 -9v1m8 8h1m-9 8v1m-6.4 -15.4l.7 .7m12.1 -.7l-.7 .7m0 11.4l.7 .7m-12.1 -.7l-.7 .7"></path> </svg> </button> <button id="header__moon" onclick="toLightMode()" title="Switch to light mode" class="relative w-10 h-10 focus:outline-none focus:shadow-outline text-gray-500"> <svg style="width:24px;height:24px" viewBox="0 0 24 24"> <path fill="currentColor" d="M17.75,4.09L15.22,6.03L16.13,9.09L13.5,7.28L10.87,9.09L11.78,6.03L9.25,4.09L12.44,4L13.5,1L14.56,4L17.75,4.09M21.25,11L19.61,12.25L20.2,14.23L18.5,13.06L16.8,14.23L17.39,12.25L15.75,11L17.81,10.95L18.5,9L19.19,10.95L21.25,11M18.97,15.95C19.8,15.87 20.69,17.05 20.16,17.8C19.84,18.25 19.5,18.67 19.08,19.07C15.17,23 8.84,23 4.94,19.07C1.03,15.17 1.03,8.83 4.94,4.93C5.34,4.53 5.76,4.17 6.21,3.85C6.96,3.32 8.14,4.21 8.06,5.04C7.79,7.9 8.75,10.87 10.95,13.06C13.14,15.26 16.1,16.22 18.97,15.95M17.33,17.97C14.5,17.81 11.7,16.64 9.53,14.5C7.36,12.31 6.2,9.5 6.04,6.68C3.23,9.82 3.34,14.64 6.35,17.66C9.37,20.67 14.19,20.78 17.33,17.97Z" /> </svg> </button> <button id="header__indeterminate" onclick="toDarkMode()" title="Switch to dark mode" class="relative w-10 h-10 focus:outline-none focus:shadow-outline text-gray-500"> <svg style="width:24px;height:24px" viewBox="0 0 24 24"> <path fill="currentColor" d="M12 2A10 10 0 0 0 2 12A10 10 0 0 0 12 22A10 10 0 0 0 22 12A10 10 0 0 0 12 2M12 4A8 8 0 0 1 20 12A8 8 0 0 1 12 20V4Z" /> </svg> </button> <button class="ml-2 relative w-10 h-10 p-2 text-red-600 lg:hidden focus:outline-none focus:shadow-outline" aria-label="Menu" @click.prevent="navIsOpen = !navIsOpen"> <svg x-show="! navIsOpen" x-transition.opacity class="absolute inset-0 mt-2 ml-2 w-6 h-6" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"><line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="18" x2="21" y2="18"></line></svg> <svg x-show="navIsOpen" x-transition.opacity x-cloak class="absolute inset-0 mt-2 ml-2 w-6 h-6" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg> </button> </div> </div> <span :class="{ 'shadow-sm': navIsOpen }" class="absolute inset-0 z-20 pointer-events-none"></span> </div> <div x-show="navIsOpen" x-transition:enter="duration-150" x-transition:leave="duration-100 ease-in" x-cloak > <nav x-show="navIsOpen" x-cloak class="absolute w-full transform origin-top shadow-sm z-10" x-transition:enter="duration-150 ease-out" x-transition:enter-start="opacity-0 -translate-y-8 scale-75" x-transition:enter-end="opacity-100 scale-100" x-transition:leave="duration-100 ease-in" x-transition:leave-start="opacity-100 scale-100" x-transition:leave-end="opacity-0 -translate-y-8 scale-75" > <div class="relative p-8 bg-white docs_sidebar dark:bg-dark-600"> <ul> <li> <h2>Prologue</h2> <ul> <li> <a href="/docs/11.x/releases">Release Notes</a> </li> <li> <a href="/docs/11.x/upgrade">Upgrade Guide</a> </li> <li> <a href="/docs/11.x/contributions">Contribution Guide</a> </li> </ul> </li> <li> <h2>Getting Started</h2> <ul> <li> <a href="/docs/11.x/installation">Installation</a> </li> <li> <a href="/docs/11.x/configuration">Configuration</a> </li> <li> <a href="/docs/11.x/structure">Directory Structure</a> </li> <li> <a href="/docs/11.x/frontend">Frontend</a> </li> <li> <a href="/docs/11.x/starter-kits">Starter Kits</a> </li> <li> <a href="/docs/11.x/deployment">Deployment</a> </li> </ul> </li> <li> <h2>Architecture Concepts</h2> <ul> <li> <a href="/docs/11.x/lifecycle">Request Lifecycle</a> </li> <li> <a href="/docs/11.x/container">Service Container</a> </li> <li> <a href="/docs/11.x/providers">Service Providers</a> </li> <li> <a href="/docs/11.x/facades">Facades</a> </li> </ul> </li> <li> <h2>The Basics</h2> <ul> <li> <a href="/docs/11.x/routing">Routing</a> </li> <li> <a href="/docs/11.x/middleware">Middleware</a> </li> <li> <a href="/docs/11.x/csrf">CSRF Protection</a> </li> <li> <a href="/docs/11.x/controllers">Controllers</a> </li> <li> <a href="/docs/11.x/requests">Requests</a> </li> <li> <a href="/docs/11.x/responses">Responses</a> </li> <li> <a href="/docs/11.x/views">Views</a> </li> <li> <a href="/docs/11.x/blade">Blade Templates</a> </li> <li> <a href="/docs/11.x/vite">Asset Bundling</a> </li> <li> <a href="/docs/11.x/urls">URL Generation</a> </li> <li> <a href="/docs/11.x/session">Session</a> </li> <li> <a href="/docs/11.x/validation">Validation</a> </li> <li> <a href="/docs/11.x/errors">Error Handling</a> </li> <li> <a href="/docs/11.x/logging">Logging</a> </li> </ul> </li> <li> <h2>Digging Deeper</h2> <ul> <li> <a href="/docs/11.x/artisan">Artisan Console</a> </li> <li> <a href="/docs/11.x/broadcasting">Broadcasting</a> </li> <li> <a href="/docs/11.x/cache">Cache</a> </li> <li> <a href="/docs/11.x/collections">Collections</a> </li> <li> <a href="/docs/11.x/concurrency">Concurrency</a> </li> <li> <a href="/docs/11.x/context">Context</a> </li> <li> <a href="/docs/11.x/contracts">Contracts</a> </li> <li> <a href="/docs/11.x/events">Events</a> </li> <li> <a href="/docs/11.x/filesystem">File Storage</a> </li> <li> <a href="/docs/11.x/helpers">Helpers</a> </li> <li> <a href="/docs/11.x/http-client">HTTP Client</a> </li> <li> <a href="/docs/11.x/localization">Localization</a> </li> <li> <a href="/docs/11.x/mail">Mail</a> </li> <li> <a href="/docs/11.x/notifications">Notifications</a> </li> <li> <a href="/docs/11.x/packages">Package Development</a> </li> <li> <a href="/docs/11.x/processes">Processes</a> </li> <li> <a href="/docs/11.x/queues">Queues</a> </li> <li> <a href="/docs/11.x/rate-limiting">Rate Limiting</a> </li> <li> <a href="/docs/11.x/strings">Strings</a> </li> <li> <a href="/docs/11.x/scheduling">Task Scheduling</a> </li> </ul> </li> <li> <h2>Security</h2> <ul> <li> <a href="/docs/11.x/authentication">Authentication</a> </li> <li> <a href="/docs/11.x/authorization">Authorization</a> </li> <li> <a href="/docs/11.x/verification">Email Verification</a> </li> <li> <a href="/docs/11.x/encryption">Encryption</a> </li> <li> <a href="/docs/11.x/hashing">Hashing</a> </li> <li> <a href="/docs/11.x/passwords">Password Reset</a> </li> </ul> </li> <li> <h2>Database</h2> <ul> <li> <a href="/docs/11.x/database">Getting Started</a> </li> <li> <a href="/docs/11.x/queries">Query Builder</a> </li> <li> <a href="/docs/11.x/pagination">Pagination</a> </li> <li> <a href="/docs/11.x/migrations">Migrations</a> </li> <li> <a href="/docs/11.x/seeding">Seeding</a> </li> <li> <a href="/docs/11.x/redis">Redis</a> </li> <li> <a href="/docs/11.x/mongodb">MongoDB</a> </li> </ul> </li> <li> <h2>Eloquent ORM</h2> <ul> <li> <a href="/docs/11.x/eloquent">Getting Started</a> </li> <li> <a href="/docs/11.x/eloquent-relationships">Relationships</a> </li> <li> <a href="/docs/11.x/eloquent-collections">Collections</a> </li> <li> <a href="/docs/11.x/eloquent-mutators">Mutators / Casts</a> </li> <li> <a href="/docs/11.x/eloquent-resources">API Resources</a> </li> <li> <a href="/docs/11.x/eloquent-serialization">Serialization</a> </li> <li> <a href="/docs/11.x/eloquent-factories">Factories</a> </li> </ul> </li> <li> <h2>Testing</h2> <ul> <li> <a href="/docs/11.x/testing">Getting Started</a> </li> <li> <a href="/docs/11.x/http-tests">HTTP Tests</a> </li> <li> <a href="/docs/11.x/console-tests">Console Tests</a> </li> <li> <a href="/docs/11.x/dusk">Browser Tests</a> </li> <li> <a href="/docs/11.x/database-testing">Database</a> </li> <li> <a href="/docs/11.x/mocking">Mocking</a> </li> </ul> </li> <li class="sub--on"> <h2>Packages</h2> <ul> <li> <a href="/docs/11.x/starter-kits#laravel-breeze">Breeze</a> </li> <li> <a href="/docs/11.x/billing">Cashier (Stripe)</a> </li> <li class="active"> <a href="/docs/11.x/cashier-paddle">Cashier (Paddle)</a> </li> <li> <a href="/docs/11.x/dusk">Dusk</a> </li> <li> <a href="/docs/11.x/envoy">Envoy</a> </li> <li> <a href="/docs/11.x/fortify">Fortify</a> </li> <li> <a href="/docs/11.x/folio">Folio</a> </li> <li> <a href="/docs/11.x/homestead">Homestead</a> </li> <li> <a href="/docs/11.x/horizon">Horizon</a> </li> <li> <a href="https://jetstream.laravel.com">Jetstream</a> </li> <li> <a href="/docs/11.x/mix">Mix</a> </li> <li> <a href="/docs/11.x/octane">Octane</a> </li> <li> <a href="/docs/11.x/passport">Passport</a> </li> <li> <a href="/docs/11.x/pennant">Pennant</a> </li> <li> <a href="/docs/11.x/pint">Pint</a> </li> <li> <a href="/docs/11.x/precognition">Precognition</a> </li> <li> <a href="/docs/11.x/prompts">Prompts</a> </li> <li> <a href="/docs/11.x/pulse">Pulse</a> </li> <li> <a href="/docs/11.x/reverb">Reverb</a> </li> <li> <a href="/docs/11.x/sail">Sail</a> </li> <li> <a href="/docs/11.x/sanctum">Sanctum</a> </li> <li> <a href="/docs/11.x/scout">Scout</a> </li> <li> <a href="/docs/11.x/socialite">Socialite</a> </li> <li> <a href="/docs/11.x/telescope">Telescope</a> </li> <li> <a href="/docs/11.x/valet">Valet</a> </li> </ul> </li> <li> <a href="/api/11.x">API Documentation</a> </li> </ul> </div> </nav> </div> </header> <section class="flex-1 dark:bg-dark-700"> <div class="max-w-screen-lg px-8 sm:px-16 lg:px-24"> <div class="flex flex-col items-end border-b border-gray-200 py-1 transition-colors dark:border-gray-700 lg:mt-8 lg:flex-row-reverse"> <div class="hidden lg:flex items-center justify-center ml-8"> <button id="header__sun" onclick="toSystemMode()" title="Switch to system theme" class="relative w-10 h-10 focus:outline-none focus:shadow-outline text-gray-500"> <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-sun" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"> <path stroke="none" d="M0 0h24v24H0z" fill="none"></path> <circle cx="12" cy="12" r="4"></circle> <path d="M3 12h1m8 -9v1m8 8h1m-9 8v1m-6.4 -15.4l.7 .7m12.1 -.7l-.7 .7m0 11.4l.7 .7m-12.1 -.7l-.7 .7"></path> </svg> </button> <button id="header__moon" onclick="toLightMode()" title="Switch to light mode" class="relative w-10 h-10 focus:outline-none focus:shadow-outline text-gray-500"> <svg style="width:24px;height:24px" viewBox="0 0 24 24"> <path fill="currentColor" d="M17.75,4.09L15.22,6.03L16.13,9.09L13.5,7.28L10.87,9.09L11.78,6.03L9.25,4.09L12.44,4L13.5,1L14.56,4L17.75,4.09M21.25,11L19.61,12.25L20.2,14.23L18.5,13.06L16.8,14.23L17.39,12.25L15.75,11L17.81,10.95L18.5,9L19.19,10.95L21.25,11M18.97,15.95C19.8,15.87 20.69,17.05 20.16,17.8C19.84,18.25 19.5,18.67 19.08,19.07C15.17,23 8.84,23 4.94,19.07C1.03,15.17 1.03,8.83 4.94,4.93C5.34,4.53 5.76,4.17 6.21,3.85C6.96,3.32 8.14,4.21 8.06,5.04C7.79,7.9 8.75,10.87 10.95,13.06C13.14,15.26 16.1,16.22 18.97,15.95M17.33,17.97C14.5,17.81 11.7,16.64 9.53,14.5C7.36,12.31 6.2,9.5 6.04,6.68C3.23,9.82 3.34,14.64 6.35,17.66C9.37,20.67 14.19,20.78 17.33,17.97Z" /> </svg> </button> <button id="header__indeterminate" onclick="toDarkMode()" title="Switch to dark mode" class="relative w-10 h-10 focus:outline-none focus:shadow-outline text-gray-500"> <svg style="width:24px;height:24px" viewBox="0 0 24 24"> <path fill="currentColor" d="M12 2A10 10 0 0 0 2 12A10 10 0 0 0 12 22A10 10 0 0 0 22 12A10 10 0 0 0 12 2M12 4A8 8 0 0 1 20 12A8 8 0 0 1 12 20V4Z" /> </svg> </button> </div> <div class="w-full lg:w-40 lg:pl-12"> <div> <label class="text-gray-600 text-xs tracking-widest uppercase dark:text-gray-500" for="version-switcher">Version</label> <div x-data class="relative w-full bg-white transition-all duration-500 focus-within:border-gray-600 dark:bg-gray-800"> <select id="version-switcher" aria-label="Laravel version" class="appearance-none flex-1 w-full px-0 py-1 placeholder-gray-900 tracking-wide bg-white border-transparent focus:outline-none dark:bg-dark-700 dark:text-gray-400 dark:placeholder-gray-500" @change="window.location = $event.target.value" > <option value="https://laravel.com/docs/master/cashier-paddle">Master</option> <option selected value="https://laravel.com/docs/11.x/cashier-paddle">11.x</option> <option value="https://laravel.com/docs/10.x/cashier-paddle">10.x</option> <option value="https://laravel.com/docs/9.x/cashier-paddle">9.x</option> <option value="https://laravel.com/docs/8.x/cashier-paddle">8.x</option> <option value="https://laravel.com/docs/7.x/cashier-paddle">7.x</option> <option value="https://laravel.com/docs/6.x/cashier-paddle">6.x</option> <option value="https://laravel.com/docs/5.8/cashier-paddle">5.8</option> <option value="https://laravel.com/docs/5.7/cashier-paddle">5.7</option> <option value="https://laravel.com/docs/5.6/cashier-paddle">5.6</option> <option value="https://laravel.com/docs/5.5/cashier-paddle">5.5</option> <option value="https://laravel.com/docs/5.4/cashier-paddle">5.4</option> <option value="https://laravel.com/docs/5.3/cashier-paddle">5.3</option> <option value="https://laravel.com/docs/5.2/cashier-paddle">5.2</option> <option value="https://laravel.com/docs/5.1/cashier-paddle">5.1</option> <option value="https://laravel.com/docs/5.0/cashier-paddle">5.0</option> <option value="https://laravel.com/docs/4.2/cashier-paddle">4.2</option> </select> <img class="absolute inset-y-0 right-0 mt-2.5 w-2.5 h-2.5 text-gray-900 pointer-events-none dark:hidden" src="/img/icons/drop_arrow.min.svg" alt="" width="10" height="10"> <img class="absolute inset-y-0 right-0 mt-2.5 w-2.5 h-2.5 text-gray-900 pointer-events-none hidden dark:block" src="/img/icons/drop_arrow.dark.min.svg" alt="" width="10" height="10"> </div> </div> </div> <div class="relative mt-8 flex items-center justify-end w-full h-10 lg:mt-0"> <div class="flex-1 flex items-center"> <button id="docsearch" class="text-gray-800 transition-colors dark:text-gray-400 w-full"></button> </div> </div> </div> <section class="mt-8 md:mt-16"> <section class="docs_main max-w-prose"> <div id="main-content"> <h1>Laravel Cashier (Paddle)</h1> <ul> <li> <a href="#introduction">Introduction</a> </li> <li> <a href="#upgrading-cashier">Upgrading Cashier</a> </li> <li> <a href="#installation">Installation</a> <ul> <li> <a href="#paddle-sandbox">Paddle Sandbox</a> </li> </ul> </li> <li> <a href="#configuration">Configuration</a> <ul> <li> <a href="#billable-model">Billable Model</a> </li> <li> <a href="#api-keys">API Keys</a> </li> <li> <a href="#paddle-js">Paddle JS</a> </li> <li> <a href="#currency-configuration">Currency Configuration</a> </li> <li> <a href="#overriding-default-models">Overriding Default Models</a> </li> </ul> </li> <li> <a href="#quickstart">Quickstart</a> <ul> <li> <a href="#quickstart-selling-products">Selling Products</a> </li> <li> <a href="#quickstart-selling-subscriptions">Selling Subscriptions</a> </li> </ul> </li> <li> <a href="#checkout-sessions">Checkout Sessions</a> <ul> <li> <a href="#overlay-checkout">Overlay Checkout</a> </li> <li> <a href="#inline-checkout">Inline Checkout</a> </li> <li> <a href="#guest-checkouts">Guest Checkouts</a> </li> </ul> </li> <li> <a href="#price-previews">Price Previews</a> <ul> <li> <a href="#customer-price-previews">Customer Price Previews</a> </li> <li> <a href="#price-discounts">Discounts</a> </li> </ul> </li> <li> <a href="#customers">Customers</a> <ul> <li> <a href="#customer-defaults">Customer Defaults</a> </li> <li> <a href="#retrieving-customers">Retrieving Customers</a> </li> <li> <a href="#creating-customers">Creating Customers</a> </li> </ul> </li> <li> <a href="#subscriptions">Subscriptions</a> <ul> <li> <a href="#creating-subscriptions">Creating Subscriptions</a> </li> <li> <a href="#checking-subscription-status">Checking Subscription Status</a> </li> <li> <a href="#subscription-single-charges">Subscription Single Charges</a> </li> <li> <a href="#updating-payment-information">Updating Payment Information</a> </li> <li> <a href="#changing-plans">Changing Plans</a> </li> <li> <a href="#subscription-quantity">Subscription Quantity</a> </li> <li> <a href="#subscriptions-with-multiple-products">Subscriptions With Multiple Products</a> </li> <li> <a href="#multiple-subscriptions">Multiple Subscriptions</a> </li> <li> <a href="#pausing-subscriptions">Pausing Subscriptions</a> </li> <li> <a href="#canceling-subscriptions">Canceling Subscriptions</a> </li> </ul> </li> <li> <a href="#subscription-trials">Subscription Trials</a> <ul> <li> <a href="#with-payment-method-up-front">With Payment Method Up Front</a> </li> <li> <a href="#without-payment-method-up-front">Without Payment Method Up Front</a> </li> <li> <a href="#extend-or-activate-a-trial">Extend or Activate a Trial</a> </li> </ul> </li> <li> <a href="#handling-paddle-webhooks">Handling Paddle Webhooks</a> <ul> <li> <a href="#defining-webhook-event-handlers">Defining Webhook Event Handlers</a> </li> <li> <a href="#verifying-webhook-signatures">Verifying Webhook Signatures</a> </li> </ul> </li> <li> <a href="#single-charges">Single Charges</a> <ul> <li> <a href="#charging-for-products">Charging for Products</a> </li> <li> <a href="#refunding-transactions">Refunding Transactions</a> </li> <li> <a href="#crediting-transactions">Crediting Transactions</a> </li> </ul> </li> <li> <a href="#transactions">Transactions</a> <ul> <li> <a href="#past-and-upcoming-payments">Past and Upcoming Payments</a> </li> </ul> </li> <li> <a href="#testing">Testing</a> </li> </ul> <h2 id="introduction"><a href="#introduction">Introduction</a></h2> <div class="mb-10 max-w-2xl mx-auto px-4 py-8 shadow-lg lg:flex lg:items-center callout"> <div class="w-20 h-20 mb-6 flex items-center justify-center shrink-0 lg:mb-0 bg-red-600"> <div class="opacity-75"><svg width="6" height="35" viewBox="0 0 6 35" xmlns="http://www.w3.org/2000/svg"><title>exclamation</title><path d="M0 29h6v6H0v-6zM0 0h6v24H0V0z" fill="#FFF" fill-rule="nonzero"/></svg> </div> </div> <p class="mb-0 lg:ml-6 callout"> This documentation is for Cashier Paddle 2.x's integration with Paddle Billing. If you're still using Paddle Classic, you should use <a href="https://github.com/laravel/cashier-paddle/tree/1.x">Cashier Paddle 1.x</a>.</p> </div> <p><a href="https://github.com/laravel/cashier-paddle">Laravel Cashier Paddle</a> provides an expressive, fluent interface to <a href="https://paddle.com">Paddle's</a> subscription billing services. It handles almost all of the boilerplate subscription billing code you are dreading. In addition to basic subscription management, Cashier can handle: swapping subscriptions, subscription "quantities", subscription pausing, cancelation grace periods, and more.</p> <p>Before digging into Cashier Paddle, we recommend you also review Paddle's <a href="https://developer.paddle.com/concepts/overview">concept guides</a> and <a href="https://developer.paddle.com/api-reference/overview">API documentation</a>.</p> <h2 id="upgrading-cashier"><a href="#upgrading-cashier">Upgrading Cashier</a></h2> <p>When upgrading to a new version of Cashier, it's important that you carefully review <a href="https://github.com/laravel/cashier-paddle/blob/master/UPGRADE.md">the upgrade guide</a>.</p> <h2 id="installation"><a href="#installation">Installation</a></h2> <p>First, install the Cashier package for Paddle using the Composer package manager:</p> <div class="code-container"> <pre><code data-theme="olaolu-palenight" data-lang="shell" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BFC7D5;">composer </span><span style="color: #BFC7D5;">require</span><span style="color: #BFC7D5;"> </span><span style="color: #BFC7D5;">laravel/cashier-paddle</span></div></code></pre> </div> <p>Next, you should publish the Cashier migration files using the <code>vendor:publish</code> Artisan command:</p> <div class="code-container"> <pre><code data-theme="olaolu-palenight" data-lang="shell" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BFC7D5;">php </span><span style="color: #BFC7D5;">artisan</span><span style="color: #BFC7D5;"> </span><span style="color: #BFC7D5;">vendor:publish</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">--tag=</span><span style="color: #D9F5DD;">"</span><span style="color: #C3E88D;">cashier-migrations</span><span style="color: #D9F5DD;">"</span></div></code></pre> </div> <p>Then, you should run your application's database migrations. The Cashier migrations will create a new <code>customers</code> table. In addition, new <code>subscriptions</code> and <code>subscription_items</code> tables will be created to store all of your customer's subscriptions. Lastly, a new <code>transactions</code> table will be created to store all of the Paddle transactions associated with your customers:</p> <div class="code-container"> <pre><code data-theme="olaolu-palenight" data-lang="shell" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BFC7D5;">php </span><span style="color: #BFC7D5;">artisan</span><span style="color: #BFC7D5;"> </span><span style="color: #BFC7D5;">migrate</span></div></code></pre> </div> <div class="mb-10 max-w-2xl mx-auto px-4 py-8 shadow-lg lg:flex lg:items-center callout"> <div class="w-20 h-20 mb-6 flex items-center justify-center shrink-0 lg:mb-0 bg-red-600"> <div class="opacity-75"><svg width="6" height="35" viewBox="0 0 6 35" xmlns="http://www.w3.org/2000/svg"><title>exclamation</title><path d="M0 29h6v6H0v-6zM0 0h6v24H0V0z" fill="#FFF" fill-rule="nonzero"/></svg> </div> </div> <p class="mb-0 lg:ml-6 callout"> To ensure Cashier properly handles all Paddle events, remember to <a href="#handling-paddle-webhooks">set up Cashier's webhook handling</a>.</p> </div> <h3 id="paddle-sandbox"><a href="#paddle-sandbox">Paddle Sandbox</a></h3> <p>During local and staging development, you should <a href="https://sandbox-login.paddle.com/signup">register a Paddle Sandbox account</a>. This account will give you a sandboxed environment to test and develop your applications without making actual payments. You may use Paddle's <a href="https://developer.paddle.com/concepts/payment-methods/credit-debit-card">test card numbers</a> to simulate various payment scenarios.</p> <p>When using the Paddle Sandbox environment, you should set the <code>PADDLE_SANDBOX</code> environment variable to <code>true</code> within your application's <code>.env</code> file:</p> <div class="code-container"> <pre><code data-theme="olaolu-palenight" data-lang="ini" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">PADDLE_SANDBOX</span><span style="color: #BFC7D5;">=true</span></div></code></pre> </div> <p>After you have finished developing your application you may <a href="https://paddle.com">apply for a Paddle vendor account</a>. Before your application is placed into production, Paddle will need to approve your application's domain.</p> <h2 id="configuration"><a href="#configuration">Configuration</a></h2> <h3 id="billable-model"><a href="#billable-model">Billable Model</a></h3> <p>Before using Cashier, you must add the <code>Billable</code> trait to your user model definition. This trait provides various methods to allow you to perform common billing tasks, such as creating subscriptions and updating payment method information:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Laravel\Paddle\</span><span style="color: #FFCB8B;">Billable</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #C792EA;">class</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB6B;">User</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">extends</span><span style="color: #BFC7D5;"> </span><span style="color: #A9C77D;">Authenticatable</span></div><div class='line'><span style="color: #BFC7D5;">{</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">Billable</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color: #BFC7D5;">}</span></div></code></pre> <p>If you have billable entities that are not users, you may also add the trait to those classes:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Database\Eloquent\</span><span style="color: #FFCB8B;">Model</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Laravel\Paddle\</span><span style="color: #FFCB8B;">Billable</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #C792EA;">class</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB6B;">Team</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">extends</span><span style="color: #BFC7D5;"> </span><span style="color: #A9C77D;">Model</span></div><div class='line'><span style="color: #BFC7D5;">{</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">Billable</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color: #BFC7D5;">}</span></div></code></pre> <h3 id="api-keys"><a href="#api-keys">API Keys</a></h3> <p>Next, you should configure your Paddle keys in your application's <code>.env</code> file. You can retrieve your Paddle API keys from the Paddle control panel:</p> <div class="code-container"> <pre><code data-theme="olaolu-palenight" data-lang="ini" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">PADDLE_CLIENT_SIDE_TOKEN</span><span style="color: #BFC7D5;">=your-paddle-client-side-token</span></div><div class='line'><span style="color: #C792EA;">PADDLE_API_KEY</span><span style="color: #BFC7D5;">=your-paddle-api-key</span></div><div class='line'><span style="color: #C792EA;">PADDLE_RETAIN_KEY</span><span style="color: #BFC7D5;">=your-paddle-retain-key</span></div><div class='line'><span style="color: #C792EA;">PADDLE_WEBHOOK_SECRET</span><span style="color: #BFC7D5;">=</span><span style="color: #D9F5DD;">"</span><span style="color: #C3E88D;">your-paddle-webhook-secret</span><span style="color: #D9F5DD;">"</span></div><div class='line'><span style="color: #C792EA;">PADDLE_SANDBOX</span><span style="color: #BFC7D5;">=true</span></div></code></pre> </div> <p>The <code>PADDLE_SANDBOX</code> environment variable should be set to <code>true</code> when you are using <a href="#paddle-sandbox">Paddle's Sandbox environment</a>. The <code>PADDLE_SANDBOX</code> variable should be set to <code>false</code> if you are deploying your application to production and are using Paddle's live vendor environment.</p> <p>The <code>PADDLE_RETAIN_KEY</code> is optional and should only be set if you're using Paddle with <a href="https://developer.paddle.com/paddlejs/retain">Retain</a>.</p> <h3 id="paddle-js"><a href="#paddle-js">Paddle JS</a></h3> <p>Paddle relies on its own JavaScript library to initiate the Paddle checkout widget. You can load the JavaScript library by placing the <code>@paddleJS</code> Blade directive right before your application layout's closing <code></head></code> tag:</p> <div class="code-container"> <pre><code data-theme="olaolu-palenight" data-lang="blade" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #89DDFF;"><</span><span style="color: #FF5572;">head</span><span style="color: #89DDFF;">></span></div><div class='line'><span style="color: #BFC7D5;"> ...</span></div><div class='line'> </div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">@paddleJS</span></div><div class='line'><span style="color: #89DDFF;"></</span><span style="color: #FF5572;">head</span><span style="color: #89DDFF;">></span></div></code></pre> </div> <h3 id="currency-configuration"><a href="#currency-configuration">Currency Configuration</a></h3> <p>You can specify a locale to be used when formatting money values for display on invoices. Internally, Cashier utilizes <a href="https://www.php.net/manual/en/class.numberformatter.php">PHP's <code>NumberFormatter</code> class</a> to set the currency locale:</p> <div class="code-container"> <pre><code data-theme="olaolu-palenight" data-lang="ini" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">CASHIER_CURRENCY_LOCALE</span><span style="color: #BFC7D5;">=nl_BE</span></div></code></pre> </div> <div class="mb-10 max-w-2xl mx-auto px-4 py-8 shadow-lg lg:flex lg:items-center callout"> <div class="w-20 h-20 mb-6 flex items-center justify-center shrink-0 lg:mb-0 bg-red-600"> <div class="opacity-75"><svg width="6" height="35" viewBox="0 0 6 35" xmlns="http://www.w3.org/2000/svg"><title>exclamation</title><path d="M0 29h6v6H0v-6zM0 0h6v24H0V0z" fill="#FFF" fill-rule="nonzero"/></svg> </div> </div> <p class="mb-0 lg:ml-6 callout"> In order to use locales other than <code>en</code>, ensure the <code>ext-intl</code> PHP extension is installed and configured on your server.</p> </div> <h3 id="overriding-default-models"><a href="#overriding-default-models">Overriding Default Models</a></h3> <p>You are free to extend the models used internally by Cashier by defining your own model and extending the corresponding Cashier model:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Laravel\Paddle\</span><span style="color: #FFCB8B;">Subscription</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">as</span><span style="color: #BFC7D5;"> CashierSubscription;</span></div><div class='line'> </div><div class='line'><span style="color: #C792EA;">class</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB6B;">Subscription</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">extends</span><span style="color: #BFC7D5;"> </span><span style="color: #A9C77D;">CashierSubscription</span></div><div class='line'><span style="color: #BFC7D5;">{</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #697098;">//</span><span style="color: #697098;"> ...</span></div><div class='line'><span style="color: #BFC7D5;">}</span></div></code></pre> <p>After defining your model, you may instruct Cashier to use your custom model via the <code>Laravel\Paddle\Cashier</code> class. Typically, you should inform Cashier about your custom models in the <code>boot</code> method of your application's <code>App\Providers\AppServiceProvider</code> class:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> App\Models\Cashier\</span><span style="color: #FFCB8B;">Subscription</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> App\Models\Cashier\</span><span style="color: #FFCB8B;">Transaction</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #697098;">/**</span></div><div class='line'><span style="color: #697098;"> * Bootstrap any application services.</span></div><div class='line'><span style="color: #697098;"> </span><span style="color: #697098;">*/</span></div><div class='line'><span style="color: #C792EA;">public</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">boot</span><span style="color: #D9F5DD;">()</span><span style="color: #89DDFF;">:</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">void</span></div><div class='line'><span style="color: #BFC7D5;">{</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">Cashier</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">useSubscriptionModel</span><span style="color: #BFC7D5;">(</span><span style="color: #FFCB8B;">Subscription</span><span style="color: #89DDFF;">::</span><span style="color: #C792EA;">class</span><span style="color: #BFC7D5;">);</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">Cashier</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">useTransactionModel</span><span style="color: #BFC7D5;">(</span><span style="color: #FFCB8B;">Transaction</span><span style="color: #89DDFF;">::</span><span style="color: #C792EA;">class</span><span style="color: #BFC7D5;">);</span></div><div class='line'><span style="color: #BFC7D5;">}</span></div></code></pre> <h2 id="quickstart"><a href="#quickstart">Quickstart</a></h2> <h3 id="quickstart-selling-products"><a href="#quickstart-selling-products">Selling Products</a></h3> <div class="mb-10 max-w-2xl mx-auto px-4 py-8 shadow-lg lg:flex lg:items-center callout"> <div class="w-20 h-20 mb-6 flex items-center justify-center shrink-0 lg:mb-0 bg-purple-600"> <div class="opacity-75"><svg width="28" height="40" viewBox="0 0 28 40" xmlns="http://www.w3.org/2000/svg"><title>lightbulb</title><path d="M12 28h4v-8h-4v8zM8 40h12v-8H8v8zm13.98-14.52c-1.001.705-1.661 1.545-1.98 2.52H8c-.416-.959-1.076-1.799-1.98-2.52A13.99 13.99 0 0 1 0 14C0 6.272 6.272 0 14 0s14 6.272 14 14a13.99 13.99 0 0 1-6.02 11.48z" fill="#FFF" fill-rule="nonzero"/></svg></div> </div> <p class="mb-0 lg:ml-6 callout"> Before utilizing Paddle Checkout, you should define Products with fixed prices in your Paddle dashboard. In addition, you should <a href="#handling-paddle-webhooks">configure Paddle's webhook handling</a>.</p> </div> <p>Offering product and subscription billing via your application can be intimidating. However, thanks to Cashier and <a href="https://www.paddle.com/billing/checkout">Paddle's Checkout Overlay</a>, you can easily build modern, robust payment integrations.</p> <p>To charge customers for non-recurring, single-charge products, we'll utilize Cashier to charge customers with Paddle's Checkout Overlay, where they will provide their payment details and confirm their purchase. Once the payment has been made via the Checkout Overlay, the customer will be redirected to a success URL of your choosing within your application:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Http\</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #FFCB8B;">Route</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">get</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">/buy</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">(</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$request</span><span style="color: #D9F5DD;">)</span><span style="color: #BFC7D5;"> {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$checkout</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$request</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">user</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">checkout</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_deluxe_album</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">)</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">returnTo</span><span style="color: #BFC7D5;">(</span><span style="color: #82AAFF;">route</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">dashboard</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">));</span></div><div class='line'> </div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">return</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">view</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">buy</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">,</span><span style="color: #82AAFF;"> </span><span style="color: #BFC7D5;">[</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">checkout</span><span style="color: #D9F5DD;">'</span><span style="color: #82AAFF;"> </span><span style="color: #89DDFF;">=></span><span style="color: #82AAFF;"> </span><span style="color: #BFC7D5;">$</span><span style="color: #BEC5D4;">checkout</span><span style="color: #BFC7D5;">]);</span></div><div class='line'><span style="color: #BFC7D5;">})</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">name</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">checkout</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">);</span></div></code></pre> <p>As you can see in the example above, we will utilize Cashier's provided <code>checkout</code> method to create a checkout object to present the customer the Paddle Checkout Overlay for a given "price identifier". When using Paddle, "prices" refer to <a href="https://developer.paddle.com/build/products/create-products-prices">defined prices for specific products</a>.</p> <p>If necessary, the <code>checkout</code> method will automatically create a customer in Paddle and connect that Paddle customer record to the corresponding user in your application's database. After completing the checkout session, the customer will be redirected to a dedicated success page where you can display an informational message to the customer.</p> <p>In the <code>buy</code> view, we will include a button to display the Checkout Overlay. The <code>paddle-button</code> Blade component is included with Cashier Paddle; however, you may also <a href="#manually-rendering-an-overlay-checkout">manually render an overlay checkout</a>:</p> <div class="code-container"> <pre><code data-theme="olaolu-palenight" data-lang="html" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #89DDFF;"><</span><span style="color: #FF5572;">x-paddle-button</span><span style="color: #89DDFF;"> </span><span style="color: #FFCB6B;">:checkout</span><span style="color: #89DDFF;">=</span><span style="color: #D9F5DD;">"</span><span style="color: #C3E88D;">$checkout</span><span style="color: #D9F5DD;">"</span><span style="color: #89DDFF;"> </span><span style="color: #FFCB6B;">class</span><span style="color: #89DDFF;">=</span><span style="color: #D9F5DD;">"</span><span style="color: #C3E88D;">px-8 py-4</span><span style="color: #D9F5DD;">"</span><span style="color: #89DDFF;">></span></div><div class='line'><span style="color: #BFC7D5;"> Buy Product</span></div><div class='line'><span style="color: #89DDFF;"></</span><span style="color: #FF5572;">x-paddle-button</span><span style="color: #89DDFF;">></span></div></code></pre> </div> <h4 id="providing-meta-data-to-paddle-checkout"><a href="#providing-meta-data-to-paddle-checkout">Providing Meta Data to Paddle Checkout</a></h4> <p>When selling products, it's common to keep track of completed orders and purchased products via <code>Cart</code> and <code>Order</code> models defined by your own application. When redirecting customers to Paddle's Checkout Overlay to complete a purchase, you may need to provide an existing order identifier so that you can associate the completed purchase with the corresponding order when the customer is redirected back to your application.</p> <p>To accomplish this, you may provide an array of custom data to the <code>checkout</code> method. Let's imagine that a pending <code>Order</code> is created within our application when a user begins the checkout process. Remember, the <code>Cart</code> and <code>Order</code> models in this example are illustrative and not provided by Cashier. You are free to implement these concepts based on the needs of your own application:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> App\Models\</span><span style="color: #FFCB8B;">Cart</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> App\Models\</span><span style="color: #FFCB8B;">Order</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Http\</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #FFCB8B;">Route</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">get</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">/cart/{cart}/checkout</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">(</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$request</span><span style="color: #BFC7D5;">, </span><span style="color: #FFCB8B;">Cart</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$cart</span><span style="color: #D9F5DD;">)</span><span style="color: #BFC7D5;"> {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$order</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">Order</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">create</span><span style="color: #BFC7D5;">([</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">cart_id</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">=></span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$cart</span><span style="color: #89DDFF;">->id</span><span style="color: #BFC7D5;">,</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">price_ids</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">=></span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$cart</span><span style="color: #89DDFF;">->price_ids</span><span style="color: #BFC7D5;">,</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">status</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">=></span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">incomplete</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">,</span></div><div class='line'><span style="color: #BFC7D5;"> ]);</span></div><div class='line'> </div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$checkout</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$request</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">user</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">checkout</span><span style="color: #BFC7D5;">(</span><span style="color: #BEC5D4;">$order</span><span style="color: #89DDFF;">->price_ids</span><span style="color: #BFC7D5;">)</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">customData</span><span style="color: #BFC7D5;">([</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">order_id</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">=></span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$order</span><span style="color: #89DDFF;">->id</span><span style="color: #BFC7D5;">]);</span></div><div class='line'> </div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">return</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">view</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">billing</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">,</span><span style="color: #82AAFF;"> </span><span style="color: #BFC7D5;">[</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">checkout</span><span style="color: #D9F5DD;">'</span><span style="color: #82AAFF;"> </span><span style="color: #89DDFF;">=></span><span style="color: #82AAFF;"> </span><span style="color: #BFC7D5;">$</span><span style="color: #BEC5D4;">checkout</span><span style="color: #BFC7D5;">]);</span></div><div class='line'><span style="color: #BFC7D5;">})</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">name</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">checkout</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">);</span></div></code></pre> <p>As you can see in the example above, when a user begins the checkout process, we will provide all of the cart / order's associated Paddle price identifiers to the <code>checkout</code> method. Of course, your application is responsible for associating these items with the "shopping cart" or order as a customer adds them. We also provide the order's ID to the Paddle Checkout Overlay via the <code>customData</code> method.</p> <p>Of course, you will likely want to mark the order as "complete" once the customer has finished the checkout process. To accomplish this, you may listen to the webhooks dispatched by Paddle and raised via events by Cashier to store order information in your database.</p> <p>To get started, listen for the <code>TransactionCompleted</code> event dispatched by Cashier. Typically, you should register the event listener in the <code>boot</code> method of your application's <code>AppServiceProvider</code>:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> App\Listeners\</span><span style="color: #FFCB8B;">CompleteOrder</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Support\Facades\</span><span style="color: #FFCB8B;">Event</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Laravel\Paddle\Events\</span><span style="color: #FFCB8B;">TransactionCompleted</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #697098;">/**</span></div><div class='line'><span style="color: #697098;"> * Bootstrap any application services.</span></div><div class='line'><span style="color: #697098;"> </span><span style="color: #697098;">*/</span></div><div class='line'><span style="color: #C792EA;">public</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">boot</span><span style="color: #D9F5DD;">()</span><span style="color: #89DDFF;">:</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">void</span></div><div class='line'><span style="color: #BFC7D5;">{</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #FFCB6B;">Event</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">listen</span><span style="color: #BFC7D5;">(</span><span style="color: #FFCB8B;">TransactionCompleted</span><span style="color: #89DDFF;">::</span><span style="color: #C792EA;">class</span><span style="color: #BFC7D5;">, </span><span style="color: #FFCB8B;">CompleteOrder</span><span style="color: #89DDFF;">::</span><span style="color: #C792EA;">class</span><span style="color: #BFC7D5;">);</span></div><div class='line'><span style="color: #BFC7D5;">}</span></div></code></pre> <p>In this example, the <code>CompleteOrder</code> listener might look like the following:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">namespace</span><span style="color: #BFC7D5;"> App\Listeners;</span></div><div class='line'> </div><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> App\Models\</span><span style="color: #FFCB8B;">Order</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Laravel\Paddle\</span><span style="color: #FFCB8B;">Cashier</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Laravel\Paddle\Events\</span><span style="color: #FFCB8B;">TransactionCompleted</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #C792EA;">class</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB6B;">CompleteOrder</span></div><div class='line'><span style="color: #BFC7D5;">{</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #697098;">/**</span></div><div class='line'><span style="color: #697098;"> * Handle the incoming Cashier webhook event.</span></div><div class='line'><span style="color: #697098;"> </span><span style="color: #697098;">*/</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">public</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">handle</span><span style="color: #D9F5DD;">(</span><span style="color: #FFCB8B;">TransactionCompleted</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$event</span><span style="color: #D9F5DD;">)</span><span style="color: #89DDFF;">:</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">void</span></div><div class='line'><span style="color: #BFC7D5;"> {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$orderId</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$event</span><span style="color: #89DDFF;">->payload</span><span style="color: #BFC7D5;">[</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">data</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">][</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">custom_data</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">][</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">order_id</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">] </span><span style="color: #89DDFF;">??</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">null</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$order</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">Order</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">findOrFail</span><span style="color: #BFC7D5;">(</span><span style="color: #BEC5D4;">$orderId</span><span style="color: #BFC7D5;">);</span></div><div class='line'> </div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$order</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">update</span><span style="color: #BFC7D5;">([</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">status</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">=></span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">completed</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">]);</span></div><div class='line'><span style="color: #BFC7D5;"> }</span></div><div class='line'><span style="color: #BFC7D5;">}</span></div></code></pre> <p>Please refer to Paddle's documentation for more information on the <a href="https://developer.paddle.com/webhooks/transactions/transaction-completed">data contained by the <code>transaction.completed</code> event</a>.</p> <h3 id="quickstart-selling-subscriptions"><a href="#quickstart-selling-subscriptions">Selling Subscriptions</a></h3> <div class="mb-10 max-w-2xl mx-auto px-4 py-8 shadow-lg lg:flex lg:items-center callout"> <div class="w-20 h-20 mb-6 flex items-center justify-center shrink-0 lg:mb-0 bg-purple-600"> <div class="opacity-75"><svg width="28" height="40" viewBox="0 0 28 40" xmlns="http://www.w3.org/2000/svg"><title>lightbulb</title><path d="M12 28h4v-8h-4v8zM8 40h12v-8H8v8zm13.98-14.52c-1.001.705-1.661 1.545-1.98 2.52H8c-.416-.959-1.076-1.799-1.98-2.52A13.99 13.99 0 0 1 0 14C0 6.272 6.272 0 14 0s14 6.272 14 14a13.99 13.99 0 0 1-6.02 11.48z" fill="#FFF" fill-rule="nonzero"/></svg></div> </div> <p class="mb-0 lg:ml-6 callout"> Before utilizing Paddle Checkout, you should define Products with fixed prices in your Paddle dashboard. In addition, you should <a href="#handling-paddle-webhooks">configure Paddle's webhook handling</a>.</p> </div> <p>Offering product and subscription billing via your application can be intimidating. However, thanks to Cashier and <a href="https://www.paddle.com/billing/checkout">Paddle's Checkout Overlay</a>, you can easily build modern, robust payment integrations.</p> <p>To learn how to sell subscriptions using Cashier and Paddle's Checkout Overlay, let's consider the simple scenario of a subscription service with a basic monthly (<code>price_basic_monthly</code>) and yearly (<code>price_basic_yearly</code>) plan. These two prices could be grouped under a "Basic" product (<code>pro_basic</code>) in our Paddle dashboard. In addition, our subscription service might offer an Expert plan as <code>pro_expert</code>.</p> <p>First, let's discover how a customer can subscribe to our services. Of course, you can imagine the customer might click a "subscribe" button for the Basic plan on our application's pricing page. This button will invoke a Paddle Checkout Overlay for their chosen plan. To get started, let's initiate a checkout session via the <code>checkout</code> method:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Http\</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #FFCB8B;">Route</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">get</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">/subscribe</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">(</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$request</span><span style="color: #D9F5DD;">)</span><span style="color: #BFC7D5;"> {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$checkout</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$request</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">user</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">checkout</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">price_basic_monthly</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">)</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">returnTo</span><span style="color: #BFC7D5;">(</span><span style="color: #82AAFF;">route</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">dashboard</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">));</span></div><div class='line'> </div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">return</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">view</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">subscribe</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">,</span><span style="color: #82AAFF;"> </span><span style="color: #BFC7D5;">[</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">checkout</span><span style="color: #D9F5DD;">'</span><span style="color: #82AAFF;"> </span><span style="color: #89DDFF;">=></span><span style="color: #82AAFF;"> </span><span style="color: #BFC7D5;">$</span><span style="color: #BEC5D4;">checkout</span><span style="color: #BFC7D5;">]);</span></div><div class='line'><span style="color: #BFC7D5;">})</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">name</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">subscribe</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">);</span></div></code></pre> <p>In the <code>subscribe</code> view, we will include a button to display the Checkout Overlay. The <code>paddle-button</code> Blade component is included with Cashier Paddle; however, you may also <a href="#manually-rendering-an-overlay-checkout">manually render an overlay checkout</a>:</p> <div class="code-container"> <pre><code data-theme="olaolu-palenight" data-lang="html" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #89DDFF;"><</span><span style="color: #FF5572;">x-paddle-button</span><span style="color: #89DDFF;"> </span><span style="color: #FFCB6B;">:checkout</span><span style="color: #89DDFF;">=</span><span style="color: #D9F5DD;">"</span><span style="color: #C3E88D;">$checkout</span><span style="color: #D9F5DD;">"</span><span style="color: #89DDFF;"> </span><span style="color: #FFCB6B;">class</span><span style="color: #89DDFF;">=</span><span style="color: #D9F5DD;">"</span><span style="color: #C3E88D;">px-8 py-4</span><span style="color: #D9F5DD;">"</span><span style="color: #89DDFF;">></span></div><div class='line'><span style="color: #BFC7D5;"> Subscribe</span></div><div class='line'><span style="color: #89DDFF;"></</span><span style="color: #FF5572;">x-paddle-button</span><span style="color: #89DDFF;">></span></div></code></pre> </div> <p>Now, when the Subscribe button is clicked, the customer will be able to enter their payment details and initiate their subscription. To know when their subscription has actually started (since some payment methods require a few seconds to process), you should also <a href="#handling-paddle-webhooks">configure Cashier's webhook handling</a>.</p> <p>Now that customers can start subscriptions, we need to restrict certain portions of our application so that only subscribed users can access them. Of course, we can always determine a user's current subscription status via the <code>subscribed</code> method provided by Cashier's <code>Billable</code> trait:</p> <div class="code-container"> <pre><code data-theme="olaolu-palenight" data-lang="blade" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">@if </span><span style="color: #BFC7D5;">(</span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscribed</span><span style="color: #BFC7D5;">())</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;"><</span><span style="color: #FF5572;">p</span><span style="color: #89DDFF;">></span><span style="color: #BFC7D5;">You are subscribed.</span><span style="color: #89DDFF;"></</span><span style="color: #FF5572;">p</span><span style="color: #89DDFF;">></span></div><div class='line'><span style="color: #C792EA;">@endif</span></div></code></pre> </div> <p>We can even easily determine if a user is subscribed to specific product or price:</p> <div class="code-container"> <pre><code data-theme="olaolu-palenight" data-lang="blade" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">@if </span><span style="color: #BFC7D5;">(</span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscribedToProduct</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pro_basic</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">))</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;"><</span><span style="color: #FF5572;">p</span><span style="color: #89DDFF;">></span><span style="color: #BFC7D5;">You are subscribed to our Basic product.</span><span style="color: #89DDFF;"></</span><span style="color: #FF5572;">p</span><span style="color: #89DDFF;">></span></div><div class='line'><span style="color: #C792EA;">@endif</span></div><div class='line'> </div><div class='line'><span style="color: #C792EA;">@if </span><span style="color: #BFC7D5;">(</span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscribedToPrice</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">price_basic_monthly</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">))</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;"><</span><span style="color: #FF5572;">p</span><span style="color: #89DDFF;">></span><span style="color: #BFC7D5;">You are subscribed to our monthly Basic plan.</span><span style="color: #89DDFF;"></</span><span style="color: #FF5572;">p</span><span style="color: #89DDFF;">></span></div><div class='line'><span style="color: #C792EA;">@endif</span></div></code></pre> </div> <h4 id="quickstart-building-a-subscribed-middleware"><a href="#quickstart-building-a-subscribed-middleware">Building a Subscribed Middleware</a></h4> <p>For convenience, you may wish to create a <a href="/docs/11.x/middleware">middleware</a> which determines if the incoming request is from a subscribed user. Once this middleware has been defined, you may easily assign it to a route to prevent users that are not subscribed from accessing the route:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #D3423E;"><?php</span></div><div class='line'> </div><div class='line'><span style="color: #C792EA;">namespace</span><span style="color: #BFC7D5;"> App\Http\Middleware;</span></div><div class='line'> </div><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">Closure</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Http\</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Symfony\Component\HttpFoundation\</span><span style="color: #FFCB8B;">Response</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #C792EA;">class</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB6B;">Subscribed</span></div><div class='line'><span style="color: #BFC7D5;">{</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #697098;">/**</span></div><div class='line'><span style="color: #697098;"> * Handle an incoming request.</span></div><div class='line'><span style="color: #697098;"> </span><span style="color: #697098;">*/</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">public</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">handle</span><span style="color: #D9F5DD;">(</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$request</span><span style="color: #BFC7D5;">, </span><span style="color: #FFCB8B;">Closure</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$next</span><span style="color: #D9F5DD;">)</span><span style="color: #89DDFF;">:</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">Response</span></div><div class='line'><span style="color: #BFC7D5;"> {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">if</span><span style="color: #BFC7D5;"> (</span><span style="color: #C792EA;">!</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$request</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">user</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">?-></span><span style="color: #82AAFF;">subscribed</span><span style="color: #BFC7D5;">()) {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #697098;">//</span><span style="color: #697098;"> Redirect user to billing page and ask them to subscribe...</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">return</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">redirect</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">/subscribe</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">);</span></div><div class='line'><span style="color: #BFC7D5;"> }</span></div><div class='line'> </div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">return</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$next</span><span style="color: #BFC7D5;">(</span><span style="color: #BEC5D4;">$request</span><span style="color: #BFC7D5;">);</span></div><div class='line'><span style="color: #BFC7D5;"> }</span></div><div class='line'><span style="color: #BFC7D5;">}</span></div></code></pre> <p>Once the middleware has been defined, you may assign it to a route:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> App\Http\Middleware\</span><span style="color: #FFCB8B;">Subscribed</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #FFCB8B;">Route</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">get</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">/dashboard</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">()</span><span style="color: #BFC7D5;"> {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #697098;">//</span><span style="color: #697098;"> ...</span></div><div class='line'><span style="color: #BFC7D5;">})</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">middleware</span><span style="color: #BFC7D5;">([</span><span style="color: #FFCB8B;">Subscribed</span><span style="color: #89DDFF;">::</span><span style="color: #C792EA;">class</span><span style="color: #BFC7D5;">]);</span></div></code></pre> <h4 id="quickstart-allowing-customers-to-manage-their-billing-plan"><a href="#quickstart-allowing-customers-to-manage-their-billing-plan">Allowing Customers to Manage Their Billing Plan</a></h4> <p>Of course, customers may want to change their subscription plan to another product or "tier". In our example from above, we'd want to allow the customer to change their plan from a monthly subscription to a yearly subscription. For this you'll need to implement something like a button that leads to the below route:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Http\</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #FFCB8B;">Route</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">put</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">/subscription/{price}/swap</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">(</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$request</span><span style="color: #BFC7D5;">, </span><span style="color: #BEC5D4;">$price</span><span style="color: #D9F5DD;">)</span><span style="color: #BFC7D5;"> {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">swap</span><span style="color: #BFC7D5;">(</span><span style="color: #BEC5D4;">$price</span><span style="color: #BFC7D5;">); </span><span style="color: #697098;">//</span><span style="color: #697098;"> With "$price" being "price_basic_yearly" for this example.</span></div><div class='line'> </div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">return</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">redirect</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">route</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">dashboard</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">);</span></div><div class='line'><span style="color: #BFC7D5;">})</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">name</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">subscription.swap</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">);</span></div></code></pre> <p>Besides swapping plans you'll also need to allow your customers to cancel their subscription. Like swapping plans, provide a button that leads to the following route:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Http\</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #FFCB8B;">Route</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">put</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">/subscription/cancel</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">(</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$request</span><span style="color: #BFC7D5;">, </span><span style="color: #BEC5D4;">$price</span><span style="color: #D9F5DD;">)</span><span style="color: #BFC7D5;"> {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">cancel</span><span style="color: #BFC7D5;">();</span></div><div class='line'> </div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">return</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">redirect</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">route</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">dashboard</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">);</span></div><div class='line'><span style="color: #BFC7D5;">})</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">name</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">subscription.cancel</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">);</span></div></code></pre> <p>And now your subscription will get canceled at the end of its billing period.</p> <div class="mb-10 max-w-2xl mx-auto px-4 py-8 shadow-lg lg:flex lg:items-center callout"> <div class="w-20 h-20 mb-6 flex items-center justify-center shrink-0 lg:mb-0 bg-purple-600"> <div class="opacity-75"><svg width="28" height="40" viewBox="0 0 28 40" xmlns="http://www.w3.org/2000/svg"><title>lightbulb</title><path d="M12 28h4v-8h-4v8zM8 40h12v-8H8v8zm13.98-14.52c-1.001.705-1.661 1.545-1.98 2.52H8c-.416-.959-1.076-1.799-1.98-2.52A13.99 13.99 0 0 1 0 14C0 6.272 6.272 0 14 0s14 6.272 14 14a13.99 13.99 0 0 1-6.02 11.48z" fill="#FFF" fill-rule="nonzero"/></svg></div> </div> <p class="mb-0 lg:ml-6 callout"> As long as you have configured Cashier's webhook handling, Cashier will automatically keep your application's Cashier-related database tables in sync by inspecting the incoming webhooks from Paddle. So, for example, when you cancel a customer's subscription via Paddle's dashboard, Cashier will receive the corresponding webhook and mark the subscription as "canceled" in your application's database.</p> </div> <h2 id="checkout-sessions"><a href="#checkout-sessions">Checkout Sessions</a></h2> <p>Most operations to bill customers are performed using "checkouts" via Paddle's <a href="https://developer.paddle.com/build/checkout/build-overlay-checkout">Checkout Overlay widget</a> or by utilizing <a href="https://developer.paddle.com/build/checkout/build-branded-inline-checkout">inline checkout</a>.</p> <p>Before processing checkout payments using Paddle, you should define your application's <a href="https://developer.paddle.com/build/transactions/default-payment-link#set-default-link">default payment link</a> in your Paddle checkout settings dashboard.</p> <h3 id="overlay-checkout"><a href="#overlay-checkout">Overlay Checkout</a></h3> <p>Before displaying the Checkout Overlay widget, you must generate a checkout session using Cashier. A checkout session will inform the checkout widget of the billing operation that should be performed:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Http\</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #FFCB8B;">Route</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">get</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">/buy</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">(</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$request</span><span style="color: #D9F5DD;">)</span><span style="color: #BFC7D5;"> {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$checkout</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">checkout</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_34567</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">)</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">returnTo</span><span style="color: #BFC7D5;">(</span><span style="color: #82AAFF;">route</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">dashboard</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">));</span></div><div class='line'> </div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">return</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">view</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">billing</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">,</span><span style="color: #82AAFF;"> </span><span style="color: #BFC7D5;">[</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">checkout</span><span style="color: #D9F5DD;">'</span><span style="color: #82AAFF;"> </span><span style="color: #89DDFF;">=></span><span style="color: #82AAFF;"> </span><span style="color: #BFC7D5;">$</span><span style="color: #BEC5D4;">checkout</span><span style="color: #BFC7D5;">]);</span></div><div class='line'><span style="color: #BFC7D5;">});</span></div></code></pre> <p>Cashier includes a <code>paddle-button</code> <a href="/docs/11.x/blade#components">Blade component</a>. You may pass the checkout session to this component as a "prop". Then, when this button is clicked, Paddle's checkout widget will be displayed:</p> <div class="code-container"> <pre><code data-theme="olaolu-palenight" data-lang="html" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #89DDFF;"><</span><span style="color: #FF5572;">x-paddle-button</span><span style="color: #89DDFF;"> </span><span style="color: #FFCB6B;">:checkout</span><span style="color: #89DDFF;">=</span><span style="color: #D9F5DD;">"</span><span style="color: #C3E88D;">$checkout</span><span style="color: #D9F5DD;">"</span><span style="color: #89DDFF;"> </span><span style="color: #FFCB6B;">class</span><span style="color: #89DDFF;">=</span><span style="color: #D9F5DD;">"</span><span style="color: #C3E88D;">px-8 py-4</span><span style="color: #D9F5DD;">"</span><span style="color: #89DDFF;">></span></div><div class='line'><span style="color: #BFC7D5;"> Subscribe</span></div><div class='line'><span style="color: #89DDFF;"></</span><span style="color: #FF5572;">x-paddle-button</span><span style="color: #89DDFF;">></span></div></code></pre> </div> <p>By default, this will display the widget using Paddle's default styling. You can customize the widget by adding <a href="https://developer.paddle.com/paddlejs/html-data-attributes">Paddle supported attributes</a> like the <code>data-theme='light'</code> attribute to the component:</p> <div class="code-container"> <pre><code data-theme="olaolu-palenight" data-lang="html" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #89DDFF;"><</span><span style="color: #FF5572;">x-paddle-button</span><span style="color: #89DDFF;"> </span><span style="color: #FFCB6B;">:url</span><span style="color: #89DDFF;">=</span><span style="color: #D9F5DD;">"</span><span style="color: #C3E88D;">$payLink</span><span style="color: #D9F5DD;">"</span><span style="color: #89DDFF;"> </span><span style="color: #FFCB6B;">class</span><span style="color: #89DDFF;">=</span><span style="color: #D9F5DD;">"</span><span style="color: #C3E88D;">px-8 py-4</span><span style="color: #D9F5DD;">"</span><span style="color: #89DDFF;"> </span><span style="color: #FFCB6B;">data-theme</span><span style="color: #89DDFF;">=</span><span style="color: #D9F5DD;">"</span><span style="color: #C3E88D;">light</span><span style="color: #D9F5DD;">"</span><span style="color: #89DDFF;">></span></div><div class='line'><span style="color: #BFC7D5;"> Subscribe</span></div><div class='line'><span style="color: #89DDFF;"></</span><span style="color: #FF5572;">x-paddle-button</span><span style="color: #89DDFF;">></span></div></code></pre> </div> <p>The Paddle checkout widget is asynchronous. Once the user creates a subscription within the widget, Paddle will send your application a webhook so that you may properly update the subscription state in your application's database. Therefore, it's important that you properly <a href="#handling-paddle-webhooks">set up webhooks</a> to accommodate for state changes from Paddle.</p> <div class="mb-10 max-w-2xl mx-auto px-4 py-8 shadow-lg lg:flex lg:items-center callout"> <div class="w-20 h-20 mb-6 flex items-center justify-center shrink-0 lg:mb-0 bg-red-600"> <div class="opacity-75"><svg width="6" height="35" viewBox="0 0 6 35" xmlns="http://www.w3.org/2000/svg"><title>exclamation</title><path d="M0 29h6v6H0v-6zM0 0h6v24H0V0z" fill="#FFF" fill-rule="nonzero"/></svg> </div> </div> <p class="mb-0 lg:ml-6 callout"> After a subscription state change, the delay for receiving the corresponding webhook is typically minimal but you should account for this in your application by considering that your user's subscription might not be immediately available after completing the checkout.</p> </div> <h4 id="manually-rendering-an-overlay-checkout"><a href="#manually-rendering-an-overlay-checkout">Manually Rendering an Overlay Checkout</a></h4> <p>You may also manually render an overlay checkout without using Laravel's built-in Blade components. To get started, generate the checkout session <a href="#overlay-checkout">as demonstrated in previous examples</a>:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Http\</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #FFCB8B;">Route</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">get</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">/buy</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">(</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$request</span><span style="color: #D9F5DD;">)</span><span style="color: #BFC7D5;"> {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$checkout</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">checkout</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_34567</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">)</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">returnTo</span><span style="color: #BFC7D5;">(</span><span style="color: #82AAFF;">route</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">dashboard</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">));</span></div><div class='line'> </div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">return</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">view</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">billing</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">,</span><span style="color: #82AAFF;"> </span><span style="color: #BFC7D5;">[</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">checkout</span><span style="color: #D9F5DD;">'</span><span style="color: #82AAFF;"> </span><span style="color: #89DDFF;">=></span><span style="color: #82AAFF;"> </span><span style="color: #BFC7D5;">$</span><span style="color: #BEC5D4;">checkout</span><span style="color: #BFC7D5;">]);</span></div><div class='line'><span style="color: #BFC7D5;">});</span></div></code></pre> <p>Next, you may use Paddle.js to initialize the checkout. In this example, we will create a link that is assigned the <code>paddle_button</code> class. Paddle.js will detect this class and display the overlay checkout when the link is clicked:</p> <div class="code-container"> <pre><code data-theme="olaolu-palenight" data-lang="blade" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #D3423E;"><?php</span></div><div class='line'><span style="color: #BEC5D4;">$items</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$checkout</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">getItems</span><span style="color: #BFC7D5;">();</span></div><div class='line'><span style="color: #BEC5D4;">$customer</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$checkout</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">getCustomer</span><span style="color: #BFC7D5;">();</span></div><div class='line'><span style="color: #BEC5D4;">$custom</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$checkout</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">getCustomData</span><span style="color: #BFC7D5;">();</span></div><div class='line'><span style="color: #D3423E;">?></span></div><div class='line'> </div><div class='line'><span style="color: #89DDFF;"><</span><span style="color: #FF5572;">a</span></div><div class='line'><span style="color: #89DDFF;"> </span><span style="color: #FFCB6B;">href</span><span style="color: #89DDFF;">=</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">#!</span><span style="color: #D9F5DD;">'</span></div><div class='line'><span style="color: #89DDFF;"> </span><span style="color: #FFCB6B;">class</span><span style="color: #89DDFF;">=</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">paddle_button</span><span style="color: #D9F5DD;">'</span></div><div class='line'><span style="color: #89DDFF;"> </span><span style="color: #FFCB6B;">data-items</span><span style="color: #89DDFF;">=</span><span style="color: #D9F5DD;">'</span><span style="color: #89DDFF;">{!!</span><span style="color: #C3E88D;"> </span><span style="color: #89DDFF;">json_encode</span><span style="color: #BFC7D5;">($</span><span style="color: #BEC5D4;">items</span><span style="color: #BFC7D5;">)</span><span style="color: #C3E88D;"> </span><span style="color: #89DDFF;">!!}</span><span style="color: #D9F5DD;">'</span></div><div class='line'><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">@if </span><span style="color: #89DDFF;">(</span><span style="color: #BEC5D4;">$customer</span><span style="color: #89DDFF;">) </span><span style="color: #FFCB6B;">data-customer-id</span><span style="color: #89DDFF;">=</span><span style="color: #D9F5DD;">'</span><span style="color: #89DDFF;">{{</span><span style="color: #C3E88D;"> </span><span style="color: #BEC5D4;">$customer</span><span style="color: #89DDFF;">->paddle_id</span><span style="color: #C3E88D;"> </span><span style="color: #89DDFF;">}}</span><span style="color: #D9F5DD;">'</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">@endif</span></div><div class='line'><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">@if </span><span style="color: #89DDFF;">(</span><span style="color: #BEC5D4;">$custom</span><span style="color: #89DDFF;">) </span><span style="color: #FFCB6B;">data-custom-data</span><span style="color: #89DDFF;">=</span><span style="color: #D9F5DD;">'</span><span style="color: #89DDFF;">{{</span><span style="color: #C3E88D;"> </span><span style="color: #89DDFF;">json_encode</span><span style="color: #BFC7D5;">($</span><span style="color: #BEC5D4;">custom</span><span style="color: #BFC7D5;">)</span><span style="color: #C3E88D;"> </span><span style="color: #89DDFF;">}}</span><span style="color: #D9F5DD;">'</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">@endif</span></div><div class='line'><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">@if </span><span style="color: #89DDFF;">(</span><span style="color: #BEC5D4;">$returnUrl</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">=</span><span style="color: #89DDFF;"> </span><span style="color: #BEC5D4;">$checkout</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">getReturnUrl</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">) </span><span style="color: #FFCB6B;">data-success-url</span><span style="color: #89DDFF;">=</span><span style="color: #D9F5DD;">'</span><span style="color: #89DDFF;">{{</span><span style="color: #C3E88D;"> </span><span style="color: #BEC5D4;">$returnUrl</span><span style="color: #C3E88D;"> </span><span style="color: #89DDFF;">}}</span><span style="color: #D9F5DD;">'</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">@endif</span></div><div class='line'><span style="color: #89DDFF;">></span></div><div class='line'><span style="color: #BFC7D5;"> Buy Product</span></div><div class='line'><span style="color: #89DDFF;"></</span><span style="color: #FF5572;">a</span><span style="color: #89DDFF;">></span></div></code></pre> </div> <h3 id="inline-checkout"><a href="#inline-checkout">Inline Checkout</a></h3> <p>If you don't want to make use of Paddle's "overlay" style checkout widget, Paddle also provides the option to display the widget inline. While this approach does not allow you to adjust any of the checkout's HTML fields, it allows you to embed the widget within your application.</p> <p>To make it easy for you to get started with inline checkout, Cashier includes a <code>paddle-checkout</code> Blade component. To get started, you should <a href="#overlay-checkout">generate a checkout session</a>:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Http\</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #FFCB8B;">Route</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">get</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">/buy</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">(</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$request</span><span style="color: #D9F5DD;">)</span><span style="color: #BFC7D5;"> {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$checkout</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">checkout</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_34567</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">)</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">returnTo</span><span style="color: #BFC7D5;">(</span><span style="color: #82AAFF;">route</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">dashboard</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">));</span></div><div class='line'> </div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">return</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">view</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">billing</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">,</span><span style="color: #82AAFF;"> </span><span style="color: #BFC7D5;">[</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">checkout</span><span style="color: #D9F5DD;">'</span><span style="color: #82AAFF;"> </span><span style="color: #89DDFF;">=></span><span style="color: #82AAFF;"> </span><span style="color: #BFC7D5;">$</span><span style="color: #BEC5D4;">checkout</span><span style="color: #BFC7D5;">]);</span></div><div class='line'><span style="color: #BFC7D5;">});</span></div></code></pre> <p>Then, you may pass the checkout session to the component's <code>checkout</code> attribute:</p> <div class="code-container"> <pre><code data-theme="olaolu-palenight" data-lang="blade" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #89DDFF;"><</span><span style="color: #FF5572;">x-paddle-checkout</span><span style="color: #89DDFF;"> </span><span style="color: #FFCB6B;">:checkout</span><span style="color: #89DDFF;">=</span><span style="color: #D9F5DD;">"</span><span style="color: #C3E88D;">$checkout</span><span style="color: #D9F5DD;">"</span><span style="color: #89DDFF;"> </span><span style="color: #FFCB6B;">class</span><span style="color: #89DDFF;">=</span><span style="color: #D9F5DD;">"</span><span style="color: #C3E88D;">w-full</span><span style="color: #D9F5DD;">"</span><span style="color: #89DDFF;"> /></span></div></code></pre> </div> <p>To adjust the height of the inline checkout component, you may pass the <code>height</code> attribute to the Blade component:</p> <div class="code-container"> <pre><code data-theme="olaolu-palenight" data-lang="blade" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #89DDFF;"><</span><span style="color: #FF5572;">x-paddle-checkout</span><span style="color: #89DDFF;"> </span><span style="color: #FFCB6B;">:checkout</span><span style="color: #89DDFF;">=</span><span style="color: #D9F5DD;">"</span><span style="color: #C3E88D;">$checkout</span><span style="color: #D9F5DD;">"</span><span style="color: #89DDFF;"> </span><span style="color: #FFCB6B;">class</span><span style="color: #89DDFF;">=</span><span style="color: #D9F5DD;">"</span><span style="color: #C3E88D;">w-full</span><span style="color: #D9F5DD;">"</span><span style="color: #89DDFF;"> </span><span style="color: #FFCB6B;">height</span><span style="color: #89DDFF;">=</span><span style="color: #D9F5DD;">"</span><span style="color: #C3E88D;">500</span><span style="color: #D9F5DD;">"</span><span style="color: #89DDFF;"> /></span></div></code></pre> </div> <p>Please consult Paddle's <a href="https://developer.paddle.com/build/checkout/build-branded-inline-checkout">guide on Inline Checkout</a> and <a href="https://developer.paddle.com/build/checkout/set-up-checkout-default-settings">available checkout settings</a> for further details on the inline checkout's customization options.</p> <h4 id="manually-rendering-an-inline-checkout"><a href="#manually-rendering-an-inline-checkout">Manually Rendering an Inline Checkout</a></h4> <p>You may also manually render an inline checkout without using Laravel's built-in Blade components. To get started, generate the checkout session <a href="#inline-checkout">as demonstrated in previous examples</a>:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Http\</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #FFCB8B;">Route</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">get</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">/buy</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">(</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$request</span><span style="color: #D9F5DD;">)</span><span style="color: #BFC7D5;"> {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$checkout</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">checkout</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_34567</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">)</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">returnTo</span><span style="color: #BFC7D5;">(</span><span style="color: #82AAFF;">route</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">dashboard</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">));</span></div><div class='line'> </div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">return</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">view</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">billing</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">,</span><span style="color: #82AAFF;"> </span><span style="color: #BFC7D5;">[</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">checkout</span><span style="color: #D9F5DD;">'</span><span style="color: #82AAFF;"> </span><span style="color: #89DDFF;">=></span><span style="color: #82AAFF;"> </span><span style="color: #BFC7D5;">$</span><span style="color: #BEC5D4;">checkout</span><span style="color: #BFC7D5;">]);</span></div><div class='line'><span style="color: #BFC7D5;">});</span></div></code></pre> <p>Next, you may use Paddle.js to initialize the checkout. In this example, we will demonstrate this using <a href="https://github.com/alpinejs/alpine">Alpine.js</a>; however, you are free to modify this example for your own frontend stack:</p> <div class="code-container"> <pre><code data-theme="olaolu-palenight" data-lang="blade" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #D3423E;"><?php</span></div><div class='line'><span style="color: #BEC5D4;">$options</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$checkout</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">options</span><span style="color: #BFC7D5;">();</span></div><div class='line'> </div><div class='line'><span style="color: #BEC5D4;">$options</span><span style="color: #BFC7D5;">[</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">settings</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">][</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">frameTarget</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">] </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">paddle-checkout</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color: #BEC5D4;">$options</span><span style="color: #BFC7D5;">[</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">settings</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">][</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">frameInitialHeight</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">] </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #F78C6C;">366</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color: #D3423E;">?></span></div><div class='line'> </div><div class='line'><span style="color: #89DDFF;"><</span><span style="color: #FF5572;">div</span><span style="color: #89DDFF;"> </span><span style="color: #FFCB6B;">class</span><span style="color: #89DDFF;">=</span><span style="color: #D9F5DD;">"</span><span style="color: #C3E88D;">paddle-checkout</span><span style="color: #D9F5DD;">"</span><span style="color: #89DDFF;"> </span><span style="color: #FFCB6B;">x-data</span><span style="color: #89DDFF;">=</span><span style="color: #D9F5DD;">"</span><span style="color: #C3E88D;">{}</span><span style="color: #D9F5DD;">"</span><span style="color: #89DDFF;"> </span><span style="color: #FFCB6B;">x-init</span><span style="color: #89DDFF;">=</span><span style="color: #D9F5DD;">"</span></div><div class='line'><span style="color: #C3E88D;"> Paddle.Checkout.open(</span><span style="color: #C792EA;">@json</span><span style="color: #C3E88D;">(</span><span style="color: #BEC5D4;">$options</span><span style="color: #C3E88D;">));</span></div><div class='line'><span style="color: #D9F5DD;">"</span><span style="color: #89DDFF;">></span></div><div class='line'><span style="color: #89DDFF;"></</span><span style="color: #FF5572;">div</span><span style="color: #89DDFF;">></span></div></code></pre> </div> <h3 id="guest-checkouts"><a href="#guest-checkouts">Guest Checkouts</a></h3> <p>Sometimes, you may need to create a checkout session for users that do not need an account with your application. To do so, you may use the <code>guest</code> method:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Http\</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Laravel\Paddle\</span><span style="color: #FFCB8B;">Checkout</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #FFCB8B;">Route</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">get</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">/buy</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">(</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$request</span><span style="color: #D9F5DD;">)</span><span style="color: #BFC7D5;"> {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$checkout</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">Checkout</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">guest</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_34567</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">)</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">returnTo</span><span style="color: #BFC7D5;">(</span><span style="color: #82AAFF;">route</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">home</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">));</span></div><div class='line'> </div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">return</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">view</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">billing</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">,</span><span style="color: #82AAFF;"> </span><span style="color: #BFC7D5;">[</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">checkout</span><span style="color: #D9F5DD;">'</span><span style="color: #82AAFF;"> </span><span style="color: #89DDFF;">=></span><span style="color: #82AAFF;"> </span><span style="color: #BFC7D5;">$</span><span style="color: #BEC5D4;">checkout</span><span style="color: #BFC7D5;">]);</span></div><div class='line'><span style="color: #BFC7D5;">});</span></div></code></pre> <p>Then, you may provide the checkout session to the <a href="#overlay-checkout">Paddle button</a> or <a href="#inline-checkout">inline checkout</a> Blade components.</p> <h2 id="price-previews"><a href="#price-previews">Price Previews</a></h2> <p>Paddle allows you to customize prices per currency, essentially allowing you to configure different prices for different countries. Cashier Paddle allows you to retrieve all of these prices using the <code>previewPrices</code> method. This method accepts the price IDs you wish to retrieve prices for:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Laravel\Paddle\</span><span style="color: #FFCB8B;">Cashier</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #BEC5D4;">$prices</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">Cashier</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">previewPrices</span><span style="color: #BFC7D5;">([</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_123</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_456</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">]);</span></div></code></pre> <p>The currency will be determined based on the IP address of the request; however, you may optionally provide a specific country to retrieve prices for:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Laravel\Paddle\</span><span style="color: #FFCB8B;">Cashier</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #BEC5D4;">$prices</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">Cashier</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">previewPrices</span><span style="color: #BFC7D5;">([</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_123</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_456</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">], [</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">address</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">=></span><span style="color: #BFC7D5;"> [</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">country_code</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">=></span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">BE</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">,</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">postal_code</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">=></span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">1234</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">,</span></div><div class='line'><span style="color: #BFC7D5;">]]);</span></div></code></pre> <p>After retrieving the prices you may display them however you wish:</p> <div class="code-container"> <pre><code data-theme="olaolu-palenight" data-lang="blade" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #89DDFF;"><</span><span style="color: #FF5572;">ul</span><span style="color: #89DDFF;">></span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">@foreach </span><span style="color: #BFC7D5;">(</span><span style="color: #BEC5D4;">$prices</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">as</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$price</span><span style="color: #BFC7D5;">)</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;"><</span><span style="color: #FF5572;">li</span><span style="color: #89DDFF;">>{{</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$price</span><span style="color: #89DDFF;">->product</span><span style="color: #BFC7D5;">[</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">name</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">] </span><span style="color: #89DDFF;">}}</span><span style="color: #BFC7D5;"> - </span><span style="color: #89DDFF;">{{</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$price</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">total</span><span style="color: #BFC7D5;">() </span><span style="color: #89DDFF;">}}</</span><span style="color: #FF5572;">li</span><span style="color: #89DDFF;">></span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">@endforeach</span></div><div class='line'><span style="color: #89DDFF;"></</span><span style="color: #FF5572;">ul</span><span style="color: #89DDFF;">></span></div></code></pre> </div> <p>You may also display the subtotal price and tax amount separately:</p> <div class="code-container"> <pre><code data-theme="olaolu-palenight" data-lang="blade" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #89DDFF;"><</span><span style="color: #FF5572;">ul</span><span style="color: #89DDFF;">></span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">@foreach </span><span style="color: #BFC7D5;">(</span><span style="color: #BEC5D4;">$prices</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">as</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$price</span><span style="color: #BFC7D5;">)</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;"><</span><span style="color: #FF5572;">li</span><span style="color: #89DDFF;">>{{</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$price</span><span style="color: #89DDFF;">->product</span><span style="color: #BFC7D5;">[</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">name</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">] </span><span style="color: #89DDFF;">}}</span><span style="color: #BFC7D5;"> - </span><span style="color: #89DDFF;">{{</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$price</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subtotal</span><span style="color: #BFC7D5;">() </span><span style="color: #89DDFF;">}}</span><span style="color: #BFC7D5;"> (+ </span><span style="color: #89DDFF;">{{</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$price</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">tax</span><span style="color: #BFC7D5;">() </span><span style="color: #89DDFF;">}}</span><span style="color: #BFC7D5;"> tax)</span><span style="color: #89DDFF;"></</span><span style="color: #FF5572;">li</span><span style="color: #89DDFF;">></span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">@endforeach</span></div><div class='line'><span style="color: #89DDFF;"></</span><span style="color: #FF5572;">ul</span><span style="color: #89DDFF;">></span></div></code></pre> </div> <p>For more information, <a href="https://developer.paddle.com/api-reference/pricing-preview/preview-prices">checkout Paddle's API documentation regarding price previews</a>.</p> <h3 id="customer-price-previews"><a href="#customer-price-previews">Customer Price Previews</a></h3> <p>If a user is already a customer and you would like to display the prices that apply to that customer, you may do so by retrieving the prices directly from the customer instance:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> App\Models\</span><span style="color: #FFCB8B;">User</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #BEC5D4;">$prices</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">User</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">find</span><span style="color: #BFC7D5;">(</span><span style="color: #F78C6C;">1</span><span style="color: #BFC7D5;">)</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">previewPrices</span><span style="color: #BFC7D5;">([</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_123</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_456</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">]);</span></div></code></pre> <p>Internally, Cashier will use the user's customer ID to retrieve the prices in their currency. So, for example, a user living in the United States will see prices in US dollars while a user in Belgium will see prices in Euros. If no matching currency can be found, the default currency of the product will be used. You can customize all prices of a product or subscription plan in the Paddle control panel.</p> <h3 id="price-discounts"><a href="#price-discounts">Discounts</a></h3> <p>You may also choose to display prices after a discount. When calling the <code>previewPrices</code> method, you provide the discount ID via the <code>discount_id</code> option:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Laravel\Paddle\</span><span style="color: #FFCB8B;">Cashier</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #BEC5D4;">$prices</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">Cashier</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">previewPrices</span><span style="color: #BFC7D5;">([</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_123</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_456</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">], [</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">discount_id</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">=></span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">dsc_123</span><span style="color: #D9F5DD;">'</span></div><div class='line'><span style="color: #BFC7D5;">]);</span></div></code></pre> <p>Then, display the calculated prices:</p> <div class="code-container"> <pre><code data-theme="olaolu-palenight" data-lang="blade" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #89DDFF;"><</span><span style="color: #FF5572;">ul</span><span style="color: #89DDFF;">></span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">@foreach </span><span style="color: #BFC7D5;">(</span><span style="color: #BEC5D4;">$prices</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">as</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$price</span><span style="color: #BFC7D5;">)</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;"><</span><span style="color: #FF5572;">li</span><span style="color: #89DDFF;">>{{</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$price</span><span style="color: #89DDFF;">->product</span><span style="color: #BFC7D5;">[</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">name</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">] </span><span style="color: #89DDFF;">}}</span><span style="color: #BFC7D5;"> - </span><span style="color: #89DDFF;">{{</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$price</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">total</span><span style="color: #BFC7D5;">() </span><span style="color: #89DDFF;">}}</</span><span style="color: #FF5572;">li</span><span style="color: #89DDFF;">></span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">@endforeach</span></div><div class='line'><span style="color: #89DDFF;"></</span><span style="color: #FF5572;">ul</span><span style="color: #89DDFF;">></span></div></code></pre> </div> <h2 id="customers"><a href="#customers">Customers</a></h2> <h3 id="customer-defaults"><a href="#customer-defaults">Customer Defaults</a></h3> <p>Cashier allows you to define some useful defaults for your customers when creating checkout sessions. Setting these defaults allow you to pre-fill a customer's email address and name so that they can immediately move on to the payment portion of the checkout widget. You can set these defaults by overriding the following methods on your billable model:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #697098;">/**</span></div><div class='line'><span style="color: #697098;"> * Get the customer's name to associate with Paddle.</span></div><div class='line'><span style="color: #697098;"> </span><span style="color: #697098;">*/</span></div><div class='line'><span style="color: #C792EA;">public</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">paddleName</span><span style="color: #D9F5DD;">()</span><span style="color: #89DDFF;">:</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">string</span><span style="color: #BFC7D5;">|</span><span style="color: #C792EA;">null</span></div><div class='line'><span style="color: #BFC7D5;">{</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">return</span><span style="color: #BFC7D5;"> </span><span style="color: #FF5572;">$this</span><span style="color: #89DDFF;">->name</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color: #BFC7D5;">}</span></div><div class='line'> </div><div class='line'><span style="color: #697098;">/**</span></div><div class='line'><span style="color: #697098;"> * Get the customer's email address to associate with Paddle.</span></div><div class='line'><span style="color: #697098;"> </span><span style="color: #697098;">*/</span></div><div class='line'><span style="color: #C792EA;">public</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">paddleEmail</span><span style="color: #D9F5DD;">()</span><span style="color: #89DDFF;">:</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">string</span><span style="color: #BFC7D5;">|</span><span style="color: #C792EA;">null</span></div><div class='line'><span style="color: #BFC7D5;">{</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">return</span><span style="color: #BFC7D5;"> </span><span style="color: #FF5572;">$this</span><span style="color: #89DDFF;">->email</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color: #BFC7D5;">}</span></div></code></pre> <p>These defaults will be used for every action in Cashier that generates a <a href="#checkout-sessions">checkout session</a>.</p> <h3 id="retrieving-customers"><a href="#retrieving-customers">Retrieving Customers</a></h3> <p>You can retrieve a customer by their Paddle Customer ID using the <code>Cashier::findBillable</code> method. This method will return an instance of the billable model:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Laravel\Paddle\</span><span style="color: #FFCB8B;">Cashier</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">Cashier</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">findBillable</span><span style="color: #BFC7D5;">(</span><span style="color: #BEC5D4;">$customerId</span><span style="color: #BFC7D5;">);</span></div></code></pre> <h3 id="creating-customers"><a href="#creating-customers">Creating Customers</a></h3> <p>Occasionally, you may wish to create a Paddle customer without beginning a subscription. You may accomplish this using the <code>createAsCustomer</code> method:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BEC5D4;">$customer</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">createAsCustomer</span><span style="color: #BFC7D5;">();</span></div></code></pre> <p>An instance of <code>Laravel\Paddle\Customer</code> is returned. Once the customer has been created in Paddle, you may begin a subscription at a later date. You may provide an optional <code>$options</code> array to pass in any additional <a href="https://developer.paddle.com/api-reference/customers/create-customer">customer creation parameters that are supported by the Paddle API</a>:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BEC5D4;">$customer</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">createAsCustomer</span><span style="color: #BFC7D5;">(</span><span style="color: #BEC5D4;">$options</span><span style="color: #BFC7D5;">);</span></div></code></pre> <h2 id="subscriptions"><a href="#subscriptions">Subscriptions</a></h2> <h3 id="creating-subscriptions"><a href="#creating-subscriptions">Creating Subscriptions</a></h3> <p>To create a subscription, first retrieve an instance of your billable model from your database, which will typically be an instance of <code>App\Models\User</code>. Once you have retrieved the model instance, you may use the <code>subscribe</code> method to create the model's checkout session:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Http\</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #FFCB8B;">Route</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">get</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">/user/subscribe</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">(</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$request</span><span style="color: #D9F5DD;">)</span><span style="color: #BFC7D5;"> {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$checkout</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$request</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">user</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscribe</span><span style="color: #BFC7D5;">(</span><span style="color: #BEC5D4;">$premium</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #F78C6C;">12345</span><span style="color: #BFC7D5;">, </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">default</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">)</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">returnTo</span><span style="color: #BFC7D5;">(</span><span style="color: #82AAFF;">route</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">home</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">));</span></div><div class='line'> </div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">return</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">view</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">billing</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">,</span><span style="color: #82AAFF;"> </span><span style="color: #BFC7D5;">[</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">checkout</span><span style="color: #D9F5DD;">'</span><span style="color: #82AAFF;"> </span><span style="color: #89DDFF;">=></span><span style="color: #82AAFF;"> </span><span style="color: #BFC7D5;">$</span><span style="color: #BEC5D4;">checkout</span><span style="color: #BFC7D5;">]);</span></div><div class='line'><span style="color: #BFC7D5;">});</span></div></code></pre> <p>The first argument given to the <code>subscribe</code> method is the specific price the user is subscribing to. This value should correspond to the price's identifier in Paddle. The <code>returnTo</code> method accepts a URL that your user will be redirected to after they successfully complete the checkout. The second argument passed to the <code>subscribe</code> method should be the internal "type" of the subscription. If your application only offers a single subscription, you might call this <code>default</code> or <code>primary</code>. This subscription type is only for internal application usage and is not meant to be displayed to users. In addition, it should not contain spaces and it should never be changed after creating the subscription.</p> <p>You may also provide an array of custom metadata regarding the subscription using the <code>customData</code> method:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BEC5D4;">$checkout</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$request</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">user</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscribe</span><span style="color: #BFC7D5;">(</span><span style="color: #BEC5D4;">$premium</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #F78C6C;">12345</span><span style="color: #BFC7D5;">, </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">default</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">)</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">customData</span><span style="color: #BFC7D5;">([</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">key</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">=></span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">value</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">])</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">returnTo</span><span style="color: #BFC7D5;">(</span><span style="color: #82AAFF;">route</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">home</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">));</span></div></code></pre> <p>Once a subscription checkout session has been created, the checkout session may be provided to the <code>paddle-button</code> <a href="#overlay-checkout">Blade component</a> that is included with Cashier Paddle:</p> <div class="code-container"> <pre><code data-theme="olaolu-palenight" data-lang="blade" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #89DDFF;"><</span><span style="color: #FF5572;">x-paddle-button</span><span style="color: #89DDFF;"> </span><span style="color: #FFCB6B;">:checkout</span><span style="color: #89DDFF;">=</span><span style="color: #D9F5DD;">"</span><span style="color: #C3E88D;">$checkout</span><span style="color: #D9F5DD;">"</span><span style="color: #89DDFF;"> </span><span style="color: #FFCB6B;">class</span><span style="color: #89DDFF;">=</span><span style="color: #D9F5DD;">"</span><span style="color: #C3E88D;">px-8 py-4</span><span style="color: #D9F5DD;">"</span><span style="color: #89DDFF;">></span></div><div class='line'><span style="color: #BFC7D5;"> Subscribe</span></div><div class='line'><span style="color: #89DDFF;"></</span><span style="color: #FF5572;">x-paddle-button</span><span style="color: #89DDFF;">></span></div></code></pre> </div> <p>After the user has finished their checkout, a <code>subscription_created</code> webhook will be dispatched from Paddle. Cashier will receive this webhook and setup the subscription for your customer. In order to make sure all webhooks are properly received and handled by your application, ensure you have properly <a href="#handling-paddle-webhooks">setup webhook handling</a>.</p> <h3 id="checking-subscription-status"><a href="#checking-subscription-status">Checking Subscription Status</a></h3> <p>Once a user is subscribed to your application, you may check their subscription status using a variety of convenient methods. First, the <code>subscribed</code> method returns <code>true</code> if the user has a valid subscription, even if the subscription is currently within its trial period:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">if</span><span style="color: #BFC7D5;"> (</span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscribed</span><span style="color: #BFC7D5;">()) {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #697098;">//</span><span style="color: #697098;"> ...</span></div><div class='line'><span style="color: #BFC7D5;">}</span></div></code></pre> <p>If your application offers multiple subscriptions, you may specify the subscription when invoking the <code>subscribed</code> method:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">if</span><span style="color: #BFC7D5;"> (</span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscribed</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">default</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">)) {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #697098;">//</span><span style="color: #697098;"> ...</span></div><div class='line'><span style="color: #BFC7D5;">}</span></div></code></pre> <p>The <code>subscribed</code> method also makes a great candidate for a <a href="/docs/11.x/middleware">route middleware</a>, allowing you to filter access to routes and controllers based on the user's subscription status:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #D3423E;"><?php</span></div><div class='line'> </div><div class='line'><span style="color: #C792EA;">namespace</span><span style="color: #BFC7D5;"> App\Http\Middleware;</span></div><div class='line'> </div><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">Closure</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Http\</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Symfony\Component\HttpFoundation\</span><span style="color: #FFCB8B;">Response</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #C792EA;">class</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB6B;">EnsureUserIsSubscribed</span></div><div class='line'><span style="color: #BFC7D5;">{</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #697098;">/**</span></div><div class='line'><span style="color: #697098;"> * Handle an incoming request.</span></div><div class='line'><span style="color: #697098;"> *</span></div><div class='line'><span style="color: #697098;"> * </span><span style="color: #C792EA;">@param</span><span style="color: #697098;"> </span><span style="color: #697098;">\</span><span style="color: #FFCB8B;">Closure</span><span style="color: #697098;">(\</span><span style="color: #697098;">Illuminate</span><span style="color: #697098;">\</span><span style="color: #697098;">Http</span><span style="color: #697098;">\</span><span style="color: #FFCB8B;">Request</span><span style="color: #697098;">): </span><span style="color: #697098;">(\</span><span style="color: #697098;">Symfony</span><span style="color: #697098;">\</span><span style="color: #697098;">Component</span><span style="color: #697098;">\</span><span style="color: #697098;">HttpFoundation</span><span style="color: #697098;">\</span><span style="color: #FFCB8B;">Response</span><span style="color: #697098;">) $</span><span style="color: #FFCB8B;">next</span></div><div class='line'><span style="color: #697098;"> </span><span style="color: #697098;">*/</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">public</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">handle</span><span style="color: #D9F5DD;">(</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$request</span><span style="color: #BFC7D5;">, </span><span style="color: #FFCB8B;">Closure</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$next</span><span style="color: #D9F5DD;">)</span><span style="color: #89DDFF;">:</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">Response</span></div><div class='line'><span style="color: #BFC7D5;"> {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">if</span><span style="color: #BFC7D5;"> (</span><span style="color: #BEC5D4;">$request</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">user</span><span style="color: #BFC7D5;">() </span><span style="color: #C792EA;">&&</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">!</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$request</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">user</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscribed</span><span style="color: #BFC7D5;">()) {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #697098;">//</span><span style="color: #697098;"> This user is not a paying customer...</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">return</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">redirect</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">/billing</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">);</span></div><div class='line'><span style="color: #BFC7D5;"> }</span></div><div class='line'> </div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">return</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$next</span><span style="color: #BFC7D5;">(</span><span style="color: #BEC5D4;">$request</span><span style="color: #BFC7D5;">);</span></div><div class='line'><span style="color: #BFC7D5;"> }</span></div><div class='line'><span style="color: #BFC7D5;">}</span></div></code></pre> <p>If you would like to determine if a user is still within their trial period, you may use the <code>onTrial</code> method. This method can be useful for determining if you should display a warning to the user that they are still on their trial period:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">if</span><span style="color: #BFC7D5;"> (</span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">onTrial</span><span style="color: #BFC7D5;">()) {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #697098;">//</span><span style="color: #697098;"> ...</span></div><div class='line'><span style="color: #BFC7D5;">}</span></div></code></pre> <p>The <code>subscribedToPrice</code> method may be used to determine if the user is subscribed to a given plan based on a given Paddle price ID. In this example, we will determine if the user's <code>default</code> subscription is actively subscribed to the monthly price:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">if</span><span style="color: #BFC7D5;"> (</span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscribedToPrice</span><span style="color: #BFC7D5;">(</span><span style="color: #BEC5D4;">$monthly</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_123</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">default</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">)) {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #697098;">//</span><span style="color: #697098;"> ...</span></div><div class='line'><span style="color: #BFC7D5;">}</span></div></code></pre> <p>The <code>recurring</code> method may be used to determine if the user is currently on an active subscription and is no longer within their trial period or on a grace period:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">if</span><span style="color: #BFC7D5;"> (</span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">recurring</span><span style="color: #BFC7D5;">()) {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #697098;">//</span><span style="color: #697098;"> ...</span></div><div class='line'><span style="color: #BFC7D5;">}</span></div></code></pre> <h4 id="canceled-subscription-status"><a href="#canceled-subscription-status">Canceled Subscription Status</a></h4> <p>To determine if the user was once an active subscriber but has canceled their subscription, you may use the <code>canceled</code> method:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">if</span><span style="color: #BFC7D5;"> (</span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">canceled</span><span style="color: #BFC7D5;">()) {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #697098;">//</span><span style="color: #697098;"> ...</span></div><div class='line'><span style="color: #BFC7D5;">}</span></div></code></pre> <p>You may also determine if a user has canceled their subscription, but are still on their "grace period" until the subscription fully expires. For example, if a user cancels a subscription on March 5th that was originally scheduled to expire on March 10th, the user is on their "grace period" until March 10th. In addition, the <code>subscribed</code> method will still return <code>true</code> during this time:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">if</span><span style="color: #BFC7D5;"> (</span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">onGracePeriod</span><span style="color: #BFC7D5;">()) {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #697098;">//</span><span style="color: #697098;"> ...</span></div><div class='line'><span style="color: #BFC7D5;">}</span></div></code></pre> <h4 id="past-due-status"><a href="#past-due-status">Past Due Status</a></h4> <p>If a payment fails for a subscription, it will be marked as <code>past_due</code>. When your subscription is in this state it will not be active until the customer has updated their payment information. You may determine if a subscription is past due using the <code>pastDue</code> method on the subscription instance:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">if</span><span style="color: #BFC7D5;"> (</span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">pastDue</span><span style="color: #BFC7D5;">()) {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #697098;">//</span><span style="color: #697098;"> ...</span></div><div class='line'><span style="color: #BFC7D5;">}</span></div></code></pre> <p>When a subscription is past due, you should instruct the user to <a href="#updating-payment-information">update their payment information</a>.</p> <p>If you would like subscriptions to still be considered valid when they are <code>past_due</code>, you may use the <code>keepPastDueSubscriptionsActive</code> method provided by Cashier. Typically, this method should be called in the <code>register</code> method of your <code>AppServiceProvider</code>:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Laravel\Paddle\</span><span style="color: #FFCB8B;">Cashier</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #697098;">/**</span></div><div class='line'><span style="color: #697098;"> * Register any application services.</span></div><div class='line'><span style="color: #697098;"> </span><span style="color: #697098;">*/</span></div><div class='line'><span style="color: #C792EA;">public</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">register</span><span style="color: #D9F5DD;">()</span><span style="color: #89DDFF;">:</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">void</span></div><div class='line'><span style="color: #BFC7D5;">{</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">Cashier</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">keepPastDueSubscriptionsActive</span><span style="color: #BFC7D5;">();</span></div><div class='line'><span style="color: #BFC7D5;">}</span></div></code></pre> <div class="mb-10 max-w-2xl mx-auto px-4 py-8 shadow-lg lg:flex lg:items-center callout"> <div class="w-20 h-20 mb-6 flex items-center justify-center shrink-0 lg:mb-0 bg-red-600"> <div class="opacity-75"><svg width="6" height="35" viewBox="0 0 6 35" xmlns="http://www.w3.org/2000/svg"><title>exclamation</title><path d="M0 29h6v6H0v-6zM0 0h6v24H0V0z" fill="#FFF" fill-rule="nonzero"/></svg> </div> </div> <p class="mb-0 lg:ml-6 callout"> When a subscription is in a <code>past_due</code> state it cannot be changed until payment information has been updated. Therefore, the <code>swap</code> and <code>updateQuantity</code> methods will throw an exception when the subscription is in a <code>past_due</code> state.</p> </div> <h4 id="subscription-scopes"><a href="#subscription-scopes">Subscription Scopes</a></h4> <p>Most subscription states are also available as query scopes so that you may easily query your database for subscriptions that are in a given state:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #697098;">//</span><span style="color: #697098;"> Get all valid subscriptions...</span></div><div class='line'><span style="color: #BEC5D4;">$subscriptions</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">Subscription</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">query</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">valid</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">get</span><span style="color: #BFC7D5;">();</span></div><div class='line'> </div><div class='line'><span style="color: #697098;">//</span><span style="color: #697098;"> Get all of the canceled subscriptions for a user...</span></div><div class='line'><span style="color: #BEC5D4;">$subscriptions</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscriptions</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">canceled</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">get</span><span style="color: #BFC7D5;">();</span></div></code></pre> <p>A complete list of available scopes is available below:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #FFCB8B;">Subscription</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">query</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">valid</span><span style="color: #BFC7D5;">();</span></div><div class='line'><span style="color: #FFCB8B;">Subscription</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">query</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">onTrial</span><span style="color: #BFC7D5;">();</span></div><div class='line'><span style="color: #FFCB8B;">Subscription</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">query</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">expiredTrial</span><span style="color: #BFC7D5;">();</span></div><div class='line'><span style="color: #FFCB8B;">Subscription</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">query</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">notOnTrial</span><span style="color: #BFC7D5;">();</span></div><div class='line'><span style="color: #FFCB8B;">Subscription</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">query</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">active</span><span style="color: #BFC7D5;">();</span></div><div class='line'><span style="color: #FFCB8B;">Subscription</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">query</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">recurring</span><span style="color: #BFC7D5;">();</span></div><div class='line'><span style="color: #FFCB8B;">Subscription</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">query</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">pastDue</span><span style="color: #BFC7D5;">();</span></div><div class='line'><span style="color: #FFCB8B;">Subscription</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">query</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">paused</span><span style="color: #BFC7D5;">();</span></div><div class='line'><span style="color: #FFCB8B;">Subscription</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">query</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">notPaused</span><span style="color: #BFC7D5;">();</span></div><div class='line'><span style="color: #FFCB8B;">Subscription</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">query</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">onPausedGracePeriod</span><span style="color: #BFC7D5;">();</span></div><div class='line'><span style="color: #FFCB8B;">Subscription</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">query</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">notOnPausedGracePeriod</span><span style="color: #BFC7D5;">();</span></div><div class='line'><span style="color: #FFCB8B;">Subscription</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">query</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">canceled</span><span style="color: #BFC7D5;">();</span></div><div class='line'><span style="color: #FFCB8B;">Subscription</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">query</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">notCanceled</span><span style="color: #BFC7D5;">();</span></div><div class='line'><span style="color: #FFCB8B;">Subscription</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">query</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">onGracePeriod</span><span style="color: #BFC7D5;">();</span></div><div class='line'><span style="color: #FFCB8B;">Subscription</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">query</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">notOnGracePeriod</span><span style="color: #BFC7D5;">();</span></div></code></pre> <h3 id="subscription-single-charges"><a href="#subscription-single-charges">Subscription Single Charges</a></h3> <p>Subscription single charges allow you to charge subscribers with a one-time charge on top of their subscriptions. You must provide one or multiple price ID's when invoking the <code>charge</code> method:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #697098;">//</span><span style="color: #697098;"> Charge a single price...</span></div><div class='line'><span style="color: #BEC5D4;">$response</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">charge</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_123</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">);</span></div><div class='line'> </div><div class='line'><span style="color: #697098;">//</span><span style="color: #697098;"> Charge multiple prices at once...</span></div><div class='line'><span style="color: #BEC5D4;">$response</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">charge</span><span style="color: #BFC7D5;">([</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_123</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_456</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">]);</span></div></code></pre> <p>The <code>charge</code> method will not actually charge the customer until the next billing interval of their subscription. If you would like to bill the customer immediately, you may use the <code>chargeAndInvoice</code> method instead:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BEC5D4;">$response</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">chargeAndInvoice</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_123</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">);</span></div></code></pre> <h3 id="updating-payment-information"><a href="#updating-payment-information">Updating Payment Information</a></h3> <p>Paddle always saves a payment method per subscription. If you want to update the default payment method for a subscription, you should redirect your customer to Paddle's hosted payment method update page using the <code>redirectToUpdatePaymentMethod</code> method on the subscription model:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Http\</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #FFCB8B;">Route</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">get</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">/update-payment-method</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">(</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$request</span><span style="color: #D9F5DD;">)</span><span style="color: #BFC7D5;"> {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$user</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$request</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">user</span><span style="color: #BFC7D5;">();</span></div><div class='line'> </div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">return</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">redirectToUpdatePaymentMethod</span><span style="color: #BFC7D5;">();</span></div><div class='line'><span style="color: #BFC7D5;">});</span></div></code></pre> <p>When a user has finished updating their information, a <code>subscription_updated</code> webhook will be dispatched by Paddle and the subscription details will be updated in your application's database.</p> <h3 id="changing-plans"><a href="#changing-plans">Changing Plans</a></h3> <p>After a user has subscribed to your application, they may occasionally want to change to a new subscription plan. To update the subscription plan for a user, you should pass the Paddle price's identifier to the subscription's <code>swap</code> method:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> App\Models\</span><span style="color: #FFCB8B;">User</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">User</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">find</span><span style="color: #BFC7D5;">(</span><span style="color: #F78C6C;">1</span><span style="color: #BFC7D5;">);</span></div><div class='line'> </div><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">swap</span><span style="color: #BFC7D5;">(</span><span style="color: #BEC5D4;">$premium</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_456</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">);</span></div></code></pre> <p>If you would like to swap plans and immediately invoice the user instead of waiting for their next billing cycle, you may use the <code>swapAndInvoice</code> method:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">User</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">find</span><span style="color: #BFC7D5;">(</span><span style="color: #F78C6C;">1</span><span style="color: #BFC7D5;">);</span></div><div class='line'> </div><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">swapAndInvoice</span><span style="color: #BFC7D5;">(</span><span style="color: #BEC5D4;">$premium</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_456</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">);</span></div></code></pre> <h4 id="prorations"><a href="#prorations">Prorations</a></h4> <p>By default, Paddle prorates charges when swapping between plans. The <code>noProrate</code> method may be used to update the subscriptions without prorating the charges:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">default</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">)</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">noProrate</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">swap</span><span style="color: #BFC7D5;">(</span><span style="color: #BEC5D4;">$premium</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_456</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">);</span></div></code></pre> <p>If you would like to disable proration and invoice customers immediately, you may use the <code>swapAndInvoice</code> method in combination with <code>noProrate</code>:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">default</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">)</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">noProrate</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">swapAndInvoice</span><span style="color: #BFC7D5;">(</span><span style="color: #BEC5D4;">$premium</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_456</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">);</span></div></code></pre> <p>Or, to not bill your customer for a subscription change, you may utilize the <code>doNotBill</code> method:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">default</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">)</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">doNotBill</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">swap</span><span style="color: #BFC7D5;">(</span><span style="color: #BEC5D4;">$premium</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_456</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">);</span></div></code></pre> <p>For more information on Paddle's proration policies, please consult Paddle's <a href="https://developer.paddle.com/concepts/subscriptions/proration">proration documentation</a>.</p> <h3 id="subscription-quantity"><a href="#subscription-quantity">Subscription Quantity</a></h3> <p>Sometimes subscriptions are affected by "quantity". For example, a project management application might charge $10 per month per project. To easily increment or decrement your subscription's quantity, use the <code>incrementQuantity</code> and <code>decrementQuantity</code> methods:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">User</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">find</span><span style="color: #BFC7D5;">(</span><span style="color: #F78C6C;">1</span><span style="color: #BFC7D5;">);</span></div><div class='line'> </div><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">incrementQuantity</span><span style="color: #BFC7D5;">();</span></div><div class='line'> </div><div class='line'><span style="color: #697098;">//</span><span style="color: #697098;"> Add five to the subscription's current quantity...</span></div><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">incrementQuantity</span><span style="color: #BFC7D5;">(</span><span style="color: #F78C6C;">5</span><span style="color: #BFC7D5;">);</span></div><div class='line'> </div><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">decrementQuantity</span><span style="color: #BFC7D5;">();</span></div><div class='line'> </div><div class='line'><span style="color: #697098;">//</span><span style="color: #697098;"> Subtract five from the subscription's current quantity...</span></div><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">decrementQuantity</span><span style="color: #BFC7D5;">(</span><span style="color: #F78C6C;">5</span><span style="color: #BFC7D5;">);</span></div></code></pre> <p>Alternatively, you may set a specific quantity using the <code>updateQuantity</code> method:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">updateQuantity</span><span style="color: #BFC7D5;">(</span><span style="color: #F78C6C;">10</span><span style="color: #BFC7D5;">);</span></div></code></pre> <p>The <code>noProrate</code> method may be used to update the subscription's quantity without prorating the charges:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">noProrate</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">updateQuantity</span><span style="color: #BFC7D5;">(</span><span style="color: #F78C6C;">10</span><span style="color: #BFC7D5;">);</span></div></code></pre> <h4 id="quantities-for-subscription-with-multiple-products"><a href="#quantities-for-subscription-with-multiple-products">Quantities for Subscriptions With Multiple Products</a></h4> <p>If your subscription is a <a href="#subscriptions-with-multiple-products">subscription with multiple products</a>, you should pass the ID of the price whose quantity you wish to increment or decrement as the second argument to the increment / decrement methods:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">incrementQuantity</span><span style="color: #BFC7D5;">(</span><span style="color: #F78C6C;">1</span><span style="color: #BFC7D5;">, </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">price_chat</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">);</span></div></code></pre> <h3 id="subscriptions-with-multiple-products"><a href="#subscriptions-with-multiple-products">Subscriptions With Multiple Products</a></h3> <p><a href="https://developer.paddle.com/build/subscriptions/add-remove-products-prices-addons">Subscription with multiple products</a> allow you to assign multiple billing products to a single subscription. For example, imagine you are building a customer service "helpdesk" application that has a base subscription price of $10 per month but offers a live chat add-on product for an additional $15 per month.</p> <p>When creating subscription checkout sessions, you may specify multiple products for a given subscription by passing an array of prices as the first argument to the <code>subscribe</code> method:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Http\</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #FFCB8B;">Route</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">post</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">/user/subscribe</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">(</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$request</span><span style="color: #D9F5DD;">)</span><span style="color: #BFC7D5;"> {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$checkout</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$request</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">user</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscribe</span><span style="color: #BFC7D5;">([</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">price_monthly</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">,</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">price_chat</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">,</span></div><div class='line'><span style="color: #BFC7D5;"> ]);</span></div><div class='line'> </div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">return</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">view</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">billing</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">,</span><span style="color: #82AAFF;"> </span><span style="color: #BFC7D5;">[</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">checkout</span><span style="color: #D9F5DD;">'</span><span style="color: #82AAFF;"> </span><span style="color: #89DDFF;">=></span><span style="color: #82AAFF;"> </span><span style="color: #BFC7D5;">$</span><span style="color: #BEC5D4;">checkout</span><span style="color: #BFC7D5;">]);</span></div><div class='line'><span style="color: #BFC7D5;">});</span></div></code></pre> <p>In the example above, the customer will have two prices attached to their <code>default</code> subscription. Both prices will be charged on their respective billing intervals. If necessary, you may pass an associative array of key / value pairs to indicate a specific quantity for each price:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">User</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">find</span><span style="color: #BFC7D5;">(</span><span style="color: #F78C6C;">1</span><span style="color: #BFC7D5;">);</span></div><div class='line'> </div><div class='line'><span style="color: #BEC5D4;">$checkout</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscribe</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">default</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, [</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">price_monthly</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">price_chat</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">=></span><span style="color: #BFC7D5;"> </span><span style="color: #F78C6C;">5</span><span style="color: #BFC7D5;">]);</span></div></code></pre> <p>If you would like to add another price to an existing subscription, you must use the subscription's <code>swap</code> method. When invoking the <code>swap</code> method, you should also include the subscription's current prices and quantities as well:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">User</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">find</span><span style="color: #BFC7D5;">(</span><span style="color: #F78C6C;">1</span><span style="color: #BFC7D5;">);</span></div><div class='line'> </div><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">swap</span><span style="color: #BFC7D5;">([</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">price_chat</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">price_original</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">=></span><span style="color: #BFC7D5;"> </span><span style="color: #F78C6C;">2</span><span style="color: #BFC7D5;">]);</span></div></code></pre> <p>The example above will add the new price, but the customer will not be billed for it until their next billing cycle. If you would like to bill the customer immediately you may use the <code>swapAndInvoice</code> method:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">swapAndInvoice</span><span style="color: #BFC7D5;">([</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">price_chat</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">price_original</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">=></span><span style="color: #BFC7D5;"> </span><span style="color: #F78C6C;">2</span><span style="color: #BFC7D5;">]);</span></div></code></pre> <p>You may remove prices from subscriptions using the <code>swap</code> method and omitting the price you want to remove:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">swap</span><span style="color: #BFC7D5;">([</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">price_original</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">=></span><span style="color: #BFC7D5;"> </span><span style="color: #F78C6C;">2</span><span style="color: #BFC7D5;">]);</span></div></code></pre> <div class="mb-10 max-w-2xl mx-auto px-4 py-8 shadow-lg lg:flex lg:items-center callout"> <div class="w-20 h-20 mb-6 flex items-center justify-center shrink-0 lg:mb-0 bg-red-600"> <div class="opacity-75"><svg width="6" height="35" viewBox="0 0 6 35" xmlns="http://www.w3.org/2000/svg"><title>exclamation</title><path d="M0 29h6v6H0v-6zM0 0h6v24H0V0z" fill="#FFF" fill-rule="nonzero"/></svg> </div> </div> <p class="mb-0 lg:ml-6 callout"> You may not remove the last price on a subscription. Instead, you should simply cancel the subscription.</p> </div> <h3 id="multiple-subscriptions"><a href="#multiple-subscriptions">Multiple Subscriptions</a></h3> <p>Paddle allows your customers to have multiple subscriptions simultaneously. For example, you may run a gym that offers a swimming subscription and a weight-lifting subscription, and each subscription may have different pricing. Of course, customers should be able to subscribe to either or both plans.</p> <p>When your application creates subscriptions, you may provide the type of the subscription to the <code>subscribe</code> method as the second argument. The type may be any string that represents the type of subscription the user is initiating:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Http\</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #FFCB8B;">Route</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">post</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">/swimming/subscribe</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">(</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$request</span><span style="color: #D9F5DD;">)</span><span style="color: #BFC7D5;"> {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$checkout</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$request</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">user</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscribe</span><span style="color: #BFC7D5;">(</span><span style="color: #BEC5D4;">$swimmingMonthly</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_123</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">swimming</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">);</span></div><div class='line'> </div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">return</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">view</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">billing</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">,</span><span style="color: #82AAFF;"> </span><span style="color: #BFC7D5;">[</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">checkout</span><span style="color: #D9F5DD;">'</span><span style="color: #82AAFF;"> </span><span style="color: #89DDFF;">=></span><span style="color: #82AAFF;"> </span><span style="color: #BFC7D5;">$</span><span style="color: #BEC5D4;">checkout</span><span style="color: #BFC7D5;">]);</span></div><div class='line'><span style="color: #BFC7D5;">});</span></div></code></pre> <p>In this example, we initiated a monthly swimming subscription for the customer. However, they may want to swap to a yearly subscription at a later time. When adjusting the customer's subscription, we can simply swap the price on the <code>swimming</code> subscription:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">swimming</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">)</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">swap</span><span style="color: #BFC7D5;">(</span><span style="color: #BEC5D4;">$swimmingYearly</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_456</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">);</span></div></code></pre> <p>Of course, you may also cancel the subscription entirely:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">swimming</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">)</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">cancel</span><span style="color: #BFC7D5;">();</span></div></code></pre> <h3 id="pausing-subscriptions"><a href="#pausing-subscriptions">Pausing Subscriptions</a></h3> <p>To pause a subscription, call the <code>pause</code> method on the user's subscription:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">pause</span><span style="color: #BFC7D5;">();</span></div></code></pre> <p>When a subscription is paused, Cashier will automatically set the <code>paused_at</code> column in your database. This column is used to determine when the <code>paused</code> method should begin returning <code>true</code>. For example, if a customer pauses a subscription on March 1st, but the subscription was not scheduled to recur until March 5th, the <code>paused</code> method will continue to return <code>false</code> until March 5th. This is because a user is typically allowed to continue using an application until the end of their billing cycle.</p> <p>By default, pausing happens at the next billing interval so the customer can use the remainder of the period they paid for. If you want to pause a subscription immediately, you may use the <code>pauseNow</code> method:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">pauseNow</span><span style="color: #BFC7D5;">();</span></div></code></pre> <p>Using the <code>pauseUntil</code> method, you can pause the subscription until a specific moment in time:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">pauseUntil</span><span style="color: #BFC7D5;">(</span><span style="color: #82AAFF;">now</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">addMonth</span><span style="color: #BFC7D5;">());</span></div></code></pre> <p>Or, you may use the <code>pauseNowUntil</code> method to immediately pause the subscription until a given point in time:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">pauseNowUntil</span><span style="color: #BFC7D5;">(</span><span style="color: #82AAFF;">now</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">addMonth</span><span style="color: #BFC7D5;">());</span></div></code></pre> <p>You may determine if a user has paused their subscription but are still on their "grace period" using the <code>onPausedGracePeriod</code> method:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">if</span><span style="color: #BFC7D5;"> (</span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">onPausedGracePeriod</span><span style="color: #BFC7D5;">()) {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #697098;">//</span><span style="color: #697098;"> ...</span></div><div class='line'><span style="color: #BFC7D5;">}</span></div></code></pre> <p>To resume a paused subscription, you may invoke the <code>resume</code> method on the subscription:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">resume</span><span style="color: #BFC7D5;">();</span></div></code></pre> <div class="mb-10 max-w-2xl mx-auto px-4 py-8 shadow-lg lg:flex lg:items-center callout"> <div class="w-20 h-20 mb-6 flex items-center justify-center shrink-0 lg:mb-0 bg-red-600"> <div class="opacity-75"><svg width="6" height="35" viewBox="0 0 6 35" xmlns="http://www.w3.org/2000/svg"><title>exclamation</title><path d="M0 29h6v6H0v-6zM0 0h6v24H0V0z" fill="#FFF" fill-rule="nonzero"/></svg> </div> </div> <p class="mb-0 lg:ml-6 callout"> A subscription cannot be modified while it is paused. If you want to swap to a different plan or update quantities you must resume the subscription first.</p> </div> <h3 id="canceling-subscriptions"><a href="#canceling-subscriptions">Canceling Subscriptions</a></h3> <p>To cancel a subscription, call the <code>cancel</code> method on the user's subscription:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">cancel</span><span style="color: #BFC7D5;">();</span></div></code></pre> <p>When a subscription is canceled, Cashier will automatically set the <code>ends_at</code> column in your database. This column is used to determine when the <code>subscribed</code> method should begin returning <code>false</code>. For example, if a customer cancels a subscription on March 1st, but the subscription was not scheduled to end until March 5th, the <code>subscribed</code> method will continue to return <code>true</code> until March 5th. This is done because a user is typically allowed to continue using an application until the end of their billing cycle.</p> <p>You may determine if a user has canceled their subscription but are still on their "grace period" using the <code>onGracePeriod</code> method:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">if</span><span style="color: #BFC7D5;"> (</span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">onGracePeriod</span><span style="color: #BFC7D5;">()) {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #697098;">//</span><span style="color: #697098;"> ...</span></div><div class='line'><span style="color: #BFC7D5;">}</span></div></code></pre> <p>If you wish to cancel a subscription immediately, you may call the <code>cancelNow</code> method on the subscription:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">cancelNow</span><span style="color: #BFC7D5;">();</span></div></code></pre> <p>To stop a subscription on its grace period from canceling, you may invoke the <code>stopCancelation</code> method:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">stopCancelation</span><span style="color: #BFC7D5;">();</span></div></code></pre> <div class="mb-10 max-w-2xl mx-auto px-4 py-8 shadow-lg lg:flex lg:items-center callout"> <div class="w-20 h-20 mb-6 flex items-center justify-center shrink-0 lg:mb-0 bg-red-600"> <div class="opacity-75"><svg width="6" height="35" viewBox="0 0 6 35" xmlns="http://www.w3.org/2000/svg"><title>exclamation</title><path d="M0 29h6v6H0v-6zM0 0h6v24H0V0z" fill="#FFF" fill-rule="nonzero"/></svg> </div> </div> <p class="mb-0 lg:ml-6 callout"> Paddle's subscriptions cannot be resumed after cancelation. If your customer wishes to resume their subscription, they will have to create a new subscription.</p> </div> <h2 id="subscription-trials"><a href="#subscription-trials">Subscription Trials</a></h2> <h3 id="with-payment-method-up-front"><a href="#with-payment-method-up-front">With Payment Method Up Front</a></h3> <p>If you would like to offer trial periods to your customers while still collecting payment method information up front, you should use set a trial time in the Paddle dashboard on the price your customer is subscribing to. Then, initiate the checkout session as normal:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Http\</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #FFCB8B;">Route</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">get</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">/user/subscribe</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">(</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$request</span><span style="color: #D9F5DD;">)</span><span style="color: #BFC7D5;"> {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$checkout</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$request</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">user</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscribe</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_monthly</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">)</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">returnTo</span><span style="color: #BFC7D5;">(</span><span style="color: #82AAFF;">route</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">home</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">));</span></div><div class='line'> </div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">return</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">view</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">billing</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">,</span><span style="color: #82AAFF;"> </span><span style="color: #BFC7D5;">[</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">checkout</span><span style="color: #D9F5DD;">'</span><span style="color: #82AAFF;"> </span><span style="color: #89DDFF;">=></span><span style="color: #82AAFF;"> </span><span style="color: #BFC7D5;">$</span><span style="color: #BEC5D4;">checkout</span><span style="color: #BFC7D5;">]);</span></div><div class='line'><span style="color: #BFC7D5;">});</span></div></code></pre> <p>When your application receives the <code>subscription_created</code> event, Cashier will set the trial period ending date on the subscription record within your application's database as well as instruct Paddle to not begin billing the customer until after this date.</p> <div class="mb-10 max-w-2xl mx-auto px-4 py-8 shadow-lg lg:flex lg:items-center callout"> <div class="w-20 h-20 mb-6 flex items-center justify-center shrink-0 lg:mb-0 bg-red-600"> <div class="opacity-75"><svg width="6" height="35" viewBox="0 0 6 35" xmlns="http://www.w3.org/2000/svg"><title>exclamation</title><path d="M0 29h6v6H0v-6zM0 0h6v24H0V0z" fill="#FFF" fill-rule="nonzero"/></svg> </div> </div> <p class="mb-0 lg:ml-6 callout"> If the customer's subscription is not canceled before the trial ending date they will be charged as soon as the trial expires, so you should be sure to notify your users of their trial ending date.</p> </div> <p>You may determine if the user is within their trial period using either the <code>onTrial</code> method of the user instance or the <code>onTrial</code> method of the subscription instance. The two examples below are equivalent:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">if</span><span style="color: #BFC7D5;"> (</span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">onTrial</span><span style="color: #BFC7D5;">()) {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #697098;">//</span><span style="color: #697098;"> ...</span></div><div class='line'><span style="color: #BFC7D5;">}</span></div><div class='line'> </div><div class='line'><span style="color: #C792EA;">if</span><span style="color: #BFC7D5;"> (</span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">onTrial</span><span style="color: #BFC7D5;">()) {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #697098;">//</span><span style="color: #697098;"> ...</span></div><div class='line'><span style="color: #BFC7D5;">}</span></div></code></pre> <p>To determine if an existing trial has expired, you may use the <code>hasExpiredTrial</code> methods:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">if</span><span style="color: #BFC7D5;"> (</span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">hasExpiredTrial</span><span style="color: #BFC7D5;">()) {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #697098;">//</span><span style="color: #697098;"> ...</span></div><div class='line'><span style="color: #BFC7D5;">}</span></div><div class='line'> </div><div class='line'><span style="color: #C792EA;">if</span><span style="color: #BFC7D5;"> (</span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">hasExpiredTrial</span><span style="color: #BFC7D5;">()) {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #697098;">//</span><span style="color: #697098;"> ...</span></div><div class='line'><span style="color: #BFC7D5;">}</span></div></code></pre> <p>To determine if a user is on trial for a specific subscription type, you may provide the type to the <code>onTrial</code> or <code>hasExpiredTrial</code> methods:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">if</span><span style="color: #BFC7D5;"> (</span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">onTrial</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">default</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">)) {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #697098;">//</span><span style="color: #697098;"> ...</span></div><div class='line'><span style="color: #BFC7D5;">}</span></div><div class='line'> </div><div class='line'><span style="color: #C792EA;">if</span><span style="color: #BFC7D5;"> (</span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">hasExpiredTrial</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">default</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">)) {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #697098;">//</span><span style="color: #697098;"> ...</span></div><div class='line'><span style="color: #BFC7D5;">}</span></div></code></pre> <h3 id="without-payment-method-up-front"><a href="#without-payment-method-up-front">Without Payment Method Up Front</a></h3> <p>If you would like to offer trial periods without collecting the user's payment method information up front, you may set the <code>trial_ends_at</code> column on the customer record attached to your user to your desired trial ending date. This is typically done during user registration:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> App\Models\</span><span style="color: #FFCB8B;">User</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">User</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">create</span><span style="color: #BFC7D5;">([</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #697098;">//</span><span style="color: #697098;"> ...</span></div><div class='line'><span style="color: #BFC7D5;">]);</span></div><div class='line'> </div><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">createAsCustomer</span><span style="color: #BFC7D5;">([</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">trial_ends_at</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">=></span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">now</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">addDays</span><span style="color: #BFC7D5;">(</span><span style="color: #F78C6C;">10</span><span style="color: #BFC7D5;">)</span></div><div class='line'><span style="color: #BFC7D5;">]);</span></div></code></pre> <p>Cashier refers to this type of trial as a "generic trial", since it is not attached to any existing subscription. The <code>onTrial</code> method on the <code>User</code> instance will return <code>true</code> if the current date is not past the value of <code>trial_ends_at</code>:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">if</span><span style="color: #BFC7D5;"> (</span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">onTrial</span><span style="color: #BFC7D5;">()) {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #697098;">//</span><span style="color: #697098;"> User is within their trial period...</span></div><div class='line'><span style="color: #BFC7D5;">}</span></div></code></pre> <p>Once you are ready to create an actual subscription for the user, you may use the <code>subscribe</code> method as usual:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Http\</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #FFCB8B;">Route</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">get</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">/user/subscribe</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">(</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$request</span><span style="color: #D9F5DD;">)</span><span style="color: #BFC7D5;"> {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$checkout</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscribe</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_monthly</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">)</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">returnTo</span><span style="color: #BFC7D5;">(</span><span style="color: #82AAFF;">route</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">home</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">));</span></div><div class='line'> </div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">return</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">view</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">billing</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">,</span><span style="color: #82AAFF;"> </span><span style="color: #BFC7D5;">[</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">checkout</span><span style="color: #D9F5DD;">'</span><span style="color: #82AAFF;"> </span><span style="color: #89DDFF;">=></span><span style="color: #82AAFF;"> </span><span style="color: #BFC7D5;">$</span><span style="color: #BEC5D4;">checkout</span><span style="color: #BFC7D5;">]);</span></div><div class='line'><span style="color: #BFC7D5;">});</span></div></code></pre> <p>To retrieve the user's trial ending date, you may use the <code>trialEndsAt</code> method. This method will return a Carbon date instance if a user is on a trial or <code>null</code> if they aren't. You may also pass an optional subscription type parameter if you would like to get the trial ending date for a specific subscription other than the default one:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">if</span><span style="color: #BFC7D5;"> (</span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">onTrial</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">default</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">)) {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$trialEndsAt</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">trialEndsAt</span><span style="color: #BFC7D5;">();</span></div><div class='line'><span style="color: #BFC7D5;">}</span></div></code></pre> <p>You may use the <code>onGenericTrial</code> method if you wish to know specifically that the user is within their "generic" trial period and has not created an actual subscription yet:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">if</span><span style="color: #BFC7D5;"> (</span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">onGenericTrial</span><span style="color: #BFC7D5;">()) {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #697098;">//</span><span style="color: #697098;"> User is within their "generic" trial period...</span></div><div class='line'><span style="color: #BFC7D5;">}</span></div></code></pre> <h3 id="extend-or-activate-a-trial"><a href="#extend-or-activate-a-trial">Extend or Activate a Trial</a></h3> <p>You can extend an existing trial period on a subscription by invoking the <code>extendTrial</code> method and specifying the moment in time that the trial should end:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">extendTrial</span><span style="color: #BFC7D5;">(</span><span style="color: #82AAFF;">now</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">addDays</span><span style="color: #BFC7D5;">(</span><span style="color: #F78C6C;">5</span><span style="color: #BFC7D5;">));</span></div></code></pre> <p>Or, you may immediately activate a subscription by ending its trial by calling the <code>activate</code> method on the subscription:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">activate</span><span style="color: #BFC7D5;">();</span></div></code></pre> <h2 id="handling-paddle-webhooks"><a href="#handling-paddle-webhooks">Handling Paddle Webhooks</a></h2> <p>Paddle can notify your application of a variety of events via webhooks. By default, a route that points to Cashier's webhook controller is registered by the Cashier service provider. This controller will handle all incoming webhook requests.</p> <p>By default, this controller will automatically handle canceling subscriptions that have too many failed charges, subscription updates, and payment method changes; however, as we'll soon discover, you can extend this controller to handle any Paddle webhook event you like.</p> <p>To ensure your application can handle Paddle webhooks, be sure to <a href="https://vendors.paddle.com/alerts-webhooks">configure the webhook URL in the Paddle control panel</a>. By default, Cashier's webhook controller responds to the <code>/paddle/webhook</code> URL path. The full list of all webhooks you should enable in the Paddle control panel are:</p> <ul> <li>Customer Updated</li> <li>Transaction Completed</li> <li>Transaction Updated</li> <li>Subscription Created</li> <li>Subscription Updated</li> <li>Subscription Paused</li> <li>Subscription Canceled</li> </ul> <div class="mb-10 max-w-2xl mx-auto px-4 py-8 shadow-lg lg:flex lg:items-center callout"> <div class="w-20 h-20 mb-6 flex items-center justify-center shrink-0 lg:mb-0 bg-red-600"> <div class="opacity-75"><svg width="6" height="35" viewBox="0 0 6 35" xmlns="http://www.w3.org/2000/svg"><title>exclamation</title><path d="M0 29h6v6H0v-6zM0 0h6v24H0V0z" fill="#FFF" fill-rule="nonzero"/></svg> </div> </div> <p class="mb-0 lg:ml-6 callout"> Make sure you protect incoming requests with Cashier's included <a href="/docs/11.x/cashier-paddle#verifying-webhook-signatures">webhook signature verification</a> middleware.</p> </div> <h4 id="webhooks-csrf-protection"><a href="#webhooks-csrf-protection">Webhooks and CSRF Protection</a></h4> <p>Since Paddle webhooks need to bypass Laravel's <a href="/docs/11.x/csrf">CSRF protection</a>, you should ensure that Laravel does not attempt to verify the CSRF token for incoming Paddle webhooks. To accomplish this, you should exclude <code>paddle/*</code> from CSRF protection in your application's <code>bootstrap/app.php</code> file:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">withMiddleware</span><span style="color: #BFC7D5;">(</span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">(</span><span style="color: #FFCB8B;">Middleware</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$middleware</span><span style="color: #D9F5DD;">)</span><span style="color: #BFC7D5;"> {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$middleware</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">validateCsrfTokens</span><span style="color: #BFC7D5;">(except: [</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">paddle/*</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">,</span></div><div class='line'><span style="color: #BFC7D5;"> ]);</span></div><div class='line'><span style="color: #BFC7D5;">})</span></div></code></pre> <h4 id="webhooks-local-development"><a href="#webhooks-local-development">Webhooks and Local Development</a></h4> <p>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 <a href="https://ngrok.com/">Ngrok</a> or <a href="https://expose.dev/docs/introduction">Expose</a>. If you are developing your application locally using <a href="/docs/11.x/sail">Laravel Sail</a>, you may use Sail's <a href="/docs/11.x/sail#sharing-your-site">site sharing command</a>.</p> <h3 id="defining-webhook-event-handlers"><a href="#defining-webhook-event-handlers">Defining Webhook Event Handlers</a></h3> <p>Cashier automatically handles subscription cancelation on failed charges and other common Paddle webhooks. However, if you have additional webhook events you would like to handle, you may do so by listening to the following events that are dispatched by Cashier:</p> <ul> <li> <code>Laravel\Paddle\Events\WebhookReceived</code> </li> <li> <code>Laravel\Paddle\Events\WebhookHandled</code> </li> </ul> <p>Both events contain the full payload of the Paddle webhook. For example, if you wish to handle the <code>transaction.billed</code> webhook, you may register a <a href="/docs/11.x/events#defining-listeners">listener</a> that will handle the event:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #D3423E;"><?php</span></div><div class='line'> </div><div class='line'><span style="color: #C792EA;">namespace</span><span style="color: #BFC7D5;"> App\Listeners;</span></div><div class='line'> </div><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Laravel\Paddle\Events\</span><span style="color: #FFCB8B;">WebhookReceived</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #C792EA;">class</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB6B;">PaddleEventListener</span></div><div class='line'><span style="color: #BFC7D5;">{</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #697098;">/**</span></div><div class='line'><span style="color: #697098;"> * Handle received Paddle webhooks.</span></div><div class='line'><span style="color: #697098;"> </span><span style="color: #697098;">*/</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">public</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">handle</span><span style="color: #D9F5DD;">(</span><span style="color: #FFCB8B;">WebhookReceived</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$event</span><span style="color: #D9F5DD;">)</span><span style="color: #89DDFF;">:</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">void</span></div><div class='line'><span style="color: #BFC7D5;"> {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">if</span><span style="color: #BFC7D5;"> (</span><span style="color: #BEC5D4;">$event</span><span style="color: #89DDFF;">->payload</span><span style="color: #BFC7D5;">[</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">event_type</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">] </span><span style="color: #C792EA;">===</span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">transaction.billed</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">) {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #697098;">//</span><span style="color: #697098;"> Handle the incoming event...</span></div><div class='line'><span style="color: #BFC7D5;"> }</span></div><div class='line'><span style="color: #BFC7D5;"> }</span></div><div class='line'><span style="color: #BFC7D5;">}</span></div></code></pre> <p>Cashier also emit events dedicated to the type of the received webhook. In addition to the full payload from Paddle, they also contain the relevant models that were used to process the webhook such as the billable model, the subscription, or the receipt:</p> <div class="content-list" markdown="1"> <ul> <li> <code>Laravel\Paddle\Events\CustomerUpdated</code> </li> <li> <code>Laravel\Paddle\Events\TransactionCompleted</code> </li> <li> <code>Laravel\Paddle\Events\TransactionUpdated</code> </li> <li> <code>Laravel\Paddle\Events\SubscriptionCreated</code> </li> <li> <code>Laravel\Paddle\Events\SubscriptionUpdated</code> </li> <li> <code>Laravel\Paddle\Events\SubscriptionPaused</code> </li> <li> <code>Laravel\Paddle\Events\SubscriptionCanceled</code> </li> </ul> </div> <p>You can also override the default, built-in webhook route by defining the <code>CASHIER_WEBHOOK</code> environment variable in your application's <code>.env</code> file. This value should be the full URL to your webhook route and needs to match the URL set in your Paddle control panel:</p> <div class="code-container"> <pre><code data-theme="olaolu-palenight" data-lang="ini" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">CASHIER_WEBHOOK</span><span style="color: #BFC7D5;">=https://example.com/my-paddle-webhook-url</span></div></code></pre> </div> <h3 id="verifying-webhook-signatures"><a href="#verifying-webhook-signatures">Verifying Webhook Signatures</a></h3> <p>To secure your webhooks, you may use <a href="https://developer.paddle.com/webhook-reference/verifying-webhooks">Paddle's webhook signatures</a>. For convenience, Cashier automatically includes a middleware which validates that the incoming Paddle webhook request is valid.</p> <p>To enable webhook verification, ensure that the <code>PADDLE_WEBHOOK_SECRET</code> environment variable is defined in your application's <code>.env</code> file. The webhook secret may be retrieved from your Paddle account dashboard.</p> <h2 id="single-charges"><a href="#single-charges">Single Charges</a></h2> <h3 id="charging-for-products"><a href="#charging-for-products">Charging for Products</a></h3> <p>If you would like to initiate a product purchase for a customer, you may use the <code>checkout</code> method on a billable model instance to generate a checkout session for the purchase. The <code>checkout</code> method accepts one or multiple price ID's. If necessary, an associative array may be used to provide the quantity of the product that is being purchased:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Http\</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #FFCB8B;">Route</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">get</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">/buy</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">(</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$request</span><span style="color: #D9F5DD;">)</span><span style="color: #BFC7D5;"> {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$checkout</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$request</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">user</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">checkout</span><span style="color: #BFC7D5;">([</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_tshirt</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_socks</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">=></span><span style="color: #BFC7D5;"> </span><span style="color: #F78C6C;">5</span><span style="color: #BFC7D5;">]);</span></div><div class='line'> </div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">return</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">view</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">buy</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">,</span><span style="color: #82AAFF;"> </span><span style="color: #BFC7D5;">[</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">checkout</span><span style="color: #D9F5DD;">'</span><span style="color: #82AAFF;"> </span><span style="color: #89DDFF;">=></span><span style="color: #82AAFF;"> </span><span style="color: #BFC7D5;">$</span><span style="color: #BEC5D4;">checkout</span><span style="color: #BFC7D5;">]);</span></div><div class='line'><span style="color: #BFC7D5;">});</span></div></code></pre> <p>After generating the checkout session, you may use Cashier's provided <code>paddle-button</code> <a href="#overlay-checkout">Blade component</a> to allow the user to view the Paddle checkout widget and complete the purchase:</p> <div class="code-container"> <pre><code data-theme="olaolu-palenight" data-lang="blade" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #89DDFF;"><</span><span style="color: #FF5572;">x-paddle-button</span><span style="color: #89DDFF;"> </span><span style="color: #FFCB6B;">:checkout</span><span style="color: #89DDFF;">=</span><span style="color: #D9F5DD;">"</span><span style="color: #C3E88D;">$checkout</span><span style="color: #D9F5DD;">"</span><span style="color: #89DDFF;"> </span><span style="color: #FFCB6B;">class</span><span style="color: #89DDFF;">=</span><span style="color: #D9F5DD;">"</span><span style="color: #C3E88D;">px-8 py-4</span><span style="color: #D9F5DD;">"</span><span style="color: #89DDFF;">></span></div><div class='line'><span style="color: #BFC7D5;"> Buy</span></div><div class='line'><span style="color: #89DDFF;"></</span><span style="color: #FF5572;">x-paddle-button</span><span style="color: #89DDFF;">></span></div></code></pre> </div> <p>A checkout session has a <code>customData</code> method, allowing you to pass any custom data you wish to the underlying transaction creation. Please consult <a href="https://developer.paddle.com/build/transactions/custom-data">the Paddle documentation</a> to learn more about the options available to you when passing custom data:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BEC5D4;">$checkout</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">checkout</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_tshirt</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">)</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">customData</span><span style="color: #BFC7D5;">([</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">custom_option</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">=></span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$value</span><span style="color: #BFC7D5;">,</span></div><div class='line'><span style="color: #BFC7D5;"> ]);</span></div></code></pre> <h3 id="refunding-transactions"><a href="#refunding-transactions">Refunding Transactions</a></h3> <p>Refunding transactions will return the refunded amount to your customer's payment method that was used at the time of purchase. If you need to refund a Paddle purchase, you may use the <code>refund</code> method on a <code>Cashier\Paddle\Transaction</code> model. This method accepts a reason as the first argument, one or more price ID's to refund with optional amounts as an associative array. You may retrieve the transactions for a given billable model using the <code>transactions</code> method.</p> <p>For example, imagine we want to refund a specific transaction for prices <code>pri_123</code> and <code>pri_456</code>. We want to fully refund <code>pri_123</code>, but only refund two dollars for <code>pri_456</code>:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> App\Models\</span><span style="color: #FFCB8B;">User</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">User</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">find</span><span style="color: #BFC7D5;">(</span><span style="color: #F78C6C;">1</span><span style="color: #BFC7D5;">);</span></div><div class='line'> </div><div class='line'><span style="color: #BEC5D4;">$transaction</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">transactions</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">first</span><span style="color: #BFC7D5;">();</span></div><div class='line'> </div><div class='line'><span style="color: #BEC5D4;">$response</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$transaction</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">refund</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">Accidental charge</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, [</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_123</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, </span><span style="color: #697098;">//</span><span style="color: #697098;"> Fully refund this price...</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_456</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">=></span><span style="color: #BFC7D5;"> </span><span style="color: #F78C6C;">200</span><span style="color: #BFC7D5;">, </span><span style="color: #697098;">//</span><span style="color: #697098;"> Only partially refund this price...</span></div><div class='line'><span style="color: #BFC7D5;">]);</span></div></code></pre> <p>The example above refunds specific line items in a transaction. If you want to refund the entire transaction, simply provide a reason:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BEC5D4;">$response</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$transaction</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">refund</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">Accidental charge</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">);</span></div></code></pre> <p>For more information on refunds, please consult <a href="https://developer.paddle.com/build/transactions/create-transaction-adjustments">Paddle's refund documentation</a>.</p> <div class="mb-10 max-w-2xl mx-auto px-4 py-8 shadow-lg lg:flex lg:items-center callout"> <div class="w-20 h-20 mb-6 flex items-center justify-center shrink-0 lg:mb-0 bg-red-600"> <div class="opacity-75"><svg width="6" height="35" viewBox="0 0 6 35" xmlns="http://www.w3.org/2000/svg"><title>exclamation</title><path d="M0 29h6v6H0v-6zM0 0h6v24H0V0z" fill="#FFF" fill-rule="nonzero"/></svg> </div> </div> <p class="mb-0 lg:ml-6 callout"> Refunds must always be approved by Paddle before fully processing.</p> </div> <h3 id="crediting-transactions"><a href="#crediting-transactions">Crediting Transactions</a></h3> <p>Just like refunding, you can also credit transactions. Crediting transactions will add the funds to the customer's balance so it may be used for future purchases. Crediting transactions can only be done for manually-collected transactions and not for automatically-collected transactions (like subscriptions) since Paddle handles subscription credits automatically:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BEC5D4;">$transaction</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">transactions</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">first</span><span style="color: #BFC7D5;">();</span></div><div class='line'> </div><div class='line'><span style="color: #697098;">//</span><span style="color: #697098;"> Credit a specific line item fully...</span></div><div class='line'><span style="color: #BEC5D4;">$response</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$transaction</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">credit</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">Compensation</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, </span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">pri_123</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">);</span></div></code></pre> <p>For more info, <a href="https://developer.paddle.com/build/transactions/create-transaction-adjustments">see Paddle's documentation on crediting</a>.</p> <div class="mb-10 max-w-2xl mx-auto px-4 py-8 shadow-lg lg:flex lg:items-center callout"> <div class="w-20 h-20 mb-6 flex items-center justify-center shrink-0 lg:mb-0 bg-red-600"> <div class="opacity-75"><svg width="6" height="35" viewBox="0 0 6 35" xmlns="http://www.w3.org/2000/svg"><title>exclamation</title><path d="M0 29h6v6H0v-6zM0 0h6v24H0V0z" fill="#FFF" fill-rule="nonzero"/></svg> </div> </div> <p class="mb-0 lg:ml-6 callout"> Credits can only be applied for manually-collected transactions. Automatically-collected transactions are credited by Paddle themselves.</p> </div> <h2 id="transactions"><a href="#transactions">Transactions</a></h2> <p>You may easily retrieve an array of a billable model's transactions via the <code>transactions</code> property:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> App\Models\</span><span style="color: #FFCB8B;">User</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">User</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">find</span><span style="color: #BFC7D5;">(</span><span style="color: #F78C6C;">1</span><span style="color: #BFC7D5;">);</span></div><div class='line'> </div><div class='line'><span style="color: #BEC5D4;">$transactions</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">->transactions</span><span style="color: #BFC7D5;">;</span></div></code></pre> <p>Transactions represent payments for your products and purchases and are accompanied by invoices. Only completed transactions are stored in your application's database.</p> <p>When listing the transactions for a customer, you may use the transaction instance's methods to display the relevant payment information. For example, you may wish to list every transaction in a table, allowing the user to easily download any of the invoices:</p> <div class="code-container"> <pre><code data-theme="olaolu-palenight" data-lang="html" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #89DDFF;"><</span><span style="color: #FF5572;">table</span><span style="color: #89DDFF;">></span></div><div class='line'><span style="color: #BFC7D5;"> @foreach ($transactions as $transaction)</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;"><</span><span style="color: #FF5572;">tr</span><span style="color: #89DDFF;">></span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;"><</span><span style="color: #FF5572;">td</span><span style="color: #89DDFF;">></span><span style="color: #BFC7D5;">{{ $transaction->billed_at->toFormattedDateString() }}</span><span style="color: #89DDFF;"></</span><span style="color: #FF5572;">td</span><span style="color: #89DDFF;">></span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;"><</span><span style="color: #FF5572;">td</span><span style="color: #89DDFF;">></span><span style="color: #BFC7D5;">{{ $transaction->total() }}</span><span style="color: #89DDFF;"></</span><span style="color: #FF5572;">td</span><span style="color: #89DDFF;">></span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;"><</span><span style="color: #FF5572;">td</span><span style="color: #89DDFF;">></span><span style="color: #BFC7D5;">{{ $transaction->tax() }}</span><span style="color: #89DDFF;"></</span><span style="color: #FF5572;">td</span><span style="color: #89DDFF;">></span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;"><</span><span style="color: #FF5572;">td</span><span style="color: #89DDFF;">><</span><span style="color: #FF5572;">a</span><span style="color: #89DDFF;"> </span><span style="color: #FFCB6B;">href</span><span style="color: #89DDFF;">=</span><span style="color: #D9F5DD;">"</span><span style="color: #C3E88D;">{{ route('download-invoice', $transaction->id) }}</span><span style="color: #D9F5DD;">"</span><span style="color: #89DDFF;"> </span><span style="color: #FFCB6B;">target</span><span style="color: #89DDFF;">=</span><span style="color: #D9F5DD;">"</span><span style="color: #C3E88D;">_blank</span><span style="color: #D9F5DD;">"</span><span style="color: #89DDFF;">></span><span style="color: #BFC7D5;">Download</span><span style="color: #89DDFF;"></</span><span style="color: #FF5572;">a</span><span style="color: #89DDFF;">></</span><span style="color: #FF5572;">td</span><span style="color: #89DDFF;">></span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;"></</span><span style="color: #FF5572;">tr</span><span style="color: #89DDFF;">></span></div><div class='line'><span style="color: #BFC7D5;"> @endforeach</span></div><div class='line'><span style="color: #89DDFF;"></</span><span style="color: #FF5572;">table</span><span style="color: #89DDFF;">></span></div></code></pre> </div> <p>The <code>download-invoice</code> route may look like the following:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Http\</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Laravel\Paddle\</span><span style="color: #FFCB8B;">Transaction</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #FFCB8B;">Route</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">get</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">/download-invoice/{transaction}</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">, </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">(</span><span style="color: #FFCB8B;">Request</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$request</span><span style="color: #BFC7D5;">, </span><span style="color: #FFCB8B;">Transaction</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$transaction</span><span style="color: #D9F5DD;">)</span><span style="color: #BFC7D5;"> {</span></div><div class='line'><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">return</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$transaction</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">redirectToInvoicePdf</span><span style="color: #BFC7D5;">();</span></div><div class='line'><span style="color: #BFC7D5;">})</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">name</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">download-invoice</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">);</span></div></code></pre> <h3 id="past-and-upcoming-payments"><a href="#past-and-upcoming-payments">Past and Upcoming Payments</a></h3> <p>You may use the <code>lastPayment</code> and <code>nextPayment</code> methods to retrieve and display a customer's past or upcoming payments for recurring subscriptions:</p> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> App\Models\</span><span style="color: #FFCB8B;">User</span><span style="color: #BFC7D5;">;</span></div><div class='line'> </div><div class='line'><span style="color: #BEC5D4;">$user</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">User</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">find</span><span style="color: #BFC7D5;">(</span><span style="color: #F78C6C;">1</span><span style="color: #BFC7D5;">);</span></div><div class='line'> </div><div class='line'><span style="color: #BEC5D4;">$subscription</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">subscription</span><span style="color: #BFC7D5;">();</span></div><div class='line'> </div><div class='line'><span style="color: #BEC5D4;">$lastPayment</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$subscription</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">lastPayment</span><span style="color: #BFC7D5;">();</span></div><div class='line'><span style="color: #BEC5D4;">$nextPayment</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$subscription</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">nextPayment</span><span style="color: #BFC7D5;">();</span></div></code></pre> <p>Both of these methods will return an instance of <code>Laravel\Paddle\Payment</code>; however, <code>lastPayment</code> will return <code>null</code> when transactions have not been synced by webhooks yet, while <code>nextPayment</code> will return <code>null</code> when the billing cycle has ended (such as when a subscription has been canceled):</p> <div class="code-container"> <pre><code data-theme="olaolu-palenight" data-lang="blade" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BFC7D5;">Next payment: </span><span style="color: #89DDFF;">{{</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$nextPayment</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">amount</span><span style="color: #BFC7D5;">() </span><span style="color: #89DDFF;">}}</span><span style="color: #BFC7D5;"> due on </span><span style="color: #89DDFF;">{{</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$nextPayment</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">date</span><span style="color: #BFC7D5;">()</span><span style="color: #89DDFF;">-></span><span style="color: #82AAFF;">format</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">'</span><span style="color: #C3E88D;">d/m/Y</span><span style="color: #D9F5DD;">'</span><span style="color: #BFC7D5;">) </span><span style="color: #89DDFF;">}}</span></div></code></pre> </div> <h2 id="testing"><a href="#testing">Testing</a></h2> <p>While testing, you should manually test your billing flow to make sure your integration works as expected.</p> <p>For automated tests, including those executed within a CI environment, you may use <a href="/docs/11.x/http-client#testing">Laravel's HTTP Client</a> to fake HTTP calls made to Paddle. Although this does not test the actual responses from Paddle, it does provide a way to test your application without actually calling Paddle's API.</p> <script async type="text/javascript" src="//cdn.carbonads.com/carbon.js?serve=CKYILK3E&placement=laravelcom" id="_carbonads_js"></script> </div> </section> </section> </div> </section> </div> </div> <footer class="relative pt-12 dark:bg-dark-700"> <div class="max-w-screen-2xl mx-auto w-full px-8"> <div> <a href="/" class="inline-flex"> <img class="w-16 h-16" src="/img/logomark.min.svg" alt="Laravel" width="64" height="64" loading="lazy"> </a> </div> <div class="mt-6 grid grid-cols-12 md:gap-x-8 gap-y-12 sm:mt-12"> <div class="col-span-12 lg:col-span-4"> <p class="max-w-sm text-xs text-gray-700 sm:text-sm dark:text-gray-500"> Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel attempts to take the pain out of development by easing common tasks used in most web projects.</p> <ul class="mt-6 flex items-center space-x-3"> <li> <a href="https://x.com/laravelphp"> <img class="hidden dark:inline-block w-6 h-6" src="/img/social/x.dark.min.svg" alt="X" width="24" height="20" loading="lazy"> <img class="inline-block dark:hidden w-6 h-6" src="/img/social/x.min.svg" alt="X" width="24" height="20" loading="lazy"> </a> </li> <li> <a href="https://github.com/laravel"> <img class="hidden dark:inline-block w-6 h-6" src="/img/social/github.dark.min.svg" alt="GitHub" width="24" height="24" loading="lazy"> <img class="inline-block dark:hidden w-6 h-6" src="/img/social/github.min.svg" alt="GitHub" width="24" height="24" loading="lazy"> </a> </li> <li> <a href="https://discord.gg/laravel"> <img class="hidden dark:inline-block w-6 h-6" src="/img/social/discord.dark.min.svg" alt="Discord" width="21" height="24" loading="lazy"> <img class="inline-block dark:hidden w-6 h-6" src="/img/social/discord.min.svg" alt="Discord" width="21" height="24" loading="lazy"> </a> </li> <li> <a href="https://www.youtube.com/laravelphp"> <img class="hidden dark:inline-block w-6 h-6" src="/img/social/youtube.dark.min.svg" alt="YouTube" width="169" height="150" loading="lazy"> <img class="inline-block dark:hidden w-6 h-6" src="/img/social/youtube.min.svg" alt="YouTube" width="169" height="150" loading="lazy"> </a> </li> </ul> </div> <div class="text-xs col-span-6 md:col-span-3 lg:col-span-2"> <span class="uppercase dark:text-gray-200">Highlights</span> <div class="mt-5"> <ul class="space-y-3 text-gray-700 dark:text-gray-500"> <li> <a href="/docs/11.x/releases" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Release Notes</a> </li> <li> <a href="/docs/11.x/installation" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Getting Started</a> </li> <li> <a href="/docs/11.x/routing" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Routing</a> </li> <li> <a href="/docs/11.x/blade" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Blade Templates</a> </li> <li> <a href="/docs/11.x/authentication" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Authentication</a> </li> <li> <a href="/docs/11.x/authorization" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Authorization</a> </li> <li> <a href="/docs/11.x/artisan" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Artisan Console</a> </li> <li> <a href="/docs/11.x/database" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Database</a> </li> <li> <a href="/docs/11.x/eloquent" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Eloquent ORM</a> </li> <li> <a href="/docs/11.x/testing" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Testing</a> </li> </ul> </div> </div> <div class="text-xs col-span-6 md:col-span-3 lg:col-span-2"> <span class="uppercase dark:text-gray-200">Resources</span> <div class="mt-5"> <ul class="space-y-3 text-gray-700 dark:text-gray-500"> <li> <a href="https://bootcamp.laravel.com" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Laravel Bootcamp</a> </li> <li> <a href="https://laracasts.com" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Laracasts</a> </li> <li> <a href="https://laravel-news.com" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Laravel News</a> </li> <li> <a href="https://laracon.us" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Laracon</a> </li> <li> <a href="https://laracon.au" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Laracon AU</a> </li> <li> <a href="https://laracon.eu/" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Laracon EU</a> </li> <li> <a href="https://laracon.in/" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Laracon India</a> </li> <li> <a href="https://larabelles.com/" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Larabelles</a> </li> <li> <a href="https://laravel.com/careers" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Careers</a> </li> <li> <a href="https://larajobs.com/?partner=5" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Jobs</a> </li> <li> <a href="https://laracasts.com/discuss" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Forums</a> </li> <li> <a href="/trademark" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Trademark</a> </li> </ul> </div> </div> <div class="text-xs col-span-6 md:col-span-3 lg:col-span-2"> <span class="uppercase dark:text-gray-200">Partners</span> <div class="mt-5"> <ul class="space-y-3 text-gray-700 dark:text-gray-500"> <li> <a href="https://vehikl.com" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Vehikl</a> </li> <li> <a href="https://webreinvent.com/?utm_source=laravel&utm_medium=laravel.com&utm_campaign=footer-link" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">WebReinvent</a> </li> <li> <a href="https://tighten.co" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Tighten</a> </li> <li> <a href="https://www.bacancytechnology.com/hire-laravel-developer?utm_source=laravel&utm_medium=partners.laravel&utm_campaign=sponsors" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Bacancy</a> </li> <li> <a href="https://64robots.com/" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">64 Robots</a> </li> <li> <a href="https://activelogic.com/" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Active Logic</a> </li> <li> <a href="https://www.blackairplane.com/" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Black Airplane</a> </li> <li> <a href="https://www.byte5.net/" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Byte 5</a> </li> <li> <a href="https://www.curotec.com/services/technologies/laravel/" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Curotec</a> </li> <li> <a href="https://www.cyber-duck.co.uk/how-we-work/technology/laravel?utm_source=Laravel%20Partner&utm_medium=Sponsorship" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Cyber-Duck</a> </li> <li> <a href="https://devsquad.com/" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">DevSquad</a> </li> <li> <a href="https://jump24.co.uk/" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Jump24</a> </li> <li> <a href="https://kirschbaumdevelopment.com/" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Kirschbaum</a> </li> </ul> </div> </div> <div class="text-xs col-span-6 md:col-span-3 lg:col-span-2"> <span class="uppercase dark:text-gray-200">Ecosystem</span> <div class="mt-5"> <ul class="space-y-3 text-gray-700 dark:text-gray-500"> <li> <a href="/docs/11.x/starter-kits#laravel-breeze" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Breeze</a> </li> <li> <a href="/docs/11.x/billing" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Cashier</a> </li> <li> <a href="/docs/11.x/dusk" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Dusk</a> </li> <li> <a href="/docs/11.x/broadcasting" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Echo</a> </li> <li> <a href="https://envoyer.io" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Envoyer</a> </li> <li> <a href="https://forge.laravel.com" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Forge</a> </li> <li> <a href="https://herd.laravel.com" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Herd</a> </li> <li> <a href="/docs/11.x/horizon" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Horizon</a> </li> <li> <a href="https://inertiajs.com" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Inertia</a> </li> <li> <a href="https://jetstream.laravel.com" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Jetstream</a> </li> <li> <a href="https://livewire.laravel.com" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Livewire</a> </li> <li> <a href="https://nova.laravel.com" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Nova</a> </li> <li> <a href="/docs/11.x/octane" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Octane</a> </li> <li> <a href="/docs/11.x/pennant" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Pennant</a> </li> <li> <a href="/docs/11.x/pint" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Pint</a> </li> <li> <a href="/docs/11.x/prompts" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Prompts</a> </li> <li> <a href="https://pulse.laravel.com" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Pulse</a> </li> <li> <a href="https://reverb.laravel.com" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Reverb</a> </li> <li> <a href="/docs/11.x/sail" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Sail</a> </li> <li> <a href="/docs/11.x/sanctum" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Sanctum</a> </li> <li> <a href="/docs/11.x/scout" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Scout</a> </li> <li> <a href="/docs/11.x/socialite" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Socialite</a> </li> <li> <a href="https://spark.laravel.com" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Spark</a> </li> <li> <a href="/docs/11.x/telescope" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Telescope</a> </li> <li> <a href="https://vapor.laravel.com" class="transition-colors hover:text-gray-600 dark:hover:text-gray-400">Vapor</a> </li> </ul> </div> </div> </div> <div class="mt-10 border-t pt-6 pb-16 border-gray-200 dark:border-dark-500"> <p class="text-xs text-gray-700 dark:text-gray-400"> Laravel is a Trademark of Laravel Holdings Inc.<br /> Copyright © 2011-2024 Laravel Holdings Inc. </p> <p class="mt-6 text-xs text-gray-700 dark:text-gray-400"> Code highlighting provided by <a href="https://torchlight.dev">Torchlight</a> </p> </div> </div> </footer> <script> var algolia_app_id = 'E3MIRNPJH5'; var algolia_search_key = '1fa3a8fec06eb1858d6ca137211225c0'; var version = '11.x'; </script> <script> var _gaq=[['_setAccount','UA-23865777-1'],['_trackPageview']]; (function(d,t){ var g=d.createElement(t),s=d.getElementsByTagName(t)[0]; g.src=('https:'==location.protocol?'//ssl':'//www')+'.google-analytics.com/ga.js'; s.parentNode.insertBefore(g,s) }(document,'script')); </script> <!-- HubSpot --> <script type="text/javascript" id="hs-script-loader" async defer src="//js-na1.hs-scripts.com/45240648.js"></script> <div class="fixed"> <input type="text"> </div> </body> </html>