Skip to content

Customization Playbooks

This section answers the most practical question a buyer or developer will have:

“I understand the system. Now how do I safely change it?”

Instead of vague advice, this section provides clear playbooks :

  • what to change
  • where to change it
  • what side effects to expect
  • what not to touch

Each playbook is based on real extension scenarios .


Adding a New Payment Gateway (Stripe / Razorpay)

Goal

Add a new payment provider without breaking existing purchases .

Correct Approach

  1. Create a new app
    payments_stripe
    payments_razorpay
    
  2. Follow the same contract as payments_dodo:
  3. Initiate checkout
  4. Receive webhook
  5. Update Order
  6. Create PurchasedProduct

What You Reuse

  • payments.Order
  • payments.PurchasedProduct
  • Download logic
  • Access checks

What You Must NOT Do

  • Do not grant access directly
  • Do not duplicate Order models

Why This Works

payments defines what access means

Provider apps only define how payment happens


Making Support Free or Subscription-Based

Scenario A – Free Support

If you want free support:

  • Remove PurchasedProduct dependency
  • OR auto-create a “support entitlement”

⚠️ Strong Warning

This breaks a core revenue guardrail.

Recommended instead:

  • Create a free tier product
  • Grant access via PurchasedProduct as usual

Scenario B – Subscription Support

  1. Extend PurchasedProduct with:
  2. expiry date
  3. plan type
  4. Update:
  5. has_active_support_request
  6. support eligibility checks

Do NOT:

  • Move logic into depsupport
  • Bypass ownership checks

Adding Product Versions or Changelogs

Goal

Show detailed update history instead of a 3-day badge.

Safe Approach

  • Create ProductVersion model
  • Link it to Product
  • Show latest version info in UI

Keep:

  • Update badge logic intact
  • updated_at meaningful

Do NOT:

  • Remove update badge logic
  • Store versions inside PurchasedProduct

Allowing Multiple Files per Product

Correct Pattern

  • Create ProductAsset model
  • ForeignKey → Product
  • Control visibility per asset

Reuse:

  • Signed URL download logic
  • Ownership checks via PurchasedProduct

Do NOT:

  • Store multiple files in JSON
  • Expose raw storage URLs

Adding Roles (Admin, Affiliate, Manager)

Correct Way

  • Add flags to User is_affiliate = True
  • Add mixins similar to:
  • IsSellerMixin
  • IsCustomerMixin

Do NOT:

  • Create new user tables
  • Hardcode role checks in views

Customizing Seller Dashboard Metrics

Safe Customizations

  • Add new cards
  • Add new charts
  • Add cached analytics

Use:

  • Aggregations on Orders
  • PurchasedProduct counts

Avoid:

  • Querying payment providers live
  • Heavy queries without caching

Changing Storage Provider (AWS S3 / GCP)

Correct Approach

  • Modify STORAGES settings only
  • Keep storage API intact

Why this works:

  • File access is abstracted
  • Download logic stays unchanged

Never:

  • Hardcode storage logic in views
  • Change file access permissions casually

Customizing Authentication Flow

Safe Changes

  • UI changes
  • Add OTP or magic links
  • Add new OAuth providers

Dangerous Changes

  • Removing email verification
  • Changing login redirect logic

Remember:

Auth is system entry point .


Adding APIs (Mobile / Public)

  • Create a new api app
  • Reuse:
  • models
  • access rules
  • Expose only read operations first

Do NOT:

  • Put APIs inside existing apps
  • Expose PurchasedProduct write access

Customization Golden Rules

  1. Never bypass PurchasedProduct
  2. Never grant access in UI
  3. Never let providers decide access
  4. Never duplicate ownership
  5. Never break role symmetry

If a change violates any of the above, rethink it.