Configuring a Service Provider
Configuring a Service Provider
Once credentials are in place (Setting Up a Provider), you choose how documents flow in and out: webhook for real-time inbound, polling for scheduled pull, or both.
Webhook (inbound, real-time)
A webhook lets your service provider notify your ERPNext as soon as a document arrives — typically within seconds.
1. Configure the webhook URL in your provider's dashboard:
https://your-domain.com/api/method/edocument_integration.api.webhook
The webhook accepts:
- Method: POST
- Body: raw PEPPOL UBL XML
- Authentication: public (no auth header required — the endpoint is
allow_guest)
2. What happens on receipt:
- EDocument record created
- XML attached as a file
- Profile auto-detected from the XML namespace (CustomizationID)
- Company auto-detected from the buyer's EndpointID
- Validation runs
Response back to the provider:
{ "status": "success", "result": { "edocument": "EDOC-00001" } }
3. Security considerations
Because the endpoint is public, anyone with the URL can POST XML to it. In practice this is acceptable because:
- The XML is validated against XSD + Schematron — junk doesn't survive
- The buyer's EndpointID must match a Company on your site
- Failed validation creates an EDocument with "Validation Failed" status, which a System Manager can review
If you want to harden further:
- Put a WAF rule on the URL that only allows your provider's IP ranges
- Add a shared-secret header check in a
before_inserthook on EDocument
Polling (inbound, scheduled)
If your provider doesn't support webhooks (or you prefer pull semantics), polling fetches the inbox periodically.
Automatic polling: The app installs a daily scheduled task that polls all active Integration Settings with the Recommand integrator. See scheduler_events in edocument_integration/hooks.py.
Manual polling: On the EDocument Integration Settings form, click Poll Incoming Documents. The app:
- Calls the provider's inbox endpoint
- For each unread document: checks if
EDocument.referencealready exists (duplicate skip), creates an EDocument record, attaches the XML, validates - Returns a count: "Processed 2 invoice(s)" or "Skipped 1 duplicate(s)"
Duplicate prevention
Both inbound paths set EDocument.reference to the provider's document ID. If a re-poll or a webhook retry would re-import the same document, the duplicate check kicks in:
existing = frappe.db.exists("EDocument", {"reference": document_id})
if existing:
return {"skipped": True, "reason": "duplicate"}
Skipped duplicates are logged to Error Log with the document ID so you have an audit trail.
Outbound — API method
For outbound, there's nothing to configure beyond credentials. The transmission happens when you click Transmit via API on an EDocument. See Sending & Receiving.
Troubleshooting
| Symptom | Where to look |
|---|---|
| Webhook not firing | Provider dashboard logs — confirm URL is correct, payload is well-formed XML |
| Webhook returns 500 | Error Log in ERPNext — full traceback |
| Polling pulls nothing | Integration Settings: verify credentials with Test Connection if available; check API key hasn't been rotated |
| Transmission succeeds but recipient never gets it | Provider tracking dashboard — the document may be queued at the receiver's Access Point |
| Duplicate documents | Check that reference is being set; an old EDocument without reference won't trigger the dedup check |