vibeflow-n8n/examples/safe-refund.workflow.json
2026-07-22 13:56:34 -03:00

85 lines
3.1 KiB
JSON

{
"name": "Safe refund with outcome contract",
"nodes": [
{
"id": "webhook",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"parameters": { "authentication": "headerAuth", "path": "refund" },
"credentials": { "httpHeaderAuth": { "id": "credential-reference", "name": "Webhook Header Auth" } }
},
{
"id": "idempotency",
"name": "Claim idempotency event",
"type": "n8n-nodes-base.postgres",
"parameters": {
"operation": "executeQuery",
"query": "INSERT INTO event_ledger (event_id) VALUES ($1) ON CONFLICT (event_id) DO NOTHING RETURNING event_id"
}
},
{
"id": "audit",
"name": "Record refund audit",
"type": "n8n-nodes-base.postgres",
"parameters": { "operation": "insert", "table": "refund_audit" }
},
{
"id": "approval",
"name": "Approve refund",
"type": "n8n-nodes-base.if",
"parameters": { "conditions": { "boolean": [{ "value1": "={{ $json.approved }}", "value2": true }] } }
},
{
"id": "amount",
"name": "Limit refund amount",
"type": "n8n-nodes-base.if",
"parameters": {
"conditions": { "number": [{ "value1": "={{ $json.amount }}", "operation": "smallerEqual", "value2": 500 }] },
"currency": "USD"
}
},
{
"id": "counterparty",
"name": "Allow refund account",
"type": "n8n-nodes-base.switch",
"parameters": { "value": "={{ $json.counterparty }}", "rules": [{ "value": "merchant-primary" }] }
},
{
"id": "refund",
"name": "Issue refund",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueErrorOutput",
"parameters": { "method": "POST", "url": "https://payments.invalid/refund" }
},
{
"id": "failure-alert",
"name": "Notify refund failure",
"type": "n8n-nodes-base.slack",
"parameters": { "channel": "operations", "text": "Notify failure for refund {{ $json.event_id }}" }
},
{
"id": "compensation",
"name": "Compensate transaction",
"type": "n8n-nodes-base.httpRequest",
"parameters": { "method": "POST", "url": "https://payments.invalid/reverse", "operation": "compensate" }
}
],
"connections": {
"Webhook": { "main": [[{ "node": "Claim idempotency event", "type": "main", "index": 0 }]] },
"Claim idempotency event": { "main": [[{ "node": "Record refund audit", "type": "main", "index": 0 }]] },
"Record refund audit": { "main": [[{ "node": "Approve refund", "type": "main", "index": 0 }]] },
"Approve refund": { "main": [[{ "node": "Limit refund amount", "type": "main", "index": 0 }], []] },
"Limit refund amount": { "main": [[{ "node": "Allow refund account", "type": "main", "index": 0 }], []] },
"Allow refund account": { "main": [[{ "node": "Issue refund", "type": "main", "index": 0 }], []] },
"Issue refund": {
"main": [
[],
[
{ "node": "Notify refund failure", "type": "main", "index": 0 },
{ "node": "Compensate transaction", "type": "main", "index": 0 }
]
]
}
},
"settings": { "executionTimeout": 120, "errorWorkflow": "global-error-handler" }
}