# BukioPay AI Integration Guide ## Overview BukioPay é um gateway de pagamentos Pix para aplicações web, bots e negócios digitais. - Base URL: `https://api.bukiopay.com/api/v1` - OpenAPI: `https://app.bukiopay.com/openapi.json` - Formato: JSON - Valores monetários: reais, com casas decimais. Exemplo: `10.50` representa R$ 10,50. - Valor mínimo de uma cobrança Pix: R$ 1,00. ## Authentication Use uma API key da BukioPay no header Bearer: ```http Authorization: Bearer sk_live_YOUR_API_KEY Content-Type: application/json ``` A API não usa `X-API-Key`. Chaves são exibidas uma única vez durante sua criação e devem permanecer somente no backend. Escopos exigidos: - `transaction.create`: criar ou cancelar cobranças. - `transaction.verify`: listar ou consultar cobranças. - `*`: acesso total. ## Create Pix Payment `POST /transactions` Request: ```json { "type": "PIX_IN", "amount": 100.00, "has_products": false, "description": "Pedido 123", "customer": { "name": "Cliente Exemplo", "email": "cliente@example.com" }, "include_qr_image": true } ``` Response: ```json { "success": true, "message": "Transação PIX criada com sucesso", "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "type": "PIX_IN", "status": "PENDING", "amount": 100, "feeAmount": 0.85, "netAmount": 99.15, "has_products": false, "coverFee": false, "currency": "BRL", "description": "Pedido 123", "customer": { "name": "Cliente Exemplo", "email": "cliente@example.com" }, "payment": { "copyPaste": "000201...", "qrCodeBase64": "iVBORw0KGgo...", "qrcodeUrl": "data:image/png;base64,iVBORw0KGgo..." }, "externalReference": "A1B2C3D4", "gateway": "woovi", "expiresAt": null, "createdAt": "2026-08-06T12:00:00.000Z" }, "requestId": "req_A1B2C3D4" } ``` `payment.copyPaste` é o código Pix copia e cola. `payment.qrCodeBase64` é uma imagem PNG em base64 puro. Quando `include_qr_image` for `false`, os campos de imagem podem ser nulos. ## List Payments `GET /transactions` Escopo: `transaction.verify`. Query parameters: - `type`: padrão `PIX_IN`. - `status`: `PENDING`, `COMPLETED`, `CANCELLED` ou `FAILED`. - `has_products`: `true` ou `false`. - `search`: busca por ID, referência, pagador, cliente, documento ou descrição. - `dateFrom`: início inclusivo em ISO 8601. - `dateTo`: fim exclusivo em ISO 8601. - `limit`: entre 1 e 100; padrão 20. - `offset`: inteiro maior ou igual a zero. Example: ```http GET /transactions?type=PIX_IN&status=COMPLETED&limit=20&offset=0 Authorization: Bearer sk_live_YOUR_API_KEY ``` A resposta contém `data.transactions` e `data.pagination`. ## Get Payment `GET /transactions/{id}` Escopo: `transaction.verify`. Retorna os dados da cobrança da loja autenticada. O objeto `payment` é retornado quando há código Pix ou imagem QR persistida. ## Cancel Payment `DELETE /transactions/{id}` Escopo: `transaction.create`. O cancelamento marca internamente uma cobrança não paga como `CANCELLED`. Uma cobrança `COMPLETED` não pode ser cancelada. Esse endpoint não representa estorno de um pagamento concluído. Response: ```json { "success": true, "message": "Transação cancelada com sucesso", "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "status": "CANCELLED" }, "requestId": "req_A1B2C3D4" } ``` ## Outgoing Webhooks A URL do webhook e seu secret são configurados ao criar uma API key no painel BukioPay. Em produção, a URL deve usar HTTPS. O evento de pagamento atualmente emitido pelos fluxos Pix é: - `payment.paid` Envelope: ```json { "event": "payment.paid", "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "type": "PIX_IN", "status": "paid", "amount": 100, "currency": "BRL", "hasProducts": false, "customer": { "name": "Cliente Exemplo", "document": null }, "externalReference": "A1B2C3D4", "referenceId": "gateway-reference", "paidAt": "2026-08-06T12:05:00.000Z" }, "requestId": "req_0123456789abcdef", "createdAt": "2026-08-06T12:05:01.000Z" } ``` Headers enviados: ```http Content-Type: application/json User-Agent: BukioPay-Webhooks/1.0 X-Webhook-Event: payment.paid X-Webhook-Id: req_0123456789abcdef X-Webhook-Signature: t=1786017901,v1=HEX_SIGNATURE ``` ### Verify Webhook Signature A assinatura é HMAC-SHA256 sobre: ```text TIMESTAMP.RAW_JSON_BODY ``` Use o timestamp `t` e a assinatura hexadecimal `v1` do header `X-Webhook-Signature`. Compare assinaturas em tempo constante e valide uma tolerância de tempo adequada para evitar replay. JavaScript/Node.js: ```js import crypto from "node:crypto"; export function verifyBukioWebhook(rawBody, signatureHeader, secret) { const fields = Object.fromEntries( signatureHeader.split(",").map((part) => part.split("=", 2)) ); const signedPayload = `${fields.t}.${rawBody}`; const expected = crypto .createHmac("sha256", secret) .update(signedPayload) .digest("hex"); const receivedBuffer = Buffer.from(fields.v1 || "", "hex"); const expectedBuffer = Buffer.from(expected, "hex"); return receivedBuffer.length === expectedBuffer.length && crypto.timingSafeEqual(receivedBuffer, expectedBuffer); } ``` Python: ```python import hashlib import hmac def verify_bukio_webhook(raw_body: bytes, signature_header: str, secret: str) -> bool: fields = dict(part.split("=", 1) for part in signature_header.split(",")) signed_payload = fields["t"].encode() + b"." + raw_body expected = hmac.new(secret.encode(), signed_payload, hashlib.sha256).hexdigest() return hmac.compare_digest(expected, fields.get("v1", "")) ``` Responda rapidamente com HTTP `2xx` após validar e persistir o evento. Use `requestId` ou o ID da transação para idempotência. ## Error Codes - `400 Bad Request`: parâmetros ou datas inválidos, valor abaixo de R$ 1,00 ou tentativa de cancelar cobrança paga. - `401 Unauthorized`: header Bearer ausente, vazio ou API key inválida. - `403 Forbidden`: loja não autorizada ou API key sem o escopo necessário. - `404 Not Found`: transação não encontrada para a loja autenticada. - `429 Too Many Requests`: limite de requisições excedido; respeite `Retry-After` quando presente. - `500 Internal Server Error`: erro interno ou de persistência. - `501 Not Implemented`: tipo diferente de `PIX_IN` ainda não implementado. - `502 Bad Gateway`: falha ou resultado incerto durante a criação no gateway de pagamento. - `503 Service Unavailable`: autenticação, lock ou infraestrutura temporariamente indisponível; faça retry com backoff quando indicado. Formato típico: ```json { "success": false, "error": "Bad Request", "message": "amount deve ser um número maior que zero", "requestId": "req_A1B2C3D4" } ``` Alguns erros de middleware podem omitir `success` ou `requestId`; sempre trate o status HTTP como fonte principal. ## JavaScript Example ```js const response = await fetch("https://api.bukiopay.com/api/v1/transactions", { method: "POST", headers: { Authorization: `Bearer ${process.env.BUKIOPAY_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ type: "PIX_IN", amount: 100, has_products: false, customer: { name: "Cliente Exemplo", email: "cliente@example.com" }, }), }); const result = await response.json(); if (!response.ok) throw new Error(result.message || "BukioPay request failed"); console.log(result.data.payment.copyPaste); ``` ## Python Example ```python import os import requests response = requests.post( "https://api.bukiopay.com/api/v1/transactions", headers={ "Authorization": f"Bearer {os.environ['BUKIOPAY_API_KEY']}", "Content-Type": "application/json", }, json={ "type": "PIX_IN", "amount": 100.00, "has_products": False, "customer": {"name": "Cliente Exemplo", "email": "cliente@example.com"}, }, timeout=20, ) response.raise_for_status() print(response.json()["data"]["payment"]["copyPaste"]) ``` ## PHP Example ```php "PIX_IN", "amount" => 100.00, "has_products" => false, "customer" => ["name" => "Cliente Exemplo", "email" => "cliente@example.com"] ]); $ch = curl_init("https://api.bukiopay.com/api/v1/transactions"); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer " . getenv("BUKIOPAY_API_KEY"), "Content-Type: application/json", ], CURLOPT_POSTFIELDS => $payload, CURLOPT_TIMEOUT => 20, ]); $result = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($status < 200 || $status >= 300) throw new RuntimeException($result); echo json_decode($result, true)["data"]["payment"]["copyPaste"]; ``` ## Best Practices - Nunca exponha a API key em React, navegador, aplicativo público ou repositório. - Use apenas HTTPS. - Solicite somente os escopos necessários para cada integração. - Salve o `data.id`, `externalReference` e `requestId` para rastreabilidade. - Valide a assinatura usando o corpo bruto exato do webhook. - Processe webhooks de forma idempotente. - Use timeouts e retry com backoff apenas em falhas transitórias. - Se a criação retornar `PaymentCreationUnknown`, não crie outra cobrança imediatamente; consulte ou reconcilie a transação existente. - Nunca considere um pagamento aprovado apenas por informação recebida do frontend.