[Proposal] In-App Purchases for Open edX (Purchases & Upgrades)

[Proposal] In-App Purchases for Open edX (Purchases & Upgrades)

Status

Ready for Review

Contributing Team

Raccoon Gang

Coordinator

 

Earlier Discovery

N/A

Github

[Proposal] In-App Purchases for Open edX (Purchases & Upgrades) · Issue #476 · openedx/platform-roadmap

Linked Initiatives

 

Type

 

Overview

 

image-20251111-115239.png

 

View the Github ticket for proposal status update


Overview

This proposal introduces a lightweight, compliant, and maintainable foundation for selling course access in Open edX across iOS/Android and the web - without reviving deprecated ecommerce. It supports two business models:

  • Pay-to-Enroll: the course is fully gated until purchase; buying grants enrollment into a paid mode (e.g., no-id-professional/professional).

  • Upgrade-Lite: learners start in audit; purchasing upgrades their mode to a paid one and unlocks graded assessments and a completion certificate.

Both flows run through one server pipeline driven by provider webhooks (default: RevenueCat), unifying entitlements across platforms.

Problem

Self-hosted Open edX lacks a maintained, first-party mobile purchase path; legacy ecommerce is deprecated. Operators need a review-safe way to sell access on mobile and web with minimal operational overhead, synchronized entitlements, and clear store compliance.

Use Cases

Learner Stories

  1. Pay-to-Enroll Access

  • As a learner,

  • I need to purchase a course directly from my mobile app or the web,

  • In order to gain access to this course.

  1. Upgrade from Audit Mode

  • As a learner,

  • I need to upgrade from the audit mode to a paid mode within the app or website,

  • in order to unlock graded assessments and receive a verified completion.

  1. Purchase Restoration

  • As a learner using iOS or Android,

  • I need to restore my past purchases when reinstalling or switching devices,

  • in order to retain access to my paid courses without repurchasing them.

  1. Pending Transaction Handling

  • As a learner on Android,

  • I need to see clear message when a payment is pending,

  • in order to understand that my purchase is being processed and will unlock access once confirmed.

Operator Stories

  1. Unified Entitlement Management

  • As an operator,

  • I need to sell courses across the web and mobile platforms while keeping entitlements synchronized through a single server pipeline,

  • in order to avoid duplicate product configurations and ensure consistent learner access across devices.

  1. Web Sales Integration

  • As an operator,

  • I need to use Stripe for web purchases that are automatically synced with mobile entitlements via the provider (e.g., RevenueCat),

  • in order to maintain compliance and operational simplicity across payment channels.

Compliance Stories

  1. Refund and Revocation Management

  • As a finance or compliance officer,

  • I need to ensure that refunds or chargebacks automatically trigger access revocation in the LMS,

  • in order to keep financial records accurate and meet platform audit and refund requirements.

 

Proposed solution

Implement a Purchase Gateway - a thin server layer plus a receipt/entitlement provider (RevenueCat by default) that unifies App Store, Google Play, and Stripe into a single entitlement model. Clients (iOS/Android/Web) display store prices, initiate native purchase, and do not unlock locally; they wait for the server grant.

Key principles

  • Single logical_product_id per course (e.g., edu.acme.course.<slug>), reused across App Store, Play, and Stripe. The provider maps the logical ID to native store objects and unifies entitlements.

  • Server as the source of truth: only the server modifies access via existing LMS APIs (enroll, changeMode, unenroll/downgrade).

  • Web and mobile in sync: Stripe purchases are ingested by the provider, which emits events to the server; the server updates LMS access.

  • Compliance-first: Mobile digital access goes through native IAP; web uses Stripe under the operator’s domain; prices come from store metadata/provider offerings (never hard-coded).

  • Minimal v1 scope (no subscriptions/IDV), with a clean path to future extensions via provider adapters.

In scope (v1)

  • Provider SDK on iOS/Android (plus web integration for Stripe).

  • Per-course non-consumable products (optional server-side TTL for time-boxed access).

  • Server-side validation via provider webhooks: purchase, refund, revoke (and renewal later).

  • Restore (iOS) and Pending (Android).

  • Admin mapping: course_id → logical_product_id → target_mode, active, optional expires_at.

Out of scope (v1)

  • ID-verification & proctoring.

  • Subscriptions, bundles, coupons, complex price experiments.

  • Building our own receipt/refund system (delegated to the provider).

Implementation plan

Milestone 1 - MVP (shared pipeline + Upgrade-Lite)

  • Mobile: fetch price (StoreKit/Play Billing or provider offerings); purchase; Restore/Pending; “Processing…” state; client polling of server//me/enrollments until access changes.

  • Web: Stripe Checkout/Payments; success ingested by the provider; same “Processing…” pattern until server grant.

  • Server: Purchase Gateway (mapping, webhook handler, idempotent enroll/changeMode/unenroll, LMS integration, audit log).

  • Operator setup: create store products/Stripe prices; fill mapping.

Milestone 2 - Operational polish

  • Admin UI/CSV import for mapping; localized copy; batch product prefetch.

  • Alerting for webhook failures; nightly reconciliation for drift.

Milestone 3 - Extensions (optional)

  • Time-boxed access via server expires_at; parity banners on web.

  • Subscriptions/bundles; coupons; selective IDV/proctoring per course/program.

  • Provider swapping (Adapty/Qonversion) via a thin adapter; server contracts unchanged.

Long-term ownership & maintenance plans

Long-term day-to-day ownership: AXIM Mobile WG, in collaboration with Open edX Mobile maintainers. Operators own their Stripe accounts and store products. Server interfaces and event logs are documented; the provider adapter is isolated for maintainability.

Ownership & Collaboration

  • Engineering/Tech: AXIM Mobile WG + Open edX Mobile maintainers.

  • Product UX/UI WG: paywall/process copy, localization, accessibility.

  • Compliance/Legal: adherence to store/Stripe policies and regional regulations.

Contact person

Ivan Stepanok - ivan.stepanok@raccoongang.com

Optional additions

Business Models & UX (detail)

  • Pay-to-Enroll: the course is locked; purchase ⇒ enroll(user, course_id, mode=paid) (e.g., no-id-professional/professional, configurable).

  • Upgrade-Lite: audit allows read-only learning; purchase ⇒ changeMode(..., new_mode) + unlocks graded/certificate. We intentionally exclude IDV/proctoring in v1 for simplicity.

Provider strategy

  • Default - RevenueCat: centralizes validation, refunds/revocations, entitlements, cross-platform identity, and web (Stripe) ingestion. The small fee replaces building/maintaining our own receipt/refund logic.

  • Alternatives: Adapty, Qonversion via a thin adapter; server contracts remain unchanged.

Security & Privacy

  • Signed webhooks, HTTPS everywhere, least-privilege keys.

  • Idempotency keyed by transaction_id.

  • Client is never the authority; only the server changes access.

  • Minimal PII; align with operator GDPR/FERPA requirements.

Error handling & edge cases

  • Network errors → retries with backoff; remain in “Processing…” until grant.

  • Duplicate webhooks → idempotent operations.

  • Refund/chargeback → provider event → server revokes → client reflects loss of access at next check.

  • User switch → logout clears provider session; entitlements are recalculated.

Competitive Research (brief)

  • Coursera/Udemy et al.: strict IAP compliance, unified storefronts, server-controlled access; fewer review rejections, consistent UX - industry standards.

  • Open edX opportunity: provide self-hosted operators with an “out-of-the-box” way to sell access without heavyweight ecommerce.

Impact on App Store Visibility

Compliant native IAP flows and predictable purchase→grant behavior reduce review risk and improve paywall→purchase conversion, which tends to lift behavioral metrics (sessions, active devices) and organic visibility in the stores.

Telemetry & Success Criteria

Functional

  • p95 “purchase → server grant” ≤ 30s.

  • Verified Restore/Pending scenarios on iOS/Android.

  • Zero reliance on deprecated ecommerce.

Business

  • Conversion from paywall_view → purchase (mobile/web), uplift vs. baseline.

  • Share of paid enrollments, revenue per course/device, refund/chargeback rate and resolution speed.

  • Fewer support tickets about access and “lost” purchases.

Technical/Reliability

  • All server operations idempotent; 100% event coverage in audit logs.

  • ≥ 99.9% successful webhook processing; fast alerting.

  • Daily reconciliation limits entitlement drift to ≤ N records per 100k users.

Open Questions for Rollout/Releases

  • Ship site-config JSON for mapping first, or deliver an Admin UI from day one?

  • Which paid mode should be the default for upgrades (no-id-professional vs. professional)?

  • Keep time-boxed access purely as a server policy (expires_at) without subscriptions, or design an “upgrade-to-subscription” path early?

 

Implementation Plan

Raccoon Gang is currently looking for funding for this proposal.

raccoongang-looking-for-funding.png