AlphornAlphorn Docs

E-commerce Order Notifications

E-commerce notifications for new orders, refund requests, low inventory, and failed payments, routed to the right team via webhooks.

E-commerce notifications have different audiences - operations needs to know about new orders, finance cares about refunds, and warehouse cares about inventory. Alphorn routes each event to the right channel.

New order notification

fetch only rejects on network errors, so each example checks res.ok and throws on a 4xx/5xx response. Catch the error where you call these functions, so a failed notification doesn't break checkout.

async function onNewOrder(order) {
  const res = await fetch("https://app.alphorn.dev/n/V1StGXR8_Z5jdHi6B-myT", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${process.env.ALPHORN_API_KEY}`,
    },
    body: JSON.stringify({
      title: `New order #${order.id}`,
      message: `${order.customerName} - ${order.items.length} items - ${order.currency} ${order.total.toFixed(2)}`,
      priority: order.total > 500 ? 4 : 2,
      tags: ["order", "new", order.total > 500 ? "high-value" : "standard"],
    }),
  });
  if (!res.ok) throw new Error(`Alphorn responded ${res.status}`);
}

Refund requests

async function onRefundRequested(order, reason) {
  const res = await fetch("https://app.alphorn.dev/n/V1StGXR8_Z5jdHi6B-myT", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${process.env.ALPHORN_API_KEY}`,
    },
    body: JSON.stringify({
      title: `Refund requested: Order #${order.id}`,
      message: `Amount: ${order.currency} ${order.total.toFixed(2)}\nReason: ${reason}\nCustomer: ${order.customerEmail}`,
      priority: 3,
      tags: ["order", "refund"],
    }),
  });
  if (!res.ok) throw new Error(`Alphorn responded ${res.status}`);
}

Low inventory alerts

import os
import requests

def check_inventory(products, threshold=5):
    for product in products:
        if product.stock <= threshold:
            requests.post(
                "https://app.alphorn.dev/n/V1StGXR8_Z5jdHi6B-myT",
                headers={"Authorization": "Bearer " + os.environ["ALPHORN_API_KEY"]},
                json={
                    "title": f"Low stock: {product.name}",
                    "message": f"Only {product.stock} units remaining (SKU: {product.sku})",
                    "priority": 4 if product.stock == 0 else 3,
                    "tags": ["inventory", "low-stock",
                             "out-of-stock" if product.stock == 0 else "warning"],
                },
                timeout=10,
            ).raise_for_status()  # raises on 4xx/5xx

Failed payment alerts

async function onPaymentFailed(order, error) {
  const res = await fetch("https://app.alphorn.dev/n/V1StGXR8_Z5jdHi6B-myT", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${process.env.ALPHORN_API_KEY}`,
    },
    body: JSON.stringify({
      title: `Payment failed: Order #${order.id}`,
      message: `${error.message}\nCustomer: ${order.customerEmail}\nAmount: ${order.currency} ${order.total.toFixed(2)}`,
      priority: 3,
      tags: ["order", "payment-failed"],
    }),
  });
  if (!res.ok) throw new Error(`Alphorn responded ${res.status}`);
}

Routing examples

ChannelFilterPurpose
Slack (#orders)Tags has any of newNew order feed
Slack (#finance)Tags has any of refundRefund requests for finance team
Slack (#warehouse)Tags has any of inventoryStock alerts for warehouse
TelegramTags has any of high-valueFounder gets notified on big orders
EmailTags has any of orderFull order archive
PagerDutyTags has any of out-of-stockEscalate sold-out products

On this page