moneyflydocs

Sandbox

Conta demo pública pra testar a integração end-to-end com credenciais fixas, sem cadastro.

Sandbox

A conta sandbox do Moneyfly é uma conta demo pública com credenciais fixas, dedicada a quem quer testar a integração antes de criar conta de verdade. Tudo aqui é simulado — nenhum dinheiro real circula, nenhum PIX real é emitido. Mas o fluxo é idêntico ao de produção: mesmas rotas, mesmo formato de resposta, mesmo HMAC dos webhooks.

Credenciais

Públicas e estáveis — pode copiar/colar sem medo:

CampoValor
Painel webapp.moneyflybr.com/login
Emaildemo@moneyflybr.com
Senhamoneyfly-sandbox-2026
client-idmf_pk_test_demo_sandbox_2026
client-secretmf_sk_test_demo_sandbox_2026_publico_NUNCA_USE_EM_PROD

Como funciona

Quando você cria uma cobrança PIX ou um saque com a conta sandbox, o gateway:

  1. Cria a Transaction com status pending exatamente como em produção.
  2. Após 30 segundos, o nosso simulador interno marca a transaction como paid (mesmo caminho que a provedora real seguiria).
  3. O webhook outbound é disparado pra URL configurada — assinado com HMAC-SHA256, igual produção.

Resultado prático: você cria QR code → espera 30s → vê webhook chegar → testa todo o seu código de integração sem precisar se cadastrar nem mover dinheiro.

Webhook por request

No sandbox, o webhook URL vai no body de cada cobrança, no campo webhook_url. Cada request pode apontar pra uma URL diferente — útil pra testar localmente com ngrok/webhook.site/seu próprio endpoint.

{
  "amount": 1000,
  "webhook_url": "https://webhook.site/seu-uuid",
  ...
}

Quando o pagamento simulado dispara (30s depois), o gateway faz POST na URL que você passou, assinando o body com HMAC-SHA256.

HMAC do sandbox

O secret usado pra assinar webhooks da sandbox é público e fixo:

mf_sandbox_webhook_secret_2026_publico_NUNCA_USE_EM_PROD

Header enviado: x-moneyfly-signature: t=<unix_seconds>,v1=<hex>. Pra validar (mesmo esquema da prod, ver Webhooks):

import { createHmac, timingSafeEqual } from 'node:crypto';

const SECRET = 'mf_sandbox_webhook_secret_2026_publico_NUNCA_USE_EM_PROD';

function verify(rawBody, signatureHeader) {
  const parts = Object.fromEntries(
    signatureHeader.split(',').map((p) => p.split('=')),
  );
  if (!parts.t || !parts.v1) return false;
  // Anti-replay: timestamp deve estar dentro de 5 min
  if (Math.abs(Math.floor(Date.now() / 1000) - Number(parts.t)) > 300) return false;
  const signed = `${parts.t}.${rawBody}`;
  const expected = createHmac('sha256', SECRET).update(signed).digest('hex');
  return timingSafeEqual(Buffer.from(expected, 'hex'), Buffer.from(parts.v1, 'hex'));
}

Em produção, o secret é gerado por webhook cadastrado no painel — único e privado por merchant. O sandbox usa essa constante pública pra simplificar testes.

Webhooks em painel: bloqueado

Você não pode criar/editar/deletar webhooks no painel da conta sandbox — botões ficam desabilitados. Use o webhook_url do body de cada request em vez disso.

O que está bloqueado

A sandbox é compartilhada entre todos os devs externos testando o produto. Pra evitar que um trave os outros, algumas operações são proibidas:

  • Criar / revogar credenciais de API (use a client-id / client-secret fixos documentados acima)
  • Criar / editar / pausar webhooks (use webhook_url no body de cada request)
  • Trocar senha, email ou ativar 2FA
  • Transferência interna pra outros merchants

Tentar qualquer dessas retorna 403 Forbidden com mensagem explicativa. As operações permitidas cobrem o fluxo principal do gateway: criar cobrança, gerar payout, consultar saldo, ver histórico de transações.

Reset diário

Toda madrugada 3am UTC o sandbox passa por um reset automático:

  • Saldo do merchant volta a 0 (via lançamento contábil compensatório — histórico fica preservado pra debug)
  • Idempotency keys são limpos (pode reusar as mesmas keys do dia anterior)
  • 2FA é desativado caso alguém tenha conseguido ativar

Se você está testando algo e o reset acontece no meio, basta criar uma nova cobrança — saldo cresce de novo conforme você "paga" via simulação.

Exemplo: criar QR code via curl

curl -X POST https://api.moneyflybr.com/v1/pix/qrcode \
  -H "client-id: mf_pk_test_demo_sandbox_2026" \
  -H "client-secret: mf_sk_test_demo_sandbox_2026_publico_NUNCA_USE_EM_PROD" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "content-type: application/json" \
  -d '{
    "amount": 1000,
    "external_id": "pedido_001",
    "expires_in": 1800,
    "webhook_url": "https://webhook.site/seu-uuid",
    "payer": {
      "name": "Teste Pagador",
      "document": "12345678909",
      "email": "teste@exemplo.com"
    }
  }'

Resposta inclui o internal_id, o qrcode (copia-e-cola PIX), e a expires_at. Em 30 segundos, o webhook deposit.paid chega na URL que você passou em webhook_url.

Exemplo: criar saque

Depois de "receber" alguns depósitos (saldo > 0), você pode testar payout:

curl -X POST https://api.moneyflybr.com/v1/pix/payout \
  -H "client-id: mf_pk_test_demo_sandbox_2026" \
  -H "client-secret: mf_sk_test_demo_sandbox_2026_publico_NUNCA_USE_EM_PROD" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "content-type: application/json" \
  -d '{
    "amount": 500,
    "pix_key": "+5511999999999",
    "pix_key_type": "phone",
    "webhook_url": "https://webhook.site/seu-uuid",
    "beneficiary": {
      "name": "Beneficiário Teste",
      "document": "12345678909"
    }
  }'

30 segundos depois, o saque vira paid e o webhook payout.paid é disparado.

Migrando pra produção

Quando você terminar de testar e quiser ir pra produção:

  1. Crie sua conta normal em app.moneyflybr.com/signup
  2. Complete o KYC (documentos + dados bancários)
  3. Aguarde aprovação (geralmente 1 dia útil)
  4. Em Integrações gere suas credenciais reais (mf_pk_live_* / mf_sk_live_*)
  5. Substitua no seu código — o resto da integração funciona idêntico, só o credentials muda

Não precisa adaptar nada do código de integração — sandbox e produção usam exatamente o mesmo schema de request/response.