Skip to content

Developer notes

WhatsApp Commerce never talks to Meta itself. It builds template messages and queues them in Telegram & WhatsApp Order Notifications 1.1+ (Service::enqueue() with a Messaging\Message of channel whatsapp), which sends them with its WhatsApp Cloud API provider, retries, records delivery reports and handles opt-outs. Incoming replies arrive on that add-on’s signed webhook and reach this add-on through its hook kv_order_notifications_messaging_inbound.

Class Role
Config Settings, flows, Meta categories, log statuses, cron key
Partners Which Kavio Labs add-ons are active and recent enough (ONM 1.1, ORG 1.1, ACR 1.2, RRE, PSA)
Sender Phone normalization, consent rule, template / free-form sends through Order Notifications, log rows
Flows COD (Order Risk Guard hook + built-in), cart (ACR API + built-in capture), payment, review (RRE + built-in)
StockChannel ChannelInterface of Price Drop & Back-in-Stock Alerts
Tracker Inbound replies, recovered orders
Runner One cron run (lock in ?:kv_wac_state)
Stats, Templates, Log, Links, State Report, template suggestions, log queries, signed links, state
Hook Use
kv_order_notifications_messaging_inbound Quick-reply payloads confirm_<order> / cancel_<order>; other replies mark the answered message
kv_order_risk_guard_send_code Sends the COD confirmation (with the code) on WhatsApp and adds whatsapp to the channels
kv_price_stock_alerts_register_channels Registers the WhatsApp channel
change_order_status_post Built-in COD confirmation on order placement, built-in review planning, “payment received” after a reminder
place_order_post Cart and stock recoveries (top-level order only)
delete_user Removes the account and phone from the log rows
  • Order Risk Guard 1.1: fn_kv_order_risk_guard_confirm_order($order_id, 'whatsapp', $reason), fn_kv_order_risk_guard_cancel_order(...).
  • Abandoned Cart Recovery Pro 1.2: fn_kv_abandoned_cart_recovery_get_abandoned_carts(), fn_kv_abandoned_cart_recovery_get_recovery_link(['channel' => 'whatsapp', 'coupon' => ...]), fn_kv_abandoned_cart_recovery_mark_link_failed().
  • Review Request Emails: reads ?:kv_rre_requests (sent, not reviewed) and links with Links::reviewUrl().

Every call is guarded by Partners::*Ready() (active add-on, minimum version, function or class exists).

Table Contents
?:kv_wac_messages One row per message or skipped attempt: flow, reference (order, ACR cart, saved-cart time, RRE request, product), order, user, phone (E.164), Meta category, template, language, Order Notifications message id, status (Q queued, P planned, X not sent with the reason in note), reply (confirm/cancel/text), click, recovered order and total
?:kv_wac_state Last run, run lock, “payment received” markers

Messages in the queue of Order Notifications carry the events wac_cod, wac_cart, wac_payment, wac_review, wac_stock, wac_reply (their names are added to its log on install and removed on uninstall).

  • Quick-reply payloads are accepted only from the phone number of the order they name.
  • A second answer for the same checkout changes nothing.
  • The built-in cart link is signed (HMAC-SHA256 with a per-store secret) and only records the click before it opens the cart.
  • The cron URL needs the key; the console command runs only from the console.

No storefront templates, scripts or blocks. Storefront output only on kv_whatsapp_commerce.cart (redirect, Cache-Control: no-store) and the cron URL. Cron runs write to the own state table, never to ?:storage_data.

Order Notifications sends to <base>/whatsapp when KV_ORDER_NOTIFICATIONS_MESSAGING_API_BASE is defined in local_conf.php of a development store; point it at a local mock of the Graph API and post signed webhook bodies (X-Hub-Signature-256 with the app secret) to its webhook URL to simulate button taps.