This workflow follows the Emailsend → HTTP Request recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "Automa\u00e7\u00e3o de Chargeback - Contesta\u00e7\u00e3o SaaS",
"nodes": [
{
"parameters": {
"path": "chargeback-webhook",
"responseMode": "onReceived",
"options": {}
},
"id": "webhook-trigger",
"name": "Webhook Trigger - Pagar.me",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1,
"position": [
250,
300
],
"notes": "Recebe eventos: charge.chargebacked, chargeback.created, chargeback.updated"
},
{
"parameters": {
"authentication": "customAuth",
"customAuth": {
"authentication": "basicAuth",
"user": "={{ env.PAGARME_API_KEY }}",
"password": ""
},
"requestMethod": "POST",
"url": "https://api.pagar.me/core/v5/charges/{{$node[\"webhook-trigger\"].json.data.charge_id}}",
"options": {},
"headers": {
"Content-Type": "application/json"
}
},
"id": "http-pagarme-charge",
"name": "HTTP - Buscar Charge da Pagar.me",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [
500,
250
],
"dependsOn": [
"webhook-trigger"
]
},
{
"parameters": {
"authentication": "customAuth",
"customAuth": {
"authentication": "basicAuth",
"user": "={{ env.SHOPIFY_API_ACCESS_TOKEN }}",
"password": ""
},
"requestMethod": "GET",
"url": "https://{{ env.SHOPIFY_STORE_URL }}/admin/api/{{ env.SHOPIFY_API_VERSION }}/orders/search.json?query=name:{{ $node[\"webhook-trigger\"].json.data.order_id }}",
"options": {},
"headers": {
"X-Shopify-Access-Token": "{{ env.SHOPIFY_API_ACCESS_TOKEN }}"
}
},
"id": "http-shopify-order",
"name": "HTTP - Buscar Order Shopify",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [
500,
450
],
"dependsOn": [
"webhook-trigger"
],
"notes": "Retorna vazio se SHOPIFY_API_ACCESS_TOKEN n\u00e3o configurado"
},
{
"parameters": {
"mode": "raw",
"jsonOutput": true,
"jsCode": "// Validar HMAC SHA-256 do webhook\nconst crypto = require('crypto');\nconst payload = $input.body.rawBody || JSON.stringify($input.body);\nconst signature = $headers['x-hub-signature'];\nconst expectedSignature = crypto\n .createHmac('sha256', process.env.PAGARME_WEBHOOK_SECRET)\n .update(payload)\n .digest('hex');\n\nconst isValid = signature === expectedSignature;\n\nreturn {\n valid: isValid,\n signature: signature,\n expected: expectedSignature,\n timestamp: new Date().toISOString()\n};"
},
"id": "code-hmac-validation",
"name": "Code - Validar HMAC SHA-256",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
250,
500
],
"dependsOn": [
"webhook-trigger"
]
},
{
"parameters": {
"database": "{{ env.DATABASE_URL }}",
"queryType": "raw",
"query": "INSERT INTO webhook_logs (event_type, webhook_id, payload, signature_valid, created_at)\nVALUES (\n '{{ $node[\"webhook-trigger\"].json.type }}',\n '{{ $node[\"webhook-trigger\"].json.data.id }}',\n '{{ JSON.stringify($node[\"webhook-trigger\"].json.data) }}'::jsonb,\n {{ $node[\"code-hmac-validation\"].json.valid }},\n CURRENT_TIMESTAMP\n)\nRETURNING id;"
},
"id": "postgres-webhook-log",
"name": "PostgreSQL - Salvar Webhook Log",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.3,
"position": [
750,
400
],
"dependsOn": [
"code-hmac-validation"
]
},
{
"parameters": {
"database": "{{ env.DATABASE_URL }}",
"queryType": "raw",
"query": "INSERT INTO chargebacks (\n chargeback_id,\n order_id,\n amount,\n currency,\n reason,\n status,\n metadata,\n received_at\n) VALUES (\n '{{ $node[\"http-pagarme-charge\"].json.chargeback_id }}',\n '{{ $node[\"http-pagarme-charge\"].json.metadata.order_id }}',\n {{ $node[\"http-pagarme-charge\"].json.amount }} / 100,\n '{{ $node[\"http-pagarme-charge\"].json.currency || \"BRL\" }}',\n '{{ $node[\"http-pagarme-charge\"].json.reason }}',\n 'open',\n '{{ JSON.stringify($node[\"http-pagarme-charge\"].json.data) }}'::jsonb,\n CURRENT_TIMESTAMP\n)\nON CONFLICT (chargeback_id) DO UPDATE\nSET status = EXCLUDED.status, updated_at = CURRENT_TIMESTAMP\nRETURNING id, chargeback_id;"
},
"id": "postgres-chargeback",
"name": "PostgreSQL - Salvar Chargeback",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.3,
"position": [
750,
250
],
"dependsOn": [
"http-pagarme-charge"
]
},
{
"parameters": {
"database": "{{ env.DATABASE_URL }}",
"queryType": "raw",
"query": "INSERT INTO orders (\n order_id,\n customer_name,\n customer_email,\n customer_phone,\n customer_cpf,\n transaction_date,\n transaction_amount,\n currency,\n payment_method,\n last_four_digits,\n card_brand,\n shopify_order_id,\n shopify_metadata,\n created_at\n) VALUES (\n '{{ $node[\"http-pagarme-charge\"].json.metadata.order_id }}',\n '{{ $node[\"http-pagarme-charge\"].json.customer.name }}',\n '{{ $node[\"http-pagarme-charge\"].json.customer.email }}',\n '{{ $node[\"http-pagarme-charge\"].json.customer.phone }}',\n '{{ $node[\"http-pagarme-charge\"].json.customer.document }}',\n '{{ $node[\"http-pagarme-charge\"].json.created_at }}',\n {{ $node[\"http-pagarme-charge\"].json.amount }} / 100,\n '{{ $node[\"http-pagarme-charge\"].json.currency || \"BRL\" }}',\n '{{ $node[\"http-pagarme-charge\"].json.payment_method }}',\n '{{ $node[\"http-pagarme-charge\"].json.card.last_four_digits || \"\" }}',\n '{{ $node[\"http-pagarme-charge\"].json.card.brand || \"\" }}',\n '{{ $node[\"http-shopify-order\"].json.orders?.[0]?.id || \"\" }}',\n '{{ JSON.stringify($node[\"http-shopify-order\"].json.orders?.[0]) }}'::jsonb,\n CURRENT_TIMESTAMP\n)\nON CONFLICT (order_id) DO UPDATE\nSET updated_at = CURRENT_TIMESTAMP\nRETURNING id, order_id;"
},
"id": "postgres-order",
"name": "PostgreSQL - Salvar Order",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.3,
"position": [
750,
300
],
"dependsOn": [
"http-pagarme-charge",
"http-shopify-order"
]
},
{
"parameters": {
"authentication": "customAuth",
"customAuth": {
"authentication": "bearer",
"credentialsExpired": false,
"token": "{{ env.ANTHROPIC_API_KEY }}"
},
"requestMethod": "POST",
"url": "https://api.anthropic.com/v1/messages",
"options": {},
"body": {
"contentType": "application/json",
"values": {
"model": "{{ env.CLAUDE_TRIAGE_MODEL || \"claude-haiku-4-5-20251001\" }}",
"max_tokens": 500,
"system": "Voc\u00ea \u00e9 um especialista em chargebacks. Classifique o tipo e analise viabilidade. Retorne JSON: { \"tipo\": \"...\", \"viabilidade\": 0.0-1.0, \"motivo\": \"...\" }",
"messages": [
{
"role": "user",
"content": "Analise este chargeback:\n\nMotivo: {{ $node[\"http-pagarme-charge\"].json.reason }}\nValor: R$ {{ $node[\"http-pagarme-charge\"].json.amount / 100 }}\nPedido: {{ $node[\"http-pagarme-charge\"].json.metadata.order_id }}\nData da transa\u00e7\u00e3o: {{ $node[\"http-pagarme-charge\"].json.created_at }}"
}
]
}
}
},
"id": "http-claude-triage",
"name": "HTTP - Claude Triagem (Haiku)",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [
1000,
150
],
"dependsOn": [
"http-pagarme-charge"
]
},
{
"parameters": {
"toEmail": "{{ env.ADMIN_EMAIL }}",
"subject": "\u26a0\ufe0f Novo Chargeback: {{ $node[\"http-pagarme-charge\"].json.chargeback_id }}",
"emailType": "html",
"htmlMessage": "<html><body>\n<h2>Novo Chargeback Recebido</h2>\n<p><strong>ID:</strong> {{ $node[\"http-pagarme-charge\"].json.chargeback_id }}</p>\n<p><strong>Valor:</strong> R$ {{ $node[\"http-pagarme-charge\"].json.amount / 100 }}</p>\n<p><strong>Motivo:</strong> {{ $node[\"http-pagarme-charge\"].json.reason }}</p>\n<p><strong>Tipo:</strong> {{ $node[\"http-claude-triage\"].json.content[0].text | jsonParse | property('tipo') }}</p>\n<p><strong>Viabilidade:</strong> {{ ($node[\"http-claude-triage\"].json.content[0].text | jsonParse | property('viabilidade')) * 100 }}%</p>\n<p><a href=\"{{ env.APP_URL }}/dashboard\">Abrir Dashboard</a></p>\n</body></html>"
},
"id": "email-alert",
"name": "Email - Alerta Admin",
"type": "n8n-nodes-base.emailSend",
"typeVersion": 1,
"position": [
1250,
300
],
"dependsOn": [
"http-claude-triage"
]
},
{
"parameters": {
"text": "\ud83d\udea8 Novo Chargeback\n\n*ID:* {{ $node[\"http-pagarme-charge\"].json.chargeback_id }}\n*Valor:* R$ {{ $node[\"http-pagarme-charge\"].json.amount / 100 }}\n*Motivo:* {{ $node[\"http-pagarme-charge\"].json.reason }}\n*Viabilidade:* {{ ($node[\"http-claude-triage\"].json.content[0].text | jsonParse | property('viabilidade')) * 100 }}%\n\n<{{ env.APP_URL }}/dashboard|Abrir Dashboard>"
},
"id": "slack-alert",
"name": "Slack - Notificar Chargeback",
"type": "n8n-nodes-base.slack",
"typeVersion": 1,
"position": [
1250,
450
],
"dependsOn": [
"http-claude-triage"
],
"credentials": {
"slackApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"authentication": "customAuth",
"customAuth": {
"authentication": "bearer",
"credentialsExpired": false,
"token": "{{ env.ANTHROPIC_API_KEY }}"
},
"requestMethod": "POST",
"url": "https://api.anthropic.com/v1/messages",
"options": {},
"body": {
"contentType": "application/json",
"values": {
"model": "{{ env.CLAUDE_LEGAL_MODEL || \"claude-3-5-sonnet-20241022\" }}",
"max_tokens": 2000,
"system": "Voc\u00ea \u00e9 advogado especialista em chargebacks. Gere parecer jur\u00eddico completo citando Art. 42-A e 49 do CDC, e Resolu\u00e7\u00e3o BCB 150. Retorne JSON: { \"parecer\": \"...\", \"argumentos\": [...], \"recomendacao\": \"...\", \"confianca\": 0.0-1.0 }",
"messages": [
{
"role": "user",
"content": "Gere parecer jur\u00eddico para defesa de chargeback:\n\nChargeback ID: {{ $node[\"http-pagarme-charge\"].json.chargeback_id }}\nMotivo: {{ $node[\"http-pagarme-charge\"].json.reason }}\nValor: R$ {{ $node[\"http-pagarme-charge\"].json.amount / 100 }}\nData da transa\u00e7\u00e3o: {{ $node[\"http-pagarme-charge\"].json.created_at }}\nCliente: {{ $node[\"http-pagarme-charge\"].json.customer.name }}\nPedido: {{ $node[\"http-pagarme-charge\"].json.metadata.order_id }}\n\nDados adicionais:\n{{ JSON.stringify($node[\"http-pagarme-charge\"].json.metadata) }}"
}
]
}
}
},
"id": "http-claude-legal",
"name": "HTTP - Claude Reda\u00e7\u00e3o Jur\u00eddica (Sonnet)",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [
1000,
250
],
"dependsOn": [
"http-pagarme-charge"
]
},
{
"parameters": {
"mode": "raw",
"jsonOutput": true,
"jsCode": "// Extrair an\u00e1lise de Claude e estruturar para database\nconst claudeResponse = $input.body;\nconst content = claudeResponse.content[0].text;\n\n// Parse JSON response from Claude\nlet analysis;\ntry {\n const jsonMatch = content.match(/{[\\s\\S]*}/);\n analysis = JSON.parse(jsonMatch[0]);\n} catch (e) {\n analysis = {\n parecer: content,\n argumentos: [],\n recomendacao: 'An\u00e1lise manual necess\u00e1ria',\n confianca: 0.5\n };\n}\n\nreturn {\n parecer: analysis.parecer,\n argumentos: analysis.argumentos || [],\n recomendacao: analysis.recomendacao,\n confianca: analysis.confianca || 0.5,\n avisos: analysis.avisos || []\n};"
},
"id": "code-parse-claude",
"name": "Code - Parse Resposta Claude",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1250,
150
],
"dependsOn": [
"http-claude-legal"
]
},
{
"parameters": {
"database": "{{ env.DATABASE_URL }}",
"queryType": "raw",
"query": "INSERT INTO defenses (\n chargeback_id,\n status,\n defense_text,\n defense_data,\n includes_shopify,\n legal_analysis,\n viability_score,\n created_by\n) VALUES (\n '{{ $node[\"http-pagarme-charge\"].json.chargeback_id }}',\n 'drafted',\n '{{ $node[\"code-parse-claude\"].json.parecer }}',\n '{{ JSON.stringify($node[\"code-parse-claude\"].json) }}'::jsonb,\n {{ $node[\"http-shopify-order\"].json.orders?.length > 0 }},\n '{{ JSON.stringify({ parecer: $node[\"code-parse-claude\"].json.parecer, argumentos: $node[\"code-parse-claude\"].json.argumentos, recomendacao: $node[\"code-parse-claude\"].json.recomendacao }) }}'::jsonb,\n {{ $node[\"code-parse-claude\"].json.confianca }},\n 'system'\n)\nON CONFLICT DO NOTHING\nRETURNING id, chargeback_id;"
},
"id": "postgres-defense",
"name": "PostgreSQL - Salvar Defesa",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.3,
"position": [
1500,
150
],
"dependsOn": [
"code-parse-claude",
"postgres-chargeback"
]
},
{
"parameters": {
"toEmail": "{{ $node[\"http-pagarme-charge\"].json.customer.email }}",
"subject": "\u2713 Dossi\u00ea de Defesa Preparado - Chargeback {{ $node[\"http-pagarme-charge\"].json.chargeback_id }}",
"emailType": "html",
"htmlMessage": "<html><body>\n<h2>Dossi\u00ea de Defesa Gerado</h2>\n<p>Prezado cliente,</p>\n<p>Seu dossi\u00ea de defesa foi preparado com sucesso.</p>\n<p><strong>Chargeback:</strong> {{ $node[\"http-pagarme-charge\"].json.chargeback_id }}</p>\n<p><strong>Valor:</strong> R$ {{ $node[\"http-pagarme-charge\"].json.amount / 100 }}</p>\n<p><strong>Recomenda\u00e7\u00e3o:</strong> {{ $node[\"code-parse-claude\"].json.recomendacao }}</p>\n<p><a href=\"{{ env.APP_URL }}/rascunhos/{{ $node[\"postgres-defense\"].json[0].id }}\">Revisar Dossi\u00ea</a></p>\n<p>Atenciosamente,<br>Contesta\u00e7\u00e3o SaaS</p>\n</body></html>"
},
"id": "email-user",
"name": "Email - Notificar User",
"type": "n8n-nodes-base.emailSend",
"typeVersion": 1,
"position": [
1500,
300
],
"dependsOn": [
"postgres-defense"
]
}
],
"connections": {
"webhook-trigger": {
"main": [
[
{
"node": "http-pagarme-charge",
"type": "main",
"index": 0
},
{
"node": "http-shopify-order",
"type": "main",
"index": 0
},
{
"node": "code-hmac-validation",
"type": "main",
"index": 0
}
]
]
},
"code-hmac-validation": {
"main": [
[
{
"node": "postgres-webhook-log",
"type": "main",
"index": 0
}
]
]
},
"http-pagarme-charge": {
"main": [
[
{
"node": "postgres-chargeback",
"type": "main",
"index": 0
},
{
"node": "postgres-order",
"type": "main",
"index": 0
},
{
"node": "http-claude-triage",
"type": "main",
"index": 0
},
{
"node": "http-claude-legal",
"type": "main",
"index": 0
}
]
]
},
"http-shopify-order": {
"main": [
[
{
"node": "postgres-order",
"type": "main",
"index": 0
}
]
]
},
"postgres-chargeback": {
"main": [
[
{
"node": "postgres-defense",
"type": "main",
"index": 0
}
]
]
},
"http-claude-triage": {
"main": [
[
{
"node": "email-alert",
"type": "main",
"index": 0
},
{
"node": "slack-alert",
"type": "main",
"index": 0
}
]
]
},
"http-claude-legal": {
"main": [
[
{
"node": "code-parse-claude",
"type": "main",
"index": 0
}
]
]
},
"code-parse-claude": {
"main": [
[
{
"node": "postgres-defense",
"type": "main",
"index": 0
},
{
"node": "email-user",
"type": "main",
"index": 0
}
]
]
},
"postgres-defense": {
"main": [
[
{
"node": "email-user",
"type": "main",
"index": 0
}
]
]
}
},
"active": true,
"settings": {
"executionOrder": "v1"
},
"description": "Workflow completo para automa\u00e7\u00e3o de chargeback: Webhook \u2192 Valida\u00e7\u00e3o HMAC \u2192 Buscar dados Pagar.me/Shopify \u2192 Claude Triagem + Reda\u00e7\u00e3o \u2192 PostgreSQL \u2192 Notifica\u00e7\u00f5es",
"tags": [
"chargeback",
"automacao",
"claude",
"pagarme"
]
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
slackApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Automação de Chargeback - Contestação SaaS. Uses httpRequest, postgres, emailSend, slack. Webhook trigger; 14 nodes.
Source: https://github.com/fepo/Chargebackinho/blob/d16e2034cfec2059649a1157e19033bfdef81f28/n8n/workflow-automacao-chargeback.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This workflow automates end-to-end research analysis by coordinating multiple AI models—including NVIDIA NIM (Llama), OpenAI GPT-4, and Claude to analyze uploaded documents, extract insights, and gene
Advanced Workflow with Branching and Error Handling. Uses emailSend, httpRequest, postgres, slack. Webhook trigger; 12 nodes.
This n8n workflow automates task creation and scheduled reminders for users via a Telegram bot, ensuring timely notifications across multiple channels like email and Slack. It streamlines task managem
QA Platform — Jira Story to Test Workflow. Uses jiraTrigger, postgres, httpRequest, slack. Webhook trigger; 20 nodes.
This workflow provides a complete, automated post-purchase solution triggered by a successful payment webhook from Abacate Pay. (For international users, think of Abacate Pay as 'the Brazilian Stripe'