{
  "name": "UniTV WhatsApp - Postgres + Pagamentos v1",
  "nodes": [
    {
      "parameters": {"httpMethod":"POST","path":"unitvia-pagamentos","responseMode":"onReceived","options":{}},
      "id":"webhook-unitv-pg","name":"Entrada WhatsApp","type":"n8n-nodes-base.webhook","typeVersion":2,"position":[-1100,0],"webhookId":"unitvia-pagamentos"
    },
    {
      "parameters": {"jsCode":"const b=$json.body??$json; if(String(b.EventType??'messages').toLowerCase()!=='messages') return []; return [{json:$json}];"},
      "id":"filter-messages-unitv","name":"Filtrar somente mensagens","type":"n8n-nodes-base.code","typeVersion":2,"position":[-990,0]
    },
    {
      "parameters": {"jsCode":"const root=$json.body??$json; const data=root.data??root; const msg=data.message??data; const raw=String(msg.text??data.text??data.wa_lastMessageTextVote??'').trim(); const selected=String(msg.buttonOrListid??msg.listReply?.id??data.buttonOrListid??'').trim(); const text=(selected||raw).normalize('NFD').replace(/[\\u0300-\\u036f]/g,'').toLowerCase().trim(); const phone=String(data.phone??data.chat?.phone??data.from??data.sender??'').replace(/\\D/g,''); const id=text.replace(/[^a-z0-9]/g,''); const period=id.includes('1y')||/1\\s*ano|anual/.test(text)?'1y':id.includes('6m')||/6\\s*mes/.test(text)?'6m':id.includes('3m')||/3\\s*mes/.test(text)?'3m':id.includes('1m')||/1\\s*mes/.test(text)?'1m':''; const command=/^(comprar|comprar_conta|buy|1)$/.test(id)?'buy':/^(renovar|renew|2)$/.test(id)?'renew':/^(consultar|consultar_conta|consulta|3)$/.test(id)?'consult':/^confirmo$/.test(id)?'confirm':/^(paguei|pago|pagamento|pix_pago)$/.test(id)?'paid':period?'period':/^(oi|ola|bomdia|boatarde|boanoite|menu|opcoes|opções)$/.test(id)?'menu':'unknown'; const sn=(text.match(/\\b[a-z0-9]{6}\\b/i)||[])[0]||''; const customerName=String(data.name??data.chat?.name??data.chat?.wa_name??'').trim(); const requestId=String(msg.id??data.messageid??Date.now()); return [{json:{phone,raw,text,command,period,sn,customerName,requestId,sessionKey:'unitv:'+phone}}];"},
      "id":"normalize-unitv-pg","name":"Normalizar entrada","type":"n8n-nodes-base.code","typeVersion":2,"position":[-880,0]
    },
    {
      "parameters": {"operation":"executeQuery","query":"={{ (() => { const j=$json; const esc=v=>String(v??'').replace(/'/g,\"''\"); return `INSERT INTO unitv_whatsapp_sessions (phone,operation,sn,period,customer_name,last_text,updated_at) VALUES ('${esc(j.phone)}','${esc(j.command)}',NULLIF('${esc(j.sn)}',''),NULLIF('${esc(j.period)}',''),NULLIF('${esc(j.customerName)}',''), '${esc(j.raw)}', NOW()) ON CONFLICT (phone) DO UPDATE SET operation=CASE WHEN '${esc(j.command)}' IN ('buy','renew','consult') THEN EXCLUDED.operation ELSE unitv_whatsapp_sessions.operation END, sn=COALESCE(NULLIF('${esc(j.sn)}',''),unitv_whatsapp_sessions.sn), period=COALESCE(NULLIF('${esc(j.period)}',''),unitv_whatsapp_sessions.period), customer_name=COALESCE(NULLIF('${esc(j.customerName)}',''),unitv_whatsapp_sessions.customer_name), last_text=EXCLUDED.last_text, updated_at=NOW();`; })() }}","options":{}},
      "id":"pg-session-in","name":"Postgres - salvar sessão","type":"n8n-nodes-base.postgres","typeVersion":2.5,"position":[-650,0],"credentials":{"postgres":{"name":"Postgres UniTV Workflow"}}
    },
    {
      "parameters": {"rules":{"values":[{"conditions":{"options":{"caseSensitive":false,"leftValue":"","typeValidation":"strict"},"conditions":[{"leftValue":"={{$node['Normalizar entrada'].json.command}}","rightValue":"menu","operator":{"type":"string","operation":"equals"}}],"combinator":"and"},"renameOutput":true,"outputKey":"menu"},{"conditions":{"options":{"caseSensitive":false,"leftValue":"","typeValidation":"strict"},"conditions":[{"leftValue":"={{$node['Normalizar entrada'].json.command}}","rightValue":"buy","operator":{"type":"string","operation":"equals"}}],"combinator":"and"},"renameOutput":true,"outputKey":"comprar"},{"conditions":{"options":{"caseSensitive":false,"leftValue":"","typeValidation":"strict"},"conditions":[{"leftValue":"={{$node['Normalizar entrada'].json.command}}","rightValue":"renew","operator":{"type":"string","operation":"equals"}}],"combinator":"and"},"renameOutput":true,"outputKey":"renovar"},{"conditions":{"options":{"caseSensitive":false,"leftValue":"","typeValidation":"strict"},"conditions":[{"leftValue":"={{$node['Normalizar entrada'].json.command}}","rightValue":"period","operator":{"type":"string","operation":"equals"}}],"combinator":"and"},"renameOutput":true,"outputKey":"periodo"},{"conditions":{"options":{"caseSensitive":false,"leftValue":"","typeValidation":"strict"},"conditions":[{"leftValue":"={{$node['Normalizar entrada'].json.command}}","rightValue":"confirm","operator":{"type":"string","operation":"equals"}}],"combinator":"and"},"renameOutput":true,"outputKey":"confirmar"},{"conditions":{"options":{"caseSensitive":false,"leftValue":"","typeValidation":"strict"},"conditions":[{"leftValue":"={{$node['Normalizar entrada'].json.command}}","rightValue":"paid","operator":{"type":"string","operation":"equals"}}],"combinator":"and"},"renameOutput":true,"outputKey":"pago"},{"conditions":{"options":{"caseSensitive":false,"leftValue":"","typeValidation":"strict"},"conditions":[{"leftValue":"={{$node['Normalizar entrada'].json.command}}","rightValue":"consult","operator":{"type":"string","operation":"equals"}}],"combinator":"and"},"renameOutput":true,"outputKey":"consulta"}]},"options":{}},
      "id":"switch-unitv-pg","name":"Escolher operação","type":"n8n-nodes-base.switch","typeVersion":3.2,"position":[-410,0]
    },
    {
      "parameters":{"method":"POST","url":"https://tectonny.uazapi.com/send/menu","sendHeaders":true,"headerParameters":{"parameters":[{"name":"token","value":"={{$env.UAZAPI_TOKEN}}"},{"name":"Content-Type","value":"application/json"}]},"sendBody":true,"specifyBody":"json","jsonBody":"={{ JSON.stringify({number:$node['Normalizar entrada'].json.phone,type:'list',text:'Escolha uma opção:',footerText:'UniTV Automation',listButton:'Ver opções',choices:['Comprar conta|buy','Renovar conta|renew','Consultar conta|consult'],readchat:true,delay:500}) }}","options":{}},
      "id":"menu-principal-pg","name":"Uazapi - menu principal","type":"n8n-nodes-base.httpRequest","typeVersion":4.2,"position":[-120,-300]
    },
    {
      "parameters":{"method":"POST","url":"https://tectonny.uazapi.com/send/menu","sendHeaders":true,"headerParameters":{"parameters":[{"name":"token","value":"={{$env.UAZAPI_TOKEN}}"},{"name":"Content-Type","value":"application/json"}]},"sendBody":true,"specifyBody":"json","jsonBody":"={{ JSON.stringify({number:$node['Normalizar entrada'].json.phone,type:'list',text:'Qual período deseja?',footerText:'Escolha uma opção',listButton:'Ver períodos',choices:['1 mês|1m','3 meses|3m','6 meses|6m','1 ano|1y'],readchat:true,delay:500}) }}","options":{}},
      "id":"menu-periodo-pg","name":"Uazapi - menu de períodos","type":"n8n-nodes-base.httpRequest","typeVersion":4.2,"position":[-120,-100]
    },
    {
      "parameters":{"method":"POST","url":"https://automation.tectonny.com.br/api.php","authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth","sendQuery":true,"queryParameters":{"parameters":[{"name":"action","value":"simular"}]},"sendBody":true,"specifyBody":"json","jsonBody":"={{ JSON.stringify({sn:$node['Normalizar entrada'].json.sn,periodo:$node['Normalizar entrada'].json.period,operacao_direta:true,incluir_senha:false}) }}","options":{}},
      "id":"simulate-renew-pg","name":"Automation - simular renovação","type":"n8n-nodes-base.httpRequest","typeVersion":4.2,"position":[-120,100],"credentials":{"httpHeaderAuth":{"name":"Automation Bearer"}}
    },
    {
      "parameters":{"operation":"executeQuery","query":"={{ (() => { const j=$node['Normalizar entrada'].json; const esc=v=>String(v??'').replace(/'/g,\"''\"); return `UPDATE unitv_whatsapp_sessions SET operation='renew',sn='${esc(j.sn)}',period='${esc(j.period)}',payment_status='AWAITING_CONFIRM',updated_at=NOW(),expires_at=NOW()+INTERVAL '30 minutes' WHERE phone='${esc(j.phone)}';`; })() }}","options":{}},
      "id":"pg-await-confirm","name":"Postgres - aguardar confirmação","type":"n8n-nodes-base.postgres","typeVersion":2.5,"position":[120,100],"credentials":{"postgres":{"name":"Postgres UniTV Workflow"}}
    },
    {
      "parameters":{"method":"POST","url":"={{$env.UAZAPI_SEND_URL}}","sendHeaders":true,"headerParameters":{"parameters":[{"name":"token","value":"={{$env.UAZAPI_TOKEN}}"},{"name":"Content-Type","value":"application/json"}]},"sendBody":true,"specifyBody":"json","jsonBody":"={{ (()=>{const d=$node['Automation - simular renovação'].json.data??{}; const custo=d.custo??d.amount??d.amount_cents/100??0; return JSON.stringify({number:$node['Normalizar entrada'].json.phone,type:'text',text:`Conta: ${$node['Normalizar entrada'].json.sn}\\nPeríodo: ${$node['Normalizar entrada'].json.period}\\nValor: R$ ${Number(custo).toFixed(2).replace('.',',')}\\n\\nResponda CONFIRMO para gerar o Pix.`,delay:500,readchat:true});})() }}","options":{}},
      "id":"send-simulation-pg","name":"Uazapi - enviar simulação","type":"n8n-nodes-base.httpRequest","typeVersion":4.2,"position":[360,100]
    },
    {
      "parameters":{"operation":"executeQuery","query":"={{`SELECT * FROM unitv_whatsapp_sessions WHERE phone='${String($node['Normalizar entrada'].json.phone).replace(/'/g,\"''\")}';`}}","options":{}},
      "id":"pg-load-confirm","name":"Postgres - carregar sessão","type":"n8n-nodes-base.postgres","typeVersion":2.5,"position":[-120,300],"credentials":{"postgres":{"name":"Postgres UniTV Workflow"}}
    },
    {
      "parameters":{"method":"POST","url":"https://renovar.tectonny.com.br/internal_pix.php","authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth","sendBody":true,"specifyBody":"json","jsonBody":"={{ JSON.stringify({mode:'renew',sn:$json.sn,period:$json.period}) }}","options":{}},
      "id":"generate-pix-pg","name":"Renovar - gerar Pix","type":"n8n-nodes-base.httpRequest","typeVersion":4.2,"position":[120,300],"credentials":{"httpHeaderAuth":{"name":"Login renovar"}}
    },
    {
      "parameters":{"operation":"executeQuery","query":"={{ (()=>{const d=$json.data??$json; const j=$node['Normalizar entrada'].json; const esc=v=>String(v??'').replace(/'/g,\"''\"); return `UPDATE unitv_whatsapp_sessions SET public_id='${esc(d.public_id)}',amount_cents=${Number(d.amount_cents||0)},payment_status='PENDING',payload='${esc(JSON.stringify(d))}'::jsonb,updated_at=NOW(),expires_at=NOW()+INTERVAL '30 minutes' WHERE phone='${esc(j.phone)}';`;})() }}","options":{}},
      "id":"pg-save-pix","name":"Postgres - salvar cobrança","type":"n8n-nodes-base.postgres","typeVersion":2.5,"position":[360,300],"credentials":{"postgres":{"name":"Postgres UniTV Workflow"}}
    },
    {
      "parameters":{"method":"POST","url":"https://tectonny.uazapi.com/send/request-payment","sendHeaders":true,"headerParameters":{"parameters":[{"name":"token","value":"={{$env.UAZAPI_TOKEN}}"},{"name":"Content-Type","value":"application/json"}]},"sendBody":true,"specifyBody":"json","jsonBody":"={{(()=>{const d=$node['Renovar - gerar Pix'].json.data??$node['Renovar - gerar Pix'].json; return JSON.stringify({number:$node['Normalizar entrada'].json.phone,amount:Number(d.amount_cents||0)/100,text:'Pagamento da renovação UniTV',pixKey:d.pix_code,pixType:'EVP',delay:800,readchat:true});})() }}","options":{}},
      "id":"send-pix-pg","name":"Uazapi - enviar cobrança Pix","type":"n8n-nodes-base.httpRequest","typeVersion":4.2,"position":[600,300]
    },
    {
      "parameters":{"method":"GET","url":"https://renovar.tectonny.com.br/internal_status.php","authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth","sendQuery":true,"queryParameters":{"parameters":[{"name":"pedido","value":"={{$json.public_id}}"}]},"options":{}},
      "id":"status-pix-pg","name":"Renovar - consultar pagamento","type":"n8n-nodes-base.httpRequest","typeVersion":4.2,"position":[120,500],"credentials":{"httpHeaderAuth":{"name":"Login renovar"}}
    },
    {
      "parameters":{"method":"GET","url":"https://automation.tectonny.com.br/api.php","authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth","sendQuery":true,"queryParameters":{"parameters":[{"name":"action","value":"contas"},{"name":"q","value":"={{$node['Normalizar entrada'].json.sn}}"},{"name":"page_size","value":"20"}]},"options":{}},
      "id":"consult-account-pg","name":"Automation - consultar conta","type":"n8n-nodes-base.httpRequest","typeVersion":4.2,"position":[-120,700],"credentials":{"httpHeaderAuth":{"name":"Automation Bearer"}}
    },
    {
      "parameters":{"jsCode":"const d=$json.data??{}; const a=(d.list??[])[0]??{}; const i=$node['Normalizar entrada'].json; return [{json:{phone:i.phone,text:a.sn?`Conta ${a.sn}\\nNome: ${a.snName??a.cliente_nome??'não informado'}\\nVencimento: ${a.expireTime??'não informado'}\\nStatus: ${a.statusTitle??'não informado'}`:'Conta não encontrada.'}}];"},
      "id":"format-consult-pg","name":"Formatar consulta","type":"n8n-nodes-base.code","typeVersion":2,"position":[120,700]
    },
    {
      "parameters":{"method":"POST","url":"={{$env.UAZAPI_SEND_URL}}","sendHeaders":true,"headerParameters":{"parameters":[{"name":"token","value":"={{$env.UAZAPI_TOKEN}}"},{"name":"Content-Type","value":"application/json"}]},"sendBody":true,"specifyBody":"json","jsonBody":"={{JSON.stringify({number:$json.phone,type:'text',text:$json.text,delay:500,readchat:true})}}","options":{}},
      "id":"send-generic-pg","name":"Uazapi - enviar resposta","type":"n8n-nodes-base.httpRequest","typeVersion":4.2,"position":[360,700]
    },
    {
      "parameters":{"operation":"executeQuery","query":"={{`SELECT * FROM unitv_whatsapp_sessions WHERE phone='${String($node['Normalizar entrada'].json.phone).replace(/'/g,\"''\")}';`}}","options":{}},
      "id":"pg-load-payment","name":"Postgres - carregar pagamento","type":"n8n-nodes-base.postgres","typeVersion":2.5,"position":[-120,1100],"credentials":{"postgres":{"name":"Postgres UniTV Workflow"}}
    },
    {
      "parameters":{"jsCode":"const d=$json.data??$json; const status=String(d.state??d.status??d.payment_status??'PENDING').toUpperCase(); const j=$node['Normalizar entrada'].json; return [{json:{phone:j.phone,text:status==='COMPLETED'?'Pagamento confirmado. A operação será processada automaticamente.':'Pagamento ainda pendente. Aguarde a confirmação e tente novamente depois.'}}];"},
      "id":"format-status-pg","name":"Formatar status Pix","type":"n8n-nodes-base.code","typeVersion":2,"position":[120,1100]
    },
    {
      "parameters":{"method":"POST","url":"={{$env.UAZAPI_SEND_URL}}","sendHeaders":true,"headerParameters":{"parameters":[{"name":"token","value":"={{$env.UAZAPI_TOKEN}}"},{"name":"Content-Type","value":"application/json"}]},"sendBody":true,"specifyBody":"json","jsonBody":"={{JSON.stringify({number:$json.phone,type:'text',text:$json.text,delay:500,readchat:true})}}","options":{}},
      "id":"send-status-pg","name":"Uazapi - enviar status Pix","type":"n8n-nodes-base.httpRequest","typeVersion":4.2,"position":[360,1100]
    }
  ],
  "connections": {
    "Entrada WhatsApp":{"main":[[{"node":"Filtrar somente mensagens","type":"main","index":0}]]},
    "Filtrar somente mensagens":{"main":[[{"node":"Normalizar entrada","type":"main","index":0}]]},
    "Normalizar entrada":{"main":[[{"node":"Postgres - salvar sessão","type":"main","index":0}]]},
    "Postgres - salvar sessão":{"main":[[{"node":"Escolher operação","type":"main","index":0}]]},
    "Escolher operação":{"main":[[{"node":"Uazapi - menu principal","type":"main","index":0}],[{"node":"Uazapi - menu de períodos","type":"main","index":0}],[{"node":"Uazapi - menu de períodos","type":"main","index":0}],[{"node":"Automation - simular renovação","type":"main","index":0}],[{"node":"Postgres - carregar sessão","type":"main","index":0}],[{"node":"Postgres - carregar pagamento","type":"main","index":0}],[{"node":"Automation - consultar conta","type":"main","index":0}]]},
    "Automation - simular renovação":{"main":[[{"node":"Postgres - aguardar confirmação","type":"main","index":0}]]},
    "Postgres - aguardar confirmação":{"main":[[{"node":"Uazapi - enviar simulação","type":"main","index":0}]]},
    "Postgres - carregar sessão":{"main":[[{"node":"Renovar - gerar Pix","type":"main","index":0}]]},
    "Renovar - gerar Pix":{"main":[[{"node":"Postgres - salvar cobrança","type":"main","index":0}]]},
    "Postgres - salvar cobrança":{"main":[[{"node":"Uazapi - enviar cobrança Pix","type":"main","index":0}]]},
    "Automation - consultar conta":{"main":[[{"node":"Formatar consulta","type":"main","index":0}]]},
    "Formatar consulta":{"main":[[{"node":"Uazapi - enviar resposta","type":"main","index":0}] ]},
    "Postgres - carregar pagamento":{"main":[[{"node":"Renovar - consultar pagamento","type":"main","index":0}]]},
    "Renovar - consultar pagamento":{"main":[[{"node":"Formatar status Pix","type":"main","index":0}]]},
    "Formatar status Pix":{"main":[[{"node":"Uazapi - enviar status Pix","type":"main","index":0}]]}
  },
  "active": false,
  "settings": {"executionOrder":"v1"},
  "versionId":"unitv-pg-payments-v1",
  "meta": {"templateCredsSetupCompleted": false},
  "tags": []
}
