Skip to main content
Back to Blog

Integrations

How Do You Connect a Website to ERPNext Without Losing Inquiry Details?

Published by IHP Technology9 min read

Connect the form through a server-side integration that validates the inquiry, maps fields to the installed ERPNext schema, preserves the complete message in Lead notes, and verifies delivery in the destination. IHP Technology implemented and verified this approach in its September 10, 2026 contact-flow release, including complete inquiry notes, compatible service categories, and an SMTP fallback.

The practical problem is preserving meaning across systems. A Lead can contain a name and email while omitting the project description that makes follow-up useful. This guide explains the implementation decisions behind IHP's update and provides field maps, a failure matrix, and a verification checklist for teams connecting a website to ERPNext.

Define what a complete inquiry must contain

Start with an explicit request contract. For each field, record whether it is required, its accepted values, its maximum length, and where it appears downstream. This exposes omissions before they become missing business information. Optional inputs also need semantics: an empty timeline means the visitor has not chosen one, so the integration should not invent an urgency level.

IHP's handler trims incoming strings and requires name, email, message, and a recognized website source. Company, project type, and timeline remain optional. The mapping below reflects the installed schema verified for this release; it is an implementation example, not a universal ERPNext schema. Every field also appears in the complete inquiry text used by both delivery paths.

Website inquiry fields and their verified destinations
Public fieldLimitERPNext destination
name — required120lead_name and inquiry notes
email — required254email_id and inquiry notes
company — optional200company_name and inquiry notes
projectType — optional80Mapped custom_project_type; original label in notes
timeline — optional40Inquiry notes; no custom_timeline field is sent
message — required5000Complete project description in notes
source — required80Inquiry notes; no top-level source field is sent

Scroll horizontally to read all table columns.

Map public service labels without discarding their meaning

A website and CRM can describe the same service at different levels of detail. IHP's public form distinguishes Web Apps, Mobile Apps, and Custom Software, while the installed CRM dropdown groups those requests under App Development. The server maps each label to an accepted option and retains the exact trimmed public label in the notes.

That second representation matters. Data & AI and Security both map to Other in this installation. A reviewer relying only on the dropdown would lose the distinction. The full inquiry therefore acts as the readable record of what the visitor selected, while the structured field supports the CRM's existing classification.

Inspect field names, types, required flags, and dropdown options in the target installation. IHP verified that its Lead schema had neither custom_timeline nor a separate source field. Preserving those values in notes avoided inventing unsupported properties. Changes to this mapping should be reviewed alongside changes to the public service list.

  • -Custom Software, Web Apps, and Mobile Apps map to App Development.
  • -Cloud & DevOps maps to Cloud & Infrastructure.
  • -UI/UX Design maps to Web Design/Hosting.
  • -Request for Information and Other retain their corresponding CRM options.

Keep credentials and validation on the server

The browser submits JSON to a public handler; that handler calls ERPNext. ERPNext and SMTP credentials belong in server configuration or managed secret storage. A frontend environment-variable prefix does not protect a secret when the build exposes its value to browser code.

Frappe's REST API creates documents through POST /api/resource/:doctype and supports an Authorization header containing a token formed from an API key and secret. The API user's roles apply to those requests. Design a dedicated integration identity with the permissions the workflow requires, and verify actual Lead creation rather than treating successful authentication as sufficient evidence.

The IHP handler checks field types, lengths, email shape, known project types, timelines, and the expected source value before delivery. Its exact-origin allowlist rejects unrecognized origins, but Origin is not proof of a visitor's identity. CORS does not replace authentication or rate limiting. Rate limiting and other abuse controls need a separate design appropriate to the public endpoint.

Preserve literal text in both CRM notes and email

One normalized inquiry representation reduces drift between delivery paths. IHP builds a plain-text inquiry containing labeled fields, a blank line, and the complete project description. Empty optional fields are labeled Not provided. Both ERPNext and SMTP start from this same representation.

The inspected CRM Note field is a Text Editor, so its content is interpreted as HTML. Before writing the note, the handler escapes ampersands and angle brackets, then converts line breaks to br elements. A visitor's literal <section> text remains visible text instead of becoming an HTML element. Escaping happens before inserting the generated line breaks.

SMTP receives the plain-text version, preserving the original readable message without HTML entities. Verify both representations with ampersands, angle brackets, quotation marks, and multiple lines. Comparing only raw JSON is insufficient: the CRM's rendered Notes tab is where a person must be able to read the original request.

Give each delivery attempt a defined time budget

A request that waits indefinitely gives visitors little guidance and can consume the handler's execution allowance. IHP's current flow attempts ERPNext first with a ten-second deadline. A successful ERP response ends the handler immediately. If ERPNext is unavailable, rejects the request, lacks configuration, or exceeds its deadline, the handler attempts SMTP.

The SMTP wait is bounded at 25 seconds, with separate ten-second connection and greeting timeouts and a twenty-second socket inactivity timeout. Sequential application deadlines consume up to about 35 seconds of waiting, leaving overhead within the deployed sixty-second function limit. These are configured budgets, not a promise about every visitor's end-to-end response time.

Bounding the wait does not reverse an operation already accepted downstream. Transport cleanup cannot guarantee cancellation of an active SMTP delivery. Design the response and operating procedure around that uncertainty; a timeout means the caller lacks a confirmed result, not necessarily that nothing happened.

Use a failure matrix to define recovery

The current handler returns a stable delivery indicator for successful ERPNext or SMTP attempts and a delivery_failed error when neither attempt reports success. SMTP fallback does not create an ERPNext Lead, so the business needs a process for reviewing and reconciling fallback messages. The following matrix separates handler behavior from the follow-up work it requires.

Current delivery behavior and recommended recovery checks
ConditionHandler behaviorRecovery check
Invalid inquiry400 invalid_request; no delivery attemptCorrect identified fields and preserve entered values
ERPNext returns success200 with delivery: erpnext; SMTP is skippedInspect persisted fields and rendered notes during verification
ERPNext fails; SMTP succeeds200 with delivery: smtpReview the fallback mailbox and reconcile with CRM
Both attempts report failure500 delivery_failedCheck destinations before resubmitting after an uncertain timeout
ERPNext accepts but its response is lostERP deadline can trigger SMTP fallbackCheck for the existing Lead before creating another record
SMTP accepts but completion is uncertainHandler may return delivery_failedCheck mailbox receipt; timeout alone cannot establish absence

Scroll horizontally to read all table columns.

Separate duplicate contacts from duplicate submissions

ERPNext documents a CRM setting that allows multiple Leads with the same email address. That business rule concerns contact identity; it does not establish whether two requests represent one submission retried after a timeout or two different project inquiries from the same person.

The current IHP flow has no automatic retry, durable queue, or request deduplication. If ERPNext accepts a Lead before the response times out, fallback email or a visitor's retry can produce another record of the inquiry. The integration therefore makes no exactly-once or zero-loss delivery guarantee.

For a future idempotent design, assign an identifier to each intended submission and reuse it for retries of that submission. Persist the identifier with a processing result and enforce uniqueness at the write boundary. A fresh project inquiry needs a new identifier, even when the email address is unchanged. Simply searching by email before creating a Lead can merge unrelated requests and still race under concurrent execution.

Verify content in the destination, not only the response

Treat tests as evidence for specific layers. Unit tests establish validation and transformation behavior. Local HTTP and SMTP transport tests establish what the handler sends and how deadlines behave. Neither proves that a live ERPNext installation accepts the payload or that an actual mailbox receives the fallback.

Use this checklist with synthetic inquiries and controlled destinations. Record the expected result beside each check so another engineer can repeat it after a schema or form change.

  • -Submit every public service label and compare the stored dropdown value with the mapping contract.
  • -Leave optional fields blank and confirm that notes preserve their unspecified status.
  • -Submit multiple lines, literal markup, and punctuation; compare API readback with rendered CRM notes.
  • -Reject malformed, unsupported, and overlength values without reflecting submitted content in error responses.
  • -Force an isolated ERP rejection and deadline; inspect the complete captured SMTP body.
  • -Fail both isolated destinations; verify delivery_failed and confirm the browser retains entered values.
  • -Restore a destination and verify a subsequent request succeeds.
  • -For an authorized live smoke inquiry, confirm the persisted record or received message using a unique test marker.

Release compatible changes and document the proof

When form labels change, update the backend first so it accepts both old and new payloads during deployment. IHP retained the previous service labels temporarily while adding the public website labels. This matters because visitors can keep an older page open while the current frontend changes.

The September 10 release verification recorded a public-endpoint inquiry whose complete message and fields were confirmed by authenticated ERPNext readback and the Notes tab. A separate controlled fallback check used the same handler and real SMTP configuration in an isolated process; the expected message was confirmed in the receiving mailbox. That fallback check did not change the production ERP configuration.

Those checks support a specific claim: the released integration preserved the tested inquiry in ERPNext, and its fallback delivered the tested content through SMTP. They do not establish a delivery percentage or eliminate future failures. IHP Technology's engineering contribution is the complete contract, compatible mapping, bounded failure behavior, and verification of what reached the destination.

Know when the workflow needs durable processing

If an inquiry must survive beyond the lifetime of the web request, extend the architecture with durable acceptance and background processing. This is a recommendation for a future design, not a feature of the current IHP flow. The browser should only receive an accepted-for-processing result after the inquiry or task is durably recorded.

Cloud Tasks provides persistent task queues and configurable retries, but it uses at-least-once delivery and can execute a task more than once. A worker therefore still needs idempotent effects. Queue retries also have limits; monitoring and a defined recovery path are needed for exhausted attempts.

Before adding that layer, agree on retention, access to stored inquiry content, reconciliation ownership, and the meaning of each status shown to users. The appropriate integration depends on those operating requirements. A server-side form handler with verified content preservation is a practical starting point; durable processing becomes necessary when the business requires recovery beyond the synchronous attempts described here.

Related services

  • Custom Software

    Build secure, scalable custom software with IHP Technology. We design, develop, launch, and support business-critical web and mobile applications.

  • Web Apps

    IHP Technology designs and builds performant web applications, portals, dashboards, and SaaS products with scalable cloud foundations.

  • Security

    Build and improve software with security-minded architecture, access controls, cloud hardening, monitoring, and compliance-aware engineering practices.

Keep reading