Issue PDV: |
Objetivo:
O objetivo desta integração é permitir que o sistema de gestão de pedidos (Go Delivery) se comunique corretamente com o PDV, proporcionando a gestão e o acompanhamento em tempo real dos pedidos realizados, desde a criação até a entrega.
Documentação Go Delivery:
https://abrasel-nacional.github.io/docs/#section/How-to-Start-(Setup-Guide)
GET /events:polling -
POST /events/acknowledgment
POST /orderUpdate (WEBHOOK)
GET /orders/{orderId}
POST /orders/{orderId}/confirm
POST /orders/{orderId}/readyForPickup
POST /orders/{orderId}/dispatch
POST /orders/{orderId}/delivered
POST /v1/orders/{orderId}/validateCode
POST /orders/{orderId}/requestCancellation
POST /orders/{orderId}/acceptCancellation
POST /orders/{orderId}/denyCancellation
POST /orders/{orderId}/tracking |
Escopo da Integração:
Gestão de Pedidos:
Integração com a API do Go Delivery para enviar e receber informações de pedidos, incluindo:
Criação de novos pedidos.
Atualização do status de pedidos (Confirmar, Pronto para Retirada, Despachado, Entregue).
Cancelamento de pedidos.
Rastreamento do status de pedidos.
Webhooks:
Implementação de Webhooks para recepção de atualizações de status dos pedidos em tempo real, incluindo a confirmação de entrega e mudanças de status relacionadas ao pedido.
Configuração do Webhook URL onde o Go Delivery irá enviar as atualizações de eventos, como confirmações de pedido, dispatch, cancelamento, entre outros.
Autenticação e Configuração:
Implementação da autenticação via Client ID e Client Secret para garantir a segurança da comunicação entre a plataforma interna e o Go Delivery.
Implementação de uma tela de configuração onde o usuário possa inserir e gerenciar as credenciais necessárias para a integração (Client ID, Client Secret, Webhook URL, etc.).
Processamento de Pedidos:
Recepção e validação dos pedidos através do endpoint GET /orders/{orderId}.
Capacidade de confirmar e atualizar o status do pedido por meio dos endpoints: POST /orders/{orderId}/confirm, POST /orders/{orderId}/readyForPickup, POST /orders/{orderId}/dispatch, POST /orders/{orderId}/delivered.
Implementação de endpoints para requisição de cancelamento e aceitação/negativa de cancelamento de pedidos (POST /orders/{orderId}/requestCancellation, POST /orders/{orderId}/acceptCancellation, POST /orders/{orderId}/denyCancellation).
Client ID: Necessário para autenticação com a API.
Client Secret: Usado junto com o Client ID para gerar um token de acesso.
API Base URL: A URL base para interagir com a API.
Webhook URL: Endpoint onde o sistema pode receber as atualizações de pedidos (via Webhooks).
Email: Para contato e configuração.
O Filtro do relatório possui as seguintes opções:
RN004 – Exibir na tela status - Utilizar o que já temos hoje.
Status do pedido | Cor do pedido |
|---|---|
| Pedido Novo | Roxa |
| Pedido aceito | Cinza |
| Pedido concluído | Verde |
| Pedido em entrega | Amarelo |
| Pedido cancelado ou com erro | Vermelho |
Figura 4.1
1. Endpoint para Cancelamento: POST /orders/{orderId}/requestCancellation
Finalidade: Permite o cancelamento de um pedido.
Requisição:
POST /orders/ord_123/requestCancellation
Content-Type: application/json
Authorization: Bearer <token>
{
"reason": "string"
} |
Campos:
Campo Tipo Obrigatório? Descrição reason string Sim Motivo do cancelamento (texto livre) |
Quando posso Receber Cancelamento ou Cancelar:
{
"eventType": "REQUEST_CANCELLATION",
"orderId": "123456"
}
Se aceita o cancelamento: POST /orders/{orderId}/acceptCancellation
Se não aceita o cancelamento: POST /orders/{orderId}/denyCancellation
Se o pdv solicita o cancelamento:
POST /orders/{orderId}/requestCancellation
|
Quando Pode Cancelar
Status válidos para cancelamento:
RECEIVED ou CONFIRMED (antes do preparo)
Status que impedem cancelamento:
PREPARATION_STARTED, DISPATCHED, DELIVERED
Erros Comuns
Código HTTP Código de Erro Motivo 400 INVALID_STATUS Pedido já está em preparo/entrega 404 ORDER_NOT_FOUND ID do pedido inválido |
"estimatedPreparationTime": 30
Caso não enviado será retornado o erro:
{
"error": {
"code": "MISSING_FIELD",
"message": "estimatedPreparationTime is required"
}
}
Importante:
Os status vindos da plataforma de deliveries, devem refletir no pedido no PDV.
POST /orders/{orderId}/tracking
{
"currentStatus": "DISPATCHED",
"deliveryPerson": {
"name": "João Motoboy",
"phone": "+5511999999999"
}
}
E assim que for entregue:
{
"currentStatus": "DELIVERED"
}
|
RN008 - Enviar o pedido para a retaguarda
Fluxo Completo:
GET
Servidor retorna eventos pendentes
Cliente processa cada evento
Para cada evento processado, cliente envia acknowledgment via POST /events/acknowledgment
Exemplo de Requisição:
GET /events:polling HTTP/1.1
Host: api.opendelivery.com
Authorization: Bearer {access_token} |
Exemplo de Resposta (200 OK):
{
"events": [
{
"eventId": "evt_123456789",
"type": "ORDER_CREATED",
"createdAt": "2023-04-01T12:00:00Z",
"data": {
"orderId": "ord_987654321",
"status": "RECEIVED",
"merchantId": "mch_123",
"customer": {
"name": "João Silva",
"phone": "+5511999999999"
}
}
}
]
} |
Casos de Erro:
401 Unauthorized: Token inválido ou ausente
429 Too Many Requests: Limite de polling excedido
Propósito: Confirmar o processamento bem-sucedido de um evento.
Exemplo de Requisição:
POST /events/acknowledgment HTTP/1.1
Host: api.opendelivery.com
Content-Type: application/json
Authorization: Bearer {access_token}
{
"eventId": "evt_123456789"
} |
Respostas Esperadas:
204 No Content: Confirmação bem-sucedida
400 Bad Request: eventId inválido ou já confirmado
404 Not Found: eventId não existe
Propósito: Receber notificações push sobre mudanças de estado.
Estrutura do Payload:
{
"orderId": "ord_987654321",
"status": "READY_FOR_PICKUP",
"timestamp": "2023-04-01T12:30:00Z",
"metadata": {
"readyAt": "2023-04-01T12:25:00Z",
"estimatedPickupTime": "2023-04-01T12:45:00Z"
}
} |
Resposta Esperada:
HTTP/1.1 200 OK
Content-Type: application/json
{
"success": true,
"receivedAt": "2023-04-01T12:30:05Z"
} |
Exemplo Completo:
GET /orders/ord_987654321 HTTP/1.1
Host: api.opendelivery.com
Authorization: Bearer {access_token} |
Resposta Detalhada (200 OK):
{
"orderId": "ord_987654321",
"status": "CONFIRMED",
"createdAt": "2023-04-01T12:00:00Z",
"confirmedAt": "2023-04-01T12:05:00Z",
"customer": {
"name": "João Silva",
"phone": "+5511999999999",
"deliveryAddress": {
"street": "Rua das Flores",
"number": "123",
"complement": "Apto 101",
"neighborhood": "Centro",
"city": "São Paulo",
"state": "SP",
"zipCode": "01001000"
}
},
"items": [
{
"id": "item_001",
"name": "Pizza Margherita",
"quantity": 1,
"unitPrice": 45.90,
"totalPrice": 45.90,
"notes": "Sem cebola"
}
],
"payment": {
"method": "CREDIT_CARD",
"amount": 55.90,
"deliveryFee": 10.00 -- Taxa de entrega
},
"timeline": [
{
"status": "RECEIVED",
"timestamp": "2023-04-01T12:00:00Z"
},
{
"status": "CONFIRMED",
"timestamp": "2023-04-01T12:05:00Z"
}
]
} |
Exemplo de Chamada:
POST /orders/ord_987654321/confirm HTTP/1.1
Host: api.opendelivery.com
Authorization: Bearer {access_token}
Content-Type: application/json
{
"estimatedPreparationTime": 30,
"notes": "Pedido confirmado com sucesso"
} |
Respostas Possíveis:
200 OK: Confirmação bem-sucedida
{
"status": "CONFIRMED",
"updatedAt": "2023-04-01T12:05:00Z"
} |
409 Conflict: Pedido já confirmado ou em estado inválido
Payload de Exemplo:
{
"readyAt": "2023-04-01T12:30:00Z",
"pickupCode": "A1B2C3",
"storageLocation": "Balcão Principal"
} |
Resposta de Sucesso:
{
"status": "READY_FOR_PICKUP",
"pickupCode": "A1B2C3",
"readyAt": "2023-04-01T12:30:00Z"
} |
Dados Requeridos:
{
"dispatchedAt": "2023-04-01T12:40:00Z",
"deliveryPerson": {
"name": "Carlos Entregador",
"phone": "+5511988888888",
"vehicle": {
"type": "MOTORCYCLE",
"plate": "ABC1D23"
}
}
} |
Exemplo Completo:
POST /orders/ord_987654321/delivered HTTP/1.1
Host: api.opendelivery.com
Authorization: Bearer {access_token}
Content-Type: application/json
{
"deliveredAt": "2023-04-01T13:00:00Z",
"receivedBy": "João Silva",
"confirmationMethod": "SIGNATURE",
"notes": "Assinatura eletrônica coletada"
} |
Caso de Uso:
{ "code": "A1B2C3", "validationType": "PICKUP" } |
Respostas:
Válido (200 OK):
{
"valid": true,
"message": "Código validado com sucesso"
} |
Inválido (400 Bad Request):
{
"valid": false,
"message": "Código incorreto",
"attemptsRemaining": 2
} |
Fluxo Completo:
POST /orders/{orderId}/requestCancellation - Solicitação inicial
{
"reason": "PRODUCT_UNAVAILABLE",
"details": "Ingrediente principal esgotado"
} |
POST /orders/{orderId}/acceptCancellation - Aceite pelo merchant
{
"refundAmount": 55.90,
"refundMethod": "ORIGINAL"
} |
POST /orders/{orderId}/denyCancellation - Rejeição pelo merchant
{
"reason": "PREPARATION_ALREADY_STARTED",
"alternative": "Podemos oferecer substituição do item"
} |
Exemplo Completo:
{
"timestamp": "2023-04-01T12:45:00Z",
"location": {
"latitude": -23.5505,
"longitude": -46.6333
},
"status": "IN_TRANSIT",
"estimatedTimeOfArrival": "2023-04-01T13:00:00Z"
} |
200 OK: Operação bem-sucedida com corpo de resposta
204 No Content: Sucesso sem conteúdo de retorno
400 Bad Request: Erro na estrutura da requisição
401 Unauthorized: Falha de autenticação
404 Not Found: Recurso não encontrado
409 Conflict: Conflito de estado (ex: transição inválida)
429 Too Many Requests: Limite de requisições excedido
Modelo de Erro Padrão
{
"error": {
"code": "ERR_INVALID_STATUS",
"message": "Cannot transition from current status",
"details": {
"currentStatus": "RECEIVED",
"validTransitions": ["CONFIRMED", "CANCELLED"]
}
}
} |
Headers Obrigatórios
Authorization: Bearer {access_token}
Content-Type: application/json (para POST/PUT)
Accept: application/json.
Evento ORDER_CREATED via polling
Confirmação via POST /confirm
Atualização para READY_FOR_PICKUP
Despacho via POST /dispatch
Atualizações de localização via POST /tracking
Confirmação de entrega via POST /delivered
Evento CANCELLATION_REQUESTED via polling
Merchant avalia e decide (accept/deny)
Se aceito:
Processa reembolso
Atualiza status para CANCELLED
Se rejeitado:
Fornece motivo
Pedido continua no fluxo normal