SMS Notifications
SMS messaging via Twilio. Used today for transfer + QR-pay OTPs. Optional for confirmation messages.
Setting up?
Twilio credentials + per-event SMS toggles live under Notifications Settings → SMS / Twilio section.
What It Does
| For | Means |
|---|---|
| Customer | Gets a real-time SMS for OTPs (more secure than email-only). Optional confirmations after big actions |
| Admin | Twilio integration is plug-and-play. SMS failures never break the underlying flow — email fallback always works |
Provider
Twilio is the default and only first-class integration. Build a custom provider via filter for MSG91, Plivo, Vonage, etc.
Setup
Wallet → Settings → Notifications → SMS / Twilio
| Field | Notes |
|---|---|
| Enable | global toggle |
| Account SID | from Twilio console |
| Auth Token | from Twilio console |
| From-number | E.164 format (e.g. +15551234567); must be a verified Twilio number |
| Country code default | E.164 prefix to add when customer's phone is missing it |
| Test recipient | optional — sends every SMS here when test mode is on |
What Triggers an SMS
| Event | Default | Recipient |
|---|---|---|
| Transfer OTP | ON | sender |
| Transfer received | OFF | recipient |
| Withdrawal approved | OFF | customer |
| Withdrawal paid | OFF | customer |
| QR pay OTP (when amount > threshold) | ON | sender |
Each toggle independent.
Customer Phone Numbers
Plugin reads phone from:
- The wallet plugin's own phone meta (set during registration if you've added the field)
- WooCommerce billing phone (fallback)
If neither is set → SMS skipped silently. Email-only flows still work.
Templates
Each event has an editable template with placeholders:
| Placeholder | Source |
|---|---|
{OTP} | one-time code |
{AMOUNT} | currency-formatted |
{BALANCE} | post-event balance |
{SENDER} | sender display name |
{RECIPIENT} | recipient display name |
{SITE} | site title |
{METHOD} | payout method name |
{REF} | transaction reference |
{ETA} | hold-period text |
Default OTP template:
Your {SITE} wallet OTP is {OTP}. Valid 10 min. Do not share.
Non-Fatal Failures
Twilio downtime is treated as non-blocking:
- Transfer OTP failure to send via SMS → email OTP still goes out → transfer flow proceeds
- Confirmation SMS failure is logged, not raised
- Customer never sees a Twilio error
Means transfers never break because of SMS issues.
Test Mode
Set the test recipient in settings → every outbound SMS reroutes to that number instead of the real customer. Useful for QA.
Cost Tracking
The plugin doesn't track Twilio cost. Use Twilio's own usage dashboard.
Common Scenarios
Customer OTP didn't arrive
- Check the customer's phone number is set
- Verify Twilio creds + From-number is verified
- Check Twilio console → Logs → look for the destination number
- Email OTP should still arrive — if neither, check WC mailer
Block SMS to specific countries
Twilio has Geo Permissions per account — disable countries you don't want billed for. Plugin returns Twilio's 21408 error for unauthorised geos.
Different SMS provider
Implement the provider interface and register via filter. See dev section.
When Something Goes Wrong
| Problem | Fix |
|---|---|
| OTP not received | Phone meta missing; Twilio creds wrong; from-number not verified; check Twilio console |
21408 Twilio error | Geo permission for that country not enabled in Twilio |
21610 recipient unsubscribed | Customer texted STOP — they must text START to opt back in |
| SMS arriving but blank | Template placeholder unresolved; check spelling |
| Webhook signature fails | Re-copy the auth token; rotate if compromised |
For developers — hooks + custom provider
Hooks
| Hook | Type | When |
|---|---|---|
wkwp_sms_provider | filter | swap the SMS provider class |
wkwp_sms_template_<event> | filter | mutate the template |
wkwp_sms_recipients_<event> | filter | mutate the To list |
wkwp_sms_send | filter | mutate the final body before send |
wkwp_sms_sent | action | after API success |
wkwp_sms_failed | action | after API failure |
Custom provider
Implement the WKWP_SMS_Provider interface (single send() method) and register:
add_filter( 'wkwp_sms_provider', function() {
return 'My_MSG91_Provider';
} );
Webhook delivery status
Twilio can POST status callbacks to /wp-json/wkwc_wallet/v1/twilio_webhook. Subscribe in your Twilio console → status callbacks. Plugin updates internal SMS row when status tracking is enabled.
Rate limit
Built-in: max 1 SMS per minute per recipient per event. Filterable.
