Polling
Consulta de status do pedido
O polling é uma técnica onde o cliente (seu site ou aplicativo) faz requisições repetidas a cada intervalo de tempo para verificar se o status de um pedido mudou.
Quando usar?
- Durante o loading: Enquanto o usuário aguarda a confirmação do pagamento
- Como fallback: Caso o webhook não seja recebido
- Para verificação manual: Quando o usuário clica em "Já paguei"
/v1/orders/{order_id}/statusHeaders
Authorization: Bearer {{access_token}}Resposta (pending)
{
"success": true,
"data": {
"orderId": "856e91a3-d8fd-405b-87bf-03969cbd7122",
"status": "pending",
"amount": 205000,
"lastUpdated": "2026-03-21T10:00:00Z"
}
}Resposta (paid)
{
"success": true,
"data": {
"orderId": "856e91a3-d8fd-405b-87bf-03969cbd7122",
"status": "paid",
"amount": 205000,
"transactionId": "tx_789012",
"lastUpdated": "2026-03-21T10:02:30Z"
}
}Fluxo de Pagamento
Implementação em JavaScript
// Função de polling para verificar status do pedido
async function checkPaymentStatus(orderId, token) {
let attempts = 0;
const maxAttempts = 40; // 2 minutos (3s * 40)
const intervalTime = 3000; // 3 segundos
return new Promise((resolve, reject) => {
const interval = setInterval(async () => {
try {
// 1. Consultar status
const response = await fetch(
`https://api.vpay.co.mz/v1/orders/${orderId}/status`,
{ headers: { 'Authorization': `Bearer ${token}` } }
);
const { data } = await response.json();
// 2. Verificar se pagamento foi confirmado
if (data.status === 'paid') {
clearInterval(interval);
resolve({ success: true, order: data });
}
// 3. Verificar falha
if (data.status === 'failed' || data.status === 'cancelled') {
clearInterval(interval);
reject({ success: false, error: 'Pagamento falhou' });
}
// 4. Incrementar tentativas
attempts++;
// 5. Timeout
if (attempts >= maxAttempts) {
clearInterval(interval);
reject({ success: false, error: 'Tempo esgotado' });
}
} catch (error) {
console.error('Polling error:', error);
}
}, intervalTime);
});
}
// Uso no componente React
function OrderLoading({ orderId, token }) {
const [loading, setLoading] = useState(true);
const [status, setStatus] = useState('pending');
useEffect(() => {
checkPaymentStatus(orderId, token)
.then(() => {
setLoading(false);
setStatus('paid');
// Redirecionar para página de sucesso
router.push('/order-success');
})
.catch((error) => {
setLoading(false);
setStatus('failed');
// Mostrar mensagem de erro
toast.error('Pagamento não confirmado');
});
}, [orderId, token]);
if (loading) {
return <LoadingSpinner message="Aguardando confirmação do pagamento..." />;
}
return <OrderStatus status={status} />;
}Demonstração Interativa
⏱️ Simulação: a cada 800ms consultamos o status. Após 5 consultas, o pagamento é confirmado.
Intervalo adequado
Use intervalos de 2-3 segundos. Menos que isso pode sobrecarregar o servidor, mais que isso deixa o usuário esperando.
Timeout inteligente
Defina um tempo máximo (ex: 2 minutos). Se expirar, mostre uma mensagem para o usuário e permita que ele consulte manualmente.
Backoff exponencial
Aumente gradualmente o intervalo (ex: 2s, 4s, 8s) para reduzir carga enquanto aguarda por mais tempo.
Feedback ao usuário
Mostre indicadores visuais durante o polling (spinner, mensagem de "Aguardando"). Se demorar, informe que pode demorar alguns minutos.