Operations

Abandoned checkout for digital products on WhatsApp: a recipe for Kiwify, Hotmart and Eduzz

Someone who reaches checkout and leaves almost bought. Digital product platforms know this and send an abandoned cart event by webhook. This recipe shows what each one sends, with what delay, how to test the flow before any customer and how to write the two recovery messages without sounding like pressure.

Published on · 4 min read

This article is also available in: Português · Español

What each platform sends, and when

PlatformEventPhoneDelay and details
------------
Hotmart (2.0.0)PURCHASE_OUT_OF_SHOPPING_CARTdata.buyer.phone, with country codeStarts when the person fills in name or email; Hotmart checks every 30 minutes
Kiwifycarrinho_abandonadoBlock of the cart payload; check in Test WebhookOwn format, no webhook_event_type or order_status
Eduzzcart_abandonment (reference sun.cart_abandonment)data.customer.phoneCarries data.saleRecoveryUrl, the checkout link to come back

In practice, the message never arrives the second the person closes the tab. On Hotmart, the delay of up to 30 minutes is built into the event. Write the text knowing that: 'I saw you started signing up' works better than 'you just left'. Details for each platform on Hotmart, Kiwify and Eduzz.

No-code path: the Recuperar vendas assistant

In the ZapZap dashboard, open Fluxos and click Recuperar vendas. Choose the platform, the goal 'Recover abandoned cart' and the number. The assistant creates the webhook and a flow already linked, with an immediate message and a reminder 30 minutes later, and shows the URL in the format https://api.zapzapapi.com/api/webhooks/flow/{secret}. Paste the URL into the platform, tick the cart event and save.

If you enter the platform's key in the assistant, ZapZap validates the origin of every event: Hotmart's hottok in the X-HOTMART-HOTTOK header, the HMAC-SHA1 of Kiwify's signature parameter and the HMAC-SHA256 of Eduzz's x-signature. Without a key, only the URL secret protects the webhook. ZapZap detects on its own where phone, name and product are in the payload and ignores the same phone on the same flow for 10 minutes, which absorbs redeliveries.

Test before any customer

Do not wait for a real customer to abandon a cart to find out whether it works. Fire a fake event with your own number using curl and read the response. The response {"ok":true,"triggered":1} says the flow fired; triggered: 0 says no phone was detected or the same number already received this flow in the last 10 minutes. Then open the webhook in the editor and see the sample and the field detected as the phone.

Terminal (curl)

# Test the recovery flow with a fake abandoned cart (your own number only)
curl -X POST 'https://api.zapzapapi.com/api/webhooks/flow/YOUR_SECRET' \
  -H 'Content-Type: application/json' \
  -d '{"id":"test-cart-1","event":"PURCHASE_OUT_OF_SHOPPING_CART","version":"2.0.0",
       "data":{"product":{"id":1,"name":"Test course"},
               "buyer":{"name":"Maria Test","email":"maria@example.com","phone":"5511999990001"},
               "offer":{"code":"abc123"}}}'
# expected: {"ok":true,"triggered":1}   (triggered 0 = no phone detected, or same number within 10 minutes)

The two messages: help first, urgency later and only if it is true

The first message should offer help and not demand the purchase. Example: 'Hi, Maria. I saw you started signing up for course X and did not finish. Did you have a question about the content or the payment? I can help here.' It names the product, accepts that the person may have given up and opens the conversation.

The second, 30 minutes later, only makes sense if there is a real reason: the link back (on Eduzz, saleRecoveryUrl), a payment condition you actually offer, a batch deadline that actually exists. Made-up scarcity burns trust and is the kind of thing people report. After the second, stop: ZapZap does not fire a third message on its own, and neither should you.

An abandoned cart is a contact derived from a started purchase: the person left their phone at your checkout. That is different from prospecting a cold list. Even so, make it clear on the checkout page that WhatsApp contact may happen, offer an exit in every message and respect the request. The guide on LGPD on WhatsApp details the legal basis.

And an honest limitation: ZapZap's generic webhook accepts 120 requests per minute per webhook (above that it answers 429) and fires on the detected phone; if the phone arrives without the area code, as can happen with Hotmart purchases, the flow does not fire and you need an endpoint of yours to join area code and number. ZapZap connects numbers through an unofficial, managed channel, so no recovery is free of blocking risk.

Quick summary

  • Hotmart checks carts every 30 minutes; Eduzz brings the link back in saleRecoveryUrl; Kiwify uses its own payload.
  • The Recuperar vendas assistant, under Fluxos, builds the webhook and flow with no code and validates the signature when you enter the key.
  • Test with curl on your number: triggered: 1 fires, triggered: 0 calls for a phone diagnosis.
  • At most two messages, the first offering help and the second only with a real reason.

Also read

Frequently asked questions

Does the message go out as soon as the person leaves checkout?

No. On Hotmart, the event is checked every 30 minutes. On the other platforms the delay is not documented the same way. Write the message without pretending the customer just left.

Does it work with any platform?

The assistant has Kiwify, Hotmart, Eduzz, Monetizze and Yampi. For others, the generic webhook in the flow editor detects the phone in the payload if it arrives complete. If the payload has no phone, as with Asaas, the path is an endpoint of yours.

The flow answered triggered: 0. What should I do?

Look at the webhook sample in the editor. Common causes: the phone did not arrive or does not have 10 to 13 digits, the phone came from another field, or the same number already received the flow in the last 10 minutes.

Can I send a third message?

Technically you can, but you should not. After two messages, whoever did not answer probably does not want it. Insisting raises reports, and reports are the main cause of a number being limited.

Do I need to validate the webhook signature?

It is recommended. Without the platform key saved, anyone who finds the URL can fire the flow. With the key, ZapZap rejects with 401 any event whose signature does not match.

Can I use the assistant on an affiliate product?

Only if the producer releases the buyer's data, including the phone. Without that release, the webhook arrives without a phone and the flow does not fire.

Recover the sale that almost happened

Use the Sales Recovery assistant or your own endpoint. R$15 per active number per month, with a welcome credit subject to the current campaign.