A comprehensive Frappe application for sellers to integrate with the Open Network for Digital Commerce (ONDC). This app provides complete ONDC protocol compliance including transaction flows, issue management (IGM), and settlement reconciliation (RSP).
- ONDC Protocol Compliance - Full Beckn Protocol v1.2.0 implementation
- Transaction Flows - search, select, init, confirm, status, track, cancel, update, rating, support
- IGM (Issue & Grievance Management) - Integrated with Frappe Helpdesk
- RSP (Reconciliation & Settlement) - Integrated with ERPNext Payment Reconciliation
- Network Observability - Compliance logging and SLA tracking
- Ed25519 Signing - Cryptographic request signing and verification
- Multi-domain Support - Retail, F&B, Fashion, Electronics, etc.
The ONDC Seller App acts as a BPP (Buyer-Platform Provider) — it receives requests from Buyer Apps (like Paytm, PhonePe, ONDC reference app) through the ONDC Gateway and responds with your catalog, pricing, and order fulfillment.
Buyer App (BAP) ONDC Gateway Your Seller App (BPP)
│ │ │
│── search ────────────►│── search ─────────────►│
│ │◄── on_search (catalog) ─│ ← Returns your products
│◄── on_search ─────────│ │
│ │ │
│── select ────────────►│── select ─────────────►│
│ │◄── on_select (quote) ──│ ← Returns price breakup
│◄── on_select ─────────│ │
│ │ │
│── init ──────────────►│── init ───────────────►│
│ │◄── on_init (payment) ──│ ← Returns payment & billing
│◄── on_init ───────────│ │
│ │ │
│── confirm ───────────►│── confirm ────────────►│
│ │◄── on_confirm (order) ─│ ← Order created! Returns order ID
│◄── on_confirm ────────│ │
│ │ │
│── status ────────────►│── status ─────────────►│
│ │◄── on_status ──────────│ ← Returns fulfillment status
│◄── on_status ─────────│ │
| Step | API | What Happens | Your App Does |
|---|---|---|---|
| 1 | search → on_search | Buyer searches for "milk" | Returns matching ONDC Products from your catalog with prices, images, availability |
| 2 | select → on_select | Buyer selects items and qty | Calculates quote breakup (item price + taxes + delivery charges) |
| 3 | init → on_init | Buyer provides delivery address | Returns payment details, fulfillment info, billing, and terms |
| 4 | confirm → on_confirm | Buyer confirms & pays | Creates ONDC Order in Frappe, triggers fulfillment workflow |
| 5 | status → on_status | Buyer checks order status | Returns current fulfillment state from ONDC Order |
| 6 | track → on_track | Buyer wants tracking link | Returns tracking URL if available |
| 7 | cancel → on_cancel | Buyer/Seller cancels order | Updates ONDC Order status, processes refund if applicable |
| 8 | update → on_update | Seller updates fulfillment | Sends delivery status updates (Packed → Out for Delivery → Delivered) |
Once an order is confirmed, the seller manages fulfillment through the ONDC Order DocType:
Pending → Packed → Agent Assigned → Out for Delivery → Delivered
│
(or) Cancelled / RTO
Each status change triggers an unsolicited on_status callback to the buyer app.
| Flow | APIs | Purpose |
|---|---|---|
| IGM (Issue & Grievance) | issue → on_issue, issue_status → on_issue_status |
Buyer raises complaints; mapped to Frappe Helpdesk tickets |
| RSP (Settlement) | receiver_recon → on_receiver_recon |
ONDC sends settlement details; reconciled with ERPNext payments |
| Rating | rating → on_rating |
Buyer rates the seller experience |
┌─────────────────────────────────────────────────────┐
│ Frappe Cloud / Bench │
│ │
│ ┌──────────────┐ ┌───────────────────────────┐ │
│ │ middleware.py│───►│ webhook.py │ │
│ │ (routing) │ │ (auth + dispatch) │ │
│ └──────────────┘ └───────────┬───────────────┘ │
│ │ │
│ ┌───────────────────────┼──────────┐ │
│ ▼ ▼ ▼ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────┐ │
│ │ ondc_client.py│ │ auth.py │ │ tasks.py │ │
│ │ (callbacks) │ │ (Ed25519) │ │ (sync) │ │
│ └──────┬───────┘ └──────────────┘ └──────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────┐ │
│ │ DocTypes: ONDC Settings │ ONDC Product │ │ │
│ │ ONDC Order │ ONDC Webhook Log │ │
│ └──────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────┐ │
│ │ ERPNext: Items │ Sales Orders │ Payments │ │
│ │ Helpdesk: HD Tickets (IGM) │ │
│ └──────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
- ONDC Gateway sends POST requests to your subscriber URL (e.g.,
https://your-site.frappe.cloud/search) middleware.pyintercepts the request via Frappe'sbefore_requesthook- It maps the path (
/search) to the correct handler (ondc_seller_app.api.webhook.handle_search) usingfrappe.local.form_dict.cmd webhook.pyverifies the Ed25519 signature, then dispatches to the appropriate handler- The handler processes the request and
ondc_client.pysends the async callback (e.g.,on_search) to the buyer app
- Frappe Framework v15+
- ERPNext v15+ (required for RSP/Payment features)
- Frappe Helpdesk (optional, for IGM integration)
- Go to your Frappe Cloud dashboard
- Navigate to Apps → Add App
- Enter the repository URL:
https://github.com/chinmaybhatk/Frappe-ONDC-Sellerapp.git - Install the app on your site
# Get the app
bench get-app https://github.com/chinmaybhatk/Frappe-ONDC-Sellerapp.git
# Install on your site
bench --site your-site.local install-app ondc_seller_app
# (Optional) Install Helpdesk for IGM integration
bench get-app helpdesk
bench --site your-site.local install-app helpdesk- Login to your Frappe site as Administrator
- Go to Search Bar → Type "ONDC Settings"
- Or navigate via URL:
https://your-site.frappe.cloud/app/ondc-settings
| Field | Description | Example |
|---|---|---|
| Subscriber ID | Your unique BPP ID registered with ONDC | your-company.com |
| Subscriber URL | Your public endpoint URL | https://your-site.frappe.cloud |
| Environment | ONDC environment | staging / preprod / prod |
| Domain | ONDC domain code | ONDC:RET10 (Grocery) |
| City Code | Operating city | std:080 (Bangalore) |
ONDC requires Ed25519 keys for request signing:
| Field | Description |
|---|---|
| Signing Private Key | Your Ed25519 private key (base64 encoded) |
| Signing Public Key | Your Ed25519 public key (base64 encoded) |
| Unique Key ID | Key identifier registered with ONDC registry |
| Encryption Private Key | X25519 private key for payload encryption |
| Encryption Public Key | X25519 public key for payload encryption |
from nacl.signing import SigningKey
import base64
# Generate signing keypair
signing_key = SigningKey.generate()
private_key = base64.b64encode(signing_key.encode()).decode()
public_key = base64.b64encode(signing_key.verify_key.encode()).decode()
print(f"Private Key: {private_key}")
print(f"Public Key: {public_key}")| Field | Description | Example |
|---|---|---|
| Legal Entity Name | Registered business name | Your Company Pvt Ltd |
| GSTIN | GST Identification Number | 29AAAAA0000A1Z5 |
| PAN | PAN number | AAAAA0000A |
| FSSAI License | Food license (for F&B) | 12345678901234 |
| Consumer Care Email | Support email | support@your-company.com |
| Consumer Care Phone | Support phone | +91-9876543210 |
| Field | Description |
|---|---|
| Store Name | Display name for your store |
| Store GPS | Latitude,Longitude of store |
| Store Address | Complete store address |
| Serviceability Radius | Delivery radius in km |
| Operating Hours | Store timings (HH:MM-HH:MM format) |
| Field | Description |
|---|---|
| Bank Account | ERPNext Bank Account for settlements |
| Receivable Account | Accounts Receivable ledger |
| Settlement Bank Name | Your bank name |
| Settlement Account No | Bank account number |
| Settlement IFSC | Bank IFSC code |
| Beneficiary Name | Account holder name |
Once deployed, your app exposes these endpoints:
| Endpoint | Description |
|---|---|
POST /ondc/webhook/search |
Handle catalog search requests |
POST /ondc/webhook/select |
Handle item selection |
POST /ondc/webhook/init |
Handle order initialization |
POST /ondc/webhook/confirm |
Handle order confirmation |
POST /ondc/webhook/status |
Handle order status requests |
POST /ondc/webhook/track |
Handle tracking requests |
POST /ondc/webhook/cancel |
Handle cancellation requests |
POST /ondc/webhook/update |
Handle order updates |
POST /ondc/webhook/rating |
Handle ratings |
POST /ondc/webhook/support |
Handle support requests |
| Endpoint | Description |
|---|---|
POST /on_subscribe |
Registry onboarding callback |
| Endpoint | Description |
|---|---|
POST /issue |
Receive issue/complaint from buyer |
POST /issue_status |
Check issue status |
| Endpoint | Description |
|---|---|
POST /receiver_recon |
Settlement reconciliation |
The app supports two sync sources for products. Choose based on your business model:
| Sync Source | Best For | Features |
|---|---|---|
| ERPNext Item | B2B sellers, Inventory-focused | Direct inventory integration, Stock sync |
| Frappe Webshop | B2C sellers, E-commerce | Multiple images, Web pricing, Slideshow |
| Both | Hybrid businesses | Sync from both sources |
- Go to ONDC Settings
- Under Product Sync Settings, select Product Sync Source:
ERPNext Item- Sync from ERPNext Item masterFrappe Webshop- Sync from Website ItemsBoth- Enable both sync sources
Best for B2B sellers using ERPNext for inventory management.
- Enable Sync on Item: Check the "Sync to ONDC" checkbox on any Item
- Auto-Create: When Item is saved, an ONDC Product is automatically created
- Auto-Update: Changes to Item (price, description, image) sync to ONDC Product
- Category Mapping: Item Groups are auto-mapped to ONDC categories
- Open any Item in ERPNext
- Check "Sync to ONDC" checkbox (in the first section)
- Optionally set Country of Origin and ONDC Category
- Save the Item
Run from Frappe Console:
# Enable sync for all items in a group
from ondc_seller_app.utils.bulk_sync import enable_ondc_sync_for_item_group
enable_ondc_sync_for_item_group('Grocery')
# Sync all enabled items
from ondc_seller_app.utils.bulk_sync import sync_all_items_to_ondc
sync_all_items_to_ondc()Or call the API:
curl -X POST https://your-site.frappe.cloud/api/method/ondc_seller_app.utils.bulk_sync.bulk_sync_items \
-H "Authorization: token api_key:api_secret" \
-d '{"item_group": "Grocery"}'| Field | Description |
|---|---|
| Sync to ONDC | Enable/disable ONDC sync for this item |
| ONDC Product ID | Auto-generated link to ONDC Product |
| Country of Origin | Required for ONDC (defaults to India) |
| ONDC Category | Override auto-detected category |
| Sync Status | Current sync status (Synced/Failed/Pending) |
| Last Synced | Timestamp of last successful sync |
Best for B2C sellers with consumer-facing websites using Frappe Webshop.
- Enable Sync on Website Item: Check "Sync to ONDC" checkbox
- Rich Media: Multiple images from Website Item slideshow are synced
- Web Pricing: Uses Webshop pricing rules
- Auto-Update: Changes sync automatically
- Ensure Frappe Webshop is installed
- Go to ONDC Settings → Set Product Sync Source to
Frappe WebshoporBoth - Open any Website Item
- Check "Sync to ONDC" checkbox
- Set Country of Origin and optionally ONDC Category
- Save
| Field | Description |
|---|---|
| Sync to ONDC | Enable/disable ONDC sync |
| ONDC Product ID | Auto-generated link to ONDC Product |
| Country of Origin | Required for ONDC (defaults to India) |
| ONDC Category | Override auto-detected category |
| Sync Status | Current sync status |
| Last Synced | Timestamp of last successful sync |
- Multiple Images: Syncs all images from Website Item slideshow
- Web-specific Pricing: Uses Webshop pricing rules and discounts
- SEO Data: Can leverage web-optimized descriptions
- Variant Support: Works with Website Item variants
Item Groups are automatically mapped to ONDC categories:
| Item Group | ONDC Category |
|---|---|
| Grocery | ONDC:RET10 |
| Food & Beverages | ONDC:RET11 |
| Fashion | ONDC:RET12 |
| Beauty & Personal Care | ONDC:RET13 |
| Electronics | ONDC:RET14 |
| Home & Decor | ONDC:RET15 |
| Health & Wellness | ONDC:RET16 |
| Pharma | ONDC:RET17 |
| Agriculture | ONDC:RET18 |
You can override this by setting the ONDC Category field on the Item or Website Item.
Single DocType for all ONDC configuration. Access via ONDC Settings in search.
Manages product catalog with ONDC-specific attributes:
- Linked to ERPNext Item (auto-synced)
- ONDC Product ID
- Category mappings
- Statutory requirements (FSSAI, brand owner, etc.)
- Pricing and availability
Handles order lifecycle:
- Order status tracking
- Fulfillment state machine (Pending → Packed → Agent-assigned → Out-for-delivery → Delivered)
- Payment status
- Cancellation handling
Child table for order line items.
Logs all incoming/outgoing API calls for debugging and compliance.
Network observability logging:
- API transaction logs
- IGM transaction logs
- RSP reconciliation logs
- SLA compliance metrics
When a buyer raises an issue via ONDC:
- Issue Received → Creates HD Ticket in Frappe Helpdesk
- Ticket Updated → Sends
/on_issue_statuscallback automatically - Ticket Resolved → Notifies buyer via ONDC network
The app adds these custom fields to HD Ticket:
custom_ondc_issue_id- ONDC Issue IDcustom_ondc_order_id- Related Order IDcustom_ondc_category- Issue categorycustom_bap_id- Buyer App ID
If Helpdesk is not installed, issues are logged in ONDC Webhook Log.
When settlement reconciliation request arrives:
- Reconciliation Request → Matches with ONDC Orders
- Creates Entries → Payment Entry or Journal Entry in ERPNext
- Sends Response →
/on_receiver_reconwith match status
Pramaan is ONDC's automated compliance testing platform that validates your integration.
-
Deploy your app to a publicly accessible URL
-
Go to Pramaan: https://pramaan.ondc.org
-
Configure your endpoints:
- Subscriber ID: Your BPP subscriber ID
- Subscriber URL:
https://your-site.frappe.cloud - Domain: Your registered domain (e.g.,
ONDC:RET10)
-
Run mandatory test flows:
- All transaction APIs (search through support)
- IGM flows (issue, issue_status)
- RSP flows (receiver_recon)
-
Submit report to ONDC portal
Cause: Module structure mismatch
Fix: Ensure modules.txt contains ondc_seller and the folder exists at ondc_seller_app/ondc_seller/
Cause: Invalid datetime default in DocType JSON
Fix: Remove "default": "__timestamp" from Datetime fields
Cause: Key mismatch or incorrect key format Fix: Verify keys are base64 encoded Ed25519 keys and registered with ONDC registry
Cause: Route not configured
Fix: Check hooks.py has correct website_route_rules
Check logs at:
- ONDC Webhook Log: All incoming/outgoing API calls
- ONDC Compliance Log: Network observability data
- Error Log:
bench --site your-site.local show-error-log
ondc_seller_app/
├── ondc_seller_app/
│ ├── __init__.py
│ ├── hooks.py # Frappe hooks and routes
│ ├── modules.txt # Module definition
│ ├── api/
│ │ ├── auth.py # Signature verification
│ │ ├── ondc_client.py # ONDC API client
│ │ ├── ondc_errors.py # Error codes and responses
│ │ ├── webhook.py # Webhook handlers
│ │ ├── igm_adapter.py # IGM/Helpdesk integration
│ │ ├── rsp_adapter.py # RSP/Payment integration
│ │ └── compliance_log.py # Observability logging
│ ├── ondc_seller/
│ │ ├── doctype/
│ │ │ ├── ondc_settings/
│ │ │ ├── ondc_product/
│ │ │ ├── ondc_order/
│ │ │ ├── ondc_order_item/
│ │ │ ├── ondc_webhook_log/
│ │ │ └── ondc_compliance_log/
│ │ └── report/
│ └── utils/
├── pyproject.toml
└── README.md
bench --site your-site.local run-tests --app ondc_seller_appMIT License
For issues and feature requests, please create an issue on GitHub.