webhooks::verify_and_parse checks the signature (HMAC-SHA256 over the app key plus the raw body) and returns a WebhookEvent, an enum with one variant per webhook holding that webhook’s generated model. See webhooks for how TikTok signs and delivers them.
use tiktok_shop_api::{webhooks, Error, WebhookEvent};
/// Call this with the request body exactly as received and the `Authorization` header.fn handle(raw_body: &[u8], authorization: &str) -> u16 { match webhooks::verify_and_parse("APP_KEY", "APP_SECRET", raw_body, authorization) { Err(Error::WebhookSignature) => 401, Err(_) => 400, Ok(WebhookEvent::OrderStatusChange(e)) => { if let Some(data) = &e.data { println!("order {:?} is now {:?} in shop {:?}", data.order_id, data.order_status, e.shop_id); } 200 } Ok(WebhookEvent::ReturnStatusChange(e)) => { println!("return in order {:?}", e.data.and_then(|d| d.order_id)); 200 } Ok(WebhookEvent::Unknown { event_type, .. }) => { println!("unhandled webhook type {event_type}"); 200 } // WebhookEvent is non_exhaustive: new webhook types arrive with new releases. Ok(_) => 200, }}
fn main() { println!("{}", handle(br#"{"type":9999}"#, "signature"));}- Verify the raw body. Pass the body exactly as received. Never re-serialize it: changed whitespace or key order makes the signature fail.
- Parsing is strict.
webhooks::parsereturnsError::Webhookwhen the body is not a JSON object,typeis missing or is not an integer, or a known type is missing a required field or has it null. A known type missing a required field is a parse error. - Unknown types are kept. A type this SDK does not know comes back as
WebhookEvent::Unknown. BecauseWebhookEventisnon_exhaustive, end yourmatchwith a catch-all arm. - Type names.
webhooks::EVENT_TYPESmaps a type number to its name;1isORDER_STATUS_CHANGE. - IDs keep every digit. IDs such as
shop_idare exact whether TikTok sends them as strings or as JSON numbers.
A bad signature is Error::WebhookSignature, whatever the body holds. Answer it with 401 and a parse failure (Error::Webhook) with 400, so neither is mistaken for success. webhooks::verify returns a plain bool if you want to check the signature without parsing.