MeuPedido/developer
Pedidos

Ações e idempotência

confirm, startPreparation, readyForPickup, dispatch, pickedUp, delivered e requestCancellation, com Idempotency-Key e as respostas 202, 404, 409 e 422.

Ações são as chamadas que movem o pedido pelo ciclo de vida. Todas são POST /v1/orders/{orderId}/{ação}, exigem o escopo orders:write e, com exceção de requestCancellation, não têm corpo.

Uma ação pela API percorre exatamente as mesmas regras que um clique no painel: mesma validação, mesmo histórico, mesmos efeitos (impressão, notificação ao cliente, entregador). O ator fica registrado como a sua credencial.

As ações

AçãoSituação resultanteEvento emitidoUso
POST /v1/orders/{orderId}/confirmACCEPTEDCONFIRMEDA loja aceitou o pedido.
POST /v1/orders/{orderId}/startPreparation Extensão MeuPedidoPREPARINGPREPARINGA cozinha começou. Opcional.
POST /v1/orders/{orderId}/readyForPickupREADYREADY_FOR_PICKUPPronto para sair ou para o cliente retirar.
POST /v1/orders/{orderId}/dispatchDELIVERYDISPATCHEDSaiu para entrega. Só pedido DELIVERY.
POST /v1/orders/{orderId}/pickedUp Extensão MeuPedidoDONECONCLUDEDO cliente retirou. Encerra o pedido.
POST /v1/orders/{orderId}/deliveredDONECONCLUDEDEntregue. Encerra o pedido.
POST /v1/orders/{orderId}/requestCancellationCANCELLEDCANCELLEDCancela imediatamente. Aceita corpo opcional.

pickedUp e delivered levam à mesma situação: para a loja, os dois significam pedido encerrado. Use o que descreve o que aconteceu.

Exemplo: confirmar um pedido

curl -X POST "https://api.meupedido.io/open-delivery/v1/orders/3f8a1c2d-5b6e-4f7a-9c8d-1e2f3a4b5c6d/confirm" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Idempotency-Key: confirm-3f8a1c2d-5b6e-4f7a-9c8d-1e2f3a4b5c6d"
202 Accepted
{ "status": "accepted", "situation": "ACCEPTED" }

Respostas

Toda ação responde com um dos quatro resultados abaixo.

StatusCorpoSignificado
202{"status":"accepted","situation":"ACCEPTED"}A transição foi aplicada. situation é a situação nova.
202{"status":"already_applied","situation":"ACCEPTED"}O pedido já estava nessa situação. Nada mudou e nenhum evento foi emitido.
404{"error":"order_not_found","message":"..."}O pedido não existe ou não pertence à loja da credencial.
422{"error":"invalid_transition","message":"..."}A transição não é permitida a partir da situação atual. message explica em português.

already_applied é 202, e não erro, de propósito: o caso real é um comando reenviado depois de um timeout. Tratar isso como falha faria o seu sistema mostrar erro em uma operação que já está feita.

Um orderId que não é um GUID também responde 404, no formato ProblemDetails (type, title, status, traceId).

422 Unprocessable Entity
{
  "error": "invalid_transition",
  "message": "Pedido encerrado não pode ser cancelado."
}

Exemplos de 422: dispatch em pedido INDOOR, requestCancellation em pedido DONE, qualquer ação em pedido CANCELLED.

Cancelar

requestCancellation é a única ação com corpo, e o corpo é opcional:

curl -X POST "https://api.meupedido.io/open-delivery/v1/orders/3f8a1c2d-5b6e-4f7a-9c8d-1e2f3a4b5c6d/requestCancellation" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "reason": "Produto em falta.", "code": "OTHER_CANCELLATION_REASON" }'
202 Accepted
{ "status": "accepted", "situation": "CANCELLED" }
CampoTipoDescrição
reasonstring, opcionalMotivo registrado no histórico do pedido e enviado ao lojista. Padrão: "Cancelamento solicitado pela API pública.".
codestring, opcionalAceito por compatibilidade com o padrão e ignorado. O code do evento CANCELLED é derivado de quem cancelou, não deste campo.

O cancelamento é imediato: não existe uma etapa de aprovação, e o evento CANCELLED sai com metadata.reason igual ao motivo informado. Cancelar um pedido DONE responde 422.

Sem corpo também funciona

Enviar requestCancellation sem corpo e sem Content-Type cancela com o motivo padrão.

Idempotência

Comandos de mudança de estado não são seguros de repetir por natureza, e a rede repete: um timeout do seu lado não diz se a ação foi aplicada. O cabeçalho opcional Idempotency-Key resolve isso.

POST /v1/orders/3f8a1c2d-5b6e-4f7a-9c8d-1e2f3a4b5c6d/dispatch
Authorization: Bearer {access_token}
Idempotency-Key: 2c0f6b3a-8e1d-4a9b-b7c5-0d4e8f1a2b3c

Como funciona:

  • A chave é qualquer string escolhida por você, única por credencial. Um UUID por tentativa lógica, ou um valor derivado como dispatch-{orderId}, funcionam.
  • Mesma chave, mesma requisição (mesma rota, mesma ação, mesmo corpo): a API devolve a resposta gravada na primeira vez, com o mesmo status e o mesmo corpo, sem executar de novo. Vale por 24 horas.
  • Mesma chave, requisição diferente: 409 {"error":"idempotency_key_reuse","message":"..."}. Nada é executado.
  • Respostas 202, 404 e 422 são gravadas. Erros 5xx não são, para que a repetição execute de verdade.
409 Conflict
{
  "error": "idempotency_key_reuse",
  "message": "Esta chave de idempotência já foi usada com outro conteúdo."
}

Mesmo sem Idempotency-Key, repetir uma ação já aplicada devolve already_applied e não muda nada. A chave acrescenta uma garantia a mais: a resposta exata da primeira execução, útil quando a situação do pedido já avançou por outro caminho entre a primeira tentativa e a repetição.

Boas práticas

  • Envie Idempotency-Key em toda ação. Custa um cabeçalho e elimina uma classe inteira de bugs de rede.
  • Em timeout, repita com a mesma chave. Nunca gere chave nova para a mesma intenção.
  • Antes de avançar, confira a situação atual em GET /v1/orders/{orderId} se o seu sistema pode ter ficado para trás (por exemplo, o operador avançou o pedido no painel).
  • Trate 422 como bug de fluxo ou disputa com o painel, e não como erro transitório: repetir não resolve.

Próximos passos

Nesta página