{
  "openapi": "3.1.0",
  "info": {
    "title": "WeetPay API",
    "version": "1.0.0",
    "description": "WeetPay public API to receive PIX payments (cash-in), send PIX (cash-out), look up transactions and balance. Amounts are always in **BRL reais** (`10.50` = R$ 10.50). Authenticate with the client ID and client secret generated in the dashboard, under **Developers**.",
    "contact": {
      "name": "WeetPay",
      "url": "https://docs.weetpay.com"
    }
  },
  "servers": [
    {
      "url": "https://api.weetpay.com",
      "description": "Production"
    }
  ],
  "security": [
    {
      "clientId": [],
      "clientSecret": []
    },
    {
      "basicAuth": []
    }
  ],
  "tags": [
    {
      "name": "Cash-in",
      "description": "PIX charges (dynamic QR Code)"
    },
    {
      "name": "Cash-out",
      "description": "PIX payouts"
    },
    {
      "name": "Transactions",
      "description": "Charge and payout lookup"
    },
    {
      "name": "Account",
      "description": "Wallet balance"
    }
  ],
  "paths": {
    "/api/v1/gateway/request-qrcode": {
      "post": {
        "operationId": "requestQrcode",
        "tags": [
          "Cash-in"
        ],
        "summary": "Create PIX charge",
        "description": "Creates a PIX \"copia e cola\" code (dynamic QR Code) for your customer to pay. The charge starts as `WAITING_FOR_APPROVAL` and becomes `PAID_OUT` once paid — the amount is then credited to your balance (minus the fee) and WeetPay sends a `POST` to `callbackUrl`. The QR expires after the platform-defined window (1 hour by default).\n\n`requestNumber` identifies the order in your system and **must be unique** per account (reusing it returns `400 requestNumber já utilizado`). UTM parameters in the query string (`utm_source`, `utm_campaign`, `utm_medium`, `utm_content`, `utm_term`) are stored with the charge.",
        "parameters": [
          {
            "name": "utm_source",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 300
            },
            "description": "Campaign tracking (optional), stored with the charge"
          },
          {
            "name": "utm_campaign",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 300
            },
            "description": "Campaign tracking (optional), stored with the charge"
          },
          {
            "name": "utm_medium",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 300
            },
            "description": "Campaign tracking (optional), stored with the charge"
          },
          {
            "name": "utm_content",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 300
            },
            "description": "Campaign tracking (optional), stored with the charge"
          },
          {
            "name": "utm_term",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 300
            },
            "description": "Campaign tracking (optional), stored with the charge"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RequestQrcode"
              },
              "example": {
                "requestNumber": "pedido-12345",
                "amount": 49.9,
                "callbackUrl": "https://sualoja.com.br/webhooks/weetpay",
                "client": {
                  "name": "Maria da Silva",
                  "document": "12345678909",
                  "email": "maria@email.com",
                  "phoneNumber": "11999998888"
                },
                "products": [
                  {
                    "description": "Camiseta básica",
                    "quantity": 1,
                    "value": 49.9
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Charge created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RequestQrcodeResponse"
                },
                "example": {
                  "idTransaction": "cmh1x2y3z0001ab12cd34ef56",
                  "paymentCode": "00020101021226850014br.gov.bcb.pix2563qrcode.exemplo.com.br/pix/v2/cobv/9d36b84f...5204000053039865406149.905802BR5913WEETPAY6009SAO PAULO62070503***6304ABCD",
                  "paymentCodeBase64": "iVBORw0KGgoAAAANSUhEUgAA...",
                  "response": "OK",
                  "status": "WAITING_FOR_APPROVAL"
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "response": "ERROR",
                  "message": "requestNumber já utilizado"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "response": "ERROR",
                  "message": "Credenciais inválidas"
                }
              }
            }
          },
          "403": {
            "description": "Account blocked, identity verification pending or operation not enabled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "response": "ERROR",
                  "message": "Verificação de identidade pendente",
                  "code": "KYC_REQUIRED"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "response": "ERROR",
                  "message": "Limite de requisições por minuto atingido",
                  "code": "RATE_LIMITED"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "response": "ERROR",
                  "message": "Erro interno"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/gateway/pix-payment": {
      "post": {
        "operationId": "pixPayment",
        "tags": [
          "Cash-out"
        ],
        "summary": "Send PIX (payout)",
        "description": "Sends a PIX from your balance to a PIX key. The amount and payout fee are debited immediately; the payout stays `processing` until confirmed and the result is sent to `callbackUrl` (`sucess` or `not paid`, with the amount and fee automatically refunded).\n\n**Before using it:** enable API payouts under **Developers** (requires your PIN). Unless WeetPay has enabled third-party payouts on your account, payouts can only go to the CPF/CNPJ key of the account holder. Above the platform-defined amount, the payout goes through manual approval before being sent.\n\n**Idempotency:** send the `Idempotency-Key` header (or `requestNumber` in the body). The same key always returns the same payout (response with `Idempotent-Replayed: true`) and never debits twice; the same key with a different amount or PIX key is rejected with `409`. Without a key, the same amount to the same PIX key within 1 minute returns the previous payout.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 100
            },
            "example": "saque-2026-10-30-0001",
            "description": "Unique request key from your system (`x-idempotency-key` is also accepted). Up to 100 characters."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PixPayment"
              },
              "example": {
                "amount": 150,
                "key": "12345678909",
                "typeKey": "CPF",
                "document": "12345678909",
                "callbackUrl": "https://sualoja.com.br/webhooks/weetpay-saques",
                "requestNumber": "saque-0001"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Payout registered (or the same payout, on an idempotent replay)",
            "headers": {
              "Idempotent-Replayed": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                },
                "description": "Present when the response refers to an existing payout"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PixPaymentResponse"
                },
                "example": {
                  "id": "cmh1x9k2m0004ab12xy98zt76",
                  "status": "processing"
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "response": "ERROR",
                  "message": "insufficient balance"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "response": "ERROR",
                  "message": "Credenciais inválidas"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "response": "ERROR",
                  "message": "Saque pela API não está liberado nesta conta. Ative em Desenvolvedores."
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "response": "ERROR",
                  "message": "Esta chave de idempotência já foi usada em outro saque"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "response": "ERROR",
                  "message": "Limite de requisições por minuto atingido",
                  "code": "RATE_LIMITED"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "response": "ERROR",
                  "message": "Erro interno"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/gateway/walletTransaction": {
      "post": {
        "operationId": "walletTransaction",
        "tags": [
          "Transactions"
        ],
        "summary": "Get transaction",
        "description": "Looks up a charge (`PIX_IN`) or payout (`PIX_OUT`) on your account. Send **one** identifier: `requestNumber` (yours, for charges), `idTransaction` (WeetPay's) or `endToEnd` (the PIX E2E id). Payouts are found by `idTransaction` or `endToEnd`.\n\nPending charges are re-checked with the bank on lookup (at most every 10 s), so this also works as a fallback if a callback is lost. Still, prefer callbacks: do not poll in a loop.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WalletTransaction"
              },
              "example": {
                "requestNumber": "pedido-12345"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Transaction found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "transaction"
                  ],
                  "properties": {
                    "transaction": {
                      "$ref": "#/components/schemas/Transaction"
                    }
                  }
                },
                "example": {
                  "transaction": {
                    "id": "cmh1x2y3z0001ab12cd34ef56",
                    "created_at": "2026-10-30T13:02:11.000Z",
                    "approvedDate": "2026-10-30T13:03:40.000Z",
                    "transactionType": "PIX_IN",
                    "destination": null,
                    "destinationBank": null,
                    "processingStatus": "PAID_OUT",
                    "idTransaction": "cmh1x2y3z0001ab12cd34ef56",
                    "idTransactionProvider": "E18236120202610301303s0123456789",
                    "callbackUrl": "https://sualoja.com.br/webhooks/weetpay",
                    "userSplit": null,
                    "porcentageSplit": null,
                    "amount": "49.90",
                    "requestNumber": "pedido-12345",
                    "account_id": 100123,
                    "debtorName": "MARIA DA SILVA",
                    "debtorDocument": "***.456.789-**",
                    "pixCopiaECola": null,
                    "endToEnd": "E18236120202610301303s0123456789"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "response": "ERROR",
                  "message": "Informe requestNumber, idTransaction ou endToEnd"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "response": "ERROR",
                  "message": "Credenciais inválidas"
                }
              }
            }
          },
          "403": {
            "description": "Account blocked, identity verification pending or operation not enabled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "response": "ERROR",
                  "message": "Verificação de identidade pendente",
                  "code": "KYC_REQUIRED"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "response": "ERROR",
                  "message": "Transação não encontrada"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "response": "ERROR",
                  "message": "Limite de requisições por minuto atingido",
                  "code": "RATE_LIMITED"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "response": "ERROR",
                  "message": "Erro interno"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/gateway/walletBalance": {
      "get": {
        "operationId": "walletBalance",
        "tags": [
          "Account"
        ],
        "summary": "Get balance",
        "description": "Available account balance in reais, as a string with two decimal places. This is what can be paid out right now (paid charges net of fees, minus payouts in progress).",
        "responses": {
          "200": {
            "description": "Balance",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Balance"
                },
                "example": {
                  "currentBalance": "397.70"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "response": "ERROR",
                  "message": "Credenciais inválidas"
                }
              }
            }
          },
          "403": {
            "description": "Account blocked, identity verification pending or operation not enabled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "response": "ERROR",
                  "message": "Verificação de identidade pendente",
                  "code": "KYC_REQUIRED"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "response": "ERROR",
                  "message": "Limite de requisições por minuto atingido",
                  "code": "RATE_LIMITED"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "response": "ERROR",
                  "message": "Erro interno"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "clientId": {
        "type": "apiKey",
        "in": "header",
        "name": "vspi",
        "description": "Client ID (e.g. `weetpay-100123`). Also accepted as `x-client-id`."
      },
      "clientSecret": {
        "type": "apiKey",
        "in": "header",
        "name": "vsps",
        "description": "Client secret. Also accepted as `x-client-secret`. Never expose it in front-end code."
      },
      "basicAuth": {
        "type": "http",
        "scheme": "basic",
        "description": "Alternative: `Authorization: Basic base64(client_id:client_secret)`"
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "response",
          "message"
        ],
        "properties": {
          "response": {
            "type": "string",
            "enum": [
              "ERROR"
            ]
          },
          "message": {
            "type": "string",
            "description": "Reason, in Portuguese, ready to log"
          },
          "code": {
            "type": "string",
            "enum": [
              "RATE_LIMITED",
              "ACCOUNT_BLOCKED",
              "KYC_REQUIRED"
            ],
            "description": "Present on some authentication errors"
          }
        }
      },
      "Money": {
        "oneOf": [
          {
            "type": "number"
          },
          {
            "type": "string"
          }
        ],
        "description": "Amount in reais, greater than zero, up to 2 decimal places. Number (`10.5`) or string (`\"10.50\"` or `\"10,50\"`).",
        "examples": [
          10.5
        ]
      },
      "RequestQrcode": {
        "type": "object",
        "required": [
          "requestNumber",
          "amount",
          "client"
        ],
        "properties": {
          "requestNumber": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "description": "Order identifier in your system. Unique per account."
          },
          "amount": {
            "$ref": "#/components/schemas/Money"
          },
          "callbackUrl": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri",
            "maxLength": 500,
            "description": "http(s) URL that receives the payment notice ([Callbacks](/en/docs/webhooks)). Must be public."
          },
          "client": {
            "type": "object",
            "required": [
              "name",
              "document"
            ],
            "description": "Payer",
            "properties": {
              "name": {
                "type": "string",
                "minLength": 3,
                "description": "Full name"
              },
              "document": {
                "type": "string",
                "description": "Valid CPF (11 digits) or CNPJ (14 digits); punctuation is stripped"
              },
              "email": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "email"
              },
              "phoneNumber": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Only digits are kept"
              },
              "address": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": true,
                "description": "Free-form, stored with the charge"
              }
            }
          },
          "products": {
            "type": [
              "array",
              "null"
            ],
            "maxItems": 100,
            "description": "Order items. Descriptions form the charge description (up to 140 characters).",
            "items": {
              "type": "object",
              "required": [
                "description"
              ],
              "additionalProperties": true,
              "properties": {
                "description": {
                  "type": "string",
                  "maxLength": 200
                },
                "quantity": {
                  "type": "number"
                },
                "value": {
                  "type": "number",
                  "description": "Unit price in reais"
                }
              }
            }
          },
          "split": {
            "type": [
              "object",
              "null"
            ],
            "required": [
              "account",
              "percentageSplit"
            ],
            "description": "Splits the received amount with another WeetPay account. Only for accounts with split enabled by Compliance.",
            "properties": {
              "account": {
                "oneOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "integer"
                  }
                ],
                "description": "Destination WeetPay account number (approved and active)"
              },
              "percentageSplit": {
                "type": "integer",
                "minimum": 1,
                "maximum": 100,
                "description": "Percentage (integer) sent to the destination account"
              }
            }
          }
        }
      },
      "RequestQrcodeResponse": {
        "type": "object",
        "required": [
          "idTransaction",
          "paymentCode",
          "paymentCodeBase64",
          "response",
          "status"
        ],
        "properties": {
          "idTransaction": {
            "type": "string",
            "description": "WeetPay charge ID"
          },
          "paymentCode": {
            "type": "string",
            "description": "PIX \"copia e cola\" (BR Code)"
          },
          "paymentCodeBase64": {
            "type": "string",
            "description": "QR Code PNG image in base64 (without the `data:` prefix)"
          },
          "response": {
            "type": "string",
            "enum": [
              "OK"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "WAITING_FOR_APPROVAL"
            ]
          }
        }
      },
      "PixPayment": {
        "type": "object",
        "required": [
          "amount",
          "key",
          "typeKey",
          "document"
        ],
        "properties": {
          "amount": {
            "$ref": "#/components/schemas/Money"
          },
          "key": {
            "type": "string",
            "description": "Destination PIX key"
          },
          "typeKey": {
            "type": "string",
            "enum": [
              "CPF",
              "CNPJ",
              "EMAIL",
              "PHONE",
              "EVP"
            ],
            "description": "Key type. `EVP` = random key."
          },
          "document": {
            "type": "string",
            "description": "CPF/CNPJ of the key holder. For CPF/CNPJ keys it must match the key."
          },
          "callbackUrl": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri",
            "maxLength": 500,
            "description": "URL that receives the payout result"
          },
          "requestNumber": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 100,
            "description": "Your reference; acts as the idempotency key when the `Idempotency-Key` header is absent"
          },
          "automaticWithdraw": {
            "type": "boolean",
            "description": "Accepted for compatibility and ignored: automatic sending follows platform limits"
          }
        }
      },
      "PixPaymentResponse": {
        "type": "object",
        "required": [
          "id",
          "status"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Payout ID (use as `idTransaction` on lookup)"
          },
          "status": {
            "type": "string",
            "enum": [
              "processing"
            ]
          }
        }
      },
      "WalletTransaction": {
        "type": "object",
        "description": "Send at least one field",
        "properties": {
          "requestNumber": {
            "type": "string",
            "description": "Your charge identifier"
          },
          "idTransaction": {
            "type": "string",
            "description": "WeetPay ID (charge or payout)"
          },
          "endToEnd": {
            "type": "string",
            "description": "PIX End-to-End ID"
          }
        }
      },
      "Transaction": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "approvedDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When it was paid"
          },
          "transactionType": {
            "type": "string",
            "enum": [
              "PIX_IN",
              "PIX_OUT"
            ]
          },
          "destination": {
            "type": [
              "string",
              "null"
            ],
            "description": "Destination PIX key (payouts)"
          },
          "destinationBank": {
            "type": "null"
          },
          "processingStatus": {
            "type": "string",
            "enum": [
              "WAITING_FOR_APPROVAL",
              "PAID_OUT",
              "EXPIRED",
              "CANCELED",
              "REFUNDED",
              "PROCESSING",
              "NOT_PAID"
            ],
            "description": "See the status table under Transactions"
          },
          "idTransaction": {
            "type": "string"
          },
          "idTransactionProvider": {
            "type": [
              "string",
              "null"
            ],
            "description": "PIX End-to-End, when available"
          },
          "callbackUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "userSplit": {
            "type": [
              "string",
              "null"
            ],
            "description": "Account that received the split"
          },
          "porcentageSplit": {
            "type": [
              "integer",
              "null"
            ]
          },
          "amount": {
            "type": "string",
            "description": "Amount in reais, two decimals",
            "examples": [
              "49.90"
            ]
          },
          "requestNumber": {
            "type": [
              "string",
              "null"
            ]
          },
          "account_id": {
            "type": "integer",
            "description": "Your WeetPay account number"
          },
          "debtorName": {
            "type": [
              "string",
              "null"
            ],
            "description": "Payer (paid charges)"
          },
          "debtorDocument": {
            "type": [
              "string",
              "null"
            ]
          },
          "pixCopiaECola": {
            "type": [
              "string",
              "null"
            ],
            "description": "Only while the charge is pending"
          },
          "endToEnd": {
            "type": [
              "string",
              "null"
            ]
          },
          "message": {
            "type": [
              "string",
              "null"
            ],
            "description": "Failure reason (`NOT_PAID` payouts)"
          }
        }
      },
      "Balance": {
        "type": "object",
        "required": [
          "currentBalance"
        ],
        "properties": {
          "currentBalance": {
            "type": "string",
            "description": "Available balance in reais",
            "examples": [
              "397.70"
            ]
          }
        }
      }
    }
  }
}
