Prompt
How do I build transactional notifications for order updates and password resets?
Latest observation
To build transactional notifications for things like order updates and password resets, think of them as event-driven, user-specific messages that must be delivered reliably and quickly.
1) Split transactional from marketing
Keep these separate from promotional email/SMS/push:
- Transactional: order confirmed, shipped, delivered, password reset, OTP, receipt
- Marketing: newsletters, offers, upsells
Why:
- different sending rules
- higher deliverability expectations
- different consent/compliance requirements
2) Use events as the trigger
Your app should emit events when something important happens.
Examples:
order.createdorder.paidorder.shippedorder.deliveredpassword_reset.requestedpassword_reset.completed
A notification service listens for these events and sends the right message.
3) Create notification templates
Have templates per channel and per event.
Example templates:
- Email: “Your order #1234 has shipped”
- SMS: “Order #1234 shipped. Track: …”
- Push: “Your package is on the way”
For password reset:
- Email: reset link
- SMS: one-time code
- Push: security alert, if applicable
Use variables:
{{customer_name}}{{order_id}}{{tracking_url}}{{reset_link}}{{expires_in_minutes}}
4) Prefer an async delivery pipeline
Don’t send notifications directly inside the request that updates the order or requests a reset.
Instead:
- App writes the business change to DB
- App publishes an event
- Queue/worker picks it up
- Notification service renders template
- Provider sends message
- Log result and retry if needed
This keeps your app fast and avoids lost messages if a request fails midway.
5) Make it reliable
Use:
- message queue: RabbitMQ, SQS, Kafka, Pub/Sub
- idempotency: avoid duplicate sends if the same event is processed twice
- retries with backoff
- dead-letter queue for failures
- audit logs for sent notifications
For example, if order.shipped is processed twice, use an idempotency key like:
notification:order.shipped:order123:user456
6) Handle channel selection
Choose the right channel based on urgency and user preference.
Good defaults:
- Password reset: email + optional SMS OTP
- Order updates: email, SMS for major milestones, push if user enabled it
Rules might look like:
- shipped -> email + push
- delivered -> email
- password reset -> email only, or email + SMS if high-risk
7) Secure password reset flows
For password resets, use strong security practices:
- generate a single-use, time-limited token
- store only a hashed token server-side
- token expires in 10–30 minutes
- invalidate old tokens when a new one is generated
- don’t reveal whether an email exists (“If an account exists, we sent instructions”)
- log reset requests and completions
- optionally notify user on successful password change
8) Design order notifications carefully
For order updates:
- trigger based on real business state changes
- include order ID, status, tracking info
- avoid sending too many messages
- group updates when possible
- localize time, language, and currency
Example lifecycle:
- order placed
- payment confirmed
- packed
- shipped
- out for delivery
- delivered
- delayed/cancelled
9) Add observability
Track:
- sent
- delivered
- bounced
- failed
- retried
- opened/clicked if applicable
This helps you catch:
- provider outages
- template bugs
- bad data
- delivery issues
10) A simple architecture
A common setup:
- Core app: updates orders, auth, accounts
- Event bus / queue: carries notification events
- Notification service: decides channel + template
- Provider integrations: SendGrid, SES, Twilio, Firebase, etc.
- DB: stores notification logs and preferences
Example flow: password reset
- User submits email
- Auth service creates reset token
- Save hashed token with expiry
- Publish
password_reset.requested - Notification worker sends email with reset link
- User clicks link
- Token validated and password changed
- Publish
password_reset.completed - Send confirmation email
Example flow: order shipped
- Shipping system marks order as shipped
- Emit
order.shipped - Notification worker loads customer preferences
- Render email/SMS template with tracking URL
- Send message
- Record status in notification log
Recommended minimum features
If you’re starting out, implement:
- event-based triggers
- email templates
- a queue/worker
- retry logic
- notification logs
- tokenized password reset flow
- user notification preferences
If you want, I can also provide:
- a database schema for notifications and reset tokens,
- a sample implementation in Node.js / Python / Java, or
- a reference architecture diagram.