Payment screenshot → AI reads it → log for checking

Customers send an InstaPay or wallet transfer screenshot to your Telegram bot; AI reads the amount and logs it for you to verify.

Advanced Saves ~6 hours/month MENA & local appsBy Flowngn team

Works with n8n · Make · Zapier

How it works

Trigger: Telegram — a photo is sent to your bot
  1. A customer sends the transfer screenshot (with their order number as the caption).
  2. AI reads the amount, sender, reference and date from the image.
  3. The transfer is logged in a sheet with status "to verify", and the customer gets a receipt message.
  4. Unreadable images get a polite request for a clearer screenshot.

Diagram

truefalseTScreenshot receivedTelegram TriggerRead the transferBasic LLM ChainClaude modelAnthropic Chat Mo…{ }Read detailsCode⑂Readable transfer?IfGLog for checkingGoogle SheetsTConfirm receiptTelegramTAsk for a clearer i…Telegram
Trigger App Logic Code AI

Code

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

Read details · Code node
// Mode: Run Once for Each Item
// The AI read a transfer screenshot (InstaPay, wallet or bank) and was asked for JSON like:
// {"is_transfer": true, "amount": 1250, "currency": "EGP", "sender": "Ahmed M.", "reference": "123456789", "date": "2026-10-19"}
const match = $json.text.match(/\{[\s\S]*\}/);
const t = match ? JSON.parse(match[0]) : {};
const msg = $("Screenshot received").item.json.message;

return {
  json: {
    is_transfer: t.is_transfer === true && Number(t.amount) > 0,
    amount: Number(t.amount) || 0,
    currency: t.currency || "EGP",
    sender: t.sender || "",
    reference: t.reference || "",
    date: t.date || "",
    chatId: msg.chat.id,
    caption: msg.caption || "",
  },
};

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. AI steps use a Claude model node — swap it for OpenAI, Gemini or Ollama if you prefer.

Workflow JSON
Show code (272 lines)
{
  "name": "Payment screenshot → AI reads it → log for checking (Flowngn)",
  "nodes": [
    {
      "parameters": {
        "content": "## Payment screenshot → AI reads it → log for checking\nCustomers send an InstaPay or wallet transfer screenshot to your Telegram bot; AI reads the amount and logs it for you to verify.\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": "35c47c31-9f0c-4ea1-ae8c-21fbe894577c",
      "name": "Setup notes",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -420,
        -60
      ]
    },
    {
      "parameters": {
        "updates": [
          "message"
        ],
        "additionalFields": {
          "download": true
        }
      },
      "id": "35c47c31-9f0c-4ea1-ae8c-21fbe894577c",
      "name": "Screenshot received",
      "type": "n8n-nodes-base.telegramTrigger",
      "typeVersion": 1.1,
      "position": [
        0,
        0
      ],
      "webhookId": "35c47c31-9f0c-4ea1-ae8c-21fbe894577c"
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=This image should be a payment transfer screenshot (InstaPay, mobile wallet or bank). Reply ONLY with JSON: {\"is_transfer\": true|false, \"amount\": number, \"currency\": \"EGP\", \"sender\": \"...\", \"reference\": \"...\", \"date\": \"YYYY-MM-DD\"}. If you can't read it clearly, set is_transfer to false. Never guess numbers.",
        "passthroughBinaryImages": true
      },
      "id": "35c47c31-9f0c-4ea1-ae8c-21fbe894577c",
      "name": "Read the transfer",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "typeVersion": 1.5,
      "position": [
        300,
        0
      ]
    },
    {
      "parameters": {
        "model": {
          "__rl": true,
          "value": "claude-sonnet-5",
          "mode": "list"
        },
        "options": {}
      },
      "id": "35c47c31-9f0c-4ea1-ae8c-21fbe894577c",
      "name": "Claude model",
      "type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
      "typeVersion": 1.3,
      "position": [
        300,
        220
      ]
    },
    {
      "parameters": {
        "jsCode": "// Mode: Run Once for Each Item\n// The AI read a transfer screenshot (InstaPay, wallet or bank) and was asked for JSON like:\n// {\"is_transfer\": true, \"amount\": 1250, \"currency\": \"EGP\", \"sender\": \"Ahmed M.\", \"reference\": \"123456789\", \"date\": \"2026-10-19\"}\nconst match = $json.text.match(/\\{[\\s\\S]*\\}/);\nconst t = match ? JSON.parse(match[0]) : {};\nconst msg = $(\"Screenshot received\").item.json.message;\n\nreturn {\n  json: {\n    is_transfer: t.is_transfer === true && Number(t.amount) > 0,\n    amount: Number(t.amount) || 0,\n    currency: t.currency || \"EGP\",\n    sender: t.sender || \"\",\n    reference: t.reference || \"\",\n    date: t.date || \"\",\n    chatId: msg.chat.id,\n    caption: msg.caption || \"\",\n  },\n};",
        "mode": "runOnceForEachItem"
      },
      "id": "35c47c31-9f0c-4ea1-ae8c-21fbe894577c",
      "name": "Read details",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        600,
        0
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose"
          },
          "conditions": [
            {
              "id": "c1",
              "leftValue": "={{ $json.is_transfer }}",
              "rightValue": "",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "35c47c31-9f0c-4ea1-ae8c-21fbe894577c",
      "name": "Readable transfer?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        900,
        0
      ]
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": {
          "__rl": true,
          "value": "YOUR_SPREADSHEET_ID",
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": "Transfers",
          "mode": "name"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "received": "={{ $now.toISO() }}",
            "amount": "={{ $json.amount }}",
            "currency": "={{ $json.currency }}",
            "sender": "={{ $json.sender }}",
            "reference": "={{ $json.reference }}",
            "order": "={{ $json.caption }}",
            "status": "to verify"
          }
        },
        "options": {}
      },
      "id": "35c47c31-9f0c-4ea1-ae8c-21fbe894577c",
      "name": "Log for checking",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        1200,
        0
      ]
    },
    {
      "parameters": {
        "chatId": "={{ $('Read details').item.json.chatId }}",
        "text": "=✅ Received: {{ $('Read details').item.json.amount }} {{ $('Read details').item.json.currency }} from {{ $('Read details').item.json.sender }} — we'll confirm once it's verified.",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "id": "35c47c31-9f0c-4ea1-ae8c-21fbe894577c",
      "name": "Confirm receipt",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        1500,
        0
      ]
    },
    {
      "parameters": {
        "chatId": "={{ $json.chatId }}",
        "text": "Sorry, I couldn't read that. Please send a clear screenshot of the transfer confirmation.",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "id": "35c47c31-9f0c-4ea1-ae8c-21fbe894577c",
      "name": "Ask for a clearer image",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        1200,
        220
      ]
    }
  ],
  "connections": {
    "Screenshot received": {
      "main": [
        [
          {
            "node": "Read the transfer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read the transfer": {
      "main": [
        [
          {
            "node": "Read details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read details": {
      "main": [
        [
          {
            "node": "Readable transfer?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Readable transfer?": {
      "main": [
        [
          {
            "node": "Log for checking",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Ask for a clearer image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log for checking": {
      "main": [
        [
          {
            "node": "Confirm receipt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Claude model": {
      "ai_languageModel": [
        [
          {
            "node": "Read the transfer",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    }
  },
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "tags": []
}

Open in the playground to edit →

Tips

  • Always confirm the money actually arrived in your account before shipping — screenshots can be faked.
  • Use an AI model that can read images.

Related flows