Validação do pincode de coleta

Webhook síncrono enviado pela Abbiamo quando o operador da loja digita o pincode — a transportadora destrava o motorista e responde na mesma chamada.

Este webhook é enviado somente quando a entrega foi despachada com logistic_data.pickup_verification.pincode_owner = "abbiamo" no payload da Solicitação de entrega — modelo motorista → loja (veja Pincode de coleta).

A Abbiamo já validou o PIN digitado pelo operador da loja contra a própria cópia do código. Esta chamada pede que a transportadora destrave o motorista no app dela para que a coleta física possa continuar.

A Abbiamo aguarda a resposta da transportadora na mesma requisição HTTPnão há callback. O HTTP status code e o campo code retornados pela transportadora decidem diretamente se a coleta é liberada para o operador da loja.

  • Timeout padrão: 5 segundos. Se o seu handler precisar de mais tempo, responda 200 / driver_unlocked assim que o destravamento for persistido no seu banco e finalize o resto de forma assíncrona do seu lado.
  • Retries: a Abbiamo refaz a chamada uma vez em 5xx / timeout. Não há retry em respostas 4xx.

Sempre que o operador da loja envia o pincode no dashboard da Abbiamo e a Abbiamo confirma localmente, este evento é disparado para a URL de webhook da transportadora. A transportadora precisa destravar o motorista no próprio app e responder de forma síncrona.

O payload espelha os mesmos blocos identificadores já enviados na Solicitação de entrega original (seller, carrier, identificadores da entrega, logistic_data), para que a transportadora consiga localizar a entrega nos próprios sistemas e reutilizar qualquer contexto que chegou no momento do despacho (por exemplo, um token específico do seller dentro de logistic_data.headers):

{
  "event_type": "PICKUP_PIN_VALIDATION_REQUEST",
  "event_at": "2026-05-12T14:34:17.890Z",
  "seller": {
    "seller_name": "Go Go Fruits",
    "seller_id": "eb064ede-08f3-470e-a37c-5b796a17cca8",
    "seller_document_number": "88399480000156",
    "seller_group_id": "b7d56bca-606e-405e-bf4d-9b0a3291b61d",
    "seller_contacts": [
      {
        "name": "Eduardo Silveira",
        "phone": "21999999999",
        "phone_country_code": "55",
        "email": "silveiradudu@gmail.com"
      }
    ]
  },
  "carrier": {
    "name": "CARRIER_BRAND_NAME",
    "max_dispatched_time": "14:00:00-03",
    "expected_delivery_date": "2022-12-22T23:59:00.000-03:00",
    "total_expected_delivery_price": 1200,
    "method": {
      "external_id": "name/id",
      "id": "e84b2788-5b78-40dd-95cf-75807f70aaaa",
      "name": "CARRIER_BRAND_NAME_D0",
      "type": "D0"
    }
  },
  "invoice_number": "example_invoice_number_1",
  "invoice_access_key": "42081183123141000200550010000007010046403276",
  "delivery_id": "851dc274-e090-4881-8f3c-5b660cecf059",
  "order_number": "example_carrier_payload_1",
  "logistic_data": {
    "headers": {
      "Authorization": "Bearer xxx"
    },
    "pickup_verification": {
      "pincode": true,
      "pincode_owner": "abbiamo",
      "pincode_value": "8745"
    }
  }
}

A Abbiamo é a fonte da verdade do PIN no modelo motorista → loja e já validou localmente antes de disparar este webhook. A transportadora não deve re-validar o pincode_value que vem dentro de logistic_data.pickup_verification — o único propósito deste endpoint é destravar o motorista no app da transportadora.

O pincode_value aparece aqui apenas porque o bloco logistic_data inteiro é reenviado por conveniência (assim a transportadora pode reutilizar qualquer contexto usado no momento do despacho — geralmente um token específico do seller dentro de logistic_data.headers). Se a transportadora não precisa desse contexto, pode ignorar tudo menos o delivery_id.

Respostas esperadas

A transportadora precisa responder na mesma chamada HTTP. A Abbiamo usa a resposta para decidir se transita a entrega para COLLECTED e libera a coleta no lado da loja.

HTTPcodeSignificado
200driver_unlockedMotorista destravado no app da transportadora. A Abbiamo transita a entrega para COLLECTED e retorna sucesso ao operador da loja.
200already_unlockedMotorista já estava destravado (retry idempotente do mesmo delivery_id). Mesmo efeito de driver_unlocked.
404DELIVERY_NOT_FOUNDA transportadora não reconhece este delivery_id. A Abbiamo mostra o erro ao operador. Sem retry.
409INVALID_DRIVER_STATUSO motorista não está mais em estado válido pra coletar (desistiu, já saiu do ponto de coleta, etc.). A Abbiamo bloqueia a coleta. Sem retry.
5xx / timeoutA Abbiamo refaz a chamada uma vez imediatamente. Se ainda falhar, o operador vê um erro "transportadora indisponível" no dashboard e a entrega não avança.

Exemplo de resposta para 200 / driver_unlocked:

{
  "code": "driver_unlocked",
  "delivery_id": "851dc274-e090-4881-8f3c-5b660cecf059",
  "unlocked_at": "2026-05-12T14:34:18.014Z",
  "driver": {
    "name": "Carlos Silva",
    "document_number": "12345678900"
  }
}

O endpoint da transportadora precisa aceitar uma segunda chamada com o mesmo delivery_id sem efeitos colaterais e responder 200 / already_unlocked. A Abbiamo trata driver_unlocked e already_unlocked como equivalentes (sucesso), o que mantém o comportamento de retry seguro.

Onde registrar a URL

O endpoint que escuta este evento fica na mesma URL que a transportadora registra para DELIVERY_REQUEST e CANCELLATION_REQUEST — ou em uma URL separada, se preferir. Veja Receber eventos para o passo de registro. Transportadoras que ainda não suportam o modelo motorista → loja podem pular o registro dessa URL — nesse caso, a Abbiamo simplesmente não despacha entregas com pincode_owner = "abbiamo" para a sua integração.

Nesta página