Telegram alert for failed Paymob payments

Know instantly when a customer's payment fails, so you can call them and save the sale.

Easy Saves ~2 hours/month MENA & local appsBy Flowngn team

Works with n8n · Make · Zapier

How it works

Trigger: Webhook — Paymob transaction processed callback
  1. Receive the transaction callback from Paymob.
  2. Continue only if the payment failed.
  3. Send the customer, amount and error to your Telegram.

Diagram

truePaymob callbackWebhook{ }Read paymentCode⑂Failed?IfTAlert on TelegramTelegram
Trigger App Logic Code

Code

JavaScript used in the Code step — already included in the template below.

Read payment · Code node
// Mode: Run Once for Each Item
// Paymob "transaction processed" callback → clean, easy-to-use fields.
const obj = $json.body?.obj || {};
const billing = obj.order?.shipping_data || obj.payment_key_claims?.billing_data || {};

return {
  json: {
    success: obj.success === true,
    transaction_id: obj.id,
    order_id: obj.order?.merchant_order_id || obj.order?.id,
    amount: (obj.amount_cents || 0) / 100,
    currency: obj.currency,
    method: obj.source_data?.sub_type || obj.source_data?.type || "",
    customer_name: [billing.first_name, billing.last_name].filter(Boolean).join(" "),
    phone: String(billing.phone_number || "").replace(/[^0-9]/g, ""),
    email: billing.email || "",
    error: obj.data?.message || "",
    date: obj.created_at,
  },
};

Build it

Pick your tool — same automation, step by step.

Copy and paste straight into an n8n canvas (Ctrl+V), or download and use Import from File. Then connect your own credentials and replace every YOUR_… placeholder.

Workflow JSON
Show code (143 lines)
{
  "name": "Telegram alert for failed Paymob payments (Flowngn)",
  "nodes": [
    {
      "parameters": {
        "content": "## Telegram alert for failed Paymob payments\nKnow instantly when a customer's payment fails, so you can call them and save the sale.\n\n**Setup**\n1. Open each node and connect your own credentials.\n2. Replace every YOUR_… placeholder.\n3. Test once, then activate.\n\nFree template from Flowngn",
        "height": 260,
        "width": 340
      },
      "id": "43ef56f7-3e64-497c-a29d-9f8e7687325e",
      "name": "Setup notes",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -420,
        -60
      ]
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "paymob-failed",
        "options": {}
      },
      "id": "43ef56f7-3e64-497c-a29d-9f8e7687325e",
      "name": "Paymob callback",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        0,
        0
      ],
      "webhookId": "43ef56f7-3e64-497c-a29d-9f8e7687325e"
    },
    {
      "parameters": {
        "jsCode": "// Mode: Run Once for Each Item\n// Paymob \"transaction processed\" callback → clean, easy-to-use fields.\nconst obj = $json.body?.obj || {};\nconst billing = obj.order?.shipping_data || obj.payment_key_claims?.billing_data || {};\n\nreturn {\n  json: {\n    success: obj.success === true,\n    transaction_id: obj.id,\n    order_id: obj.order?.merchant_order_id || obj.order?.id,\n    amount: (obj.amount_cents || 0) / 100,\n    currency: obj.currency,\n    method: obj.source_data?.sub_type || obj.source_data?.type || \"\",\n    customer_name: [billing.first_name, billing.last_name].filter(Boolean).join(\" \"),\n    phone: String(billing.phone_number || \"\").replace(/[^0-9]/g, \"\"),\n    email: billing.email || \"\",\n    error: obj.data?.message || \"\",\n    date: obj.created_at,\n  },\n};",
        "mode": "runOnceForEachItem"
      },
      "id": "43ef56f7-3e64-497c-a29d-9f8e7687325e",
      "name": "Read payment",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        300,
        0
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose"
          },
          "conditions": [
            {
              "id": "c1",
              "leftValue": "={{ $json.success }}",
              "rightValue": "",
              "operator": {
                "type": "boolean",
                "operation": "false",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "43ef56f7-3e64-497c-a29d-9f8e7687325e",
      "name": "Failed?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        600,
        0
      ]
    },
    {
      "parameters": {
        "chatId": "YOUR_CHAT_ID",
        "text": "=❌ دفعة فاشلة على Paymob\n💰 {{ $json.amount }} {{ $json.currency }} · طلب #{{ $json.order_id }}\n👤 {{ $json.customer_name }} · 📞 {{ $json.phone }}\n⚠️ {{ $json.error || 'بدون سبب' }}",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "id": "43ef56f7-3e64-497c-a29d-9f8e7687325e",
      "name": "Alert on Telegram",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        900,
        0
      ]
    }
  ],
  "connections": {
    "Paymob callback": {
      "main": [
        [
          {
            "node": "Read payment",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read payment": {
      "main": [
        [
          {
            "node": "Failed?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Failed?": {
      "main": [
        [
          {
            "node": "Alert on Telegram",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "tags": []
}

Open in the playground to edit →

Tips

  • A quick call or WhatsApp to the customer often recovers the order.

Related flows