Frappe-to-zoho-books

Integration Guide: Frappe with Zoho Books

Integration Flow

Purpose

To enable seamless data synchronization and management between Frappe and Zoho Books for:

  • Chart of Accounts

  • Sales Data (Sales Orders, Journal Entries, Estimates/Quotations)

Step 1: Authentication with Zoho Books

Zoho Books OAuth 2.0

  1. Visit Zoho Books OAuth documentation.

  2. Register in Zoho Developer Console to get:

    • Client ID

    • Client Secret

    • Redirect URL

Frappe Doctype: OAuth Management

Create a is_single Doctype with the following fields:

  • access_token

  • refresh_token

  • expires_in

  • client_id

  • client_secret

  • redirect_url

Cron Job: Token Refresh

Scheduled Task using the Refresh Token API:

def refresh_zoho_token():
    settings = frappe.get_single("Zoho Integration Settings")
    response = requests.post(
        "https://accounts.zoho.com/oauth/v2/token",
        data={
            "refresh_token": settings.refresh_token,
            "client_id": settings.client_id,
            "client_secret": settings.client_secret,
            "grant_type": "refresh_token",
        },
    )
    if response.status_code == 200:
        data = response.json()
        settings.access_token = data["access_token"]
        settings.expires_in = data["expires_in"]
        settings.save()
    

Step 2: Sync Chart of Accounts

Webhook in Frappe

Add hook in hooks.py:

doc_events = {
  "Chart of Account": {
    "after_save": "path.to.module.sync_chart_of_account_with_zoho"
  }
}
    

Zoho Books API Integration

def sync_chart_of_account_with_zoho(doc, method):
    settings = frappe.get_single("Zoho Integration Settings")
    headers = {
        "Authorization": f"Bearer {settings.access_token}",
        "Content-Type": "application/json",
    }
    payload = {
        "account_name": doc.account_name,
        "account_type": doc.account_type,
        "description": doc.description,
    }
    response = requests.post(
        "https://books.zoho.com/api/v3/chartofaccounts", headers=headers, json=payload
    )
    if response.status_code != 201:
        frappe.log_error(response.text, "Zoho Chart of Account Sync Error")
    

Step 3: Sync Sales Data

Sales Orders

Trigger on creation or update. Use Zoho Books API to send order data.

# Sample payload structure
{
  "customer_id": "460000000017138",
  "currency_id": "460000000000097",
  "contact_persons": ["460000000870911", "460000000870915"],
  "date": "2014-07-28",
  "line_items": [{
    "item_id": "460000000017088",
    "rate": 120,
    "quantity": 40,
    "description": "500GB, USB 2.0 interface"
  }],
  "salesorder_number": "SO-00001",
  "reference_number": "REF-001"
}
    

Other Docs

  • Journal Entries: Sync on create

  • Estimates/Quotations: Hook-based, API-driven

CRUD Operations

Use Zoho Books APIs for full Create, Read, Update, Delete operations across modules.

Conclusion

This guide outlines how to integrate Frappe with Zoho Books using OAuth2, webhooks, and Zoho APIs to sync COA and sales documents. You can extend it further using other modules in Zoho’s API suite.

1 Like

Why don’t you make custom app for this?

Nice Idea :light_bulb:

Great :+1: