01 · Resumo executivo em 60 segundos
O que a gente está construindo
Tela de checkout dentro da Uni4life onde o profissional de saúde preenche dados do cartão de crédito e paga a assinatura — sem ser redirecionado para tela da ReufyPay/Asaas. A Jéssica pediu isso explicitamente: a experiência tem que ficar dentro da Uni4life.
Onde a gente está
- Doc da Reufy — recebemos. Tem 46 endpoints, dá pra fazer tudo que precisamos.
- Arquitetura — definida. São 3 chamadas de API sequenciais (criar cliente → criar cobrança → pagar com cartão).
- Credenciais sandbox — faltam. A Reufy mandou só a doc, não criou conta de teste pra gente.
- POC no Bubble — Thais começou. Travou no primeiro passo (autenticação) porque o exemplo da doc usa um código que já expirou.
O que precisa acontecer agora
- Mandar email pro Thales (thales.ribeiro@reufy.com.br) pedindo: email + senha sandbox e confirmar cartão de teste.
- Reufy responde com as credenciais.
- Thais roda os 3 endpoints no Postman, valida que funciona.
- Thais constrói a tela no Bubble usando os mesmos 3 endpoints.
02 · O que aconteceu — narrativa
Quarta (28/05) a Reufy mandou um link de doc Postman. A doc tem dois caminhos de autenticação: o OAuth (mais complicado) e o generate_api_token (atalho). A Thais começou pelo OAuth porque é o primeiro item da lista de endpoints.
O exemplo OAuth da doc tem um code hardcoded — algo tipo st_6dc9a57597aa8a65cd1c35970e33d90d. Esse tipo de código é de uso único e expira em segundos. O exemplo da doc tá lá há semanas. Quando a Thais copiou e tentou rodar, o código já tinha expirado faz tempo — daí o erro.
Soma a isso o fato de que o exemplo também não menciona o parâmetro grant_type=authorization_code, que costuma ser obrigatório nesse tipo de chamada. Conclusão: o exemplo da doc não é runnable como está. Não tem culpa de quem tentou.
03 · Por que get_access_token falhou
O endpoint exemplo
POST https://reufy-pay.bubbleapps.io/version-test/api/1.1/oauth/access_token
Content-Type: application/x-www-form-urlencoded
client_id=bbdd1c327fc659700553acb4cc5deae5
client_secret=40dd1ffdba572a95c76bc9360a8889da
redirect_uri=https://reufy-pay.bubbleapps.io/version-test
code=st_6dc9a57597aa8a65cd1c35970e33d90d
Os 3 problemas
O code é descartável (one-shot) e expira em segundos.
Aquele st_6dc9a57... só vale 1 uso e por uns 30-60 segundos depois que o usuário clica "Autorizar" na tela da Reufy. O exemplo da doc tá lá há tempos. Já queimou.
Falta o parâmetro grant_type=authorization_code.
Bubble OAuth costuma exigir esse param obrigatório pra distinguir "estou trocando código por token" de "estou renovando token expirado". O exemplo da doc omite, e provavelmente o servidor reclama disso também.
Fluxo OAuth completo precisa de browser real.
Pra OAuth funcionar de verdade, o usuário tem que: abrir /oauth/authorize no navegador → fazer login → clicar "Autorizar" → o navegador redireciona pra um URL com ?code=... no final → tu copia esse code FRESQUINHO → manda no POST em até 30 segundos. Tudo isso pra trocar 1 code por 1 token. Trabalhoso pra Postman.
04 · O atalho — generate_api_token
(a) Login com Facebook = OAuth. Tu sai do site, vai pro Facebook, autoriza, volta. Vários passos, segurança alta.
(b) Login direto com email/senha = generate_api_token. Manda email + senha, recebe token. 1 passo, mais simples pra testar.
Pra POC, faz o (b). Quando for produção em escala, considera o (a).
A chamada
POST https://app.reufypay.com/version-test/api/1.1/wf/generate_api_token
Content-Type: application/json
{
"email": "<email_da_subconta_sandbox>",
"senha": "<senha>"
}
O retorno (formato esperado)
{
"status": "success",
"response": {
"token": "abc123def456...",
"...": "..."
}
}
Como usar o token nas próximas chamadas
Authorization: Bearer abc123def456...
05 · Fluxo de cartão crédito — 3 calls
Visão geral
1. criar_cliente
2. criar_nova_cobranca
3. pagar_cobranca_cartao
Cada call DEPENDE do retorno da anterior. No Bubble, isso vira 3 actions sequenciais; o output de uma alimenta o input da próxima.
Call 1 — criar o cliente
POST /wf/criar_cliente
Authorization: Bearer <token>
Content-Type: application/json
{
"name": "Thais Hashimoto",
"cpfCnpj": "03174766028",
"email": "thais@uni4life.com.br",
"mobilePhone": "11994072478",
"address": "Rua Teste",
"addressNumber": "702",
"complement": "bloco 30",
"province": "Centro",
"postalCode": "06702155",
"externalReference": "uni4_user_42"
}
Resposta esperada:
{
"status": "success",
"response": { "id": "cus_000006039237", "name": "Thais...", "...": "..." }
}
Guarda o id — vai usar na próxima call. Não tem unique_id separado como tu perguntou no vídeo; é só id mesmo.
Call 2 — criar a cobrança
POST /wf/criar_nova_cobranca
Authorization: Bearer <token>
{
"billingType": "CREDIT_CARD",
"customer": "cus_000006039237",
"dueDate": "2026-05-31",
"value": 100.00,
"description": "Assinatura mensal Uni4life",
"externalReference": "order_42",
"fine": { "value": 0 },
"interest": { "value": 0 },
"discount": { "value": 0 }
}
Call 3 — pagar com cartão
POST /wf/pagar_cobranca_cartao
Authorization: Bearer <token>
{
"idCobranca": "<id da call 2>",
"creditCard": {
"holderName": "THAIS HASHIMOTO",
"number": "4444 4444 4444 4444",
"expiryMonth": "08",
"expiryYear": "2030",
"ccv": "123"
},
"creditCardHolderInfo": {
"name": "Thais Hashimoto",
"email": "thais@uni4life.com.br",
"cpfCnpj": "03174766028",
"postalCode": "06702155",
"addressNumber": "702",
"addressComplement": "bloco 30",
"phone": "1133334444",
"mobilePhone": "11994072478"
}
}
Cartões de teste sandbox (padrão)
Cartões de teste universais usados em sandboxes baseadas em Asaas (que é o que a Reufy usa por baixo):
- 4444 4444 4444 4444 — Visa, geralmente APROVA
- 5184 1957 8881 1000 — Mastercard, geralmente APROVA
- Validade: qualquer mês futuro · CCV: 123
Mas o ideal é o Thales confirmar quais cartões funcionam no sandbox dele, junto com cartões que recusam propositalmente (pra a gente testar fluxo de erro).
cURL pra rodar tudo no terminal
Assim que tiver email+senha, podes rodar isso no terminal pra validar antes de mexer no Bubble:
# 1 — pega o token
TOKEN=$(curl -s -X POST https://app.reufypay.com/version-test/api/1.1/wf/generate_api_token \
-H 'Content-Type: application/json' \
-d '{"email":"<email>","senha":"<senha>"}' | jq -r '.response.token')
echo "Token: $TOKEN"
# 2 — cria cliente
CLIENTE=$(curl -s -X POST https://app.reufypay.com/version-test/api/1.1/wf/criar_cliente \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"name":"Teste","cpfCnpj":"03174766028","email":"t@t.com","mobilePhone":"11999999999"}' | jq -r '.response.id')
echo "Cliente: $CLIENTE"
# 3 — cria cobrança
COBRANCA=$(curl -s -X POST https://app.reufypay.com/version-test/api/1.1/wf/criar_nova_cobranca \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d "{\"billingType\":\"CREDIT_CARD\",\"customer\":\"$CLIENTE\",\"dueDate\":\"2026-05-31\",\"value\":100,\"description\":\"teste\",\"externalReference\":\"t1\",\"fine\":{\"value\":0},\"interest\":{\"value\":0},\"discount\":{\"value\":0}}" | jq -r '.response.id')
echo "Cobrança: $COBRANCA"
# 4 — paga
curl -X POST https://app.reufypay.com/version-test/api/1.1/wf/pagar_cobranca_cartao \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d "{\"idCobranca\":\"$COBRANCA\",\"creditCard\":{\"holderName\":\"TESTE\",\"number\":\"4444444444444444\",\"expiryMonth\":\"08\",\"expiryYear\":\"2030\",\"ccv\":\"123\"},\"creditCardHolderInfo\":{\"name\":\"Teste\",\"email\":\"t@t.com\",\"cpfCnpj\":\"03174766028\",\"postalCode\":\"06702155\",\"addressNumber\":\"100\",\"addressComplement\":\"\",\"phone\":\"1133334444\",\"mobilePhone\":\"11999999999\"}}"
06 · Quais campos a tela de checkout precisa
A tela do checkout dentro da Uni4life precisa coletar exatamente 10 campos antes de bater na sequência de 3 calls. Esses são os campos que a Reufy exige.
| Campo | De onde vem | Usado na call |
|---|---|---|
| Nome completo | paciente digita | 1 e 3 |
| CPF | paciente digita | 1 e 3 |
| paciente digita (ou Uni4life já tem) | 1 e 3 | |
| Celular | paciente digita | 1 e 3 |
| CEP / endereço / número / complemento | paciente digita (CEP autocompleta) | 1 e 3 |
| Número do cartão | paciente digita | 3 |
| Validade (MM/AAAA) | paciente digita | 3 |
| CCV | paciente digita | 3 |
| Nome impresso no cartão | paciente digita | 3 |
| externalReference | backend Uni4life (ID interno) | 1 e 2 |
07 · Próximo passo bloqueante — email pro Thales
Contato: Thales Ribeiro · thales.ribeiro@reufy.com.br · (32) 99915-1340
Sugestão de email (Luiz pode mandar, ou Thais com cópia pro Luiz):
Assunto: ReufyPay sandbox — credenciais para POC Uni4life
Olá, Thales, tudo bem?
Estamos avançando com a POC de checkout cartão de crédito da Uni4life
integrando com a ReufyPay. Lemos a documentação Postman, mapeamos
o fluxo (criar_cliente → criar_nova_cobranca → pagar_cobranca_cartao)
e identificamos 3 pendências para começar os testes:
1. Credenciais sandbox
Precisamos de uma subconta de teste com email + senha que possamos
usar no endpoint /wf/generate_api_token para gerar Bearer token.
(Alternativa: um Bearer token sandbox pré-gerado já serve.)
2. Cartões de teste
Quais números de cartão funcionam no sandbox para APROVAR a
transação? E para forçar uma transação RECUSADA, para que
possamos testar o fluxo de erro?
3. Observação sobre a doc Postman
O exemplo da seção "OAuth → get_access_token" usa um parâmetro
"code" que parece estar expirado (códigos de autorização OAuth
são one-shot). Poderia confirmar se o caminho recomendado para
integração é o "generate_api_token" via email/senha, ou o fluxo
OAuth completo? Se for o OAuth, faltaria documentar o passo
inicial /oauth/authorize e o param grant_type.
Bonus (pode ficar para um segundo momento):
Existe tokenização de cartão na Reufy para que o frontend da
Uni4life não precise tocar no PAN diretamente? Isso afeta
nosso escopo de PCI.
Fico no aguardo, qualquer coisa pode me chamar pelo WhatsApp.
Obrigada,
Thais Hashimoto / Luiz Ribeiro
Uni4life
08 · Glossário rápido
- Bearer token
- Crachá que o servidor te dá após login. Vai em todas as chamadas seguintes no header Authorization: Bearer <token>. Sem ele, qualquer endpoint retorna 401 Unauthorized.
- OAuth (authorization_code flow)
- Padrão de autenticação onde um app pede permissão pra outro em nome do usuário. Tipicamente: tu envia o usuário pra uma tela de "Autorizar" no provedor, ele autoriza, é redirecionado de volta com um code temporário, e tu troca esse code por um Bearer token. Usado pelo "Login com Google/Facebook".
- code (OAuth)
- Comprovante temporário (uns 30-60s) que o usuário recebeu depois de autorizar. Tu troca ele por um Bearer permanente. Uso único.
- API token (atalho generate_api_token)
- Equivalente prático ao Bearer mas obtido com email+senha em uma chamada só. Mais simples pra testar; sem o passo do browser.
- Sandbox
- Ambiente de teste. URLs com version-test são sandbox; live ou sem version-test é produção. Sandbox aceita cartões fake e não cobra de verdade.
- customer / cus_xxxxxxx
- ID único do cliente no sistema Reufy. Devolvido por criar_cliente, usado em criar_nova_cobranca.
- walletId
- ID de uma "carteira" de uma subconta da Reufy. SÓ é usado em split payment (quando uma cobrança é dividida entre múltiplas contas, tipo marketplace). Pra POC simples Uni4life, ignora.
- billingType
- Tipo de cobrança. Valores possíveis: CREDIT_CARD, BOLETO, PIX. Pra POC: CREDIT_CARD.
- externalReference
- Campo livre pra tu salvar um ID do TEU sistema (o ID que a Uni4life dá pra ordem de compra). A Reufy não interpreta isso, só guarda. Útil pra cruzar logs depois.
- PCI-DSS
- Padrão de segurança obrigatório quando teu sistema toca em dados de cartão (número + CCV). Exige auditoria, controles, certificação. Maioria das fintechs oferece "tokenização" pra empurrar essa responsabilidade pra ela e te deixar PCI-free.
- tokenização (de cartão)
- Em vez de teu sistema receber o número do cartão, o paciente digita num iframe (campo embutido) do gateway. O gateway retorna um TOKEN. Tu manda o token pra Reufy em vez do número. Resultado: teu sistema nunca viu o PAN, tu fica fora do escopo PCI rigoroso.