, ,

May 8, 2026 | 9 Minute Read

How Production-Grade Payment Infrastructure Was Built Through An AI Partnership For An EdTech Platform

Table of Contents

Introduction

Part 4 of the series: "Building a Production EdTech Platform on Lovable"

Everyone talks about landing pages. Nobody talks about the moment a student clicks “Pay Now,” and the 14 things that need to happen in the next 3 seconds.

Payment processing isn’t just “take money, give access.” It’s a multi-system orchestration problem: validate the amount server-side, create a secure checkout session, verify the payment cryptographically, convert a CRM lead into a contact, create a deal with financial tracking, enroll the student in the right courses, send a confirmation email, handle edge cases where the parent’s UPI account is used instead of the student’s, track EMI installments over months, unlock courses progressively, and do all of this without a single manual step.

The entire payment infrastructure for Progression School, from Razorpay order creation to LMS auto-enrollment, was built through our partnership with Lovable. We described the business logic; Lovable engineered the implementation.

At no point did we need to read Razorpay’s API documentation, configure webhook endpoints manually, or write cryptographic signature verification code.

The Architecture: Two Payment Paths, One Webhook

The platform offers two payment options for its programs:

 

Path

How It Works

Razorpay Product

Full Payment

One-time charge

Orders API

EMI

Monthly auto-debit installments

Subscriptions API

Both paths converge on a single webhook endpoint that handles everything downstream: CRM updates, course enrollment, and email notifications.

The decision to support both paths came from the founder’s understanding of the market. Indian students, especially those early in their careers, need installment options. But implementing EMI with auto-debit subscriptions is significantly more complex than one-time payments. The founder described the requirement: “Students should be able to pay in monthly installments with auto-debit, with courses unlocking progressively.” Lovable engineered the entire subscription lifecycle: plan creation, subscription management, installment tracking, and progressive course access.

Layer 1: Centralized Pricing As The Single Source Of Truth

Before any payment logic, there’s a foundational architectural decision: prices live on the server, not the client.

A shared configuration file defines every program’s pricing:

 

Every edge function (order creation, subscription creation, webhook processing) imports from this single file. Change a price once, and it propagates everywhere.

Why this matters: The client-side code never contains the actual price. When a student clicks “Pay,” the frontend sends the program name, not the amount. The backend looks up the price from the shared config and creates the Razorpay order with the validated amount. This prevents the most common payment vulnerability: client-side price tampering.

How the partnership built this: We told Lovable: “We want to change prices in one place and have it reflected everywhere: orders, subscriptions, webhook calculations.” Lovable designed the shared config module with derived helper functions (getFullPrice(), getEmiAmount(), getEmiCount()) and wired every edge function to import from it. We never needed to think about module architecture or import paths.

Layer 2: One-Time Order Creation

When a student chooses “Full Payment,” the frontend invokes a backend function:

 

The frontend receives the order_id and key_id, then opens the Razorpay checkout modal:

 

Key security detail: The Razorpay secret key never touches the frontend. The backend creates the order with authenticated API calls; the frontend only receives the order ID and publishable key.

How Lovable handled this: We said: “When the student submits the form, charge them the program fee via Razorpay.” Lovable produced two components: the backend edge function with server-side price validation, and the frontend checkout integration with the Razorpay SDK. Our only configuration step was adding Razorpay API keys as secrets. Everything else (CORS headers, error handling, the Deno runtime setup, the notes field structure that enables downstream CRM tracking) was Lovable’s engineering.

Layer 3: EMI Subscription Creation, The Complex Path

EMI is where payment infrastructure gets genuinely difficult. Razorpay Subscriptions require a two-step process:

Step 1: Create A Plan

Step 2: Create A Subscription On That Plan

The frontend then opens the Razorpay checkout with the subscription_id instead of an order_id:

 

The notes object is critical. When Razorpay sends a webhook for each installment, the notes carry the student’s email and program name, enabling the backend to correctly attribute payments to CRM records and unlock the right courses.

 

How We Navigated Razorpay’s Subscription API

Razorpay’s Subscription API has a fundamentally different model from their Orders API: Plans, Subscriptions, and recurring webhooks, each with different payload structures. We described the business requirement: “Monthly installments with auto-debit.” Lovable translated this into the two-step Plan → Subscription creation, handling the API differences, the customer_notify flag, and the critical notes structure. We never needed to understand the difference between Razorpay’s Orders and Subscriptions APIs.

Layer 4: Webhook Processing, The 650-Line Orchestrator

The webhook is the heart of the payment infrastructure. When Razorpay confirms a payment, it sends a POST request to a backend edge function. This single function handles both one-time payments (payment.captured) and subscription installments (subscription.charged).

Layer 4 of payment infrastructure

Signature Verification: Cryptographic Security

Every webhook request includes an x-razorpay-signature header. The backend verifies it using HMAC-SHA256:

 

Why crypto.subtle Instead Of Node’s Crypto? The backend runs on Deno (not Node.js), so the native Web Crypto API is used. This is faster and more secure in the Deno environment.

How This Was Built: We didn’t need to know what HMAC-SHA256 is. We said: “Razorpay sends a webhook; make sure it’s really from Razorpay.” Lovable implemented the cryptographic verification using the Deno-native Web Crypto API, chose the correct algorithm, and handled the hex encoding. We never wrote a line of cryptographic code.

Event Routing: The Deduplication Problem

Razorpay fires multiple events for a single payment. A subscription installment triggers both payment.captured AND subscription.charged. Processing both would create duplicate CRM records.

The solution: the webhook explicitly skips payment.captured and payment.authorized when the payment belongs to a subscription:

 

This ensures each payment is processed exactly once: payment.captured for one-time orders, subscription.charged for EMI installments.

How we discovered this: This wasn’t in any upfront design. We noticed duplicate CRM records after the first EMI payment and reported it: “The webhook seems to be firing twice for subscription payments.” Lovable diagnosed the issue (Razorpay sends multiple events for subscription payments) and implemented the deduplication guard. From production anomaly to deployed fix in one conversation turn.

Email Source Resolution: The Subscription Notes Problem

For one-time payments, the student’s email is in the order notes. For subscriptions, it’s in the subscription notes, but subscription.charged payloads carry the payment entity, whose email might be the payer’s bank/UPI email, not the student’s.

The webhook resolves this with a priority chain:

 

For subscription payments, the subscription notes email is always trusted over the payment instrument email. This prevents incorrect CRM attribution when a parent pays on behalf of a student.

Layer 5: Progressive Course Enrollment With LMS Integration

The most sophisticated downstream action: automatically enrolling students in the right courses on the LMS based on their payment status.

The Tier System

Courses are grouped into installment tiers in a server-side configuration:

 

  • Full payment → All courses unlocked immediately
  • EMI Installment 1 → Tier 1 only
  • EMI Installment 2 → Tiers 1 + 2
  • Final Installment → All tiers (everything unlocked)

The Enrollment Flow

The findOrCreateUser function handles a subtle edge case: if the student doesn’t exist on the LMS, it creates them, defaulting the first name to the email prefix when no name is available. This prevents the LMS API from rejecting the enrollment due to a missing required field.

Retry Logic

Course enrollment includes a built-in retry mechanism:

 

If the LMS API is temporarily unavailable, the system retries once. Failed enrollments are logged but don’t block the webhook response; CRM updates and email notifications still proceed.

How Lovable Built The Entire LMS Integration: We provided the course groupings by tier and described the progressive access model. Lovable produced three files: a configuration module (tier mapping), a client library (user creation + enrollment with retry), and the enrollment logic wired into the webhook.

Our contribution was the business decision: which courses belong to which tier. Everything else (the LMS API integration, user creation with email-prefix fallback, retry logic, “already enrolled” handling) was Lovable’s engineering.

Layer 6: Consolidated Email Notifications

After successful enrollment, the webhook sends a personalized email via the Zoho CRM Send Mail API:

 

Key design decisions:

  • The LMS’s default welcome email is disabled. We control the entire email experience.
  • Course links are dynamically generated from the LMS API, not hardcoded. If a course slug changes, the email automatically reflects it.
  • For EMI students, the email includes a note: “More courses will be unlocked with your next installment.”
  • The email is sent via Zoho CRM, not a standalone email service, ensuring it appears in the CRM’s activity timeline for our team’s visibility.

How We Handled Email Design: We described what the email should contain: “Payment confirmation, list of accessible courses with clickable links, and a note about upcoming installments for EMI students.” Lovable generated the HTML template, the dynamic course link generation (fetching slugs from the LMS API), and the Zoho Send Mail API call, including the v7 API path (different from the v2.1 used elsewhere) and the specific mail_format: “html” parameter.

Layer 7: The Safety Net, Manual Payment Sync

Production systems need escape hatches. What happens when:

  • A webhook fails silently?
  • Razorpay has a brief outage during webhook delivery?
  • A student pays but the CRM doesn’t update?

The answer: a manual sync function that we can trigger with just a Razorpay Subscription ID or Payment ID.

The manual sync edge function:

  1. Fetches the subscription/payment details from Razorpay’s API
  2. Extracts the student’s email and program from the notes
  3. Searches for the corresponding Contact or Lead in Zoho CRM
  4. If only a Lead exists, converts it to a Contact
  5. Creates/updates the Deal with payment details
  6. Enrolls the student in LMS courses
  7. Logs all steps for audit trail

This entire 400+ line safety net was built through our partnership with Lovable. We said: “We need a way to manually trigger the same webhook logic if something fails, using just the Razorpay ID.” Lovable produced the full function, including the admin dashboard UI component, mirroring every step of the webhook’s CRM logic but with additional logging and a “MANUAL SYNC” label on CRM notes to distinguish from automated entries.

The Security Model

Our payment infrastructure implements defense in depth:

 

Layer

Protection

Client-side

Never sends prices, only program names

Order creation

Server-side price lookup from shared config

Webhook verification

HMAC-SHA256 signature verification using Web Crypto API

Event deduplication

Explicit skip logic for subscription-related payment.captured events

Email resolution

Subscription notes email trusted over payment instrument email

Credential isolation

Razorpay secret key exists only in backend environment variables

Manual override

Admin-only sync function with full audit logging

None of these security patterns were explicitly part of our initial requirements. They emerged naturally from the partnership. Lovable applied engineering best practices while we focused on business logic. We said “charge them securely”; Lovable implemented server-side price validation, HMAC verification, and credential isolation.

The End-To-End Payment Flow

Here’s what happens when a student clicks “Enroll Now” and chooses the EMI plan:

crm-automation-workflow

Multiple systems are orchestrated. Zero manual steps. Three APIs (Razorpay, Zoho CRM, LMS) coordinated in a single 650-line edge function. Built by describing business logic to an AI partner.

Edge Cases That Surfaced In Production

The Duplicate Event Storm

Problem: Razorpay sends payment.authorized, payment.captured, AND subscription.charged for a single EMI installment. The first version of the webhook processed all three, creating triple CRM entries.

How we fixed it with Lovable: We reported: “Each EMI payment is creating three deals instead of one.” Lovable analyzed the Razorpay event model and implemented the deduplication guard, checking for subscription_id and invoice_id on payment.captured events and deferring to subscription.charged.

The Parent’s UPI Problem

Problem: A student’s parent pays via UPI. The payment entity shows the parent’s bank-registered phone and email, but the student’s details are in the subscription notes.

How we fixed it: We identified the business risk: “If a parent pays, the CRM is tracking the wrong person.” Lovable implemented the email priority chain, trusting subscription notes over payment entity data for subscription.charged events, and disabling phone-based CRM lookup entirely for subscription payments to prevent misattribution.

The DUPLICATE_DATA Conversion Failure

Problem: When converting a Lead to a Contact, Zoho auto-creates an Account (company). If two students from the same company both convert, the second fails with DUPLICATE_DATA on the Account.

How we fixed it: One conversation turn. We shared the error; Lovable added a fallback that catches DUPLICATE_DATA, searches for the Contact by email, and retrieves the Contact ID through the alternate path.

The Missing First Name On LMS

Problem: Some form submissions only capture email. The LMS API requires a first name for user creation.

How we fixed it: Lovable defaulted the first name to the email prefix (john@gmail.com → john), a small but production-critical detail that we didn’t need to think about.

What We Actually Did Vs. What Lovable Did

Our Contribution

Lovable’s Engineering

“We need full payment and EMI options”

Orders API + Subscriptions API with Plan creation

“Define the fee structure and installment count”

Centralized pricing config with derived helpers

“Prices should never be on the frontend”

Server-side validation with program name lookup

“Make sure webhooks are really from Razorpay”

HMAC-SHA256 using Deno’s Web Crypto API

“Each EMI should unlock more courses”

Multi-tier LMS config with progressive enrollment

“Students should get an email with course links”

Dynamic HTML email via Zoho Send Mail API

“We need a manual override if webhooks fail”

400-line manual sync function with full audit trail

“The parent’s UPI is creating wrong records”

Email priority chain + phone lookup disable for subscriptions

This is what “AI as a partner” means in practice. We brought market understanding, pricing strategy, and business process design. Lovable brought API expertise, security engineering, and infrastructure management. Neither could have built this alone, at least not in the timeframe it was built.

The Takeaway

Payment infrastructure is the single highest-leverage piece of technology in any product business. Get it wrong, and you lose revenue. Get it right, and money flows automatically while you sleep.

The traditional approach to building this would involve:

  • A payment integration developer ($100 to $150/hr) for Razorpay setup
  • A CRM developer for Zoho webhook processing
  • An LMS integration specialist for course enrollment
  • A DevOps engineer for webhook infrastructure
  • Weeks of coordination between all four

Instead, our team described the business logic to an AI partner over a few days. The same people who designed the curriculum, wrote the marketing copy, and planned the pricing strategy also “built” the payment infrastructure by partnering with Lovable and treating it as an engineering teammate.

The distance between “We want students to pay in installments and unlock courses progressively” and the working implementation was a conversation. That’s the promise of AI-partnered development: not replacing engineers, but giving domain experts the ability to build production-grade systems by describing what they need.



About the Author
Brahmpreet Singh, Senior Marketing Manager

Brahmpreet Singh, Senior Marketing Manager

Brahmpreet Singh is a marketing professional with over a decade of experience in SaaS and B2B content strategy. He enjoys blending research-driven insights with creative storytelling to support meaningful growth in organic traffic and lead generation. Brahmpreet is dedicated to building thoughtful, data-informed marketing strategies that resonate with audiences and drive long-term success.


Leave us a comment

Back to Top