Orange Subscriptions

5 min read

Orange Subscriptions involved using webhooks to process subscription invoices, with a focus on two key events: invoice.created and invoice.payment_succeeded. Testing and documentation were prioritized to improve reliability compared to previous systems, and Confluence was used to document processes. Despite some issues during launch, the project was ultimately successful in providing a reliable digital and physical subscription service for customers. Over the course of 28 months since launch, it processed around $375,000.

Created as a Senior Software Engineer at The reThinkGroup, Inc.

Table of Contents

About this project

This project was a deep dive into using webhooks from a receiving and event-processing standpoint. The main focus was on the specific types of events that were relevant to processing subscription invoices. One of the main events was invoice.created, which gathered the appropriate monthly SKU from Stripe's base_sku metadata field. The SKU identifier and processing date were attached to the Stripe invoice object, which allowed for customizing the receipt sent to customers. Another important event was invoice.payment_succeeded, leveraged to transform and send the subscription information to our order management system.

Automated testing and extensive documentation ensured improved reliability over an existing bespoke system. Confluence was leveraged to outline various processes, such as creating subscriptions and products in the Stripe dashboard, including how to set up a local production instance using the Stripe CLI. Additionally, I set up staging and production environments to ensure that any changes we made to the system would not impact our live customers. Failed background jobs also sent alert messages to Slack channels so that issues with processing invoices were handled promptly.

Despite thorough preparation, I still encountered some issues during the launch. The primary issues were that default card information was not present and the scheduled command for fetching monthly SKUs misbehaved. There were also delivery issues, such as order total mismatches and missing metadata. However, I was able to identify these issues and work to fix them promptly with no recurring hiccups. Overall, this project was a success for providing a reliable and seamless digital and physical subscription service for our customers.

In 28 months of service, it processed roughly $375,000, averaging $13,000 per month, with a the peak of 595 invoices at $30,000 and a low of 115 invoices at $6,000.

Skills Demonstrated

  • Utilized webhooks for receiving and processing events.
  • Mastered Stripe invoicing events, including invoice.created and invoice.payment_succeeded.
  • Developed a reliable and seamless digital and physical subscription service for customers.
  • Processed large volumes of invoices and managed subscription revenue.
  • Customized receipts and transformed subscription information for integration with an order management system.
  • Applied automated testing and documentation to improve reliability.
  • Outlined processes using Confluence.
  • Sent alert messages to Slack channels for failed background jobs.
  • Solved technical issues during launch through strong problem-solving skills.
  • Established staging and production environments.
  • Set up continuous deployment using GitLab CI and Laravel Forge.

Technical sheet

Technologies used on this project

  • General concepts

    • UI/UX Design
    • UI/UX Architecture
    • HTML5 (semantic)
    • CSS3 (preprocessed with SASS)
  • Infrastructure

    • Ubuntu 20.04 LTS
    • PHP v7.4
    • MariaDB v10.6
    • Nginx v1.22
    • Redis v5.0
  • Application-specific

    • Laravel Framework v7
    • Laravel Nova v3
    • Laravel Telescope v3
    • Laravel Horizon v4
    • Continuous Delivery via Gitlab CI and Laravel Forge

Screens

Dashboard

Dashboard with metrics such as our count or revenue generated by product type. Laravel Nova makes it simple to aggregate information for dashboard widgets.

Dashboard page

Listing Products

Viewing, filtering, and sorting the list of products. Products are configured here prior to being processed. There are numerous other products in Stripe handling their own reconcilliation with the accounting team.

Listing of Products

Product Details

Viewing the 252 Kids Story Poster details. The monthly SKU variants are displayed here, including the relevant Stripe metadata, if present.

Product Details

Editing a Product

Editing a particular product by clicking the note icon. Information like the type or frequency are pre-populated based on the enum type selected.

Editing a Product

SKU Details

Viewing the 252 Kids Story Poster Bundle - March, April, May 2023 SKU variant details. SKUs are automatically populated based on a periodic task that looks for products by their base_sku field. While editing SKUs is possible, it is preferred to make changes upstream.

SKU Details

Listing Invoices

Viewing, filtering, and sorting the list of invoices. Invoices that are processed get displayed on this screen. New invoices get created before their accompanying subscription due to the flow of webhook events.

Listing of Invoices

Listing Subscriptions

Viewing, filtering, and sorting the list of subscriptions. This page is less relevant as new subscriptions typically aren't created often. This system primarily covers legacy subscriptions until the Shopify store incorporates the behavior.

Listing of Subscriptions

Listing Users

Viewing, filtering, and sorting the list of users with access to the system. Users authenticate against the flagship API. User data produces an understanding of who is potentially making changes within the system.

Listing of Users

Customer Details

Viewing the Stripe customer details. This is the top-most entity in our relationship tree so a customer's subscriptions, invoices, and payments are listed here. The Stripe payload in JSON, including a link to the customer in the Stripe dashboard, is displayed to aid troubleshooting.

Customer Details

Subscription Details

Viewing the Stripe subscription details. This is our primary entity for gathering information to send to our accounting system. A subscription is created in Stripe with the necessary metadata that the system uses to populate the order sent to the accounting system. The Stripe payload in JSON, including a link to the subscription in the Stripe dashboard, is displayed to aid troubleshooting.

Subscription Details

Invoice Details

Viewing the Stripe invoice details. This is the first entity created by the invoice.created webhook event that includes partial invoice data. The Stripe custom fields, metadata, and payload JSON fields are displayed to give us an understanding of what the system processes. Links to the customer, subscription, invoice, and charge in the Stripe dashboard are displayed to aid in troubleshooting.

Invoice Details

Payment Details

Viewing the Stripe payment details. The Stripe metadata field displays the information captured for reconcilliation by the accounting team. Links to the customer, subscription, invoice, and charge in the Stripe dashboard are displayed to aid in troubleshooting.

Payment Details

Horizon

The Horizon dashboard page that gives us a glance at how our background queues are operating. Laravel Horizon helps us inspect or retry failed jobs along with basic metrics like completion time or number of failures per job.

Laravel Horizon page

Telescope

The requests page in Laravel Telescope. Telescope is leveraged in debugging or to understand how the system is operating as a whole.

Laravel Telescope page