How to add SendingThx delivery notifications and thank-you relays to a custom checkout.
SendingThx enables you to send delivery notifications and capture thank-you replies via SMS. When a customer purchases a gift, they can opt in to receive SMS notifications when the package arrives — and recipients can reply with a message of gratitude that's relayed straight back to the purchaser.
Cost: $0.50 per gift or package sent. Flat rate covers all SMS — delivery notification to recipient, confirmation to sender, and the recipient's reply if they send one. No monthly fees.
That's it. SendingThx will charge $0.50 per gift or package sent.
The SMS consent widget collects permission from customers before SendingThx sends them notifications. It's optimized for mobile with a space-efficient design, while keeping all compliance text fully visible.
In your checkout HTML, add this to the <head> section:
<script src="https://www.sendingthx.com/consent-widget.umd.min.js"></script>
This is hosted directly on sendingthx.com, so it always serves the current version — no separate CDN account or repo access required.
In your checkout form, add this where you want the consent section to appear:
<div id="sendingthx-consent"></div>
After your Stripe Elements initialization, mount the widget:
SendingThxConsent.mount('#sendingthx-consent', {
onConsent: (data) => {
// Save consent data to your form
window.sendingthxConsent = data;
},
});
The default checkbox text includes full Twilio compliance language (SMS & data rates, HELP/STOP) — no customization needed unless you want shorter labels.
The consent widget is the only additional field you need to add — names are extracted automatically from Stripe's payment data.
Stripe's Payment Element collects: billing name (sender), shipping name and address (recipient).
The consent widget collects: SMS consent checkboxes, phone numbers for sender and recipient, and an optional occasion and gift note.
<form id="checkout-form">
<!-- Stripe Payment Element (collects payment + shipping details) -->
<div id="payment-element"></div>
<!-- SendingThx SMS Consent Widget -->
<details open>
<summary>🎁 Add delivery text notifications</summary>
<div id="sendingthx-consent"></div>
</details>
<button type="submit">Complete Purchase</button>
</form>
When the customer submits the form: confirm the PaymentIntent with Stripe, extract names from Stripe's billing and shipping details, call the SendingThx API with order details and consent data, then redirect to your success page.
app.post('/api/checkout', async (req, res) => {
const {
paymentIntentId,
senderConsent, senderPhone,
recipientConsent, recipientPhone,
occasion, giftNote,
} = req.body;
const paymentIntent = await stripe.paymentIntents.retrieve(paymentIntentId);
if (paymentIntent.status !== 'succeeded') {
return res.status(400).json({ error: 'Payment not completed' });
}
// Names come from Stripe's billing_details / shipping — see full guide
// for the parseFullName() helper.
if (senderConsent && recipientConsent) {
await fetch('https://api.sendingthx.com/api/v1/orders', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.SENDINGTHX_API_KEY}`,
},
body: JSON.stringify({
stripe_payment_intent_id: paymentIntentId,
sender_phone: senderPhone, sender_consent: senderConsent,
recipient_phone: recipientPhone, recipient_consent: recipientConsent,
occasion, gift_note: giftNote,
}),
});
}
res.json({ success: true, redirectUrl: '/success' });
});
document.getElementById('checkout-form').addEventListener('submit', async (e) => {
e.preventDefault();
const result = await stripe.confirmPayment({
elements,
confirmParams: { return_url: `${window.location.origin}/success` },
redirect: 'if_required',
});
if (result.error) return console.error(result.error);
const consentData = window.SendingThxConsentData?.() || {};
const response = await fetch('/api/checkout', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
paymentIntentId: result.paymentIntent.id,
senderConsent: consentData.senderConsent || false,
senderPhone: consentData.senderPhone,
recipientConsent: consentData.recipientConsent || false,
recipientPhone: consentData.recipientPhone,
occasion: consentData.occasion,
giftNote: consentData.giftNote,
}),
});
if (response.ok) window.location.href = '/success';
});
Log in to sendingthx.com/dashboard → Usage & Billing to confirm the test event is listed. The $0.50 charge appears as a Stripe invoice on your next billing cycle — check Invoices in your Stripe Dashboard.
From sendingthx.com/dashboard, under Settings, you can enable or disable the gifter-reply relay and view the Twilio compliance language included in every message. Under Integrations, you'll find your SendingThx API key — treat it like a password, keep it out of client-side code, and rotate it if it's ever exposed.
SMS not received — verify the recipient phone is in E.164 format (+1 country code plus 10 digits), confirm the order shows up in your SendingThx dashboard.
Stripe Connect authorization failed — make sure you completed the OAuth flow at sendingthx.com/connect and that your Stripe account is in live mode, then try disconnecting and reconnecting.
API key error — copy the full key from the dashboard with no extra spaces, and check your Authorization header reads Bearer {key}.
Consent widget not showing — make sure the script tag is in <head> before your checkout code runs, check the browser console for errors, and confirm the #sendingthx-consent div exists in your HTML.
Questions about your integration can go to support@sendingthx.com.