# DMS Webhook API Documentation ## Overview This document describes the webhook endpoints that DMS (Document Management System) will call to notify the RE Workflow System after processing invoice and credit note generation requests. --- ## Table of Contents 1. [Webhook Overview](#1-webhook-overview) 2. [Authentication](#2-authentication) 3. [Invoice Webhook](#3-invoice-webhook) 4. [Credit Note Webhook](#4-credit-note-webhook) 5. [Payload Specifications](#5-payload-specifications) 6. [Error Handling](#6-error-handling) 7. [Testing](#7-testing) --- ## 1. Webhook Overview ### 1.1 Purpose After RE Workflow System pushes invoice/credit note generation requests to DMS, DMS processes them and sends webhook callbacks with the generated document details, tax information, and other metadata. ### 1.2 Webhook Flow ``` ┌─────────────────┐ ┌─────────────────┐ │ RE Workflow │ │ DMS System │ │ System │ │ │ └────────┬────────┘ └────────┬────────┘ │ │ │ POST /api/invoices/generate │ │ { request_number, dealer_code, ... }│ ├─────────────────────────────────────►│ │ │ │ │ Process Invoice │ │ Generate Document │ │ Calculate GST │ │ │ │ POST /api/v1/webhooks/dms/invoice │ │ { document_no, irn_no, ... } │◄─────────────────────────────────────┤ │ │ │ Update Invoice Record │ │ Store IRN, GST Details, etc. │ │ │ ``` --- ## 2. Authentication ### 2.1 Webhook Signature DMS must include a signature in the request header for security validation: **Header:** ``` X-DMS-Signature: ``` **Signature Generation:** 1. Create HMAC-SHA256 hash of the request body (JSON string) 2. Use the shared secret key (`DMS_WEBHOOK_SECRET`) 3. Send the hex-encoded signature in the `X-DMS-Signature` header **Example:** ```javascript const crypto = require('crypto'); const body = JSON.stringify(payload); const signature = crypto .createHmac('sha256', DMS_WEBHOOK_SECRET) .update(body) .digest('hex'); // Send in header: X-DMS-Signature: ``` ### 2.2 Environment Variable Configure the webhook secret in RE Workflow System: ```env DMS_WEBHOOK_SECRET=your_shared_secret_key_here ``` **Note:** If `DMS_WEBHOOK_SECRET` is not configured, signature validation is skipped (development mode only). --- ## 3. Invoice Webhook ### 3.1 Endpoint **URL:** `POST /api/v1/webhooks/dms/invoice` **Base URL Examples:** - Development: `http://localhost:5000/api/v1/webhooks/dms/invoice` - UAT: `https://reflow-uat.royalenfield.com/api/v1/webhooks/dms/invoice` - Production: `https://reflow.royalenfield.com/api/v1/webhooks/dms/invoice` ### 3.2 Request Headers ```http Content-Type: application/json X-DMS-Signature: User-Agent: DMS-Webhook-Client/1.0 ``` ### 3.3 Request Payload ```json { "request_number": "REQ-2025-12-0001", "document_no": "EINV-2025-001234", "document_type": "E-INVOICE", "document_date": "2025-12-17T10:30:00.000Z", "dealer_code": "DLR001", "dealer_name": "ABC Motors", "activity_name": "Marketing Campaign", "activity_description": "Q4 Marketing Campaign for Royal Enfield", "claim_amount": 150000.00, "io_number": "IO-2025-001", "item_code_no": "ITEM-001", "hsn_sac_code": "998314", "cgst_percentage": 9.0, "sgst_percentage": 9.0, "igst_percentage": 0.0, "cgst_amount": 13500.00, "sgst_amount": 13500.00, "igst_amount": 0.00, "total_amount": 177000.00, "irn_no": "IRN123456789012345678901234567890123456789012345678901234567890", "invoice_file_path": "https://dms.example.com/invoices/EINV-2025-001234.pdf", "error_message": null, "timestamp": "2025-12-17T10:30:00.000Z" } ``` ### 3.4 Payload Field Descriptions | Field | Type | Required | Description | |-------|------|----------|-------------| | `request_number` | string | ✅ Yes | Original request number from RE Workflow System (e.g., "REQ-2025-12-0001") | | `document_no` | string | ✅ Yes | Generated invoice/document number from DMS | | `document_type` | string | ✅ Yes | Type of document: "E-INVOICE" or "INVOICE" | | `document_date` | string (ISO 8601) | ✅ Yes | Date when invoice was generated | | `dealer_code` | string | ✅ Yes | Dealer code (should match original request) | | `dealer_name` | string | ✅ Yes | Dealer name (should match original request) | | `activity_name` | string | ✅ Yes | Activity name from original request | | `activity_description` | string | ✅ Yes | Activity description from original request | | `claim_amount` | number | ✅ Yes | Original claim amount (before tax) | | `io_number` | string | No | Internal Order number (if provided in original request) | | `item_code_no` | string | ✅ Yes | Item code number (provided by DMS team based on activity list) | | `hsn_sac_code` | string | ✅ Yes | HSN/SAC code for the invoice | | `cgst_percentage` | number | ✅ Yes | CGST percentage (e.g., 9.0 for 9%) | | `sgst_percentage` | number | ✅ Yes | SGST percentage (e.g., 9.0 for 9%) | | `igst_percentage` | number | ✅ Yes | IGST percentage (0.0 for intra-state, >0 for inter-state) | | `cgst_amount` | number | ✅ Yes | CGST amount in INR | | `sgst_amount` | number | ✅ Yes | SGST amount in INR | | `igst_amount` | number | ✅ Yes | IGST amount in INR | | `total_amount` | number | ✅ Yes | Total invoice amount (claim_amount + all taxes) | | `irn_no` | string | No | Invoice Reference Number (IRN) from GST portal (if generated) | | `invoice_file_path` | string | ✅ Yes | URL or path to the generated invoice PDF/document file | | `error_message` | string | No | Error message if invoice generation failed | | `timestamp` | string (ISO 8601) | ✅ Yes | Timestamp when webhook is sent | ### 3.5 Success Response **Status Code:** `200 OK` ```json { "success": true, "message": "Invoice webhook processed successfully", "data": { "message": "Invoice webhook processed successfully", "invoiceNumber": "EINV-2025-001234", "requestNumber": "REQ-2025-12-0001" } } ``` ### 3.6 Error Response **Status Code:** `400 Bad Request` or `500 Internal Server Error` ```json { "success": false, "message": "Failed to process invoice webhook", "error": "Request not found: REQ-2025-12-0001" } ``` --- ## 4. Credit Note Webhook ### 4.1 Endpoint **URL:** `POST /api/v1/webhooks/dms/credit-note` **Base URL Examples:** - Development: `http://localhost:5000/api/v1/webhooks/dms/credit-note` - UAT: `https://reflow-uat.royalenfield.com/api/v1/webhooks/dms/credit-note` - Production: `https://reflow.royalenfield.com/api/v1/webhooks/dms/credit-note` ### 4.2 Request Headers ```http Content-Type: application/json X-DMS-Signature: User-Agent: DMS-Webhook-Client/1.0 ``` ### 4.3 Request Payload ```json { "request_number": "REQ-2025-12-0001", "document_no": "CN-2025-001234", "document_type": "CREDIT_NOTE", "document_date": "2025-12-17T11:00:00.000Z", "dealer_code": "DLR001", "dealer_name": "ABC Motors", "activity_name": "Marketing Campaign", "activity_description": "Q4 Marketing Campaign for Royal Enfield", "claim_amount": 150000.00, "io_number": "IO-2025-001", "item_code_no": "ITEM-001", "hsn_sac_code": "998314", "cgst_percentage": 9.0, "sgst_percentage": 9.0, "igst_percentage": 0.0, "cgst_amount": 13500.00, "sgst_amount": 13500.00, "igst_amount": 0.00, "total_amount": 177000.00, "credit_type": "GST", "irn_no": "IRN987654321098765432109876543210987654321098765432109876543210", "sap_credit_note_no": "SAP-CN-2025-001234", "credit_note_file_path": "https://dms.example.com/credit-notes/CN-2025-001234.pdf", "error_message": null, "timestamp": "2025-12-17T11:00:00.000Z" } ``` ### 4.4 Payload Field Descriptions | Field | Type | Required | Description | |-------|------|----------|-------------| | `request_number` | string | ✅ Yes | Original request number from RE Workflow System | | `document_no` | string | ✅ Yes | Generated credit note number from DMS | | `document_type` | string | ✅ Yes | Type of document: "CREDIT_NOTE" | | `document_date` | string (ISO 8601) | ✅ Yes | Date when credit note was generated | | `dealer_code` | string | ✅ Yes | Dealer code (should match original request) | | `dealer_name` | string | ✅ Yes | Dealer name (should match original request) | | `activity_name` | string | ✅ Yes | Activity name from original request | | `activity_description` | string | ✅ Yes | Activity description from original request | | `claim_amount` | string | ✅ Yes | Original claim amount (before tax) | | `io_number` | string | No | Internal Order number (if provided) | | `item_code_no` | string | ✅ Yes | Item code number (provided by DMS team) | | `hsn_sac_code` | string | ✅ Yes | HSN/SAC code for the credit note | | `cgst_percentage` | number | ✅ Yes | CGST percentage | | `sgst_percentage` | number | ✅ Yes | SGST percentage | | `igst_percentage` | number | ✅ Yes | IGST percentage | | `cgst_amount` | number | ✅ Yes | CGST amount in INR | | `sgst_amount` | number | ✅ Yes | SGST amount in INR | | `igst_amount` | number | ✅ Yes | IGST amount in INR | | `total_amount` | number | ✅ Yes | Total credit note amount (claim_amount + all taxes) | | `credit_type` | string | ✅ Yes | Type of credit: "GST" or "Commercial Credit" | | `irn_no` | string | No | Invoice Reference Number (IRN) for credit note (if generated) | | `sap_credit_note_no` | string | ✅ Yes | SAP Credit Note Number (generated by SAP system) | | `credit_note_file_path` | string | ✅ Yes | URL or path to the generated credit note PDF/document file | | `error_message` | string | No | Error message if credit note generation failed | | `timestamp` | string (ISO 8601) | ✅ Yes | Timestamp when webhook is sent | ### 4.5 Success Response **Status Code:** `200 OK` ```json { "success": true, "message": "Credit note webhook processed successfully", "data": { "message": "Credit note webhook processed successfully", "creditNoteNumber": "CN-2025-001234", "requestNumber": "REQ-2025-12-0001" } } ``` ### 4.6 Error Response **Status Code:** `400 Bad Request` or `500 Internal Server Error` ```json { "success": false, "message": "Failed to process credit note webhook", "error": "Credit note record not found for request: REQ-2025-12-0001" } ``` --- ## 5. Payload Specifications ### 5.1 Data Mapping: RE Workflow → DMS When RE Workflow System sends data to DMS, it includes: | RE Workflow Field | DMS Receives | Notes | |-------------------|--------------|-------| | `requestNumber` | `request_number` | Direct mapping | | `dealerCode` | `dealer_code` | Direct mapping | | `dealerName` | `dealer_name` | Direct mapping | | `activityName` | `activity_name` | From claim details | | `activityDescription` | `activity_description` | From claim details | | `claimAmount` | `claim_amount` | Total claim amount | | `ioNumber` | `io_number` | If available | ### 5.2 Data Mapping: DMS → RE Workflow When DMS sends webhook, RE Workflow System stores: | DMS Webhook Field | RE Workflow Database Field | Table | |-------------------|---------------------------|-------| | `document_no` | `invoice_number` / `credit_note_number` | `claim_invoices` / `claim_credit_notes` | | `document_date` | `invoice_date` / `credit_note_date` | `claim_invoices` / `claim_credit_notes` | | `total_amount` | `invoice_amount` / `credit_note_amount` | `claim_invoices` / `claim_credit_notes` | | `invoice_file_path` | `invoice_file_path` | `claim_invoices` | | `credit_note_file_path` | `credit_note_file_path` | `claim_credit_notes` | | `irn_no` | Stored in `description` field | Both tables | | `sap_credit_note_no` | `sap_document_number` | `claim_credit_notes` | | `item_code_no` | Stored in `description` field | Both tables | | `hsn_sac_code` | Stored in `description` field | Both tables | | GST amounts | Stored in `description` field | Both tables | | `credit_type` | Stored in `description` field | `claim_credit_notes` | ### 5.3 GST Calculation Logic **Intra-State (Same State):** - CGST: Applied (e.g., 9%) - SGST: Applied (e.g., 9%) - IGST: 0% **Inter-State (Different State):** - CGST: 0% - SGST: 0% - IGST: Applied (e.g., 18%) **Total Amount Calculation:** ``` total_amount = claim_amount + cgst_amount + sgst_amount + igst_amount ``` --- ## 6. Error Handling ### 6.1 Common Error Scenarios | Error | Status Code | Description | Solution | |-------|-------------|-------------|----------| | Invalid Signature | 401 | Webhook signature validation failed | Check `DMS_WEBHOOK_SECRET` and signature generation | | Missing Required Field | 400 | Required field is missing in payload | Ensure all required fields are included | | Request Not Found | 400 | Request number doesn't exist in system | Verify request number matches original request | | Invoice Not Found | 400 | Invoice record not found for request | Ensure invoice was created before webhook | | Credit Note Not Found | 400 | Credit note record not found for request | Ensure credit note was created before webhook | | Database Error | 500 | Internal database error | Check database connection and logs | ### 6.2 Retry Logic DMS should implement retry logic for failed webhook deliveries: - **Initial Retry:** After 1 minute - **Second Retry:** After 5 minutes - **Third Retry:** After 15 minutes - **Final Retry:** After 1 hour **Maximum Retries:** 4 attempts **Retry Conditions:** - HTTP 5xx errors (server errors) - Network timeouts - Connection failures **Do NOT Retry:** - HTTP 400 errors (client errors - invalid payload) - HTTP 401 errors (authentication errors) ### 6.3 Idempotency Webhooks should be idempotent. If DMS sends the same webhook multiple times: - RE Workflow System will update the record with the latest data - No duplicate records will be created - Status will be updated to reflect the latest state --- ## 7. Testing ### 7.1 Test Invoice Webhook ```bash curl -X POST "http://localhost:5000/api/v1/webhooks/dms/invoice" \ -H "Content-Type: application/json" \ -H "X-DMS-Signature: " \ -d '{ "request_number": "REQ-2025-12-0001", "document_no": "EINV-TEST-001", "document_type": "E-INVOICE", "document_date": "2025-12-17T10:30:00.000Z", "dealer_code": "DLR001", "dealer_name": "Test Dealer", "activity_name": "Test Activity", "activity_description": "Test Description", "claim_amount": 100000.00, "io_number": "IO-TEST-001", "item_code_no": "ITEM-001", "hsn_sac_code": "998314", "cgst_percentage": 9.0, "sgst_percentage": 9.0, "igst_percentage": 0.0, "cgst_amount": 9000.00, "sgst_amount": 9000.00, "igst_amount": 0.00, "total_amount": 118000.00, "irn_no": "IRN123456789012345678901234567890123456789012345678901234567890", "invoice_file_path": "https://dms.example.com/invoices/EINV-TEST-001.pdf", "timestamp": "2025-12-17T10:30:00.000Z" }' ``` ### 7.2 Test Credit Note Webhook ```bash curl -X POST "http://localhost:5000/api/v1/webhooks/dms/credit-note" \ -H "Content-Type: application/json" \ -H "X-DMS-Signature: " \ -d '{ "request_number": "REQ-2025-12-0001", "document_no": "CN-TEST-001", "document_type": "CREDIT_NOTE", "document_date": "2025-12-17T11:00:00.000Z", "dealer_code": "DLR001", "dealer_name": "Test Dealer", "activity_name": "Test Activity", "activity_description": "Test Description", "claim_amount": 100000.00, "io_number": "IO-TEST-001", "item_code_no": "ITEM-001", "hsn_sac_code": "998314", "cgst_percentage": 9.0, "sgst_percentage": 9.0, "igst_percentage": 0.0, "cgst_amount": 9000.00, "sgst_amount": 9000.00, "igst_amount": 0.00, "total_amount": 118000.00, "credit_type": "GST", "irn_no": "IRN987654321098765432109876543210987654321098765432109876543210", "sap_credit_note_no": "SAP-CN-TEST-001", "credit_note_file_path": "https://dms.example.com/credit-notes/CN-TEST-001.pdf", "timestamp": "2025-12-17T11:00:00.000Z" }' ``` ### 7.3 Signature Calculation (Node.js Example) ```javascript const crypto = require('crypto'); function calculateSignature(payload, secret) { const body = JSON.stringify(payload); return crypto .createHmac('sha256', secret) .update(body) .digest('hex'); } const payload = { /* webhook payload */ }; const secret = process.env.DMS_WEBHOOK_SECRET; const signature = calculateSignature(payload, secret); // Use in header: X-DMS-Signature: ``` --- ## 8. Integration Checklist ### 8.1 DMS Team Checklist - [ ] Configure webhook URLs in DMS system - [ ] Set up `DMS_WEBHOOK_SECRET` (shared secret) - [ ] Implement signature generation (HMAC-SHA256) - [ ] Test webhook delivery to RE Workflow endpoints - [ ] Implement retry logic for failed deliveries - [ ] Set up monitoring/alerting for webhook failures - [ ] Document webhook payload structure - [ ] Coordinate with RE Workflow team for testing ### 8.2 RE Workflow Team Checklist - [ ] Configure `DMS_WEBHOOK_SECRET` in environment variables - [ ] Deploy webhook endpoints to UAT/Production - [ ] Test webhook endpoints with sample payloads - [ ] Verify database updates after webhook processing - [ ] Set up monitoring/alerting for webhook failures - [ ] Document webhook endpoints for DMS team - [ ] Coordinate with DMS team for integration testing --- ## 9. Support & Troubleshooting ### 9.1 Logs RE Workflow System logs webhook processing: - **Success:** `[DMSWebhook] Invoice webhook processed successfully` - **Error:** `[DMSWebhook] Error processing invoice webhook: ` - **Validation:** `[DMSWebhook] Invalid webhook signature` ### 9.2 Common Issues **Issue: Webhook signature validation fails** - Verify `DMS_WEBHOOK_SECRET` matches in both systems - Check signature calculation method (HMAC-SHA256) - Ensure request body is JSON stringified correctly **Issue: Request not found** - Verify `request_number` matches the original request - Check if request exists in RE Workflow database - Ensure request was created before webhook is sent **Issue: Invoice/Credit Note record not found** - Verify invoice/credit note was created in RE Workflow - Check if webhook is sent before record creation - Review workflow step sequence --- ## 10. Environment Configuration ### 10.1 Environment Variables Add to RE Workflow System `.env` file: ```env # DMS Webhook Configuration DMS_WEBHOOK_SECRET=your_shared_secret_key_here ``` ### 10.2 Webhook URLs by Environment | Environment | Invoice Webhook URL | Credit Note Webhook URL | |-------------|---------------------|-------------------------| | Development | `http://localhost:5000/api/v1/webhooks/dms/invoice` | `http://localhost:5000/api/v1/webhooks/dms/credit-note` | | UAT | `https://reflow-uat.royalenfield.com/api/v1/webhooks/dms/invoice` | `https://reflow-uat.royalenfield.com/api/v1/webhooks/dms/credit-note` | | Production | `https://reflow.royalenfield.com/api/v1/webhooks/dms/invoice` | `https://reflow.royalenfield.com/api/v1/webhooks/dms/credit-note` | --- **Document Version:** 1.0 **Last Updated:** December 2024 **Maintained By:** RE Workflow Development Team