{
	"info": {
		"_postman_id": "4a5e62c1-8d2b-4f9e-a1b7-d8c7b6a5f4e3",
		"name": "PayFlow — API Multi-Checkout",
		"description": "Coleção oficial de testes da API PayFlow Multi-Checkout.\n\n## Configuração rápida\n1. Acesse Configurações → Chave de API Ativa e copie a chave ativa\n2. Cole em `Variables → api_key`\n3. Ajuste `base_url` para o seu domínio\n\n## Autenticação\nTodas as requisições enviam a chave via header `X-API-KEY`.\nAlternativamente, use o parâmetro `?api_key=SUA_CHAVE`.\n\n## Códigos de resposta\n- `200` Sucesso\n- `400` Parâmetro inválido ou ausente\n- `401` Chave ausente ou inválida\n- `503` Sistema em configuração (chave não selecionada ou revogada)",
		"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
	},
	"item": [
		{
			"name": "🔑 Autenticação",
			"item": [
				{
					"name": "Testar Chave (Gerar + Consultar)",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"var res = pm.response.json();",
									"pm.test('Autenticação OK', function() {",
									"    pm.expect(pm.response.code).to.not.equal(401);",
									"    pm.expect(pm.response.code).to.not.equal(503);",
									"});",
									"if (res.pedido_id) {",
									"    pm.collectionVariables.set('ultimo_pedido_id', res.pedido_id);",
									"    console.log('Pedido criado: #' + res.pedido_id);",
									"}"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "X-API-KEY",
								"value": "{{api_key}}",
								"type": "text",
								"description": "Chave de API ativa (configurada em Configurações → Chave de API Ativa)"
							},
							{
								"key": "Content-Type",
								"value": "application/json",
								"type": "text"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n    \"valor\": \"1.00\",\n    \"nome\": \"Teste de Autenticação\",\n    \"email\": \"teste@payflow.dev\",\n    \"format\": \"json\"\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{base_url}}/gerar_pagamento",
							"host": ["{{base_url}}"],
							"path": ["gerar_pagamento"]
						},
						"description": "Gera um pedido de R$ 1,00 para confirmar que a chave está ativa e válida no banco.\nSe retornar 401 ou 503, verifique a chave em Configurações."
					},
					"response": []
				}
			],
			"description": "Testes de autenticação da API."
		},
		{
			"name": "💳 Gerar Pagamento",
			"item": [
				{
					"name": "1. Gerar Pagamento (Mínimo)",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"var res = pm.response.json();",
									"pm.test('Status 200', function() { pm.response.to.have.status(200); });",
									"pm.test('success = true', function() { pm.expect(res.success).to.be.true; });",
									"pm.test('Tem pedido_id', function() { pm.expect(res.pedido_id).to.be.a('number'); });",
									"pm.test('Tem payment_url', function() { pm.expect(res.payment_url).to.include('pagamento'); });",
									"if (res.pedido_id) pm.collectionVariables.set('ultimo_pedido_id', res.pedido_id);"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "X-API-KEY",
								"value": "{{api_key}}",
								"type": "text"
							},
							{
								"key": "Content-Type",
								"value": "application/json",
								"type": "text"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n    \"valor\": \"99.90\",\n    \"format\": \"json\"\n}",
							"options": {
								"raw": { "language": "json" }
							}
						},
						"url": {
							"raw": "{{base_url}}/gerar_pagamento",
							"host": ["{{base_url}}"],
							"path": ["gerar_pagamento"]
						},
						"description": "Cria um pedido com apenas o valor (campo obrigatório).\nRetorna `pedido_id` e `payment_url` para enviar ao cliente."
					},
					"response": []
				},
				{
					"name": "2. Gerar Pagamento (Completo)",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"var res = pm.response.json();",
									"pm.test('Status 200', function() { pm.response.to.have.status(200); });",
									"pm.test('success = true', function() { pm.expect(res.success).to.be.true; });",
									"if (res.pedido_id) pm.collectionVariables.set('ultimo_pedido_id', res.pedido_id);"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "X-API-KEY",
								"value": "{{api_key}}",
								"type": "text"
							},
							{
								"key": "Content-Type",
								"value": "application/json",
								"type": "text"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n    \"valor\": \"249.90\",\n    \"nome\": \"Maria Silva\",\n    \"email\": \"maria@email.com\",\n    \"cpf\": \"12345678900\",\n    \"telefone\": \"11999998888\",\n    \"format\": \"json\"\n}",
							"options": {
								"raw": { "language": "json" }
							}
						},
						"url": {
							"raw": "{{base_url}}/gerar_pagamento",
							"host": ["{{base_url}}"],
							"path": ["gerar_pagamento"]
						},
						"description": "Cria um pedido com todos os campos opcionais preenchidos.\nO cliente acessa `payment_url` e escolhe o gateway (PIX, boleto, cartão)."
					},
					"response": []
				},
				{
					"name": "3. Gerar Pagamento (Multi-Checkout)",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"var res = pm.response.json();",
									"pm.test('Status 200', function() { pm.response.to.have.status(200); });",
									"pm.test('success = true', function() { pm.expect(res.success).to.be.true; });"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "X-API-KEY",
								"value": "{{api_key}}",
								"type": "text"
							},
							{
								"key": "Content-Type",
								"value": "application/json",
								"type": "text"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n    \"valor\": \"50.00\",\n    \"nome\": \"João Comprador\",\n    \"email\": \"joao@email.com\",\n    \"multicheckout_id\": \"{{multicheckout_id}}\",\n    \"format\": \"json\"\n}",
							"options": {
								"raw": { "language": "json" }
							}
						},
						"url": {
							"raw": "{{base_url}}/gerar_pagamento",
							"host": ["{{base_url}}"],
							"path": ["gerar_pagamento"]
						},
						"description": "Cria um pedido vinculado a um grupo via `multicheckout_id`.\nExecute 2-3 vezes com o mesmo `multicheckout_id` para criar um grupo.\nUse 'Consultar Status (Grupo)' para ver o resumo consolidado."
					},
					"response": []
				},
				{
					"name": "4. Gerar via Query String (GET)",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"var res = pm.response.json();",
									"pm.test('Status 200', function() { pm.response.to.have.status(200); });",
									"pm.test('success = true', function() { pm.expect(res.success).to.be.true; });"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "GET",
						"header": [
							{
								"key": "X-API-KEY",
								"value": "{{api_key}}",
								"type": "text"
							}
						],
						"url": {
							"raw": "{{base_url}}/gerar_pagamento?valor=30.00&nome=Cliente+Query&email=query@email.com&format=json",
							"host": ["{{base_url}}"],
							"path": ["gerar_pagamento"],
							"query": [
								{ "key": "valor", "value": "30.00" },
								{ "key": "nome", "value": "Cliente Query" },
								{ "key": "email", "value": "query@email.com" },
								{ "key": "format", "value": "json" }
							]
						},
						"description": "Alternativa via GET com parâmetros na query string.\nA chave pode ser enviada via header `X-API-KEY` (recomendado) ou `?api_key=CHAVE`."
					},
					"response": []
				}
			],
			"description": "Endpoint: POST/GET `/gerar_pagamento`\n\nCria um pedido no banco e retorna a URL de checkout para o cliente.\n\n**Parâmetros:**\n- `valor` (obrigatório) — Valor em reais (ex: \"99.90\")\n- `nome` (opcional) — Nome do cliente\n- `email` (opcional) — Email do cliente\n- `cpf` (opcional) — CPF/CNPJ (apenas números)\n- `telefone` (opcional) — Telefone do cliente\n- `multicheckout_id` (opcional) — Agrupa pedidos num grupo\n- `format` — Sempre `\"json\"` para integrações backend\n\n**Resposta de sucesso:**\n```json\n{\n  \"success\": true,\n  \"pedido_id\": 42,\n  \"payment_url\": \"https://seu-dominio/api/pagamento?id=42\"\n}"
		},
		{
			"name": "🔍 Consultar Status",
			"item": [
				{
					"name": "1. Consultar Status (Individual)",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"var res = pm.response.json();",
									"pm.test('Status 200', function() { pm.response.to.have.status(200); });",
									"pm.test('success = true', function() { pm.expect(res.success).to.be.true; });",
									"pm.test('type = individual', function() { pm.expect(res.type).to.equal('individual'); });",
									"pm.test('Tem data.status', function() { pm.expect(res.data.status).to.be.a('string'); });",
									"console.log('Status do pedido:', res.data ? res.data.status : 'N/A');"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "GET",
						"header": [
							{
								"key": "X-API-KEY",
								"value": "{{api_key}}",
								"type": "text"
							}
						],
						"url": {
							"raw": "{{base_url}}/consultar_status?id={{ultimo_pedido_id}}&format=json",
							"host": ["{{base_url}}"],
							"path": ["consultar_status"],
							"query": [
								{ "key": "id", "value": "{{ultimo_pedido_id}}", "description": "ID do pedido (use a variável ou substitua por um número)" },
								{ "key": "format", "value": "json" }
							]
						},
						"description": "Consulta o status de um pedido individual pelo ID.\nUsa a variável `ultimo_pedido_id` definida automaticamente após 'Gerar Pagamento'."
					},
					"response": []
				},
				{
					"name": "2. Consultar Status (Grupo / Multicheckout)",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"var res = pm.response.json();",
									"pm.test('Status 200', function() { pm.response.to.have.status(200); });",
									"pm.test('success = true', function() { pm.expect(res.success).to.be.true; });",
									"pm.test('type = multicheckout', function() { pm.expect(res.type).to.equal('multicheckout'); });",
									"pm.test('Tem summary', function() { pm.expect(res.summary).to.be.an('object'); });",
									"if (res.summary) {",
									"    console.log('Total itens:', res.summary.total_items);",
									"    console.log('Pagos:', res.summary.paid_items);",
									"    console.log('Status geral:', res.summary.status_geral);",
									"}"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "GET",
						"header": [
							{
								"key": "X-API-KEY",
								"value": "{{api_key}}",
								"type": "text"
							}
						],
						"url": {
							"raw": "{{base_url}}/consultar_status?multicheckout_id={{multicheckout_id}}&format=json",
							"host": ["{{base_url}}"],
							"path": ["consultar_status"],
							"query": [
								{ "key": "multicheckout_id", "value": "{{multicheckout_id}}", "description": "ID do grupo de pedidos" },
								{ "key": "format", "value": "json" }
							]
						},
						"description": "Consulta todos os pedidos de um grupo via `multicheckout_id`.\nRetorna um resumo consolidado (total_items, paid_items, status_geral) e a lista de pedidos."
					},
					"response": []
				}
			],
			"description": "Endpoint: GET `/consultar_status`\n\nConsulta status de um pedido individual ou de um grupo multicheckout.\n\n**Parâmetros (use um dos dois):**\n- `id` — ID do pedido individual\n- `multicheckout_id` — ID do grupo de pedidos\n- `format=json` — Obrigatório\n\n**Status possíveis:**\n`pendente`, `aguardando`, `paid`, `approved`, `RECEIVED`, `CONFIRMED`, `pago`, `cancelado`, `cancelled`, `expired`, `failed`\n\n**Resposta individual:**\n```json\n{\n  \"success\": true,\n  \"type\": \"individual\",\n  \"data\": { \"id\": 42, \"status\": \"pago\", \"valor\": \"99.90\", ... }\n}\n```\n\n**Resposta grupo:**\n```json\n{\n  \"success\": true,\n  \"type\": \"multicheckout\",\n  \"summary\": { \"total_items\": 3, \"paid_items\": 2, \"status_geral\": \"parcialmente_pago\" },\n  \"items\": [...]\n}"
		},
		{
			"name": "🚨 Testes de Erro",
			"item": [
				{
					"name": "Sem API Key → 401",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test('Retorna 401', function() { pm.response.to.have.status(401); });",
									"var res = pm.response.json();",
									"pm.test('success = false', function() { pm.expect(res.success).to.be.false; });",
									"pm.test('Tem campo error', function() { pm.expect(res.error).to.be.a('string'); });",
									"console.log('Erro:', res.error);"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json",
								"type": "text"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n    \"valor\": \"10.00\",\n    \"format\": \"json\"\n}",
							"options": {
								"raw": { "language": "json" }
							}
						},
						"url": {
							"raw": "{{base_url}}/gerar_pagamento",
							"host": ["{{base_url}}"],
							"path": ["gerar_pagamento"]
						},
						"description": "Testa o comportamento quando nenhuma chave é enviada.\nEspera HTTP 401 com `{\"success\": false, \"error\": \"API Key ausente...\"}`"
					},
					"response": []
				},
				{
					"name": "Chave Inválida → 401",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test('Retorna 401', function() { pm.response.to.have.status(401); });",
									"var res = pm.response.json();",
									"pm.test('success = false', function() { pm.expect(res.success).to.be.false; });",
									"console.log('Erro:', res.error);"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "X-API-KEY",
								"value": "chave_invalida_inexistente_12345",
								"type": "text"
							},
							{
								"key": "Content-Type",
								"value": "application/json",
								"type": "text"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n    \"valor\": \"10.00\",\n    \"format\": \"json\"\n}",
							"options": {
								"raw": { "language": "json" }
							}
						},
						"url": {
							"raw": "{{base_url}}/gerar_pagamento",
							"host": ["{{base_url}}"],
							"path": ["gerar_pagamento"]
						},
						"description": "Testa com uma chave que não existe no banco.\nEspera HTTP 401 com `{\"success\": false, \"error\": \"API Key inválida.\"}`"
					},
					"response": []
				},
				{
					"name": "Valor Ausente → 400",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test('Retorna 400', function() { pm.response.to.have.status(400); });",
									"var res = pm.response.json();",
									"pm.test('success = false', function() { pm.expect(res.success).to.be.false; });",
									"console.log('Erro:', res.error);"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "X-API-KEY",
								"value": "{{api_key}}",
								"type": "text"
							},
							{
								"key": "Content-Type",
								"value": "application/json",
								"type": "text"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n    \"nome\": \"Sem Valor\",\n    \"format\": \"json\"\n}",
							"options": {
								"raw": { "language": "json" }
							}
						},
						"url": {
							"raw": "{{base_url}}/gerar_pagamento",
							"host": ["{{base_url}}"],
							"path": ["gerar_pagamento"]
						},
						"description": "Testa sem enviar o parâmetro `valor` (obrigatório).\nEspera HTTP 400 com `{\"success\": false, \"error\": \"O parâmetro 'valor' é obrigatório.\"}`"
					},
					"response": []
				},
				{
					"name": "Valor Zero → 400",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test('Retorna 400', function() { pm.response.to.have.status(400); });",
									"var res = pm.response.json();",
									"pm.test('success = false', function() { pm.expect(res.success).to.be.false; });"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{ "key": "X-API-KEY", "value": "{{api_key}}", "type": "text" },
							{ "key": "Content-Type", "value": "application/json", "type": "text" }
						],
						"body": {
							"mode": "raw",
							"raw": "{\n    \"valor\": \"0\",\n    \"format\": \"json\"\n}",
							"options": { "raw": { "language": "json" } }
						},
						"url": {
							"raw": "{{base_url}}/gerar_pagamento",
							"host": ["{{base_url}}"],
							"path": ["gerar_pagamento"]
						},
						"description": "Testa com `valor = 0`. Espera HTTP 400."
					},
					"response": []
				},
				{
					"name": "Pedido Inexistente → 400",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test('Retorna 400', function() { pm.response.to.have.status(400); });",
									"var res = pm.response.json();",
									"pm.test('success = false', function() { pm.expect(res.success).to.be.false; });"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "GET",
						"header": [
							{ "key": "X-API-KEY", "value": "{{api_key}}", "type": "text" }
						],
						"url": {
							"raw": "{{base_url}}/consultar_status?id=999999&format=json",
							"host": ["{{base_url}}"],
							"path": ["consultar_status"],
							"query": [
								{ "key": "id", "value": "999999" },
								{ "key": "format", "value": "json" }
							]
						},
						"description": "Consulta um ID que não existe. Espera HTTP 400 com `\"error\": \"Pedido não encontrado.\"`"
					},
					"response": []
				},
				{
					"name": "Sistema sem Chave Ativa → 503",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test('Retorna 503', function() { pm.response.to.have.status(503); });",
									"var res = pm.response.json();",
									"pm.test('success = false', function() { pm.expect(res.success).to.be.false; });",
									"console.log('Mensagem 503:', res.error);"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{ "key": "X-API-KEY", "value": "qualquer_chave", "type": "text" },
							{ "key": "Content-Type", "value": "application/json", "type": "text" }
						],
						"body": {
							"mode": "raw",
							"raw": "{\n    \"valor\": \"10.00\",\n    \"format\": \"json\"\n}",
							"options": { "raw": { "language": "json" } }
						},
						"url": {
							"raw": "{{base_url}}/gerar_pagamento",
							"host": ["{{base_url}}"],
							"path": ["gerar_pagamento"]
						},
						"description": "Simula o cenário onde a tabela api_keys existe mas nenhuma chave está ativa em Configurações.\nPara testar: remova o valor de ACTIVE_API_KEY no config_custom.json.\nEspera HTTP 503 com mensagem explicando que o sistema precisa de configuração."
					},
					"response": []
				}
			],
			"description": "Testes de casos de erro para verificar os comportamentos de segurança da API."
		}
	],
	"event": [
		{
			"listen": "prerequest",
			"script": {
				"type": "text/javascript",
				"exec": [
					"// Nenhum pré-processamento global necessário"
				]
			}
		},
		{
			"listen": "test",
			"script": {
				"type": "text/javascript",
				"exec": [
					"// Teste global: verificar que a resposta sempre é JSON",
					"if (pm.response.headers.get('Content-Type') &&",
					"    pm.response.headers.get('Content-Type').includes('application/json')) {",
					"    pm.test('Resposta é JSON válido', function() {",
					"        pm.response.json();",
					"    });",
					"}"
				]
			}
		}
	],
	"variable": [
		{
			"key": "base_url",
			"value": "http://localhost/api",
			"type": "string",
			"description": "URL base da API. Ajuste para o seu domínio (ex: https://meusite.com/api)"
		},
		{
			"key": "api_key",
			"value": "",
			"type": "string",
			"description": "Chave de API ativa. Copie de Configurações → Chave de API Ativa"
		},
		{
			"key": "ultimo_pedido_id",
			"value": "1",
			"type": "string",
			"description": "Preenchido automaticamente após 'Gerar Pagamento'. Usado em Consultar Status."
		},
		{
			"key": "multicheckout_id",
			"value": "grupo_teste_001",
			"type": "string",
			"description": "ID do grupo para testes de multi-checkout. Altere para isolar seus testes."
		}
	]
}
