27th of May 2024

Tracking Customer Charges in Vinoflow: A Technical Dive into Laravel and AWS Integration


Managing wine club subscriptions efficiently requires a robust and flexible system. Vinoflow, our wine club management app, leverages the TALL stack (Tailwind CSS, Alpine.js, Laravel, and Livewire) along with deep Stripe integration to handle customer charges seamlessly. This post will take you through the technical intricacies of how we achieve this using Laravel's Task Scheduling, Stripe Connect, and Laravel Vapor for serverless deployment. Beware this is a semi technical article, so not for everyone :).

The TALL Stack: Tailwind, Alpine, Laravel, and Livewire

The TALL stack is a powerful combination of technologies that enhance the development experience and performance of modern web applications. Here's a brief overview of each component:

  • Tailwind CSS: A utility-first CSS framework that provides low-level building blocks to create custom designs without leaving the HTML.
  • Alpine.js: A minimal framework for composing behaviour directly in your markup. It provides the reactive and declarative nature of big frameworks like Vue or React at a much lower cost.
  • Laravel: A PHP framework designed for web artisans. It simplifies common tasks such as routing, sessions, and caching.
  • Livewire: A full-stack framework for Laravel that makes building dynamic interfaces simple, without leaving the comfort of Laravel.

Utilising the TALL stack enables us to create a responsive and dynamic user interface while preserving the simplicity and elegance of Laravel. We heavily rely on Livewire for most interactions with the UI. However, for instances requiring immediate response, we offload the UI updates and interactions to Alpine JS. In these cases, the Livewire component is updated either through the entangle feature or during the next server call.

Deep Integration with Stripe Using Stripe Connect

To manage payments and subscriptions, Vinoflow integrates deeply with Stripe, utilising Stripe Connect for handling transactions. Stripe Connect allows us to facilitate payments on behalf of our users and manage the complex flow of funds, ensuring secure and compliant transactions.

Local Subscription Management

While Stripe offers a robust subscription management system, we chose to manage subscriptions locally rather than relying solely on Stripe's built-in features. This approach allows us to create far more customisable systems tailored to the specific needs of our customers wine club operations. Here are some key benefits of our local subscription management:

  • Flexible Billing Cycles: We can define custom billing cycles and schedules that fit the unique requirements of our customers wine club members, they are not bound to any single timeframe.
  • Custom Pricing Models: Local management allows us to implement complex pricing models, including tiered pricing, discounts, and special offers, which might be challenging with Stripe's default subscription features.
  • Comprehensive Reporting: Our goal is to build out some of the most comprehensive reporting in the industry and the local management enables us to do this. Although we are not there yet we are currently developing detailed reporting and analytics tools tailored to our customers business needs, providing insights into customer behaviour, subscription trends, and financial performance.

Automating Subscription Management with Laravel's Task Scheduling

To automate the management of wine club subscriptions, we utilise Laravel's Task Scheduling, which manages and creates jobs that are dispatched daily. These jobs handle critical tasks such as creating orders, charging customers, and updating the next order date and dispatching notifications.

SubscriptionService Class

The SubscriptionService class abstracts the core logic for managing subscriptions. It includes methods to create and manage subscriptions, calculate charges, and handle customer notifications. This abstraction ensures that our code remains clean and maintainable, testable and can easily be run from 'Jobs'.

ChargeCustomer Job

The ChargeCustomer job is responsible for processing customer charges. This job is dispatched daily and performs the following tasks:

  • Creating Orders: Generates new orders for customers based on their subscription plans.
  • Charging Customers: Uses Stripe to process the payments for these orders.
  • Updating Order Dates: Updates the next order date for each customer to ensure accurate scheduling.
  • Sending out notication emails

Here are the key snippets from the SubscriptionService class:

SubscriptionService.php

// Key methods from SubscriptionService
class SubscriptionService {
    public function createSubscription($customerData) {
        // Logic to create a new subscription
    }

    public function calculateCharge($subscription) {
        // Logic to calculate the charge amount
    }

    public function notifyCustomer($customer, $message) {
        // Logic to send notifications to the customer
    }
}

Serverless Deployment with Laravel Vapor

To ensure scalability and cost-effectiveness, we deploy Vinoflow using Laravel Vapor, a serverless deployment platform for Laravel applications. Vapor abstracts the complexities of server management, allowing us to focus on building features.

Laravel Vapor Setup

We use a standard Laravel Vapor setup which includes:

  • Environment Configuration: Managing environment variables and secrets securely.
  • Database Management: Using Amazon RDS for scalable database solutions.
  • Queue Management: Handling background jobs with Amazon SQS.
  • Storage: Utilising Amazon S3 for file storage.

Scalability and Performance

The architecture provided by Laravel Vapor ensures high availability and scalability, allowing Vinoflow to handle varying loads efficiently. Here’s why our architecture is scalable:

  • Auto-scaling: Vapor automatically scales the application up or down based on traffic. This means our app can handle sudden spikes in traffic without manual intervention.
  • Decoupled Services: By using services like Amazon SQS for job queues and Amazon S3 for storage, we decouple various parts of our system, making it easier to scale individual components independently.
  • Serverless Infrastructure: With Vapor's serverless architecture, we avoid the overhead of managing servers, ensuring our application is always running on the latest, most efficient infrastructure.
  • Cost Efficiency: We only pay for what we use, which makes the application cost-effective, especially during periods of low activity.

Code Architecture

Our code architecture also contributes to scalability:

  • Modular Design: By abstracting functionalities into services like SubscriptionService and StripeService, we maintain a clean and modular codebase, making it easier to extend and maintain.
  • Task Scheduling: Automating repetitive tasks through Laravel's Task Scheduling ensures consistent performance and reliability without manual intervention.

Vinoflow's robust architecture, powered by the TALL stack, Stripe integration, Laravel's Task Scheduling, and Laravel Vapor, ensures efficient and reliable management of wine club subscriptions. By leveraging these technologies, we provide a seamless experience for our users, handling everything from customer charges to order management effortlessly.

Here you can find more of our insights

  • All Posts