Demo project

Website to amoCRM: form requests become deals

A site form carries the request all the way to a deal card in the CRM, with validation, retries on failure and a delivery log.

integration and test bench · Node.js · amoCRM API · WordPress · PHP

in progressDeal amount is not passed from the form

1 requestcontact and deal created together
3 checksrequest filtered before the CRM call
10 of 10batch requests reached deals
3 attemptsreceiver retries the CRM call
4 statesof a request in the site log
Demo first screen: Website to amoCRM: form requests become deals

The task

A request from a website usually ends up in an inbox and in a manager’s notebook. One call never happens, one phone number goes missing, and by Friday nobody can say how many enquiries came in or what became of them. This integration exists so that a request from the form reaches a deal card in the CRM on its own, and so it is visible what arrived and what got stuck.

The project is a demonstration. The company Volokno is invented, the amoCRM account is a trial opened on 27 August 2026, and the services in the demo deals come from the price list of my own demo landing page, ChistoDom. No real customer data is involved.

The solution

A request travels through three links: the form on the site, the receiver, amoCRM.

  • The WordPress form writes the request into its own table first and only then tries to send it. If the receiver is silent, nothing is lost: the request stays in the queue and WP-Cron picks it up for another try every five minutes - up to five attempts in total, after which the request is marked as not delivered. The site’s log shows the state of every request: accepted, delivered, awaiting retry, not delivered.
  • The receiver validates before it ever touches the CRM. A name shorter than two characters, an incomplete phone number, a missing consent to personal data processing - refused with a readable reason. Such a request never lands in the pipeline, so nobody has to clean it out later.
  • In amoCRM the contact and the deal are created in a single request, and the body of the enquiry is attached as a note: name, phone, what the person needs, the page, the consent mark, the time. The manager sees what the customer actually wrote instead of a bare “website enquiry”.
  • The Source and Comment fields are created by the bench on first run and looked up by name afterwards instead of being created again.

The live run on 27 August: the CRM receiver was started on the same port the site plugin was already posting to, the Volokno form sent a request, and a deal appeared in amoCRM with the note and the Source and Comment fields filled in. A separate script fills the pipeline with invented requests: ten requests and ten created deals in one run, thirty of them in the bench log across three runs.

Details that are easy to miss

  • The failure in the log is real. The first attempt of one request goes to a port where nothing is listening, and the second goes to the live address. Nothing is written by hand: the retry sits in the log where a retry actually happened.
  • Requests are spaced out to stay under the amoCRM limit of seven per second, and retries wait longer each time. The receiver retries only network failures and server errors; a 4xx response is not retried.
  • The receiver’s response distinguishes three different kinds of failure: the body could not be parsed, the request is incomplete, the deal was not created. The site stores the response code in its own log, but for now it schedules the same retry for all three.
  • The integration log holds no phone numbers and no email addresses, only the service, the amount, the attempt history and the deal number. The access token is never printed anywhere: screenshots are taken from this bench for the portfolio.
  • The receiver shares its format with a neighbouring bench that sends requests to Telegram: same fields, same checks. Its port comes from an environment variable, so for the run it took over the Telegram bench’s port and the site plugin needed no reconfiguration.

What is still open

  • A deal created from the form arrives with a zero amount. The form does not pass the amount, and the plugin’s table has no column for it yet, so the fix starts at the form: calculate the sum from the price list and carry it through storage, delivery and the receiver.
  • The confirmation line under the submitted form still says the notification went to the master over Telegram: that text is hardcoded in the plugin and has not been rewritten for the CRM path.
  • The site does not read the reason for a refusal: it will resend an obviously incomplete request five times instead of showing the problem right away.
  • One screenshot is missing, the one showing the form and the resulting deal side by side. The trial account ends around 10 September 2026 and the run cannot be repeated on it after that. The bench itself is unaffected: it moves to another account by replacing the file with the address and the token.