Grammarly is an AI-powered communication assistant that helps more than 30 million users daily with both free and premium product offerings. This means we need a robust Billing and Payment platform to serve those different offerings, handle local currencies and payment methods, and integrate with Payment Service Providers (PSPs) and orchestrators. In this article, we’ll provide an overview of Grammarly’s Billing and Payment platform. We’ll cover the requirements, give a bird’s-eye view of how the system works, and list the patterns used to ensure high performance, scalability, and reliability.
Grammarly offers pricing plans to cater to the needs and budgets of different users:
- Grammarly Free. Anyone who has signed up for Grammarly will get grammar and spelling checks, tone detection, and punctuation suggestions.
- Grammarly Premium. This offering gives a full-fledged AI-powered assistant, providing features like full-sentence rewrites and generative AI, along with suggestions for tone and vocabulary. It also includes a rich set of advanced grammar and style improvements that focus on clarity, inclusive language, and plagiarism detection.
- Grammarly Business is designed for teams and organizations. This product offering includes all the features of Grammarly Premium, plus additional tools for team management and collaboration: account roles and permissions, SAML single sign-on support, team style guides, brand tones, and organizational snippets.
The Billing and Payment platform aims to support all options offered by the different Grammarly lines of business. Additionally, we design the system to be flexible and scalable to accommodate any new product packages the company may develop for our users.
Features and requirements
The Billing and Payment platform has internal and external users that differ in their needs.
For our external users, transparency, security, and reliability are paramount. Having a trustworthy platform is especially important as we expand into regions where consumer protections may need to be stronger, trust in banks and merchants may be low, or both.
Our internal users primarily need configurable and automated tooling available via a self-service model.
To serve these two types of users, the Billing portion of our platform includes the following features:
- Packaging: Defining a product or bundle to sell
- Billing models: Defining when the customer is charged (pre- or post-purchase, one-time or on a recurring basis, etc.) as well as custom eligibility for specific billing models
- Pricing and discounting: Determining how much to charge as well as deciding customer eligibility for particular pricing or promos
- Invoicing: Handling taxes and delivering a compliant set of documents appropriate for the customer type and location
- Accounting: Compliantly recognizing revenue and costs according to the billing model and the local financial rules
The Payments scope includes:
- Payment methods. In particular, the platform is responsible for building and maintaining payment method options, such as:
- Customer-facing UI
- Vendor connections, routing, and retries
- Internal-facing tooling
- Settlements and money movement with processing vendors
- Establishing and managing legal entities to enable local payment methods or local card-acquiring
- Managing required compliance and licensing tasks
- Payment fraud. This includes building and maintaining tools and processes to detect, prevent, and manage first-, second-, and third-party fraud.
The Billing and Payment platform is part of a broader ecosystem of Grammarly services. The platform is decoupled from other components but still tightly integrated into internal and external user flows to provide a set of self-service APIs and automated configuration tools.
To get a more concrete idea of how these components fit together, the diagram below illustrates how different services interact during a checkout flow.
Performance, scalability, and reliability
Grammarly has a worldwide reach, serving tens of millions of daily active users—a figure that’s continuously growing. For all our users, we strive to provide the best billing and payment experience. So we support multiple local currencies, including USD, EUR, GBP, and INR. To minimize payment friction and ensure high authorization rates (the percentage of successfully approved transactions), our Billing and Payment platform supports a variety of payment methods and has integrations with several leading PSPs and orchestrators. Additionally, the platform relies on third-party services to guarantee compliance with local financial rules and regulations regarding taxation, accounting, and invoicing.
To handle our performance and scalability needs, we use different patterns:
- Concurrent and parallel processing to handle the internal and external load
- Independent scaling of services to flexibly manage needed capacity
- Optimistic locking to prevent conflicts between concurrent business transactions by detecting a conflict and rolling back the business transaction
- Event-driven interservice communication and backpressure to avoid overloading downstream services and ensure scalability
In addition, the system must be both highly available and fault-tolerant. To achieve this, we use a range of mechanisms and patterns. Here are some examples:
- A transactional outbox to atomically update the database and send messages to avoid data inconsistencies
- Circuit breakers to prevent a network or service failure from cascading to other services
- A Dead Letter Queue (DLQ) to monitor and investigate/fix failed messages
- Idempotent message handling to retry requests without additional side effects
- Rate limiting to prevent one service from taking down Billing and Payment features for all services
- Timeouts to prevent long-term system overloading (with external and internal systems)
- Retrying in case an error might be self-healing (e.g., network failure, third-party service outage)
Finally, it’s critical to have a fast and up-to-date understanding of the system’s status and have the ability to troubleshoot any issues. For these purposes, we use metrics, alerting, tracing, and logging:
- Metrics are essential in tracking the system’s state and understanding behavior patterns. We use a wide range of technical and business indicators to create customized dashboards that allow us to monitor the system’s performance in real time and explore short- and long-term trends.
- We rely on technical and business alerts. Both types have different levels and use cases. For example, technical alerts may activate when a PSP becomes unavailable. Similarly, unusual changes in payment authorization rates will trigger business alerts.
- Traces and logs are indispensable for troubleshooting. In particular, we use log tracing to quickly grasp what happens for specific requests, even if they were executed asynchronously in multiple threads and different services.
It’s a challenge to manage payments at a global scale for a variety of currencies, payment methods, and product offerings. Grammarly’s Billing and Payment platform serves the needs of our users and provides tooling, widgets, and APIs to other Grammarly teams and services.
We use different patterns to handle our performance and scalability needs. Among them are concurrent and parallel processing, auto-scaling, optimistic locking, and backpressure. Additionally, various mechanisms and patterns are employed to ensure system availability and fault tolerance: transactional outbox, circuit breakers, idempotent message handling, rate-limiting, timeouts, retries, and more.
We rely heavily on different types of metrics and alerting. This allows us to have a fast and up-to-date understanding of the system’s state, as well as make data-informed decisions.
If you enjoy tackling complex challenges and want to join our team to help scale our rapidly growing platform, we are hiring!