Pular para o conteúdo principal

Guia de Integração de Pedidos Online para XDRest

Microservice: XDPeople.Soba.Table.WebAPI
Autenticação: Bearer Token (JWT) ou API Key via cabeçalho X-API-KEY Ver mais →


Introdução

Este guia descreve o processo de integração para envio e gestão de pedidos de mesa através da XDSobaAPI. O objectivo é apoiar os nossos parceiros na utilização correcta desta funcionalidade, garantindo um fluxo de pedidos fiável.

No modelo adoptado, a XDSobaAPI recebe os pedidos submetidos e assegura o seu encaminhamento para o Ponto de Venda (XDREST), onde os pedidos associados à mesa são impressos. Este modelo garante um fluxo de pedidos estável e consistente, adequado ao contexto operacional.

A integração disponibiliza endpoints específicos para as operações fundamentais do ciclo de vida dos pedidos de mesa, nomeadamente:

Adicionalmente, sempre que o endereço de email do cliente final for fornecido no momento do fecho da conta, a API envia automaticamente a factura para o email indicado.

Este guia destina-se a servir como guia de integração, descrevendo objectivamente o funcionamento geral da solução, os endpoints disponíveis e o comportamento esperado de cada operação.


Passos de Configuração

A configuração é feita através da criação e parametrização de um botão específico no ecrã de vendas do XDRest. Siga os passos abaixo para concluir o processo.

Adicionar um Novo Botão

No modo de configuração de página do XDRest, o primeiro passo é adicionar um novo botão que servirá como ponto de acesso às definições da API Soba.

  • Prima o botão Adicionar no menu lateral direito para criar um novo botão no layout de vendas.

Adicionar novo botão

Aceder às Definições do Botão

Com o novo botão seleccionado, aceda ao menu de definições para configurar a sua aparência e funcionalidade.

  • Clique em Definições no menu lateral direito.

Aceder às definições do botão

Definir a Função do Botão

Neste passo, irá associar a função específica de configuração da API Soba ao botão.

  • No campo Função, clique no ícone de pesquisa para abrir a lista de funções disponíveis.

Campo de função na janela de propriedades

  • Na janela de pesquisa de funções, procure e seleccione a função XDSOBACONFIG.
  • Após seleccionar a função, clique em Ok para confirmar.

Seleccionar XDSOBACONFIG

  • A função XDSOBACONFIG aparecerá no campo correspondente. Clique em Ok para fechar a janela de propriedades do botão.

Confirmar função XDSOBACONFIG

Guardar Alterações

Após configurar o botão, é fundamental guardar as alterações para que sejam aplicadas ao layout de vendas.

  • Clique no botão Guardar no canto inferior direito do ecrã.

Guardar alterações

Aceder ao Ecrã de Configuração da API Soba

Com o botão já configurado e guardado, saia do modo de edição. Ao clicar no novo botão XDSOBACONFIG, será apresentado o ecrã de configuração da API Soba para introdução dos dados de autenticação e identificação necessários à comunicação com a API.

Ecrã de configuração da API Soba

Detalhes dos Campos de Configuração

O formulário de configuração da API Soba contém os seguintes campos:

CampoDescrição
TerminalTerminal XD que irá receber os pedidos.
LicençaNúmero de licença do software XD. Este campo é preenchido automaticamente.
Nome da lojaNome do estabelecimento ou loja associado à licença.
UtilizadorRefere-se à licença da Conta XDCloud válida. Este é um campo de texto aberto para acomodar clientes que possam possuir múltiplas licenças XD.
Palavra PasseA palavra-passe correspondente à conta XDCloud (licença) inserida no campo Utilizador.
Ativo(Obrigatório) Ativa a comunicação com a API Soba. É necessário que esta opção esteja marcada para que a integração funcione.

Formulário de configuração Soba preenchido

Ao preencher correctamente estes campos e, de forma crucial, activar a flag 'Active', o terminal ficará apto a receber pedidos através da API Soba.


Endpoints Disponíveis

Esta secção descreve os endpoints disponíveis para a gestão de pedidos de mesa, abrangendo operações como envio de pedidos, cancelamento, transferência e fecho de conta. Para cada endpoint, são apresentados o respectivo objectivo, o método HTTP utilizado e o comportamento esperado da operação.

Antes de iniciar o envio de pedidos para a mesa, recomenda-se a consulta do endpoint de detalhes dos artigos disponíveis. Esta consulta permite compreender a estrutura de cada artigo, identificar opções, complementos ou composições, e garantir que o pedido é construído correctamente antes de ser enviado.

Consultar Detalhes do Artigo

URL: /gateway/item/{keyId}/details

Method: GET

Descrição

Este endpoint permite consultar os detalhes de um artigo, devolvendo informação estruturada de acordo com a sua característica. A resposta inclui, quando aplicável, dados relativos a menus, composições ou complementos.

Parâmetro de Rota

keyId (string, required): Identifier of the item in the system.

Estrutura da Resposta

O endpoint devolve um objecto do tipo ItemDetailDTO:

ParâmetroTipoDescrição
KeyIdstringIdentificador do artigo.
DescriptionstringDescrição do artigo.
ShortName1stringNome abreviado do artigo.
RetailPrice1decimalPreço de venda do artigo.
ItemTypeintTipo de artigo (Normal, Menu, Composto, etc.).
ComplementDetailsobjectDetalhes dos complementos (se aplicável).
MenuDetailsobjectDetalhes do menu (se aplicável).
CompositeDetailsobjectDetalhes do artigo composto (se aplicável).
PizzaDetailsobjectDetalhes do artigo Pizza (se aplicável).

Apenas as propriedades correspondentes à característica do artigo são preenchidas; as restantes podem ser devolvidas como null.

Comportamento Esperado

  • O serviço valida a existência do artigo pelo keyId.
  • Os dados retornados variam conforme a característica do artigo.
  • Complementos, menus ou composições são agregados automaticamente.
  • Artigos inexistentes retornam erro apropriado.

Ver mais →


Envio de Pedidos para uma Mesa

URL: /gateway/online-orders/table

Method: POST

Descrição

Este endpoint permite o envio de pedidos para uma mesa. Após o envio, o pedido é encaminhado para o Ponto de Venda (XDREST), onde é impresso.

O endpoint suporta uma estrutura hierárquica de artigos, permitindo o envio de produtos principais com os respectivos sub-artigos, sendo adequado para cenários como menus, combinações ou produtos com complementos.

Estrutura do Corpo do Pedido

O corpo do pedido deve ser enviado em formato JSON e seguir o modelo TableOrderRequestDTO, contendo a seguinte informação:

TableOrderRequestDTO

ParâmetroTipoObrigatórioDescrição
TableIdintSimIdentificador da mesa. Deve ser diferente de 0.
EmployeeIdintSimIdentificador do empregado responsável pelo pedido.
PersonsNumberintNãoNúmero de pessoas na mesa. Valor predefinido: 0.
ItemsList<OrderItemDTO>SimLista de artigos do pedido. Deve conter pelo menos um artigo.

OrderItemDTO

ParâmetroTipoObrigatórioDescrição
KeyIdstringNãoIdentificador do artigo no sistema. Para observações ou complementos de texto livre, este campo deve estar vazio.
DescriptionstringNãoUtilizado para observações/complementos de texto livre.
QuantitydecimalNãoQuantidade do artigo. Valor predefinido: 1.0.
PricedecimalNãoPreço do artigo. Se não informado, o sistema utiliza o preço já registado no sistema.
OptionsLineIdintNãoIdentificador da linha de opção, utilizado para associação de sub-artigos. Ver secção "Explicação do OptionsLineId".
SubItemsList<OrderItemDTO>NãoLista de sub-artigos, permitindo estrutura hierárquica (menus, composições, etc.).

Exemplos de Pedidos

Produto Normal

{ 
"TableId": 20,
"EmployeeId": 1,
"PersonsNumber": 0,
"Items": [
{
"KeyId": "134", // Coca-Cola
"Description": null,
"Quantity": 1.0,
"Price": 0.0,
"OptionsLineId": 0,
"SubItems": []
}
]
}

Tipo Menu

Nota: No exemplo abaixo, o artigo principal do menu tem OptionsLineId igual a 0, enquanto cada sub-item tem o seu respectivo OptionsLineId (correspondente ao campo LineLevel presente em MenuDetails ao obter os detalhes de um artigo do tipo Menu), utilizado para identificar a linha de opção correspondente.

{ 
"TableId": 12,
"EmployeeId": 1,
"PersonsNumber": 0,
"Items": [
{
"KeyId": "70000", // Executive Menu
"Description": null,
"Quantity": 1.0,
"Price": 0.0,
"OptionsLineId": 0,
"SubItems": [
{
"KeyId": "50261", // Soup of the Day
"Description": null,
"Quantity": 1.0,
"Price": 0.0,
"OptionsLineId": 1,
"SubItems": []
},
{
"KeyId": "50848", // Bacalhau à Brás
"Description": null,
"Quantity": 1.0,
"Price": 0.0,
"OptionsLineId": 2,
"SubItems": []
},
{
"KeyId": "51100", // Chocolate Mousse
"Description": null,
"Quantity": 1.0,
"Price": 0.0,
"OptionsLineId": 3,
"SubItems": []
}
]
}
]
}

Envio de múltiplos menus

Quando é necessário enviar mais do que um menu para a mesa, o comportamento depende da definição "Associar pedido ao menu" configurada no terminal XDRest.

Com a opção "Associar pedido ao menu" activada

Nesta configuração, o valor da propriedade Quantity do menu não deve ser incrementado. Em vez disso:

Cada menu deve:

  • Ter Quantity = 1;
  • Conter todos os seus sub-artigos (SubItems);
  • Manter uma estrutura completa, autónoma e independente.

Com a opção "Associar pedido ao menu" desactivada

Quando esta opção não está activa, é permitido enviar o menu com Quantity superior a 1, sem necessidade de repetir o artigo no array Items.

Exemplo (Com a flag Associar pedido ao menu activada):

{  
"TableId": 24,
"EmployeeId": 1,
"PersonsNumber": 0,
"Items": [
{
"KeyId": "70000", // SEAFOOD MENU WITH COMPOSITES
"Description": null,
"Quantity": 1.0,
"Price": 0.0,
"OptionsLineId": 0,
"SubItems": [
{
"KeyId": "50261", // FRIED SHRIMP
"Description": null,
"Quantity": 1.0,
"Price": 0.0,
"OptionsLineId": 1,
"SubItems": []
},
{
"KeyId": "50848", // PROFESCO WATER
"Description": null,
"Quantity": 1.0,
"Price": 0.0,
"OptionsLineId": 2,
"SubItems": []
},
{
"KeyId": "50522", // FINI DULCE DE LECHE
"Description": null,
"Quantity": 1.0,
"Price": 0.0,
"OptionsLineId": 2,
"SubItems": []
}
]
},
{
"KeyId": "70000", // SEAFOOD MENU WITH COMPOSITES
"Description": null,
"Quantity": 1.0,
"Price": 0.0,
"OptionsLineId": 0,
"SubItems": [
{
"KeyId": "50261", // FRIED SHRIMP
"Description": null,
"Quantity": 1.0,
"Price": 0.0,
"OptionsLineId": 1,
"SubItems": []
},
{
"KeyId": "50848", // PROFESCO WATER
"Description": null,
"Quantity": 1.0,
"Price": 0.0,
"OptionsLineId": 2,
"SubItems": []
},
{
"KeyId": "50522", // FINI DULCE DE LECHE
"Description": null,
"Quantity": 1.0,
"Price": 0.0,
"OptionsLineId": 2,
"SubItems": []
}
]
}
]
}

Produto Composto

{ 
"TableId": 20,
"EmployeeId": 1,
"PersonsNumber": 0,
"Items": [
{
"KeyId": "70016", // Burger Combo
"Description": null,
"Quantity": 1.0, // Could be 2, 3, whatever the desired quantity
"Price": 1.0,
"OptionsLineId": 0,
"SubItems": []
}
]
}

Produto com complementos

Ao enviar um artigo com complementos para a mesa:

  1. O artigo principal deve ser enviado normalmente, com a respectiva quantidade (Quantity);
  2. Os complementos devem ser enviados dentro do array SubItems;
  3. A quantidade de cada complemento representa o total de unidades adicionadas ao artigo principal;
  4. A quantidade do complemento pode ser igual, inferior ou superior à quantidade do artigo principal;
  5. O campo OptionsLineId pode ser utilizado com o valor 0, uma vez que os complementos não estão associados a linhas de opção fixas, funcionando apenas como adições;
  6. O sistema associa os complementos ao artigo principal exactamente como enviados no pedido.

Exemplo 1 – Complementos com a mesma quantidade do artigo principal

No exemplo abaixo:

  • São enviados 2 hambúrgueres (quantity = 2).
  • Cada complemento é enviado com uma quantidade total igual a 2, indicando que será aplicado a ambas as unidades do artigo principal.
{ 
"TableId": 10003,
"EmployeeId": 1,
"PersonsNumber": 0,
"Items": [
{
"KeyId": "B018", // Special Burger
"Description": null,
"Quantity": 2.0,
"Price": 1.0,
"OptionsLineId": 0,
"SubItems": [
{
"KeyId": "388", // Cheddar Cheese
"Description": null,
"Quantity": 2.0,
"Price": 0.0,
"OptionsLineId": 0,
"SubItems": []
},
{
"KeyId": "389", // Extra Bacon
"Description": null,
"Quantity": 2.0,
"Price": 0.0,
"OptionsLineId": 0,
"SubItems": []
},
{
"KeyId": "390", // Caramelized Onion
"Description": null,
"Quantity": 2.0,
"Price": 0.0,
"OptionsLineId": 0,
"SubItems": []
},
{
"KeyId": "391", // Special Sauce
"Description": null,
"Quantity": 4.0,
"Price": 0.0,
"OptionsLineId": 0,
"SubItems": []
}
]
}
]
}

Tipo Pizza

{ 
"TableId": 10006,
"EmployeeId": 1,
"PersonsNumber": 0,
"Items": [
{
"KeyId": "1023", // Large Pizza
"Description": null,
"Quantity": 2.0,
"Price": 0.0,
"OptionsLineId": 0,
"SubItems": [
{
"KeyId": "1007", // Mozzarella
"Description": null,
"Quantity": 2.0,
"Price": 0.0,
"OptionsLineId": 1,
"SubItems": []
},
{
"KeyId": "1009", // Pepperoni
"Description": null,
"Quantity": 2.0,
"Price": 0.0,
"OptionsLineId": 2,
"SubItems": []
},
{
"KeyId": "1014", // Mushrooms
"Description": null,
"Quantity": 2.0,
"Price": 0.0,
"OptionsLineId": 3,
"SubItems": []
},
{
"KeyId": "1016", // Bell Pepper
"Description": null,
"Quantity": 2.0,
"Price": 0.0,
"OptionsLineId": 4,
"SubItems": []
},
{
"KeyId": null,
"Description": "No Onion",
"Quantity": 2.0,
"Price": 0.0,
"OptionsLineId": 5,
"SubItems": []
}
]
}
]
}

Explicação do campo OptionsLineId

Inteiro que agrupa artigos relacionados dentro de pedidos de menu ou pizza.

Como é atribuído:

  • Artigo raiz: normalmente 0 (artigo base do pedido).
  • Menus/combos: cada "linha" da composição do menu recebe o seu próprio OptionsLineId (1, 2, 3…), proveniente do linelevel da composição do menu. Artigos na mesma linha (ex.: prato principal + acompanhamento) utilizam o mesmo número.
  • Pizzas: nas pizzas, o OptionsLineId é o número da fracção/parte onde o artigo se aplica. Pizza inteira: utilizar 1 para todos os ingredientes, opções ou observações. Meia-meia: utilizar 1 para a primeira metade e 2 para a segunda. Em três partes: 1, 2, 3; em quatro partes: 1 a 4, e assim sucessivamente, respeitando sempre o numberItems configurado para a pizza. Todos os artigos pertencentes à mesma fracção reutilizam o mesmo OptionsLineId; cada fracção diferente deve ter o seu próprio número. A API não ajusta nem herda valores automaticamente — a integração deve enviar o número correcto para cada fracção.

Exemplo Prático:

Considere um menu "Almoço Executivo" que inclui uma entrada, um prato principal e uma sobremesa:

  • O menu principal "Almoço Executivo" terá OptionsLineId: 0
  • A entrada seleccionada (ex.: Sopa do Dia) terá OptionsLineId: 1
  • O prato principal (ex.: Bacalhau à Brás) terá OptionsLineId: 2
  • A sobremesa (ex.: Mousse de Chocolate) terá OptionsLineId: 3
  • Se o prato principal tiver um acompanhamento opcional (ex.: Arroz Extra), este acompanhamento manterá o mesmo OptionsLineId: 2 do prato principal.

Casos de uso:

  • Tipos menu com múltiplas linhas de selecção (entrada, prato principal, sobremesa, etc.)
  • Tipos pizza com múltiplas categorias de ingredientes
  • Artigos complexos com opções organizadas por linhas

Ver mais →


Transferência de produtos entre mesas

URL: /gateway/online-orders/table/transfer

Method: POST

Descrição

Este endpoint permite a transferência total ou parcial de artigos entre mesas. A operação move os artigos seleccionados da mesa de origem para a mesa de destino, preservando correctamente as quantidades e a estrutura dos artigos.

A transferência é realizada com base no UniqueId de cada artigo, garantindo que apenas os artigos pretendidos são transferidos. O endpoint suporta uma estrutura hierárquica, permitindo a transferência de artigos principais e respectivos sub-artigos, como menus, artigos compostos ou pizzas com ingredientes.

TableOrderTransferRequestDTO

ParâmetroTipoObrigatórioDescrição
SourceTableIdintSimIdentificador da mesa de origem
DestinationTableIdintSimIdentificador da mesa de destino
EmployeeIdintSimIdentificador do empregado responsável pela operação
ItemsList<OrderTransferItemDTO>SimLista de artigos a transferir

OrderTransferItemDTO

ParâmetroTipoObrigatórioDescrição
UniqueIdstring (GUID)SimIdentificador único da linha do artigo a transferir
ItemTypeintNãoTipo de artigo
QuantitydecimalSimQuantidade a transferir
ItemsList<OrderTransferItemDTO>NãoSub-artigos associados ao artigo principal

Exemplos de Transferência de Produtos entre Mesas

Produto Normal/Serviço

{ 
"SourceTableId": 1,
"DestinationTableId": 5,
"EmployeeId": 1,
"Items": [
{
"UniqueId": "61a1b116-01c7-44ed-846b-c77ed11e916c ",
"KeyId": "132",
"ItemType": 0,
"Quantity": 1.0,
"Items": []
}
]
}

A transferência de artigos entre mesas segue as mesmas regras e princípios do envio de pedidos para uma mesa. A estrutura dos dados, o tratamento das quantidades e a hierarquia dos artigos mantêm-se consistentes em ambas as operações.

Em particular:

  • A identificação dos artigos é feita através do UniqueId;
  • As quantidades são respeitadas de acordo com o tipo de artigo;
  • Artigos com estrutura hierárquica (menus, compostos ou pizzas) devem ser enviados com todos os seus sub-artigos, mantendo a relação pai-filho;
  • O comportamento específico por tipo de artigo (Normal, Menu, Composto ou Pizza) é idêntico ao já descrito no envio de pedidos para uma mesa.

Desta forma, quem já integra o envio de pedidos para uma mesa pode aplicar a mesma lógica e estrutura ao utilizar o endpoint de transferência, reduzindo a complexidade da integração e evitando ambiguidades no tratamento dos artigos.

Ver mais →


Remoção de produtos

URL: /gateway/online-orders/table/void

Method: POST

Descrição

Este endpoint permite a remoção total ou parcial de produtos de um pedido associado a uma mesa. A remoção é identificada através do UniqueId de cada linha do pedido, garantindo que apenas os artigos correctos são cancelados.

O endpoint suporta uma estrutura hierárquica de artigos, permitindo a remoção de artigos principais e respectivos sub-artigos (por exemplo, pizzas com ingredientes, menus ou composições).

Estrutura do Corpo do Pedido

O corpo do pedido deve seguir o modelo TableOrderVoidRequestDTO e conter a seguinte informação:

TableOrderVoidRequestDTO

ParâmetroTipoObrigatórioDescrição
TableIdintSimIdentificador da mesa. Deve ser diferente de zero.
EmployeeIdintSimIdentificador do empregado responsável pelo cancelamento.
ItemsList<OrderVoidItemDTO>SimLista de artigos a cancelar. Deve conter pelo menos um artigo.

OrderVoidItemDTO

ParâmetroTipoObrigatórioDescrição
UniqueIdstring (GUID)SimIdentificador único da linha do artigo a cancelar.
KeyIdstringSimIdentificador do artigo na mesa, que pode corresponder a um artigo do sistema ou a observações/complementos de texto livre.
ItemTypeintNãoTipo de artigo. Ver tabela "Tipos de Artigo" abaixo.
QuantitydecimalSimQuantidade a remover. Valor predefinido: 1.0.
CancellationReasonIdintNãoIdentificador do motivo de cancelamento. Valor predefinido: 0.
ItemsList<OrderVoidItemDTO>NãoSub-artigos associados ao artigo principal, permitindo remoção hierárquica.

Exemplos de remoção de produtos

Tipo Pizza

Quando apenas 1 pizza foi enviada para a mesa e se pretende removê-la, o pedido deve conter:

  • O artigo pizza (KeyId);
  • Quantity 1;
  • Todos os respectivos ingredientes/opções (SubItems).
{ 
"TableId": 1,
"EmployeeId": 1,
"Items": [
{
"UniqueId": "725d2d06-45be-42d9-94b7-90cc2cd7dcfa",
"KeyId": "1023", // Large Pizza
"ItemType": 6,
"Quantity": 1.0,
"CancellationReasonId": 0,
"Items": [
{
"UniqueId": "0cd4ae90-3b6d-4da0-bb3a-90df8f62ab16",
"KeyId": "1006", // Extra Cheese
"ItemType": 0,
"Quantity": 1.0,
"CancellationReasonId": 0,
"Items": []
},
{
"UniqueId": "453d83c9-530c-46c0-b1a6-21fe9613c4d2",
"KeyId": "1012", // Olives
"ItemType": 0,
"Quantity": 1.0,
"CancellationReasonId": 0,
"Items": []
}
]
}
]
}

Tipo Menu

{ 
"TableId": 1,
"EmployeeId": 1,
"Items": [
{
"UniqueId": "2fcce2fb-28c7-4e7d-b1c1-7bfa298afd74",
"KeyId": "372", // Menu of the Day
"ItemType": 4,
"Quantity": 1.0,
"CancellationReasonId": 0,
"Items": [
{
"UniqueId": "63e2c6b1-58fe-4542-a768-c01eabd90044",
"KeyId": "360", // Vegetable Cream Soup
"ItemType": 0,
"Quantity": 1.0,
"CancellationReasonId": 0,
"Items": []
},
{
"UniqueId": "21235d0a-19aa-41c9-bf36-1384fb5ebe8a",
"KeyId": "187", // Grilled Chicken
"ItemType": 0,
"Quantity": 1.0,
"CancellationReasonId": 0,
"Items": []
}
]
}
]
}

Tipo Serviço/Normal

Basta indicar a quantidade que se pretende remover do produto.

{ 
"TableId": 2,
"EmployeeId": 1,
"Items": [
{
"UniqueId": "99a02507-7849-40ed-8389-db4ddfa25353",
"KeyId": "50131", // Service Fee
"ItemType": 5,
"Quantity": 2.0,
"CancellationReasonId": 0,
"Items": []
}
]
}

Os artigos do tipo Serviço ou Normal são os mais simples em termos de remoção. Não possuem hierarquia (pai/filhos) nem dependências internas. O cancelamento é feito exclusivamente com base na quantidade informada.

Regras de remoção

Tipo Menu

Um artigo do tipo Menu é tratado como um conjunto indivisível, composto pelo artigo principal (pai) e respectivos sub-artigos (filhos).

Por esta razão, o cancelamento é sempre realizado ao nível do menu, não sendo permitido remover apenas sub-artigos isolados.

O comportamento da remoção depende da forma como os menus foram enviados, consoante a definição "Associar pedido ao menu" no terminal XDRest.

Com a opção "Associar pedido ao menu" activada

Nesta configuração, cada menu é enviado como uma instância independente (Quantity = 1), mesmo que vários menus tenham o mesmo KeyId.

Exemplo:

Foram enviados 5 menus, cada um como um objecto distinto no array Items. Para remover apenas 2 desses 5 menus:

  • O pedido de cancelamento deve conter 2 objectos
  • Cada objecto representa uma instância específica do menu a cancelar.

Com a opção "Associar pedido ao menu" desactivada

Quando esta opção não está activa, é permitido enviar menus com Quantity > 1 num único objecto.

Exemplo:

Foi enviado um único objecto de menu com Quantity = 5. Para remover apenas 2 desses menus:

  • O pedido de cancelamento deve conter um único objecto de menu,
  • Com Quantity = 2, indicando a quantidade total a remover,
  • Não é necessário indicar uma instância individual para cada menu.

Regra geral

  • O pedido de remoção deve reflectir sempre a estrutura utilizada no envio original:
  • Menus enviados como instâncias individuais → remoção por instâncias individuais;
  • Menus enviados com quantidade agregada → remoção por quantidade agregada.

Tipo Serviço / Normal

Ao remover um artigo deste tipo:

  • Enviar apenas o artigo a remover;
  • Informar a quantidade exacta que se pretende remover;
  • O sistema subtrairá a quantidade removida do total existente na mesa;
  • Não é necessário enviar sub-artigos (Items vazio).

Exemplo prático No exemplo acima:

  • O artigo Service Fee (KeyId = 50131) existe na mesa;
  • Estão a ser canceladas 2 unidades deste artigo.

Tipo Composto

O tipo Composto representa um artigo pai que é formado por um ou mais artigos filhos, onde cada filho pode ter a sua própria quantidade dependendo da composição.

Por esta razão, a remoção de um composto deve considerar sempre a hierarquia completa:

  • O artigo pai (composto);
  • Todos os artigos filhos associados;
  • As quantidades correctas e proporcionais entre pai e filhos.

Não é permitido remover apenas o pai ou apenas os filhos isoladamente.

{ 
"TableId": 4,
"EmployeeId": 1,
"Items": [
{
"UniqueId": "47737e6c-b7a9-4257-b785-44e42b3a96b5",
"KeyId": "70016",
"ItemType": 18,
"Quantity": 2.0,
"CancellationReasonId": 0,
"Items": [
{
"UniqueId": "89fbf4a8-36b5-40bf-bf34-b2e499a869ae",
"KeyId": "47",
"ItemType": 0,
"Quantity": 2.0,
"CancellationReasonId": 0,
"Items": []
},
{
"UniqueId": "83cf506c-4211-44af-b78e-9ee802c18175",
"KeyId": "49",
"ItemType": 0,
"Quantity": 4.0,
"CancellationReasonId": 0,
"Items": []
}
]
}
]
}

Tipo Pizza

Quando, por exemplo, 4 pizzas idênticas são enviadas para a mesa e o objectivo é remover apenas 2, o cancelamento deve indicar:

  • Quantity = 2 no artigo pizza;
  • Os sub-artigos (ingredientes) devem também ter a quantidade proporcional (2);
  • O sistema subtrairá automaticamente a quantidade cancelada.
{ 
"TableId": 2,
"EmployeeId": 1,
"Items": [
{
"UniqueId": "19f6b61a-e295-45e4-a8e2-53774f67a9f3",
"KeyId": "70020",
"ItemType": 6,
"Quantity": 2.0,
"CancellationReasonId": 0,
"Items": [
{
"UniqueId": "6a69ebb9-9c29-4001-843e-aeaa2ce741b7",
"KeyId": "5",
"ItemType": 0,
"Quantity": 2.0,
"CancellationReasonId": 0,
"Items": []
},
{
"UniqueId": "00b03fde-0b16-47df-a33b-3a70392246e1",
"KeyId": "2",
"ItemType": 0,
"Quantity": 2.0,
"CancellationReasonId": 0,
"Items": []
},
{
"UniqueId": "3d4d2d8f-6a60-4454-9bc9-5b6348b2e439",
"KeyId": "59",
"ItemType": 0,
"Quantity": 2.0,
"CancellationReasonId": 0,
"Items": []
},
{
"UniqueId": "46975022-6b75-4e71-9f19-71699739d6a7",
"KeyId": "17",
"ItemType": 0,
"Quantity": 2.0,
"CancellationReasonId": 0,
"Items": []
}
]
}
]
}

Ver mais →


Fecho da Conta

URL: /gateway/online-orders/table/bill

Method: POST

Descrição

Este endpoint permite o fecho da conta de uma mesa. Após o processamento, é gerado o documento fiscal associado ao consumo da mesa.

Quando o campo de email do cliente final é informado no pedido, a XDSobaAPI envia automaticamente a factura para o endereço de email indicado.

Estrutura do Corpo do Pedido

TableBillRequestDTO

ParâmetroTipoObrigatórioDescrição
TableIdintSimIdentificador da mesa. Deve ser diferente de zero.
TotalAmountdecimalSimMontante total a pagar.
CustomerVatstringNãoNúmero de contribuinte do cliente. Se não informado, será assumido Consumidor Final.
CustomerEmailstringNãoEmail do cliente. Quando informado, a factura é enviada automaticamente.
MobilePhonestringNãoNúmero de telemóvel do cliente.
PaymentTypeIdintNãoIdentificador do tipo de pagamento. O valor 0 utiliza o tipo de pagamento predefinido ("OU").
EmployeeIdintSimIdentificador do empregado responsável pelo fecho da conta.

Exemplo de Pedido

{
"TableId": 6,
"TotalAmount": 40.00,
"CustomerVat": "",
"CustomerEmail": "customer@example.com",
"MobilePhone": "",
"PaymentTypeId": 1,
"EmployeeId": 1
}

Regras de Utilização do Campo paymentTypeId

Este documento estabelece as directrizes para a utilização correcta do campo paymentTypeId na API, detalhando os valores aceites, as regras de negócio associadas e os possíveis erros.

Comportamento por Defeito (Valor Predefinido)

Quando o campo paymentTypeId é omitido ou enviado com o valor 0, o sistema aplicará o tipo de pagamento predefinido, que corresponde ao mecanismo OU (Others). Neste caso, a propriedade SendToCheckingAccount será sempre definida como false.

  • Valor: 0 ou campo omitido
  • Mecanismo Resultante: OU (Outros)
  • SendToCheckingAccount: false

Tipos de Pagamento Aceites

Os seguintes tipos de mecanismos de pagamento são aceites, e para todos eles a propriedade SendToCheckingAccount deve ser false.

MecanismoDescriçãoCondição de Aceitação
OUOutrosSempre aceite.
NUNumerárioApenas se o terminal não tiver uma máquina de gestão de numerário (cashdro) configurada e activa.
CCCartão de CréditoApenas se o terminal não tiver um terminal POS (Ponto de Venda) activo.
CDCartão de DébitoApenas se o terminal não tiver um terminal POS (Ponto de Venda) activo.
Gestão de Erros

A API devolverá os seguintes erros em caso de utilização indevida do campo paymentTypeId:

  • PAYMENT_TYPE_CAN_NOT_BE_USED: Este erro ocorre se uma das seguintes condições for verdadeira:

    • O paymentTypeId enviado não existe no sistema XD.
    • O tipo de pagamento associado tem um mecanismo diferente de OU, NU, CC ou CD.
    • A propriedade SendToCheckingAccount do tipo de pagamento está definida como true.
  • PAYMENT_ERROR: Este erro é devolvido se o montante total do pagamento (totalAmount) for inferior ou igual a 0.

Resposta de Sucesso

Em caso de sucesso, o endpoint devolve a informação do documento gerado:

{
"DocumentTypeId": 1,
"DocumentSerieId": 2,
"DocumentNumber": 12345
}

Campos da Resposta

CampoTipoDescrição
DocumentTypeIdintIdentificador do tipo de documento gerado.
DocumentSerieIdintIdentificador da série do documento.
DocumentNumberintNúmero do documento fiscal gerado.

Ver mais →


Gestão de Erros

Erros Comuns (Podem ocorrer em qualquer endpoint)

Esta secção descreve os erros que podem ser devolvidos pelos endpoints de pedidos de mesa, incluindo envio, cancelamento, transferência e fecho de conta.

Todos os endpoints devolvem um objecto de resultado que, em caso de erro, contém:

  • Error code – identificador único
  • Type – indica se é um erro de autorização ou uma falha de operação
  • Message – descrição legível do erro

O cliente integrador deve sempre validar o resultado da operação e tratar os erros com base no código devolvido.

Estrutura Padrão de Erro

{
"Code": "Error.Code",
"Type": "Failure | Unauthorized",
"Message": "Error description"
}

Erros Globais do Serviço

Estes erros não dependem da operação específica e podem ocorrer em qualquer endpoint, estando normalmente relacionados com autenticação, contexto do utilizador ou disponibilidade do sistema.

Tenant.NotFound

  • Code: Tenant.NotFound
  • Type: Unauthorized
  • Descrição: O contexto do tenant não foi identificado no pedido.
  • Acção recomendada: Verificar autenticação e configuração de acesso do tenant.

Employee.NotFound

  • Code: Employee.NotFound
  • Type: Unauthorized
  • Descrição: O empregado não foi identificado no contexto do pedido.
  • Acção recomendada: Garantir que o utilizador está autenticado e correctamente associado.

XDSoftware.NotConnected

  • Code: XDSoftware.NotConnected
  • Type: Failure
  • Descrição: O Ponto de Venda (XDREST) não está ligado ou não está disponível.
  • Acção recomendada: Verificar se o XD está em execução e ligado ao SOBA.

OnlineOrder.InvalidTableId

  • Code: OnlineOrder.InvalidTableId
  • Type: Failure
  • Descrição: O identificador da mesa é inválido (valor inferior ou igual a 0).
  • Acção recomendada: Indicar uma mesa válida.

Envio de Pedido para Mesa

Error.SendToTable.{Kind}

  • Base code: Error.SendToTable
  • Type: Failure
  • Descrição: Ocorreu um erro ao enviar o pedido para a mesa.
  • Variações possíveis:
    • NoPermission – Sem permissão para realizar a operação
    • TableEmpty – Mesa vazia
    • TableInUse – Mesa em uso
    • TableInactive – Mesa inactiva
    • TableValueModified – O valor da mesa foi modificado
    • TableHasAlreadyBeenUsed – A mesa já foi utilizada

Cancelamento de Pedido

Error.SendToTableVoid.{Kind}

  • Base code: Error.SendToTableVoid
  • Type: Failure
  • Descrição: Ocorreu um erro durante o cancelamento do pedido.
  • Variações possíveis: As mesmas aplicáveis ao envio de pedidos (NoPermission, TableEmpty, TableInUse, etc.).

Transferência de Artigos entre Mesas

OnlineOrder.InvalidTableTransfer

  • Code: OnlineOrder.InvalidTableTransfer
  • Type: Failure
  • Descrição: A mesa de origem e a mesa de destino são a mesma.

Error.SendToTableTransfer.{Kind}

  • Base code: Error.SendToTableTransfer
  • Type: Failure
  • Descrição: Ocorreu um erro durante a transferência de artigos entre mesas.
  • Variações possíveis: As mesmas aplicáveis ao envio de pedidos.

Fecho de Conta

Error.Bill.{Kind}

  • Base code: Error.Bill
  • Type: Failure
  • Descrição: Ocorreu um erro durante o fecho da conta da mesa.
  • Variações possíveis:
    • NoPermission
    • TableEmpty
    • TableInUse
    • TableInactive
    • TableValueModified
    • TableHasAlreadyBeenUsed
    • PaymentTypeCanNotBeUsed
    • PaymentError

Conclusão

Este guia apresentou uma visão detalhada dos endpoints disponíveis para a integração de pedidos de mesa com a plataforma SOBA. A implementação correcta dos endpoints de envio, transferência, remoção/cancelamento e fecho de conta é fundamental para garantir um fluxo de operações estável e consistente entre os sistemas dos parceiros e o Ponto de Venda (XDREST).

Recomenda-se que os parceiros realizem testes exaustivos em ambiente de staging antes de avançar para o ambiente de produção. A validação deve incluir cenários de sucesso bem como situações de erro, para garantir que a integração está preparada para lidar com todas as eventualidades. Para questões técnicas ou dúvidas durante o processo de integração, contacte a equipa de suporte técnico.

Recursos Relacionados


Última atualização: 6 de Março de 2026