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:
- Envio de pedidos para uma mesa Ver mais →
- Remoção de produtos Ver mais →
- Transferência de produtos entre mesas Ver mais →
- Fecho da conta, com devolução da informação do documento gerado Ver mais →
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.

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.

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.

- 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.

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

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ã.

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.

Detalhes dos Campos de Configuração
O formulário de configuração da API Soba contém os seguintes campos:
| Campo | Descrição |
|---|---|
| Terminal | Terminal XD que irá receber os pedidos. |
| Licença | Número de licença do software XD. Este campo é preenchido automaticamente. |
| Nome da loja | Nome do estabelecimento ou loja associado à licença. |
| Utilizador | Refere-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 Passe | A 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. |

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âmetro | Tipo | Descrição |
|---|---|---|
| KeyId | string | Identificador do artigo. |
| Description | string | Descrição do artigo. |
| ShortName1 | string | Nome abreviado do artigo. |
| RetailPrice1 | decimal | Preço de venda do artigo. |
| ItemType | int | Tipo de artigo (Normal, Menu, Composto, etc.). |
| ComplementDetails | object | Detalhes dos complementos (se aplicável). |
| MenuDetails | object | Detalhes do menu (se aplicável). |
| CompositeDetails | object | Detalhes do artigo composto (se aplicável). |
| PizzaDetails | object | Detalhes 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.
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âmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| TableId | int | Sim | Identificador da mesa. Deve ser diferente de 0. |
| EmployeeId | int | Sim | Identificador do empregado responsável pelo pedido. |
| PersonsNumber | int | Não | Número de pessoas na mesa. Valor predefinido: 0. |
| Items | List<OrderItemDTO> | Sim | Lista de artigos do pedido. Deve conter pelo menos um artigo. |
OrderItemDTO
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| KeyId | string | Não | Identificador do artigo no sistema. Para observações ou complementos de texto livre, este campo deve estar vazio. |
| Description | string | Não | Utilizado para observações/complementos de texto livre. |
| Quantity | decimal | Não | Quantidade do artigo. Valor predefinido: 1.0. |
| Price | decimal | Não | Preço do artigo. Se não informado, o sistema utiliza o preço já registado no sistema. |
| OptionsLineId | int | Não | Identificador da linha de opção, utilizado para associação de sub-artigos. Ver secção "Explicação do OptionsLineId". |
| SubItems | List<OrderItemDTO> | Não | Lista 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:
- O artigo principal deve ser enviado normalmente, com a respectiva quantidade (Quantity);
- Os complementos devem ser enviados dentro do array SubItems;
- A quantidade de cada complemento representa o total de unidades adicionadas ao artigo principal;
- A quantidade do complemento pode ser igual, inferior ou superior à quantidade do artigo principal;
- 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;
- 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
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âmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| SourceTableId | int | Sim | Identificador da mesa de origem |
| DestinationTableId | int | Sim | Identificador da mesa de destino |
| EmployeeId | int | Sim | Identificador do empregado responsável pela operação |
| Items | List<OrderTransferItemDTO> | Sim | Lista de artigos a transferir |
OrderTransferItemDTO
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| UniqueId | string (GUID) | Sim | Identificador único da linha do artigo a transferir |
| ItemType | int | Não | Tipo de artigo |
| Quantity | decimal | Sim | Quantidade a transferir |
| Items | List<OrderTransferItemDTO> | Não | Sub-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.
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âmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| TableId | int | Sim | Identificador da mesa. Deve ser diferente de zero. |
| EmployeeId | int | Sim | Identificador do empregado responsável pelo cancelamento. |
| Items | List<OrderVoidItemDTO> | Sim | Lista de artigos a cancelar. Deve conter pelo menos um artigo. |
OrderVoidItemDTO
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| UniqueId | string (GUID) | Sim | Identificador único da linha do artigo a cancelar. |
| KeyId | string | Sim | Identificador do artigo na mesa, que pode corresponder a um artigo do sistema ou a observações/complementos de texto livre. |
| ItemType | int | Não | Tipo de artigo. Ver tabela "Tipos de Artigo" abaixo. |
| Quantity | decimal | Sim | Quantidade a remover. Valor predefinido: 1.0. |
| CancellationReasonId | int | Não | Identificador do motivo de cancelamento. Valor predefinido: 0. |
| Items | List<OrderVoidItemDTO> | Não | Sub-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": []
}
]
}
]
}
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âmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| TableId | int | Sim | Identificador da mesa. Deve ser diferente de zero. |
| TotalAmount | decimal | Sim | Montante total a pagar. |
| CustomerVat | string | Não | Número de contribuinte do cliente. Se não informado, será assumido Consumidor Final. |
| CustomerEmail | string | Não | Email do cliente. Quando informado, a factura é enviada automaticamente. |
| MobilePhone | string | Não | Número de telemóvel do cliente. |
| PaymentTypeId | int | Não | Identificador do tipo de pagamento. O valor 0 utiliza o tipo de pagamento predefinido ("OU"). |
| EmployeeId | int | Sim | Identificador 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.
| Mecanismo | Descrição | Condição de Aceitação |
|---|---|---|
| OU | Outros | Sempre aceite. |
| NU | Numerário | Apenas se o terminal não tiver uma máquina de gestão de numerário (cashdro) configurada e activa. |
| CC | Cartão de Crédito | Apenas se o terminal não tiver um terminal POS (Ponto de Venda) activo. |
| CD | Cartão de Débito | Apenas 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
| Campo | Tipo | Descrição |
|---|---|---|
| DocumentTypeId | int | Identificador do tipo de documento gerado. |
| DocumentSerieId | int | Identificador da série do documento. |
| DocumentNumber | int | Número do documento fiscal gerado. |
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
- Consultar Detalhes do Artigo - Documentação do endpoint para obter detalhes de um artigo
- Enviar Pedidos para Mesa - Documentação completa para envio de pedidos para uma mesa
- Transferir Produtos entre Mesas - Documentação para transferência de artigos entre mesas
- Remover Produtos - Documentação para cancelamento/remoção de produtos de um pedido
- Fechar Conta - Documentação para fecho da conta e geração de documento fiscal
Última atualização: 6 de Março de 2026