Developer notes
Architecture
Section titled “Architecture”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 |
Hooks used
Section titled “Hooks used”| 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 |
APIs of other add-ons it calls
Section titled “APIs of other add-ons it calls”- 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 withLinks::reviewUrl().
Every call is guarded by Partners::*Ready() (active add-on, minimum version, function or class exists).
Tables
Section titled “Tables”| 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).
Security
Section titled “Security”- 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.
Full page cache (4.21)
Section titled “Full page cache (4.21)”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.
Testing without a live number
Section titled “Testing without a live number”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.