There's no native SMS subscriber in Business Events — the built-in options stop at email, import scenario, and mobile push. Getting an SMS out on a business event means the same custom-subscriber pattern used for webhooks, pointed at an SMS gateway instead of a generic HTTP endpoint.
Picking a gateway for the region
For teams operating across East and Southern Africa, Africa's Talking is usually the more practical choice over Twilio purely on local carrier reach and cost per message — Twilio's coverage and pricing skew toward US/EU traffic. Both expose a simple REST API for sending a message to a number, which is all a Business Events subscriber needs to call.
The subscriber, and the phone number field
The recurring problem is not the API call — it's that the phone number field on the source record is free text, entered inconsistently (with or without a country code, with spaces, with a leading zero instead of +254). Normalize the number before sending, and fail loudly rather than silently swallowing a malformed number, since a silently-dropped SMS looks identical to a successfully-sent one from inside Acumatica.
public void OnBusinessEvent(SOOrder row)
{
var raw = row.ShipToPhone;
if (!TryNormalizeMsisdn(raw, defaultCountryCode: "254", out var msisdn))
{
PXTrace.WriteWarning($"SMS skipped for {row.OrderNbr}: unusable phone number '{raw}'");
return;
}
PXDatabase.Insert<OutboundEventQueue>(
new PXDataFieldAssign("RefNbr", row.OrderNbr),
new PXDataFieldAssign("EventType", "OrderConfirmedSms"),
new PXDataFieldAssign("TargetMsisdn", msisdn),
new PXDataFieldAssign("Status", "Pending"));
}
Cost is a real constraint, in a way email isn't
Email subscribers rarely need a second thought about volume. SMS does — every message has a per-unit cost, and a trigger condition that's slightly too broad (firing on every order update instead of only on confirmation) turns into a real, recurring bill instead of just noisy logs. Scope the trigger condition to the field-changed pattern described in the Business Events deep dive, not the broader row-updated pattern, and keep an eye on gateway spend the same way you'd watch any metered external API.
Sending the API call successfully only means the gateway accepted the message — it doesn't mean the carrier delivered it. Most SMS gateways offer a delivery-status webhook; if delivery confirmation matters, that webhook needs its own small endpoint to receive it, separate entirely from the business event that triggered the send.
Fallback to email when SMS fails
Because SMS delivery is less reliable than email and costs more per attempt, a sensible pattern for anything customer-facing is to treat SMS as the fast path and fall back to the email subscriber (see the email article) when the gateway call fails after retry, rather than silently dropping the notification.
Wrapping up
SMS on Business Events is a custom subscriber calling a regional gateway, with phone number normalization and cost-aware trigger scoping doing more of the reliability work than the actual API call.
Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.