{
  "name": "KyndredAI · MercadoPago → AFIP factura automática",
  "nodes": [
    {
      "parameters": {
        "content": "# 🔷 KyndredAI · MercadoPago → AFIP factura automática\n\nCuando entra un pago aprobado en MercadoPago, **verifica la firma**, trae los datos del pago, **emite la factura en AFIP** (vía tu servicio de facturación) y le manda el comprobante (CAE) al cliente por email.\n\n**Cómo funciona:** Webhook MP → valida firma `x-signature` → trae el pago de la API → arma los datos de la factura → POST a tu API de facturación AFIP → email del comprobante al cliente.\n\n**Necesitás:** Secret + Access Token de MercadoPago + un **servicio de facturación AFIP** (AFIP WSFEv1 con certificado, o un facturador tipo TusFacturas/Facturante/Colppy que exponga una API) + credencial de Gmail.\n\n⚠️ **Avanzada (Tier AR).** AFIP exige autenticación con certificado (WSAA). Lo más simple es apuntar a un facturador que te dé una API REST. Probá en homologación antes de producción.\n\nself-hosted o cloud · kyndredai.com",
        "height": 420,
        "width": 900,
        "color": 7
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        368,
        -80
      ],
      "id": "bb0a05de-fd0c-4650-b239-6ed9e9dc1260",
      "name": "README"
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "mercadopago-afip",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1,
      "position": [
        16,
        512
      ],
      "id": "801cb5e7-5f36-401a-b40f-da4abaa5e7b1",
      "name": "Recibir pago MP (Webhook)",
      "webhookId": "a2b2c2d2-2222-4222-8222-a22222222222"
    },
    {
      "parameters": {
        "jsCode": "const crypto = require('crypto');\n\n// ⚠️ PEGÁ acá tu Secret de MercadoPago\n// (Tus integraciones → Webhooks → Configurar notificaciones → Clave secreta)\nconst SECRET = 'PEGA_TU_SECRET_DE_MERCADOPAGO_ACA';\n\nconst item = $input.first();\nconst headers = item.json.headers || {};\nconst body = item.json.body || {};\nconst query = item.json.query || {};\n\nconst xSignature = headers['x-signature'] || '';\nconst xRequestId = headers['x-request-id'] || '';\nconst parts = {};\nxSignature.split(',').forEach(p => {\n  const [k, v] = p.split('=');\n  if (k && v) parts[k.trim()] = v.trim();\n});\nconst ts = parts.ts || '';\nconst v1 = parts.v1 || '';\n\nlet dataId = query['data.id'] || (body.data && body.data.id) || '';\ndataId = String(dataId);\n\nconst manifest = `id:${dataId};request-id:${xRequestId};ts:${ts};`;\nconst hash = crypto.createHmac('sha256', SECRET).update(manifest).digest('hex');\nconst signatureValid = Boolean(v1) && hash === v1;\n\nreturn [{ json: { paymentId: dataId, signatureValid } }];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        288,
        512
      ],
      "id": "66e81ff0-e089-4311-86a1-b5c89531ad14",
      "name": "Verificar firma (x-signature)"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 2
          },
          "conditions": [
            {
              "id": "a4000001-0000-4000-8000-000000000001",
              "leftValue": "={{ $json.signatureValid }}",
              "rightValue": "",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        576,
        512
      ],
      "id": "2c4d6d61-e775-46dc-a7f3-befb4a88bf68",
      "name": "¿Firma válida?"
    },
    {
      "parameters": {
        "url": "=https://api.mercadopago.com/v1/payments/{{ $json.paymentId }}",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        848,
        416
      ],
      "id": "fbfb2240-1225-4874-b406-bcf3767dc75e",
      "name": "Traer pago de MP",
      "retryOnFail": true,
      "maxTries": 3,
      "waitBetweenTries": 2000
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "a6000001-0000-4000-8000-000000000001",
              "name": "monto",
              "value": "={{ $json.transaction_amount }}",
              "type": "number"
            },
            {
              "id": "a6000002-0000-4000-8000-000000000002",
              "name": "email",
              "value": "={{ $json.payer.email }}",
              "type": "string"
            },
            {
              "id": "a6000003-0000-4000-8000-000000000003",
              "name": "nombre",
              "value": "={{ $json.payer.first_name }} {{ $json.payer.last_name }}",
              "type": "string"
            },
            {
              "id": "a6000004-0000-4000-8000-000000000004",
              "name": "doc_tipo",
              "value": "={{ $json.payer.identification.type }}",
              "type": "string"
            },
            {
              "id": "a6000005-0000-4000-8000-000000000005",
              "name": "doc_numero",
              "value": "={{ $json.payer.identification.number }}",
              "type": "string"
            },
            {
              "id": "a6000006-0000-4000-8000-000000000006",
              "name": "descripcion",
              "value": "={{ $json.description }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1120,
        416
      ],
      "id": "43adf798-2467-4777-bc2a-bee05875bc12",
      "name": "Datos de la factura"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://TU-FACTURADOR-AFIP.com/api/v1/facturas",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"tipo_comprobante\": \"factura_b\",\n  \"cliente\": {\n    \"nombre\": \"{{ $json.nombre }}\",\n    \"email\": \"{{ $json.email }}\",\n    \"doc_tipo\": \"{{ $json.doc_tipo }}\",\n    \"doc_numero\": \"{{ $json.doc_numero }}\"\n  },\n  \"importe_total\": {{ $json.monto }},\n  \"concepto\": \"{{ $json.descripcion }}\"\n}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1376,
        416
      ],
      "id": "7305c237-5cc6-4899-9bae-cd850b844f7b",
      "name": "Emitir factura (AFIP)",
      "retryOnFail": true,
      "maxTries": 3,
      "waitBetweenTries": 2000
    },
    {
      "parameters": {
        "sendTo": "={{ $('Datos de la factura').item.json.email }}",
        "subject": "=Tu comprobante — {{ $('Datos de la factura').item.json.descripcion }}",
        "emailType": "text",
        "message": "=Hola {{ $('Datos de la factura').item.json.nombre }},\n\n¡Gracias por tu compra! Adjuntamos los datos de tu comprobante fiscal:\n\n• CAE: {{ $json.cae }}\n• Vencimiento CAE: {{ $json.cae_vencimiento }}\n• Total: $ {{ $('Datos de la factura').item.json.monto }}\n\nSi necesitás el PDF o algún dato, respondé este email.\n\n¡Saludos!",
        "options": {}
      },
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        1632,
        416
      ],
      "id": "300dd7ea-a52a-4289-b4eb-dea4d96b71ac",
      "name": "Enviar comprobante",
      "retryOnFail": true,
      "maxTries": 3,
      "waitBetweenTries": 2000,
      "webhookId": "a8b8c8d8-8888-4888-8888-a88888888888"
    },
    {
      "parameters": {},
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        848,
        656
      ],
      "id": "ae1cf19e-3737-4c8b-b424-ddbe7262a970",
      "name": "Firma inválida (descartar)"
    },
    {
      "parameters": {
        "content": "## ① MercadoPago\n\n**Webhook:** en MP → *Tus integraciones → Webhooks*, pegá la URL **production** de este nodo y suscribite al evento **payment**.\n\n**Secret:** pegalo en el nodo *Verificar firma* (línea `SECRET = '...'`).\n\n**Access Token:** en *Traer pago de MP* → Credential → Header Auth → Name `Authorization`, Value `Bearer TU_ACCESS_TOKEN`.\n\n⚠️ Self-hosted: si Code falla con `crypto`, seteá `NODE_FUNCTION_ALLOW_BUILTIN=crypto`.",
        "height": 392,
        "width": 480,
        "color": 4
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -96,
        704
      ],
      "id": "46dcac13-a237-429e-94be-a5a99e3ba07e",
      "name": "Setup 1"
    },
    {
      "parameters": {
        "content": "## ② AFIP (facturación)\n\nAFIP exige certificado (WSAA), así que lo más práctico es usar un **facturador con API REST**.\n\nEn *Emitir factura (AFIP)*:\n1. Cambiá la **URL** por la de tu facturador.\n2. Ajustá el **body** (tipo de comprobante, campos) al formato que pida.\n3. Credential → Header Auth con tu token.\n\nEl email usa `{{ $json.cae }}` — renombralo al campo que devuelva tu facturador.",
        "height": 424,
        "width": 320,
        "color": 4
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        1040,
        608
      ],
      "id": "5de4f763-4b94-4013-a0c4-64064640abad",
      "name": "Setup 2"
    },
    {
      "parameters": {
        "content": "## ③ Gmail\n\nEn *Enviar comprobante* → Credential → conectá tu Gmail.\n\nPersonalizá asunto y cuerpo. Cambiá `emailType` a **html** si querés adjuntar/diseñar el comprobante.",
        "height": 248,
        "width": 300,
        "color": 4
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        1552,
        608
      ],
      "id": "75f44e76-7ba6-4181-b8be-dcc16ffc075b",
      "name": "Setup 3"
    }
  ],
  "connections": {
    "Recibir pago MP (Webhook)": {
      "main": [
        [
          {
            "node": "Verificar firma (x-signature)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Verificar firma (x-signature)": {
      "main": [
        [
          {
            "node": "¿Firma válida?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "¿Firma válida?": {
      "main": [
        [
          {
            "node": "Traer pago de MP",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Firma inválida (descartar)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Traer pago de MP": {
      "main": [
        [
          {
            "node": "Datos de la factura",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Datos de la factura": {
      "main": [
        [
          {
            "node": "Emitir factura (AFIP)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Emitir factura (AFIP)": {
      "main": [
        [
          {
            "node": "Enviar comprobante",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "pinData": {},
  "tags": []
}
