# WyzeCash: documentação da API para assistentes de IA > Gateway de pagamentos brasileiro: cobranças por Pix, cartão de crédito e cripto, links de pagamento, saldo e extrato, saques, Pix enviado, subcontas, MED e webhooks. API REST em `https://app.wyzecash.com.br/v1`, valores sempre em centavos e a chave de API no cabeçalho `Authorization: Bearer bk_live_…`. Gerado pelo servidor da WyzeCash a partir da própria API, sempre atualizado. Índice: https://app.wyzecash.com.br/llms.txt. Documentação para pessoas: https://bukio.mintlify.app. ## Como começar - **Endereço da API:** `https://app.wyzecash.com.br`. Todas as rotas de integração ficam em `/v1`. - **Chave de API:** o dono da conta cria no painel, em Integrações e API › Developer API, marcando as permissões (uma por rota). A chave (`bk_live_…`) aparece uma vez só, na criação. - **Autenticação:** `Authorization: Bearer bk_live_…` em todo pedido. - **Valores sempre em centavos** (R$ 150,00 = `15000`). - **IDs com prefixo:** `BKY-` cobrança, `LNK-` link de pagamento, `SAQ-`/`SAQ-API-` saque, `ENV-` Pix enviado, `TRF-` transferência, `EST-` estorno, `MED-` MED, `SUB-` movimento de subconta, `sacc_` subconta. - **Não existe ambiente de testes:** todo Pix é de verdade. Para testar, faça uma cobrança pequena (o mínimo vem de `GET /v1/payments/methods`). - **Para saber quando algo acontece, use webhooks** (`payment.paid`, `withdrawal.completed`...) em vez de consultar a API. - **Formato de erro:** `{ "error": { "code", "message" }, "requestId" }`: o `code` é estável para o seu sistema e a `message` está em português. ## Chave de API e permissões Cada chave tem as permissões marcadas na criação, uma por rota e ação (`recurso:ação`). Sem a permissão, a rota responde `403 FORBIDDEN`. | Grupo | Permissões | |---|---| | Cobranças | `payments:create` (Pix), `payments:create-card`, `payments:create-crypto`, `payments:get`, `payments:list` | | Links de pagamento | `payment-links:create`, `payment-links:get`, `payment-links:list`, `payment-links:update`, `payment-links:delete`, `payment-links:payments` | | Clientes | `customers:create`, `customers:get`, `customers:list`, `customers:update`, `customers:delete` | | Saques | `withdrawals:create`, `withdrawals:get`, `withdrawals:list` | | Estornos | `refunds:create`, `refunds:get`, `refunds:list` | | MED | `meds:list`, `meds:get`, `meds:respond` (responder com a defesa e as provas) | | Conta | `account:balance`, `account:fees`, `account:statement`, `account:transactions`, `account:search` | | Comprovantes | `receipts:get` | | Subcontas | `subaccounts:create`, `subaccounts:get`, `subaccounts:list`, `subaccounts:update`, `subaccounts:delete`, `subaccounts:entries`, `subaccounts:fund`, `subaccounts:transfer`, `subaccounts:return`, `subaccounts:withdraw` | - **Dinheiro saindo** (`pix:create`, `withdrawals:create`, `refunds:create`, `subaccounts:withdraw`): a chave só é criada ou editada com o 2FA ligado na conta e o código do app autenticador. - **IP liberado** é opcional: com ele, a chave só funciona desses IPs (`403 IP_NOT_ALLOWED` dos outros). - **Validade** opcional: 30, 90, 180 dias ou 1 ano. - Dê a cada sistema uma chave só com o que ele usa. ## Cobranças: Pix, cartão e cripto `POST /v1/payments` com o cabeçalho `Idempotency-Key` (8 a 128 caracteres; repetir devolve a mesma cobrança). - **Pix** (`method: "pix"`, padrão): volta `copyPaste` (o Pix Copia e Cola, que também vira o QR Code). Vale **sempre 30 minutos** (`expiresAt`). Permissão `payments:create`. - **Cartão** (`method: "card"`, à vista, a partir de R$ 5,00): volta `paymentUrl`, a página segura de pagamento; vale 30 minutos. O número do cartão nunca passa pelo seu sistema. A venda fica "A liberar" e entra no disponível depois do prazo da conta. Permissão `payments:create-card`. - **Cripto** (`method: "crypto"`, a partir de R$ 2,00): `cryptoCurrency` `ltc` (padrão), `btc`, `eth`, `sol`, `trx`, `doge`, `ada` ou `matic`; volta `crypto` com a moeda, o valor e o endereço; vale 10 minutos. Permissão `payments:create-crypto`. - **Quem paga a tarifa:** `feePaidBy: "payer"` faz quem paga pagar o valor + a tarifa (você recebe o valor inteiro); `"user"` tira a tarifa do valor. Sem ele, vale o padrão da conta. - **Valores da resposta:** `amount` (o que você pediu), `total` (o que quem paga paga), `fee`, `netAmount` (o que você recebe) e `feePaidBy`. - **Situação:** `pending` (Entrada pendente), `paid` (Pix recebido, Cartão aprovado ou Cripto recebida), `expired` (Entrada expirada) ou `refunded` (estornada). Cobrança não se cancela: sem pagamento, ela expira. Paga depois de expirar ainda entra no saldo. - **Quem pagou:** paga no Pix, a cobrança traz `payer` (nome, CPF/CNPJ mascarado e banco). - **Faixa de valor:** `GET /v1/payments/methods` diz o mínimo e o máximo de cada forma agora. Fora da faixa: `422 BELOW_PROVIDER_MINIMUM`, `422 ABOVE_PROVIDER_MAXIMUM` ou `422 ABOVE_MAXIMUM`. Forma desligada: `422 METHOD_UNAVAILABLE`. - **Avisos:** `payment.created`, `payment.paid`, `payment.expired` e `payment.refunded` no seu webhook. ## Links de pagamento `POST /v1/payment-links` cria um link (`LNK-`) com uma página pública: cada pagador abre e gera a própria cobrança `BKY-`. - `title` (obrigatório), `description`, `amount` fixo ou valores avulsos (`suggestedAmounts` até 6, `allowCustomAmount` com `minAmount`/`maxAmount`). - `methods`: `pix`, `card`, `crypto` (cartão e cripto pedem também `payments:create-card` ou `payments:create-crypto`). - `customerFields`: quais dados pedir de quem paga (`name`, `email`, `phone`, `document`); quem paga vira cliente. - Aparência: `displayName`, `accentColor` (`#RRGGBB`), `pageTheme` (`auto`, `light`, `dark`), `buttonLabel`, `thankYouMessage`, `successUrl` (só https). - Limites: `maxPayments`, `expiresAt`; `active: false` pausa. Situação: `active`, `paused`, `expired`, `sold_out`. - `feePaidBy: "payer"`: quem paga o link paga o valor + a tarifa da forma escolhida. - As cobranças do link avisam pelos mesmos webhooks `payment.*`. ## WebSocket: eventos em tempo real Para quem não tem um endereço HTTPS público (bot de Discord ou Telegram, programa num VPS). Os eventos são os mesmos dos webhooks, com o mesmo `data`. Cobrar, sacar e consultar continuam pela API. Conecte só do seu servidor, nunca do navegador ou do app (a chave de API é secreta). **Endereço:** `wss://bukio-backend-production.up.railway.app/v1/ws` **Entrar:** a chave de API no cabeçalho `Authorization: Bearer bk_live_...` ou na primeira mensagem `{ "action": "authenticate", "apiKey": "bk_live_..." }` em até 10 segundos (nunca no endereço). Resposta: `{ "event": "authenticated", "version": "1" }`. Valem as regras da API: IP liberado da chave, conta bloqueada e verificação obrigatória; chave apagada ou vencida derruba a conexão. **Mensagens do cliente** (JSON com `action`): `authenticate`, `subscribe` e `unsubscribe` (`pattern` ou `paymentId`), `ack` (`id`, opcional) e `ping`. **Inscrições:** `*`, `payment.*`, `withdrawal.*`, `pix.*`, `transfer.*`, `subaccount.*` ou um evento exato (`payment.paid`). A chave só recebe o que pode consultar: `payment.*` pede `payments:get` ou `payments:list`; `withdrawal.*`, `withdrawals:get`/`list`; `pix.*`, `pix:get`/`list`; `transfer.*`, `account:transactions` ou `account:statement`; `subaccount.*`, `subaccounts:get`/`list` (sem a permissão: `FORBIDDEN`). Por cobrança: `{ "action": "subscribe", "paymentId": "BKY-..." }` (só da sua conta; vale 30 minutos ou até ser paga ou vencer). Até 100 inscrições por conexão. **Evento:** `{ "id": "evt_...", "event": "payment.paid", "createdAt": "...", "data": { ... } }` (o `id` é o mesmo `evt_` do webhook: guarde e ignore o repetido). **Reconectar sem perder nada:** mande o `id` do último evento que recebeu em `since` no `subscribe` (`{ "action": "subscribe", "pattern": "payment.*", "since": "evt_..." }`) e a WyzeCash manda de novo o que chegou depois (até 24 horas e 500 eventos). Evento de outra conta ou mais velho: `UNKNOWN_SINCE` (consulte a API). **Ping:** a cada 30 s chega `{ "event": "ping" }`; responda `{ "action": "ping" }` (sem nenhuma mensagem em 45 s, a conexão fecha). **Limites:** 20 conexões por conta, 30 tentativas de entrar por minuto por IP, 100 mensagens por minuto por chave, 64 KB por mensagem. **Erros** (`{ "event": "error", "code": "..." }`): `INVALID_API_KEY`, `IP_NOT_ALLOWED`, `ACCOUNT_BLOCKED`, `KYC_REQUIRED`, `RATE_LIMIT`, `INVALID_ACTION`, `FORBIDDEN`, `UNKNOWN_SINCE`, `PING_TIMEOUT`. Fecha com 1008 (entrar ou regra), 1009 (mensagem grande) ou 1001 (sem resposta ao ping). Node.js: ```js import WebSocket from "ws"; let ultimo = null; function conectar() { const ws = new WebSocket("wss://bukio-backend-production.up.railway.app/v1/ws", { headers: { Authorization: `Bearer ${process.env.BUKIOPAY_API_KEY}` }, }); ws.on("open", () => ws.send(JSON.stringify({ action: "subscribe", pattern: "payment.*", since: ultimo }))); ws.on("message", (raw) => { const msg = JSON.parse(String(raw)); if (msg.event === "ping") return ws.send(JSON.stringify({ action: "ping" })); if (!msg.id) return; ultimo = msg.id; if (msg.event === "payment.paid") console.log("Pago:", msg.data.id); }); ws.on("close", () => setTimeout(conectar, 2000)); } conectar(); ``` Python: ```python import asyncio, json, os, websockets async def main(): ultimo = None while True: try: async with websockets.connect("wss://bukio-backend-production.up.railway.app/v1/ws", additional_headers={"Authorization": f"Bearer {os.environ['BUKIOPAY_API_KEY']}"}) as ws: await ws.send(json.dumps({"action": "subscribe", "pattern": "payment.*", "since": ultimo})) async for raw in ws: msg = json.loads(raw) if msg.get("event") == "ping": await ws.send(json.dumps({"action": "ping"})) elif msg.get("id"): ultimo = msg["id"] print(msg["event"], msg["data"].get("id")) except Exception: await asyncio.sleep(2) asyncio.run(main()) ``` ## Webhooks: eventos e assinatura Cadastre as URLs (até 5) no painel, em Integrações e API › Webhooks. Todas recebem todos os eventos. **Corpo:** `{ "id": "evt_...", "type": "payment.paid", "created_at": "...", "data": { "id": "BKY-...", ... } }`, valores em centavos. O mesmo `evt_` vale em todas as URLs e em todo reenvio: guarde e ignore o repetido. **Eventos:** | Evento | Quando | `data.id` | |---|---|---| | `payment.created` · `payment.paid` · `payment.expired` | cobrança criada, paga ou expirada | `BKY-` | | `payment.refunded` | estorno concluído | `BKY-` | | `pix.sent` · `pix.failed` | Pix enviado pela rota antiga `/v1/pix/payments`, que vai ser removida (use o saque) | `ENV-` | | `withdrawal.requested` · `withdrawal.completed` · `withdrawal.failed` | saque pedido, concluído (com `receiptUrl`) ou não realizado | `SAQ-` / `SAQ-API-` | | `transfer.received` · `transfer.sent` | transferência entre contas WyzeCash | `TRF-` | | `subaccount.credited` · `subaccount.debited` | movimento numa subconta | `SUB-` | | `webhook.test` | botão "Enviar teste" do painel | `TESTE` | **Assinatura:** o cabeçalho `X-Bukio-Signature: t=,v1=` traz o HMAC-SHA256 de `"."` com o segredo do webhook (no painel). Confira com comparação de tempo constante e recuse `t` com mais de 5 minutos. Node.js: ```js import crypto from "node:crypto"; function valido(corpoCru, cabecalho, segredo) { const partes = Object.fromEntries(cabecalho.split(",").map((p) => p.split("="))); const t = Number(partes.t); if (!t || Math.abs(Date.now() / 1000 - t) > 300) return false; const esperado = crypto.createHmac("sha256", segredo).update(`${t}.${corpoCru}`).digest("hex"); const recebido = Buffer.from(partes.v1 ?? "", "hex"); return recebido.length === 32 && crypto.timingSafeEqual(recebido, Buffer.from(esperado, "hex")); } ``` PHP: ```php function valido(string $corpoCru, string $cabecalho, string $segredo): bool { parse_str(str_replace(",", "&", $cabecalho), $p); $t = (int) ($p["t"] ?? 0); if (!$t || abs(time() - $t) > 300) return false; $esperado = hash_hmac("sha256", $t . "." . $corpoCru, $segredo); return hash_equals($esperado, $p["v1"] ?? ""); } ``` Python: ```python import hmac, hashlib, time def valido(corpo_cru: bytes, cabecalho: str, segredo: str) -> bool: partes = dict(p.split("=", 1) for p in cabecalho.split(",")) t = int(partes.get("t", "0")) if not t or abs(time.time() - t) > 300: return False esperado = hmac.new(segredo.encode(), f"{t}.".encode() + corpo_cru, hashlib.sha256).hexdigest() return hmac.compare_digest(esperado, partes.get("v1", "")) ``` Use sempre o **corpo cru** (os bytes como chegaram), não o JSON já convertido. **Responda 2xx em até 10 segundos.** Falhou (outra resposta, demora ou erro de rede), reenviamos depois de 1 min, 5 min, 30 min, 2 h, 8 h e 24 h: até 7 tentativas. O botão "Reenviar" do painel vale sempre. ## Idempotency-Key Obrigatória ao criar cobrança, saque, Pix enviado, estorno e nos envios entre subcontas: o cabeçalho `Idempotency-Key` (8 a 128 caracteres: letras, números, `_`, `-`, `:` e `.`). - Repetir o pedido com a mesma chave devolve o mesmo resultado, sem criar outro (use o código do seu pedido, ex.: `pedido-1052`). - A mesma chave com outros dados: `422 IDEMPOTENCY_KEY_REUSED`. - Dois pedidos iguais ao mesmo tempo: `409 IDEMPOTENCY_IN_PROGRESS`. - Sem ela: `400 IDEMPOTENCY_KEY_REQUIRED`. ## Erros Formato: `{ "error": { "code": "...", "message": "...", "details"?: {...} }, "requestId": "..." }`. Guarde o `requestId` para falar com o suporte. | HTTP | Código | Quando | |---|---|---| | 401 | `UNAUTHORIZED` | sem chave, chave errada, revogada ou vencida | | 403 | `FORBIDDEN` | a chave não tem a permissão da rota | | 403 | `IP_NOT_ALLOWED` | a chave tem IP liberado e o pedido veio de outro | | 403 | `KYC_REQUIRED` | a conta precisa terminar a verificação de identidade no painel | | 404 | `NOT_FOUND` | o recurso não existe nesta conta | | 400 | `IDEMPOTENCY_KEY_REQUIRED` | faltou o cabeçalho `Idempotency-Key` | | 422 | `IDEMPOTENCY_KEY_REUSED` | a mesma `Idempotency-Key` com outros dados | | 422 | `VALIDATION` | campo inválido (`details.fields` diz quais) | | 422 | `BELOW_MINIMUM` | valor abaixo do mínimo da operação para a conta | | 422 | `BELOW_PROVIDER_MINIMUM` · `ABOVE_PROVIDER_MAXIMUM` | valor fora da faixa da forma de pagamento | | 422 | `METHOD_UNAVAILABLE` | forma de pagamento desligada | | 422 | `INSUFFICIENT_FUNDS` | saldo disponível não cobre valor + tarifa | | 422 | `PIX_IN_PAUSED` · `PIX_OUT_PAUSED` | Pix pausado na plataforma no momento | | 429 | `RATE_LIMITED` | passou do limite; espere o `Retry-After` | | 500 | `INTERNAL` | erro do nosso lado; tente de novo | ## Limite de pedidos Com chave de API: **100 pedidos por minuto por conta**, somando todas as rotas e todas as chaves. - Toda resposta traz `RateLimit-Limit`, `RateLimit-Remaining` e `RateLimit-Reset` (segundos até liberar a próxima vaga). A conta é por janela deslizante: em nenhum intervalo de 60 segundos passam mais de 100. - Passou: `429 RATE_LIMITED` com `Retry-After`. - Criar cobrança: até 100 por minuto. - Para saber quando paga ou conclui, use os webhooks em vez de consultar em loop. ## Saques O assistente de IA (MCP) nunca faz saque, Pix enviado ou estorno: isso é só pela API no seu sistema ou no painel, com o 2FA. - **Saque:** `POST /v1/withdrawals` com `Idempotency-Key`, `amount` e a chave Pix do recebedor (`destination: { keyType, key }`, `keyType` = `cpf`, `cnpj`, `email`, `phone` ou `random`) ou um Pix Copia e Cola (`copyPaste`: o estático, com chave, ou o de cobrança, o dinâmico, que precisa trazer o valor; a resposta diz `destination.copyPaste: true`). Permissão `withdrawals:create`. Pela API não existe chave favorita. - `feeFromAmount: true` tira a tarifa do valor (sai do saldo o `amount`, chega o `amount` menos a tarifa). - O que é das subcontas não sai no saque da conta (`422 SUBACCOUNT_FUNDS`). - **Pagar alguém ou um Pix Copia e Cola:** também é o `POST /v1/withdrawals` (a rota antiga `/v1/pix/payments` vai ser removida). - **Situação:** `processing` até concluir; depois `completed` (com `receiptUrl`, o comprovante em imagem) ou `failed`/`rejected` com o motivo. Avisos: `withdrawal.completed`/`withdrawal.failed`. - Os limites de saque da conta vêm em `GET /v1/balance` (`withdrawal`). ## Estornos `POST /v1/refunds` com `Idempotency-Key`: `{ transactionId: "BKY-...", amount?, reason? }`. Total (sem `amount`) ou parcial, só de cobrança paga no Pix. Permissão `refunds:create`. - Venda com MED aberto ou em análise: `MED_IN_PROGRESS`. - Concluído, o webhook `payment.refunded` avisa (`refundId` `EST-`). ## Subcontas Para quem vende para os próprios clientes (marketplace, plataforma): o dinheiro fica no seu saldo e a subconta (`sacc_`) diz quanto é de cada cliente. Em toda rota vale o `sacc_` ou o seu `externalId`. - **Entra** pela venda (cobrança com `subaccountId` ou `split` entre até 10), pelo envio da conta (`POST /v1/subaccounts/:id/fund`, só do saldo livre) e pela transferência entre subcontas. - **Sai** pelo saque para o cliente (`POST /v1/subaccounts/:id/withdrawals`, permissão `subaccounts:withdraw`, para a chave ou o Pix Copia e Cola dele), pela devolução à conta (`/return`), pela transferência e por estorno/MED na proporção. - **MED aberto ou estorno pedido** de uma venda dela: a parte da subconta fica reservada nela (`blocked`) até terminar; o livre (`available`) é o que pode sair. - O que é das subcontas não sai nos saques, Pix e transferências da própria conta (`GET /v1/balance` traz `subaccounts` e `free`). - **Bloqueio parcial** (`lockMode`): `receive` não recebe, `withdraw` não saca nem transfere (devolver à conta continua), `full` os dois (`422 SUBACCOUNT_LOCKED`). **Bloqueio da WyzeCash** (`platformLock`, só leitura): a WyzeCash pode travar a entrada (`receive`), a saída (`withdraw`: não saca, não transfere, não devolve à conta e não é excluída) ou tudo (`full`); vale por cima do `lockMode` e só a WyzeCash tira (`422 SUBACCOUNT_LOCKED`). **Limites do saque** (`limits`: `perWithdrawal`, `daily`, `monthly`; `422 SUBACCOUNT_LIMIT`). **CPF/CNPJ do titular** opcional (`document`, sempre inteiro: mascarado é recusado com `422 INVALID_DOCUMENT`): inteiro ao abrir a subconta, mascarado na lista (a chave Pix do cliente também). - **Nome** (`name`): de 2 a 80 caracteres. Use só o nome do cliente: o CPF/CNPJ vai no `document` e o id do seu sistema no `externalId` (letras, números, ponto, hífen e sublinhado). - **Saque para o titular** (Configuração das subcontas, `holderWithdrawal`): `off` (padrão), `notify` (avisa quando o banco confirma um CPF diferente do titular; o webhook traz `destination.holderMatch: "different"`) ou `cpf_only` (só saca para a chave CPF/CNPJ do titular: `422 SUBACCOUNT_HOLDER_KEY`). O saque traz `subaccount`, a sua referência (`description`) e, concluído, `destination.document` e `destination.holderMatch`. - Cobranças e saques de uma subconta: `GET /v1/payments?subaccountId=` e `GET /v1/withdrawals?subaccountId=`. A lista traz os números de cada uma (`stats`). - Envio, transferência e devolução pedem `Idempotency-Key`. Desativada, não recebe nem saca. - Avisos: `subaccount.credited` e `subaccount.debited`. ## MED (pedido de devolução) O MED é o pedido de devolução de um Pix feito pelo banco de quem pagou. O valor fica bloqueado até a decisão. - `GET /v1/meds` e `/v1/meds/:id`: valor, `blocked`, prazo, a cobrança de origem e a situação: `open` (Aberto), `analysis` (Em análise), `rejected` (Contestado: o valor volta para você) ou `refunded` (Devolvido a quem pagou). - A defesa se envia pela API (`POST /v1/meds/:id/respond`, permissão `meds:respond`: o texto e até 5 provas em base64), pelo painel em MED e disputas, ou fica com a defesa automática ligada. As provas não voltam para baixar: ficam com a WyzeCash. - Só no Pix: cartão e cripto não têm MED. ## Tarifas - `GET /v1/fees`: a tarifa de cada operação para a conta (`fixedCents` + `percentBps`; `minCents` é o valor mínimo da operação). Vale a negociada para a conta, ou a da plataforma. - `GET /v1/fees/preview?operation=PIX_CHARGE&amount=15000`: a tarifa exata de um valor, calculada no servidor. Não calcule a tarifa no seu sistema. - Operações: `PIX_CHARGE`, `CARD_CHARGE`, `CRYPTO_CHARGE`, `WITHDRAWAL`, `CRYPTO_WITHDRAWAL`, `INTERNAL_TRANSFER`, `MED`. - `WITHDRAWAL` é a tarifa de todo Pix que sai: saque, Pix enviado e Copia e Cola (a mesma tarifa e o mesmo valor mínimo). - Sem mensalidade: só a tarifa por operação. ## O MCP da WyzeCash Endereço: `https://app.wyzecash.com.br/mcp` (HTTP, sem instalar nada). - **Sem chave:** as ferramentas de documentação (`listar_operacoes`, `ver_operacao`, `exemplo_codigo`, `buscar_documentacao`) e os prompts prontos. - **Com a chave** (`Authorization: Bearer bk_live_…` na configuração do assistente): `testar_chave` e as ferramentas da conta (criar e consultar cobranças e links, saldo, extrato, tarifas, clientes, subcontas, MED e comprovantes), só com as permissões da chave e pelas mesmas regras da API. - **Dinheiro não sai pelo MCP:** saque, Pix enviado, estorno e saldo de subconta ficam no seu sistema (pela API) ou no painel, com o 2FA. ## Rotas da API ### Cobranças #### Criar cobrança (`criar_cobranca`) `POST https://app.wyzecash.com.br/v1/payments` Cria uma cobrança (BKY-) no Pix, no cartão ou em cripto. Valores em centavos. - Permissão da chave: `payments:create` ou `payments:create-card` ou `payments:create-crypto`. - Pede o cabeçalho `Idempotency-Key` (8 a 128 caracteres). **No corpo (JSON):** - `amount` (inteiro, obrigatório, mínimo 1) - `description` (texto, até 140 caracteres) - `expiresInMinutes` (inteiro, mínimo 5, máximo 43200) - `subaccountId` (texto, formato `^[A-Za-z0-9_.-]{1,64}$`) - `split` (lista, até 10 itens) - `subaccountId` (texto, obrigatório, formato `^[A-Za-z0-9_.-]{1,64}$`) - `amount` (inteiro, obrigatório, mínimo 1) - `customerId` (texto, formato uuid) - `method` (um destes: pix, card, crypto) - `cryptoCurrency` (um destes: ltc, btc, eth, sol, trx, doge, ada, matic) - `feePaidBy` (um destes: payer, user) - `tracking` (objeto) - `utm_source` (texto, até 500 caracteres) - `utm_medium` (texto, até 500 caracteres) - `utm_campaign` (texto, até 500 caracteres) - `utm_content` (texto, até 500 caracteres) - `utm_term` (texto, até 500 caracteres) - `src` (texto, até 500 caracteres) - `sck` (texto, até 500 caracteres) - `fbc` (texto, até 500 caracteres) - `fbp` (texto, até 500 caracteres) - `gaClientId` (texto, até 500 caracteres) - `gaSessionId` (texto, até 500 caracteres) - `ip` (texto, até 500 caracteres) - `userAgent` (texto, até 500 caracteres) - `pageUrl` (texto, até 500 caracteres) **Regras:** - `method`: `pix` (padrão), `card` ou `crypto`. Cada forma pede a sua permissão: `payments:create` (Pix), `payments:create-card` (cartão), `payments:create-crypto` (cripto). - Pix: volta o `copyPaste` (Pix Copia e Cola) e vale sempre 30 minutos (`expiresAt` diz até quando). `expiresInMinutes` é aceito e ignorado. - Cartão (à vista, a partir de R$ 5,00): volta o `paymentUrl`, a página de pagamento, que vale 30 minutos. Venda no cartão fica "A liberar" e entra no disponível depois do prazo da conta. - Cripto (a partir de R$ 2,00): `cryptoCurrency` (`ltc` padrão, `btc`, `eth`, `sol`, `trx`, `doge`, `ada`, `matic`); volta `crypto` com moeda, valor e endereço; vale 10 minutos. - `feePaidBy`: `payer` (quem paga paga o valor + a tarifa e você recebe o valor inteiro) ou `user` (a tarifa sai do valor). Sem ele, vale o padrão da conta. - A resposta traz `amount` (o que você pediu), `total` (o que quem paga paga), `fee`, `netAmount` (o que você recebe) e `feePaidBy`. - `customerId` liga ao cliente; `subaccountId` credita a venda numa subconta; `split` divide entre até 10 subcontas. - Para saber quando foi paga, use o webhook `payment.paid` em vez de consultar. **Exemplo (cURL):** ```bash curl -X POST "https://app.wyzecash.com.br/v1/payments" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" \ -H "Idempotency-Key: pedido-1052" \ -H "Content-Type: application/json" \ -d '{"amount":15000,"description":"Pedido #1052","method":"pix"}' ``` **Resposta (trecho):** ```json { "id": "BKY-8K2M4QZ7XN3P", "status": "pending", "statusTitle": "Entrada pendente", "amount": 15000, "total": 15000, "fee": 50, "netAmount": 14950, "feePaidBy": "user", "refundedAmount": 0, "description": "Pedido #1052", "txid": "BKK8K2M4QZ7XN3P0000000000", "method": "pix", "methodTitle": "Pix", "copyPaste": "00020126...", "paymentUrl": null, "crypto": null, "card": null, "availableAt": null, "released": null, "expiresAt": "2026-10-15T12:30:00.000Z", "paidAt": null, "customer": null, "subaccountId": null, "split": null, "payer": null, "createdAt": "2026-10-15T12:00:00.000Z" } ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Formas de pagamento disponíveis (`formas_de_pagamento`) `GET https://app.wyzecash.com.br/v1/payments/methods` As formas que dá para cobrar agora (só as que a chave pode criar), com o valor mínimo e o máximo de cada uma, em centavos. - Permissão da chave: `payments:create` ou `payments:create-card` ou `payments:create-crypto`. **Exemplo (cURL):** ```bash curl -X GET "https://app.wyzecash.com.br/v1/payments/methods" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" ``` **Resposta (trecho):** ```json { "items": [ { "method": "pix", "title": "Pix", "available": true, "minAmount": 100, "maxAmount": 200000 } ] } ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Listar cobranças (`listar_cobrancas`) `GET https://app.wyzecash.com.br/v1/payments` As cobranças da conta, das mais novas para as mais antigas, com cursor (`limit` até 100 e o `cursor` da página anterior). `subaccountId` (o `sacc_` ou o `externalId`) traz só as de uma subconta, inclusive as divididas com ela. Filtros: `status` (`pending`, `paid`, `expired`, `refunded`), `method` (`pix`, `card`, `crypto`), `customerId` e `q` (busca no código, na descrição, em quem pagou e no nome do cliente). - Permissão da chave: `payments:list`. **Na consulta (query):** - `limit` (número, mínimo 1, máximo 100) - `cursor` (texto, até 200 caracteres) - `subaccountId` (texto, formato `^[A-Za-z0-9_.-]{1,64}$`) - `customerId` (texto, formato uuid) - `status` (um destes: pending, paid, expired, refunded) - `method` (um destes: pix, card, crypto) - `q` (texto, até 80 caracteres) **Exemplo (cURL):** ```bash curl -X GET "https://app.wyzecash.com.br/v1/payments?limit=20&status=paid" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Consultar cobrança (`consultar_cobranca`) `GET https://app.wyzecash.com.br/v1/payments/:id` Uma cobrança pelo código BKY-: situação (`pending`, `paid`, `expired`, `refunded`), valores e, paga no Pix, quem pagou (`payer`, com o CPF mascarado). - Permissão da chave: `payments:get`. **No caminho:** - `id` (texto, obrigatório) **Exemplo (cURL):** ```bash curl -X GET "https://app.wyzecash.com.br/v1/payments/BKY-8K2M4QZ7XN3P" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). ### Links de pagamento #### Criar link de pagamento (`criar_link`) `POST https://app.wyzecash.com.br/v1/payment-links` Cria um link de pagamento (LNK-): uma página pública em que cada pagador gera a própria cobrança. - Permissão da chave: `payment-links:create`. **No corpo (JSON):** - `title` (texto, obrigatório, até 80 caracteres) - `description` (texto, até 280 caracteres) - `amount` (inteiro, mínimo 1) - `minAmount` (inteiro, mínimo 1) - `maxAmount` (inteiro, mínimo 1, máximo 100000000) - `suggestedAmounts` (lista de inteiro, até 6 itens) - `allowCustomAmount` (verdadeiro/falso) - `displayName` (texto, até 60 caracteres) - `accentColor` (texto, formato `^#[0-9a-fA-F]{6}$`) - `pageTheme` (um destes: auto, light, dark) - `buttonLabel` (texto, até 40 caracteres) - `thankYouMessage` (texto, até 280 caracteres) - `successUrl` (texto, até 500 caracteres) - `collectCustomer` (verdadeiro/falso) - `customerFields` (lista com: name, email, phone, document, até 4 itens) - `maxPayments` (inteiro, mínimo 1, máximo 1000000) - `expiresAt` (texto, formato date-time) - `active` (verdadeiro/falso) - `methods` (lista com: pix, card, crypto, até 3 itens) - `feePaidBy` (um destes: payer, user) - `subaccountId` (texto, formato `^[A-Za-z0-9_.-]{1,64}$`) **Regras:** - `amount` fixo, ou sem `amount` para valores avulsos (`suggestedAmounts`, até 6, e `allowCustomAmount` com `minAmount`/`maxAmount`). - `methods`: `pix`, `card`, `crypto` (cartão e cripto pedem também `payments:create-card` ou `payments:create-crypto`). - `customerFields`: quais dados pedir (`name`, `email`, `phone`, `document`); `maxPayments` e `expiresAt` limitam o link. - `feePaidBy: "payer"`: quem paga o link paga o valor + a tarifa. **Exemplo (cURL):** ```bash curl -X POST "https://app.wyzecash.com.br/v1/payment-links" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" \ -H "Content-Type: application/json" \ -d '{"title":"Curso de violão","amount":4990}' ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Listar links de pagamento (`listar_links`) `GET https://app.wyzecash.com.br/v1/payment-links` Os links da conta com a situação (`active`, `paused`, `expired`, `sold_out`), quantas vendas e quanto recebeu. - Permissão da chave: `payment-links:list`. **Exemplo (cURL):** ```bash curl -X GET "https://app.wyzecash.com.br/v1/payment-links" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Consultar link de pagamento (`consultar_link`) `GET https://app.wyzecash.com.br/v1/payment-links/:id` Um link pelo código LNK-. - Permissão da chave: `payment-links:get`. **No caminho:** - `id` (texto, obrigatório) **Exemplo (cURL):** ```bash curl -X GET "https://app.wyzecash.com.br/v1/payment-links/LNK-7Q2M9XD4K8PA" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Editar link de pagamento (`editar_link`) `PATCH https://app.wyzecash.com.br/v1/payment-links/:id` Muda os dados do link. `active: false` pausa. - Permissão da chave: `payment-links:update`. **No caminho:** - `id` (texto, obrigatório) **No corpo (JSON):** - `title` (texto, até 80 caracteres) - `description` (texto, até 280 caracteres) - `amount` (inteiro, mínimo 1) - `minAmount` (inteiro, mínimo 1) - `maxAmount` (inteiro, mínimo 1, máximo 100000000) - `suggestedAmounts` (lista de inteiro, até 6 itens) - `allowCustomAmount` (verdadeiro/falso) - `displayName` (texto, até 60 caracteres) - `accentColor` (texto, formato `^#[0-9a-fA-F]{6}$`) - `pageTheme` (um destes: auto, light, dark) - `buttonLabel` (texto, até 40 caracteres) - `thankYouMessage` (texto, até 280 caracteres) - `successUrl` (texto, até 500 caracteres) - `collectCustomer` (verdadeiro/falso) - `customerFields` (lista com: name, email, phone, document, até 4 itens) - `maxPayments` (inteiro, mínimo 1, máximo 1000000) - `expiresAt` (texto, formato date-time) - `active` (verdadeiro/falso) - `methods` (lista com: pix, card, crypto, até 3 itens) - `feePaidBy` (um destes: payer, user) - `subaccountId` (texto, formato `^[A-Za-z0-9_.-]{1,64}$`) **Exemplo (cURL):** ```bash curl -X PATCH "https://app.wyzecash.com.br/v1/payment-links/LNK-7Q2M9XD4K8PA" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" \ -H "Content-Type: application/json" \ -d '{"active":false}' ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Excluir link de pagamento (`excluir_link`) `DELETE https://app.wyzecash.com.br/v1/payment-links/:id` O link para de funcionar; as cobranças já geradas ficam. - Permissão da chave: `payment-links:delete`. **No caminho:** - `id` (texto, obrigatório) **Exemplo (cURL):** ```bash curl -X DELETE "https://app.wyzecash.com.br/v1/payment-links/LNK-7Q2M9XD4K8PA" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Cobranças geradas por um link (`cobrancas_do_link`) `GET https://app.wyzecash.com.br/v1/payment-links/:id/payments` As cobranças BKY- que os pagadores geraram pelo link. - Permissão da chave: `payment-links:payments`. **No caminho:** - `id` (texto, obrigatório) **Exemplo (cURL):** ```bash curl -X GET "https://app.wyzecash.com.br/v1/payment-links/LNK-7Q2M9XD4K8PA/payments" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). ### Clientes #### Listar clientes (`listar_clientes`) `GET https://app.wyzecash.com.br/v1/customers` Os clientes da conta. - Permissão da chave: `customers:list`. **Exemplo (cURL):** ```bash curl -X GET "https://app.wyzecash.com.br/v1/customers" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Consultar cliente (`consultar_cliente`) `GET https://app.wyzecash.com.br/v1/customers/:id` Um cliente pelo id. - Permissão da chave: `customers:get`. **No caminho:** - `id` (texto, obrigatório) **Exemplo (cURL):** ```bash curl -X GET "https://app.wyzecash.com.br/v1/customers/3f1c2b7e-9a4d-4c11-8e2f-5b6a7c8d9e01" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Criar cliente (`criar_cliente`) `POST https://app.wyzecash.com.br/v1/customers` Cadastra um cliente (e-mail, celular e CPF/CNPJ ficam criptografados). O `id` vai no `customerId` da cobrança. - Permissão da chave: `customers:create`. **No corpo (JSON):** - `name` (texto, obrigatório, de 2 a 120 caracteres) - `email` (texto, até 254 caracteres) - `phone` (texto, até 20 caracteres) - `document` (texto, até 20 caracteres) **Exemplo (cURL):** ```bash curl -X POST "https://app.wyzecash.com.br/v1/customers" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" \ -H "Content-Type: application/json" \ -d '{"name":"Maria Souza","email":"maria@exemplo.com"}' ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Editar cliente (`editar_cliente`) `PATCH https://app.wyzecash.com.br/v1/customers/:id` Muda os dados de um cliente. - Permissão da chave: `customers:update`. **No caminho:** - `id` (texto, obrigatório) **No corpo (JSON):** - `name` (texto, de 2 a 120 caracteres) - `email` (texto, até 254 caracteres) - `phone` (texto, até 20 caracteres) - `document` (texto, até 20 caracteres) **Exemplo (cURL):** ```bash curl -X PATCH "https://app.wyzecash.com.br/v1/customers/3f1c2b7e-9a4d-4c11-8e2f-5b6a7c8d9e01" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" \ -H "Content-Type: application/json" \ -d '{"name":"Maria Souza Lima"}' ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Excluir cliente (`excluir_cliente`) `DELETE https://app.wyzecash.com.br/v1/customers/:id` Esconde o cliente; as cobranças antigas mantêm o nome. - Permissão da chave: `customers:delete`. **No caminho:** - `id` (texto, obrigatório) **Exemplo (cURL):** ```bash curl -X DELETE "https://app.wyzecash.com.br/v1/customers/3f1c2b7e-9a4d-4c11-8e2f-5b6a7c8d9e01" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). ### Conta #### Saldo (`saldo`) `GET https://app.wyzecash.com.br/v1/balance` Disponível, bloqueado e a liberar, quanto é das subcontas (`subaccounts`) e o livre (`free`), e os limites de saque do dia (`withdrawal`). - Permissão da chave: `account:balance`. **Exemplo (cURL):** ```bash curl -X GET "https://app.wyzecash.com.br/v1/balance" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Tarifas da conta (`tarifas`) `GET https://app.wyzecash.com.br/v1/fees` A tarifa de cada operação (`PIX_CHARGE`, `CARD_CHARGE`, `CRYPTO_CHARGE`, `WITHDRAWAL`, `CRYPTO_WITHDRAWAL`, `INTERNAL_TRANSFER`, `MED`): `fixedCents`, `percentBps` e `minCents` (o valor mínimo da operação). `WITHDRAWAL` vale para todo Pix que sai: saque, Pix enviado e Copia e Cola. Vale a negociada para a conta, ou a da plataforma. - Permissão da chave: `account:fees`. **Exemplo (cURL):** ```bash curl -X GET "https://app.wyzecash.com.br/v1/fees" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Prévia da tarifa de um valor (`previa_tarifa`) `GET https://app.wyzecash.com.br/v1/fees/preview` Quanto a WyzeCash cobra numa operação de um valor (calculado no servidor, nunca no seu sistema). - Permissão da chave: `account:fees`. **Na consulta (query):** - `operation` (texto, obrigatório, até 40 caracteres) - `amount` (número, obrigatório, mínimo 1, máximo 1000000000000) **Exemplo (cURL):** ```bash curl -X GET "https://app.wyzecash.com.br/v1/fees/preview?operation=PIX_CHARGE&amount=15000" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Extrato (`extrato`) `GET https://app.wyzecash.com.br/v1/statement` O extrato do painel: movimentações, cobranças em aberto ou expiradas e MED (com a Taxa de MED recebido em linha própria), com os totais do período inteiro (só na primeira página). Em páginas com `limit` (até 200) e `cursor` (o `nextCursor` da página anterior). Filtros: `days` (0, 7, 30, 90), `direction`, `category`, `method` e `q` (busca). - Permissão da chave: `account:statement`. **Na consulta (query):** - `cursor` (texto, até 200 caracteres) - `limit` (número, mínimo 1, máximo 200) - `days` (número, mínimo 0, máximo 90) - `from` (texto, até 40 caracteres) - `to` (texto, até 40 caracteres) - `direction` (um destes: all, income, expense) - `category` (um destes: pix, charge, transfer, withdraw, refund, med, referral) - `method` (um destes: pix, card, crypto) - `q` (texto, até 80 caracteres) **Exemplo (cURL):** ```bash curl -X GET "https://app.wyzecash.com.br/v1/statement?days=7" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Listar movimentações (`listar_transacoes`) `GET https://app.wyzecash.com.br/v1/transactions` Movimentações com cursor (`limit` até 100) e filtros `type` e `status`; `details` traz quem pagou ou recebeu, o banco, a chave mascarada e o EndToEndId. - Permissão da chave: `account:transactions`. **Na consulta (query):** - `limit` (número, mínimo 1, máximo 100) - `cursor` (texto, até 200 caracteres) - `type` (texto, até 200 caracteres) - `status` (texto, até 100 caracteres) - `q` (texto, até 80 caracteres) **Exemplo (cURL):** ```bash curl -X GET "https://app.wyzecash.com.br/v1/transactions?limit=50" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Consultar movimentação (`consultar_transacao`) `GET https://app.wyzecash.com.br/v1/transactions/:id` Uma movimentação pelo código com prefixo (BKY-, SAQ-, ENV-, TRF-, EST-, MED-, TAR-, SUB-, IND-). - Permissão da chave: `account:transactions`. **No caminho:** - `id` (texto, obrigatório) **Exemplo (cURL):** ```bash curl -X GET "https://app.wyzecash.com.br/v1/transactions/BKY-8K2M4QZ7XN3P" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Buscar na conta (`buscar`) `GET https://app.wyzecash.com.br/v1/search` Busca movimentações, cobranças, MED e clientes pelo código, descrição, nome ou valor (de 2 a 80 caracteres). - Permissão da chave: `account:search`. **Na consulta (query):** - `q` (texto, obrigatório, de 2 a 80 caracteres) **Exemplo (cURL):** ```bash curl -X GET "https://app.wyzecash.com.br/v1/search?q=Maria" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). ### Comprovantes #### Link do comprovante (`comprovante`) `GET https://app.wyzecash.com.br/v1/receipts/:id` O link da imagem do comprovante de um saque (SAQ-), Pix enviado (ENV-) ou transferência enviada (TRF-) concluído: `{ url }`. Ainda não concluído: `409 RECEIPT_NOT_READY`. - Permissão da chave: `receipts:get`. **No caminho:** - `id` (texto, obrigatório) **Exemplo (cURL):** ```bash curl -X GET "https://app.wyzecash.com.br/v1/receipts/SAQ-4N8R2T6V9X1Z" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). ### MED #### Listar MED (`listar_meds`) `GET https://app.wyzecash.com.br/v1/meds` Os pedidos de devolução (MED) das vendas no Pix: valor, quanto está bloqueado, prazo e situação (`open` Aberto, `analysis` Em análise, `rejected` Contestado, `refunded` Devolvido). Filtro `status` (ex.: `open,analysis`) e páginas por `cursor`. - Permissão da chave: `meds:list`. **Na consulta (query):** - `limit` (número, mínimo 1, máximo 100) - `cursor` (texto, até 200 caracteres) - `status` (texto, até 60 caracteres) **Exemplo (cURL):** ```bash curl -X GET "https://app.wyzecash.com.br/v1/meds" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Consultar MED (`consultar_med`) `GET https://app.wyzecash.com.br/v1/meds/:id` Um MED pelo código MED-, com a cobrança de origem e quem respondeu (`answered`: `user`, `auto` ou `null`). - Permissão da chave: `meds:get`. **No caminho:** - `id` (texto, obrigatório) **Exemplo (cURL):** ```bash curl -X GET "https://app.wyzecash.com.br/v1/meds/MED-2H7K9M3P5R8T" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Responder MED (`responder_med`) `POST https://app.wyzecash.com.br/v1/meds/:id/respond` Manda a defesa de um MED aberto (`defense`, de 20 a 4.000 caracteres, explicando a venda e a entrega) com até 5 provas em `evidence` (imagem JPG, PNG ou WEBP ou PDF, em base64 em `contentBase64`, até 5 MB cada). A WyzeCash leva a defesa e as provas ao banco de quem pagou; depois disso o MED segue a situação de sempre. - Permissão da chave: `meds:respond`. **No caminho:** - `id` (texto, obrigatório) **No corpo (JSON):** - `defense` (texto, obrigatório, de 1 a 4000 caracteres) - `evidence` (lista, até 5 itens) - `fileName` (texto, até 120 caracteres) - `contentBase64` (texto, obrigatório, de 4 a 7100000 caracteres) **Regras:** - Só com o MED `open` e dentro do prazo (`deadline`): depois, `409 MED_NOT_OPEN` ou `409 MED_DEADLINE_PASSED`. Uma resposta por MED. - As provas não voltam para baixar: ficam guardadas com a WyzeCash e só vão para o banco de quem pagou. - O MCP não manda a defesa: só mostra como o seu sistema faz. **Exemplo (cURL):** ```bash curl -X POST "https://app.wyzecash.com.br/v1/meds/MED-2H7K9M3P5R8T/respond" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" \ -H "Content-Type: application/json" \ -d '{"defense":"Venda do pedido 1052 entregue em 10/11/2026 às 14:20 no e-mail do comprador, que abriu o produto em seguida.","evidence":[{"fileName":"comprovante-entrega.pdf","contentBase64":"JVBERi0xLjQKJcOkw7zDtsOfCi4uLgolJUVPRgo="}]}' ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). ### Saques #### Sacar (`criar_saque`) `POST https://app.wyzecash.com.br/v1/withdrawals` Saque (SAQ-API-) por Pix para a chave enviada no pedido (`destination`) ou um Pix Copia e Cola (`copyPaste`). Pela API não existe chave favorita. - Permissão da chave: `withdrawals:create`. - Pede o cabeçalho `Idempotency-Key` (8 a 128 caracteres). - Tira dinheiro da conta: feita pelo seu sistema (pela API) ou no painel, com a permissão na chave e o 2FA ligado na conta. **No corpo (JSON):** - `amount` (inteiro, obrigatório, mínimo 1) - `pixKeyId` (texto, formato uuid) - `destination` (objeto) - `keyType` (um destes: cpf, cnpj, email, phone, random, obrigatório) - `key` (texto, obrigatório, de 3 a 77 caracteres) - `copyPaste` (texto, de 40 a 512 caracteres) - `description` (texto, até 140 caracteres) - `feeFromAmount` (verdadeiro/falso) **Regras:** - A chave com `withdrawals:create` só é criada com o 2FA ligado na conta e o código do app autenticador. - `feeFromAmount: true` tira a tarifa do valor: sai do saldo o `amount` e chega o `amount` menos a tarifa. - O que é das subcontas não sai (`422 SUBACCOUNT_FUNDS`); o saque da subconta é outra rota. - Situação: `processing` até concluir, depois `completed` (com `receiptUrl`) ou `failed`/`rejected` com o motivo. Os webhooks `withdrawal.completed` e `withdrawal.failed` avisam. **Exemplo (cURL):** ```bash curl -X POST "https://app.wyzecash.com.br/v1/withdrawals" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" \ -H "Idempotency-Key: pedido-1052" \ -H "Content-Type: application/json" \ -d '{"amount":10000,"destination":{"keyType":"email","key":"financeiro@exemplo.com"}}' ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Listar saques (`listar_saques`) `GET https://app.wyzecash.com.br/v1/withdrawals` Os saques da conta (concluído traz o `receiptUrl`; o da subconta traz `subaccount` e `destination.holderMatch`). `subaccountId` (o `sacc_` ou o `externalId`) traz só os saques de uma subconta. - Permissão da chave: `withdrawals:list`. **Na consulta (query):** - `limit` (número, mínimo 1, máximo 100) - `cursor` (texto, até 200 caracteres) - `subaccountId` (texto, formato `^[A-Za-z0-9_.-]{1,64}$`) **Exemplo (cURL):** ```bash curl -X GET "https://app.wyzecash.com.br/v1/withdrawals" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Consultar saque (`consultar_saque`) `GET https://app.wyzecash.com.br/v1/withdrawals/:id` Um saque pelo código SAQ- ou SAQ-API-. - Permissão da chave: `withdrawals:get`. **No caminho:** - `id` (texto, obrigatório) **Exemplo (cURL):** ```bash curl -X GET "https://app.wyzecash.com.br/v1/withdrawals/SAQ-4N8R2T6V9X1Z" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). ### Estornos #### Estornar uma cobrança (`criar_estorno`) `POST https://app.wyzecash.com.br/v1/refunds` Estorno (EST-) total ou parcial de uma cobrança paga no Pix (`transactionId` = o BKY-). Só no Pix. - Permissão da chave: `refunds:create`. - Pede o cabeçalho `Idempotency-Key` (8 a 128 caracteres). - Tira dinheiro da conta: feita pelo seu sistema (pela API) ou no painel, com a permissão na chave e o 2FA ligado na conta. **No corpo (JSON):** - `transactionId` (texto, obrigatório, formato `^BKY-[0-9A-Z]{12}$`) - `amount` (inteiro, mínimo 1) - `reason` (texto, até 140 caracteres) **Regras:** - A chave com `refunds:create` só é criada com o 2FA ligado na conta e o código do app autenticador. - Recusado com `MED_IN_PROGRESS` se a venda tem MED aberto ou em análise. - Concluído, o webhook `payment.refunded` avisa. **Exemplo (cURL):** ```bash curl -X POST "https://app.wyzecash.com.br/v1/refunds" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" \ -H "Idempotency-Key: pedido-1052" \ -H "Content-Type: application/json" \ -d '{"transactionId":"BKY-8K2M4QZ7XN3P","amount":5000,"reason":"Pedido cancelado"}' ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Listar estornos (`listar_estornos`) `GET https://app.wyzecash.com.br/v1/refunds` Os estornos da conta. - Permissão da chave: `refunds:list`. **Na consulta (query):** - `limit` (número, mínimo 1, máximo 100) - `cursor` (texto, até 200 caracteres) **Exemplo (cURL):** ```bash curl -X GET "https://app.wyzecash.com.br/v1/refunds" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Consultar estorno (`consultar_estorno`) `GET https://app.wyzecash.com.br/v1/refunds/:id` Um estorno pelo código EST-. - Permissão da chave: `refunds:get`. **No caminho:** - `id` (texto, obrigatório) **Exemplo (cURL):** ```bash curl -X GET "https://app.wyzecash.com.br/v1/refunds/EST-9C4F7J2L5N8Q" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). ### Subcontas #### Criar subconta (`criar_subconta`) `POST https://app.wyzecash.com.br/v1/subaccounts` Cria uma subconta (sacc_) para um cliente seu: o dinheiro fica no seu saldo e a subconta diz quanto é dele. Em toda rota vale o `sacc_` ou o seu `externalId`. - Permissão da chave: `subaccounts:create`. **No corpo (JSON):** - `name` (texto, obrigatório, de 1 a 200 caracteres) - `email` (texto, até 254 caracteres) - `externalId` (texto, até 64 caracteres) - `saleFeeBps` (inteiro, mínimo 0, máximo 10000) - `saleFeeFixed` (inteiro, mínimo 0, máximo 1000000) - `withdrawFeeBps` (inteiro, mínimo 0, máximo 10000) - `withdrawFeeFixed` (inteiro, mínimo 0, máximo 1000000) - `feeMode` (um destes: global, custom) - `metadata` (objeto) - `pixKey` (objeto) - `keyType` (um destes: cpf, cnpj, email, phone, random, obrigatório) - `key` (texto, obrigatório, de 3 a 77 caracteres) - `lockMode` (um destes: none, receive, withdraw, full) - `limits` (objeto) - `perWithdrawal` (inteiro, mínimo 1, máximo 100000000000) - `daily` (inteiro, mínimo 1, máximo 100000000000) - `monthly` (inteiro, mínimo 1, máximo 100000000000) - `document` (texto, de 11 a 20 caracteres) **Regras:** - Sem taxa no pedido, a subconta segue a taxa global da Configuração das subcontas (`feeMode: "global"`); com comissão por venda (`saleFeeBps`, `saleFeeFixed`) ou taxa por saque (`withdrawFeeBps`, `withdrawFeeFixed`), fica com a própria (`feeMode: "custom"`). `pixKey` é a chave Pix do cliente para o saque dele. - Os `limits` que não vierem no pedido usam os limites padrão da Configuração das subcontas. - O `name` tem de 2 a 80 caracteres. Use só o nome do cliente: o CPF/CNPJ vai em `document` e o id do seu sistema em `externalId`. - Opcionais: `document` (CPF ou CNPJ do titular, guardado criptografado; volta inteiro ao abrir a subconta e mascarado na lista), `lockMode` (`none`, `receive`, `withdraw` ou `full`) e `limits` (`perWithdrawal`, `daily`, `monthly` em centavos para o saque da subconta; `null` sem limite). **Exemplo (cURL):** ```bash curl -X POST "https://app.wyzecash.com.br/v1/subaccounts" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" \ -H "Content-Type: application/json" \ -d '{"name":"João Pereira","externalId":"cliente-42"}' ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Listar subcontas (`listar_subcontas`) `GET https://app.wyzecash.com.br/v1/subaccounts` As subcontas com o saldo de cada uma (`balance`, `blocked` reservado por MED ou estorno em andamento e `available` livre), as taxas que valem (`feeMode`, `saleFee`, `withdrawFee`), a pendência do MED (`medPending`, `medLocked`), os números (`stats`: vendas, recebido, taxas, devolvido, MED) e o total atribuído. - Permissão da chave: `subaccounts:list`. **Na consulta (query):** - `limit` (número, mínimo 1, máximo 100) - `cursor` (texto, até 200 caracteres) **Exemplo (cURL):** ```bash curl -X GET "https://app.wyzecash.com.br/v1/subaccounts" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Consultar subconta (`consultar_subconta`) `GET https://app.wyzecash.com.br/v1/subaccounts/:id` Uma subconta pelo `sacc_` ou pelo `externalId`. - Permissão da chave: `subaccounts:get`. **No caminho:** - `id` (texto, obrigatório) **Exemplo (cURL):** ```bash curl -X GET "https://app.wyzecash.com.br/v1/subaccounts/cliente-42" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Configuração das subcontas (`configuracao_subcontas`) `GET https://app.wyzecash.com.br/v1/subaccounts/settings` A taxa global (`saleFee`, `withdrawFee`: o que você ganha em cada venda e saque das subcontas com `feeMode` global), os limites padrão das subcontas novas (`limits`), o bloqueio automático por MED (`medAutoLock`), o saque para o titular (`holderWithdrawal`: `off`, `notify` ou `cpf_only`), quantas seguem a global (`subaccounts`) e as tarifas da WyzeCash na conta (`platform`). Centavos e pontos-base. - Permissão da chave: `subaccounts:get`. **Exemplo (cURL):** ```bash curl -X GET "https://app.wyzecash.com.br/v1/subaccounts/settings" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Mudar a Configuração das subcontas (`mudar_configuracao_subcontas`) `PUT https://app.wyzecash.com.br/v1/subaccounts/settings` Muda a taxa global (`saleFeeBps`, `saleFeeFixed`, `withdrawFeeBps`, `withdrawFeeFixed`), os limites padrão (`limits`, que não passam dos da conta), o bloqueio automático por MED (`medAutoLock`) e o saque para o titular (`holderWithdrawal`). O que não vier fica como está. Só o dono da conta. - Permissão da chave: `subaccounts:update`. **No corpo (JSON):** - `saleFeeBps` (inteiro, mínimo 0, máximo 10000) - `saleFeeFixed` (inteiro, mínimo 0, máximo 1000000) - `withdrawFeeBps` (inteiro, mínimo 0, máximo 10000) - `withdrawFeeFixed` (inteiro, mínimo 0, máximo 1000000) - `limits` (objeto) - `perWithdrawal` (inteiro, mínimo 1, máximo 100000000000) - `daily` (inteiro, mínimo 1, máximo 100000000000) - `monthly` (inteiro, mínimo 1, máximo 100000000000) - `medAutoLock` (verdadeiro/falso) - `holderWithdrawal` (um destes: off, notify, cpf_only) **Regras:** - Bloqueio automático por MED: MED numa venda da subconta sem saldo livre para reservar tudo tranca o saque dela (`medLocked`) e o que falta fica pendente (`medPending`); as próximas entradas dela reservam o que falta e, se o MED for devolvido, pagam a dívida. Sem pendência, ela destrava sozinha. - Saque para o titular: `off` (padrão) saca para qualquer chave; `notify` também, e avisa no sino quando o banco confirma um CPF/CNPJ diferente do titular (o webhook traz `destination.holderMatch: "different"`); `cpf_only` só saca para a chave CPF/CNPJ igual ao `document` da subconta (outra chave: `422 SUBACCOUNT_HOLDER_KEY`; sem `document`: `422 SUBACCOUNT_HOLDER_MISSING`; sem chave no pedido, vai para ela). **Exemplo (cURL):** ```bash curl -X PUT "https://app.wyzecash.com.br/v1/subaccounts/settings" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" \ -H "Content-Type: application/json" \ -d '{"saleFeeBps":500,"withdrawFeeFixed":100,"medAutoLock":true}' ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Exemplo da taxa das subcontas (`exemplo_configuracao_subcontas`) `GET https://app.wyzecash.com.br/v1/subaccounts/settings/preview` Quanto fica com você, com a subconta e com a WyzeCash numa venda de R$ 1,00 e de R$ 100,00 no Pix e num saque de R$ 100,00 da subconta, com a taxa informada e as tarifas da conta (`sales`, `withdrawal`). - Permissão da chave: `subaccounts:get`. **Na consulta (query):** - `saleFeeBps` (número, mínimo 0, máximo 10000) - `saleFeeFixed` (número, mínimo 0, máximo 1000000) - `withdrawFeeBps` (número, mínimo 0, máximo 10000) - `withdrawFeeFixed` (número, mínimo 0, máximo 1000000) **Exemplo (cURL):** ```bash curl -X GET "https://app.wyzecash.com.br/v1/subaccounts/settings/preview?saleFeeBps=500&withdrawFeeFixed=100" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Editar subconta (`editar_subconta`) `PATCH https://app.wyzecash.com.br/v1/subaccounts/:id` Muda os dados, a comissão (ou volta para a taxa global com `feeMode: "global"`), a chave Pix do cliente, o CPF/CNPJ do titular (`document`), o bloqueio parcial (`lockMode`: `receive` não recebe, `withdraw` não saca nem transfere, `full` os dois), os limites do saque (`limits`) ou ativa/desativa (`active`). - Permissão da chave: `subaccounts:update`. **No caminho:** - `id` (texto, obrigatório) **No corpo (JSON):** - `name` (texto, de 1 a 200 caracteres) - `email` (texto, até 254 caracteres) - `externalId` (texto, até 64 caracteres) - `saleFeeBps` (inteiro, mínimo 0, máximo 10000) - `saleFeeFixed` (inteiro, mínimo 0, máximo 1000000) - `withdrawFeeBps` (inteiro, mínimo 0, máximo 10000) - `withdrawFeeFixed` (inteiro, mínimo 0, máximo 1000000) - `feeMode` (um destes: global, custom) - `metadata` (objeto) - `pixKey` (objeto) - `keyType` (um destes: cpf, cnpj, email, phone, random, obrigatório) - `key` (texto, obrigatório, de 3 a 77 caracteres) - `lockMode` (um destes: none, receive, withdraw, full) - `limits` (objeto) - `perWithdrawal` (inteiro, mínimo 1, máximo 100000000000) - `daily` (inteiro, mínimo 1, máximo 100000000000) - `monthly` (inteiro, mínimo 1, máximo 100000000000) - `document` (texto, de 11 a 20 caracteres) - `active` (verdadeiro/falso) **Exemplo (cURL):** ```bash curl -X PATCH "https://app.wyzecash.com.br/v1/subaccounts/cliente-42" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" \ -H "Content-Type: application/json" \ -d '{"active":false}' ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Excluir subconta (`excluir_subconta`) `DELETE https://app.wyzecash.com.br/v1/subaccounts/:id` Exclui a subconta: o saldo dela volta à conta principal e o `externalId` fica livre. - Permissão da chave: `subaccounts:delete`. **No caminho:** - `id` (texto, obrigatório) **Exemplo (cURL):** ```bash curl -X DELETE "https://app.wyzecash.com.br/v1/subaccounts/cliente-42" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Movimentos da subconta (`movimentos_da_subconta`) `GET https://app.wyzecash.com.br/v1/subaccounts/:id/entries` Os movimentos SUB- da subconta; filtros `from`/`to` e `kind` (`sale`, `fund`, `transfer`, `withdraw`, `return`, `refund`, `med`). - Permissão da chave: `subaccounts:entries`. **No caminho:** - `id` (texto, obrigatório) **Na consulta (query):** - `limit` (número, mínimo 1, máximo 100) - `cursor` (texto, até 200 caracteres) - `from` (texto, até 40 caracteres) - `to` (texto, até 40 caracteres) - `kind` (texto, até 100 caracteres) **Exemplo (cURL):** ```bash curl -X GET "https://app.wyzecash.com.br/v1/subaccounts/cliente-42/entries" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Enviar saldo para a subconta (`enviar_para_subconta`) `POST https://app.wyzecash.com.br/v1/subaccounts/:id/fund` Passa um valor do seu saldo livre para a subconta (sem tarifa). - Permissão da chave: `subaccounts:fund`. - Pede o cabeçalho `Idempotency-Key` (8 a 128 caracteres). - Tira dinheiro da conta: feita pelo seu sistema (pela API) ou no painel, com a permissão na chave e o 2FA ligado na conta. **No caminho:** - `id` (texto, obrigatório) **No corpo (JSON):** - `amount` (inteiro, obrigatório, mínimo 1) - `description` (texto, até 140 caracteres) **Exemplo (cURL):** ```bash curl -X POST "https://app.wyzecash.com.br/v1/subaccounts/cliente-42/fund" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" \ -H "Idempotency-Key: pedido-1052" \ -H "Content-Type: application/json" \ -d '{"amount":5000}' ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Transferir entre subcontas (`transferir_entre_subcontas`) `POST https://app.wyzecash.com.br/v1/subaccounts/:id/transfer` Passa um valor de uma subconta para outra (`to`), sem tarifa. - Permissão da chave: `subaccounts:transfer`. - Pede o cabeçalho `Idempotency-Key` (8 a 128 caracteres). - Tira dinheiro da conta: feita pelo seu sistema (pela API) ou no painel, com a permissão na chave e o 2FA ligado na conta. **No caminho:** - `id` (texto, obrigatório) **No corpo (JSON):** - `to` (texto, obrigatório, formato `^[A-Za-z0-9_.-]{1,64}$`) - `amount` (inteiro, obrigatório, mínimo 1) - `description` (texto, até 140 caracteres) **Exemplo (cURL):** ```bash curl -X POST "https://app.wyzecash.com.br/v1/subaccounts/cliente-42/transfer" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" \ -H "Idempotency-Key: pedido-1052" \ -H "Content-Type: application/json" \ -d '{"to":"cliente-43","amount":2000}' ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Devolver da subconta para a conta (`devolver_para_a_conta`) `POST https://app.wyzecash.com.br/v1/subaccounts/:id/return` Devolve um valor da subconta para a conta principal. - Permissão da chave: `subaccounts:return`. - Pede o cabeçalho `Idempotency-Key` (8 a 128 caracteres). - Tira dinheiro da conta: feita pelo seu sistema (pela API) ou no painel, com a permissão na chave e o 2FA ligado na conta. **No caminho:** - `id` (texto, obrigatório) **No corpo (JSON):** - `amount` (inteiro, obrigatório, mínimo 1) - `description` (texto, até 140 caracteres) **Exemplo (cURL):** ```bash curl -X POST "https://app.wyzecash.com.br/v1/subaccounts/cliente-42/return" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" \ -H "Idempotency-Key: pedido-1052" \ -H "Content-Type: application/json" \ -d '{"amount":1000}' ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima). #### Saque da subconta (`saque_da_subconta`) `POST https://app.wyzecash.com.br/v1/subaccounts/:id/withdrawals` Saque do saldo livre da subconta para a chave Pix do cliente (`destination` ou a chave guardada na subconta) ou para o Pix Copia e Cola dele (`copyPaste`), dentro dos limites dela (`422 SUBACCOUNT_LIMIT`). - Permissão da chave: `subaccounts:withdraw`. - Pede o cabeçalho `Idempotency-Key` (8 a 128 caracteres). - Tira dinheiro da conta: feita pelo seu sistema (pela API) ou no painel, com a permissão na chave e o 2FA ligado na conta. **No caminho:** - `id` (texto, obrigatório) **No corpo (JSON):** - `amount` (inteiro, mínimo 1) - `destination` (objeto) - `keyType` (um destes: cpf, cnpj, email, phone, random, obrigatório) - `key` (texto, obrigatório, de 3 a 77 caracteres) - `copyPaste` (texto, de 40 a 512 caracteres) - `pixKeyId` (texto, formato uuid) - `description` (texto, até 140 caracteres) **Regras:** - A chave com `subaccounts:withdraw` só é criada com o 2FA ligado na conta e o código do app autenticador; `withdrawals:create` não vale aqui. - `description` é a sua referência (ex.: o número do pedido): volta na API, no webhook `withdrawal.*` e no comprovante do painel. A resposta traz `subaccount` (`{ id, externalId }`) e, no concluído, `destination.document` (o CPF/CNPJ que o banco confirmou, mascarado) e `destination.holderMatch` (`match`, `different` ou `unknown`). - Pix Copia e Cola (`copyPaste`, estático ou de cobrança com valor): sem valor no código, `amount` é quanto sai da subconta, como com a chave. Com valor no código, `amount` pode faltar: o cliente recebe o valor do código e sai da subconta esse valor mais a taxa (se vier, `amount` tem que ser o valor do código, senão `422 AMOUNT_MISMATCH`). - No modo `cpf_only` da Configuração, a chave é o CPF/CNPJ do titular: outra chave (ou um Copia e Cola que não seja da chave dele) é recusada (`422 SUBACCOUNT_HOLDER_KEY`) e, sem chave no pedido, vai para ela. **Exemplo (cURL):** ```bash curl -X POST "https://app.wyzecash.com.br/v1/subaccounts/cliente-42/withdrawals" \ -H "Authorization: Bearer $BUKIOPAY_API_KEY" \ -H "Idempotency-Key: pedido-1052" \ -H "Content-Type: application/json" \ -d '{"amount":5000,"description":"pedido 8841"}' ``` Erros seguem o formato `{ "error": { "code", "message" }, "requestId" }` (ver o tema Erros, acima).