You run a WooCommerce store and you want a customer to get a text when their order ships. Every tutorial for that starts the same way: install an SMS plugin, then go create a Twilio account. If you sell vapes, CBD, kratom, crypto-adjacent goods, or anything else carriers treat as high risk, that path dead-ends at a campaign registration screen that rejects your business before a single message goes out, whether the text you wanted to send was "50% off restock" or just "your order shipped."
Here's what's actually happening at that wall, and a way to send the text anyway using webhooks WooCommerce already has and an SMS gateway that doesn't route through a carrier's business-messaging registry at all.
The SMS plugin path for WooCommerce runs through Twilio
WooCommerce doesn't ship with SMS. Every "add text notifications to your store" guide points to a plugin, and the official one sold directly by WooCommerce.com is built entirely on Twilio. To use it you create a Twilio account, copy an Account SID and Auth Token out of the Twilio console, buy a Twilio phone number, and paste all three into the plugin's connection settings before it will send anything (WooCommerce Twilio SMS Notifications documentation). The plugin itself is free to configure; the sending account underneath it is a Twilio account, with Twilio's rules attached.
Third-party SMS add-ons for WooCommerce (ShopMagic's Twilio add-on, Uncanny Automator's SMS actions) work the same way: a WooCommerce-side trigger wired to a Twilio-side send. There's no WooCommerce-native SMS path that skips Twilio, because WooCommerce doesn't operate a messaging network. It's a store plugin. Somebody still has to own the carrier relationship, and by default that's Twilio.
That's a non-issue if you sell candles. It's a hard stop if you sell something Twilio's underlying carrier registry won't approve.
Where the wall actually is
Twilio numbers send business text through A2P 10DLC, the carrier-mandated system for vetting application-to-person messaging on standard 10-digit numbers. Before a WooCommerce order notification can leave a Twilio number, Twilio has to register a Brand and a Campaign for that number with The Campaign Registry, and the carriers have to approve the campaign based on what kind of business it's attached to and what it says it will send.
If your brand registration mentions cannabis, CBD, THC, or a handful of other flagged terms, Twilio rejects the campaign outright with a specific error: 30940, "Campaign rejected: Cannabis, CBD, or illegal substance content detected" (Twilio error reference, 30940). That rejection happens at registration, before any message is queued. It doesn't matter that the actual text you want to send is a shipping confirmation with no marketing language in it at all. The campaign is what gets classified, not the individual message, and a rejected campaign sends nothing.
Vape, CBD, and cannabis-adjacent retail fall under a carrier content category the industry calls SHAFT-C (sex, hate, alcohol, firearms, tobacco, cannabis), and it's one of several restricted use-case categories Twilio lists for A2P 10DLC registration alongside things like debt collection and short-term lending (Twilio's list of campaign use case types). None of that is a Twilio quirk you can appeal your way around with a better-written campaign description. It's the carrier layer working as designed, and it applies to every A2P aggregator, not just Twilio.
The webhook WooCommerce already has
WooCommerce ships with a working webhook system, and it's worth using regardless of which SMS path you take. Under WooCommerce > Settings > Advanced > Webhooks, you can create a webhook, pick a topic such as order.created or order.updated, and give it a delivery URL. When that event fires, WooCommerce POSTs the order data as JSON to your URL, with headers identifying the topic (X-WC-Webhook-Topic) and, if you set a secret, an HMAC-SHA256 signature (X-WC-Webhook-Signature) so the receiving end can verify the payload wasn't forged (WooCommerce webhooks developer documentation).
That webhook is the trigger. It doesn't send a text by itself, and it doesn't know anything about Android Texter's request format, so it needs somewhere to land. There are two ways to build that landing point, depending on whether you want to write code.
Wiring order events to a phone that isn't gated
If you're comfortable in functions.php or a code-snippets plugin, you don't need the webhook admin screen at all. WooCommerce fires an internal action, woocommerce_order_status_changed, every time an order moves between statuses, and you can hook a function directly to it:
add_action( 'woocommerce_order_status_changed', function ( $order_id, $old_status, $new_status, $order ) {
if ( $new_status !== 'completed' ) {
return;
}
$phone = $order->get_billing_phone();
if ( ! $phone ) {
return;
}
wp_remote_post( 'https://androidtexter.com/api/v1/messages/send', array(
'headers' => array(
'X-API-Key' => getenv( 'ANDROID_TEXTER_KEY' ),
'Content-Type' => 'application/json',
),
'body' => wp_json_encode( array(
'phone' => $phone,
'message' => sprintf( 'Order #%s has shipped.', $order->get_order_number() ),
) ),
) );
}, 10, 4 );
That's illustrative, not a copy-paste guarantee. Android Texter's send endpoint (POST /api/v1/messages/send, authenticated with an atx_-prefixed key in the X-API-Key header) is fully documented in the interactive Swagger UI at androidtexter.com/api/swagger and the OpenAPI 2.0 spec at /api/openapi.json. Pull the exact field names and required parameters from there before you ship this to production. The API key itself is generated from the dashboard at /dashboard/settings/api-keys, and it should live in an environment variable or a secrets manager, not hardcoded in a theme file.
Two things worth planning around while you're in there. First, the send endpoint accepts a scheduled_at timestamp, so a "your order ships tomorrow at 9am" message can queue ahead of time instead of firing the instant a status changes. Second, it supports broadcast to up to 500 phones in a single call, which matters if you're clearing a backorder queue rather than notifying one customer at a time, though the API is rate-limited to 10 send requests per second with a burst of 20, so a very large batch still needs to be chunked.
If you'd rather not touch code
The no-code version of the same idea is to point the WooCommerce webhook at an automation platform instead of a custom endpoint: Zapier, Make, or n8n can all receive the webhook's JSON payload, pull the order number and billing phone out of it, and call Android Texter's API as the next step. This blog has separate setup guides for sending SMS from Zapier, Make, and n8n that cover the Android Texter side of that connection in detail; the WooCommerce side is just picking order.created or order.updated as your trigger topic in the webhook screen described above.
What this doesn't fix
Routing the message through a phone instead of a Twilio-owned 10DLC number gets you past carrier campaign gating. It does not touch the Telephone Consumer Protection Act, and it shouldn't be treated as though it does. If a text is a marketing message rather than a transactional one tied to an order the customer placed, you still need prior express consent, you still need to honor STOP and the other standard opt-out keywords, and you're still the one holding that liability, not the gateway. A WooCommerce checkout field collecting a phone number is not automatically consent to text that number about anything you want. Keep a record of what the customer agreed to and when.
Frequently Asked Questions
Does WooCommerce have a built-in SMS notification feature?
No. WooCommerce is a WordPress plugin with no native messaging network. Every SMS option, official or third-party, is a store-side trigger connected to an outside SMS provider, and the provider WooCommerce.com's own extension uses is Twilio.
Why would a WooCommerce store's SMS plugin fail for a CBD or vape shop specifically?
Because the plugin's sending account has to register an A2P 10DLC campaign with Twilio, and Twilio rejects campaigns that mention cannabis, CBD, or related terms at registration (error 30940), before any message, marketing or transactional, is ever sent.
Do I need to register a 10DLC campaign to text customers from WooCommerce through Android Texter?
No. Android Texter routes messages through a real Android phone on a real carrier line, which is person-to-person SMS, not application-to-person traffic. There's no campaign to register and no brand to get approved. The TCPA still governs who you can text and why.
Can I send an order photo or tracking link, not just plain text?
Yes. Android Texter's send endpoint accepts media URLs for MMS, so a shipped-order text can include a photo or a tracking link the same way a plain text can, using the same POST /api/v1/messages/send call.
My WooCommerce store's Twilio-based SMS setup just got suspended. What now?
That's usually the campaign getting flagged after the fact rather than at initial registration, and it's largely unappealable in restricted categories. Swapping the sending side of your webhook or status-change hook to Android Texter's API, as shown above, replaces the blocked account without changing anything else about your store.
If your WooCommerce store sells something the carriers won't register, the fix isn't a better Twilio campaign application. It's routing the message through a channel that was never gated in the first place. Android Texter connects to the same order-status hooks and webhooks WooCommerce already gives you, sending through a real phone instead of a carrier-registered number.
