logo
logo

Introdução

O projeto Widget consiste em disponibilizar widgets que podem ser personalizados pelos desenvolvedores e incorporados aos seus aplicativos. Ao instalar o script de incorporação no seu aplicativo será exibido um botão flutuante que ao ser clicado expande disponibilizando os recursos configurados. Na versão atual o widget disponibiliza o Chat (entre merchant e consumidor), Notificações, Tracking de Pedidos e o Indicador de Status da Loja, com suporte a multi-lojas.

Widget

A documentação completa da API JavaScript do widget pode ser encontrada aqui.

Para executar o widget é necessário que o seu aplicativo seja uma aplicação web com suporte a JavaScript.

Para criar um widget, faça login no Portal do Desenvolvedor, clique no menu Widgets e depois em Cadastrar Widget. Preencha os campos necessários, personalize cor e posição e clique em Salvar. Depois de salvar clique em "Código de Incorporação" e copie o código para fazer a instalação.

Cole o código do widget na <head> das páginas do seu sistema em que o widget deve ser acessível. Após inserir o código, substitua o campo merchantIds com os UUIDs dos merchants do seu usuário.

<!-- Start of iFood Widget script-->
<script async src="https://widgets.ifood.com.br/widget.js"></script>
<script>
  window.addEventListener('load', () => {
    iFoodWidget.init({
      widgetId: 'widgetUUID',
      merchantIds: [
        // list of merchant uuids (up to 10)
      ],
    });
  });
</script>
<!-- End of iFood Widget script -->

É possível obter o UUID do merchant no Portal do Parceiro na tela Minha Loja -> Loja.

Dica

Você pode utilizar uma variável dinâmica que pode variar de acordo com as informações da sessão do usuário do seu aplicativo.

Cuidados com a Integração do Widget

O Widget deve ser tratado como um overlay na sua aplicação, ou seja, deve estar sempre visível por cima de todos os elementos na página.

Evite modificar os estilos dos elementos criados pelo Widget. Estes elementos não têm layout, classes ou IDs fixos e podem ser atualizados sem aviso prévio, causando impacto nesse tipo de modificação.

Evite também trocar a posição do widget na tela, como CSS overrides, Javascript customizado ou iframes adicionais. O widget suporta apenas as opções de posicionamento oferecidas na tela de configuração do Widget e posicionamentos não planejados podem causar problemas como widgets invisíveis ou falha ao registrar cliques em botões.

Sempre que possível use apenas a API JavaScript oficial do Widget para controlar sua visibilidade. Quaisquer outras alterações de estilo não são suportadas e podem quebrar em futuras atualizações.

Integrações com Bibliotecas e Framework

Para sistemas C# usando Blazor, é possível fazer uso da classe JSRuntime para invocar funções JavaScript de forma assíncrona.

Os próximos passos descrevem como controlar a inicialização do Widget via código C#.

  1. Carregar o script do widget e criar uma função global que o Blazor possa invocar para inicializar o widget.

Documentação:

<script src="https://widgets.ifood.com.br/widget.js"></script>
<script>
  window.startIfoodWidget = (merchantId) => {
      iFoodWidget.init({
          widgetId: widgetUUID,
          merchantIds: [merchantid],
      });
  };
</script>
  1. Criar métodos usando JSInterop para invocar startIfoodWidget do lado do C#.

Documentação:

using System.Threading.Tasks;
using Microsoft.JSInterop;

public class IFoodWidgetInterop
{
  [Inject]
  public IJSRuntime JSRuntime { get; set; }

  public async Task IniciarWidget(string merchantId)
  {
    await JsRuntime.InvokeVoidAsync("window.startIfoodWidget", merchantId);
  }
}

Com essa implementação agora é possível invocar IniciarWidget("merchantId") passando o ID do merchant para inicializar o widget.

Em sistemas usando Electron, será necessário um ajuste para abrir links externos no navegador padrão dos usuários. Isso é necessário pois em alguns momentos, o widget precisará que o usuário abra páginas no Portal do Parceiro, e esses redirecionamentos não funcionam bem no Electron, já que ele abriria em janelas fora do perfil do navegador do usuário. Para evitar que o usuário faça login novamente, sugerimos abrir links do iFood diretamente no navegador padrão do usuário.

O código abaixo deve ser adicionado no renderer process da sua aplicação:

win.webContents.setWindowOpenHandler((event) => {
  const newURL = new URL(event.url);

  if (newURL.origin.endsWith('ifood.com.br')) {
    shell.openExternal(newURL.href);
    return { action: 'deny' };
  }

  return { action: "allow" };
});

Nesse código win deve ser o objeto BrowserWindow da janela onde o script do widget será adicionado.

Dessa forma, links externos do widget abrem no navegador do usuário, sem interferir com outros links da sua aplicação.

Documentação Electron:

Dependendo de como o Content Security Policy está configurado na sua aplicação, o Electron não carregará o widget do iFood, apresentando erros como:

Para corrigir esse problema sem desativar CSP completamente, basta adicionar https://*.ifood.com.br na diretiva default-src da sua página:

<meta http-equiv="Content-Security-Policy" content="default-src https://*.ifood.com.br">

Há outras formas de configurar CSP em uma app Electron, verifique a documentação sobre CSP para mais detalhes.

Links úteis:

Autenticação e Autorização

No primeiro acesso, é necessário que o usuário autorize o widget.

Ao clicar no botão "Ir para o Portal do Parceiro" o usuário será redirecionado para o Portal do Parceiro para fazer a autorização. Caso o usuário não esteja logado será necessário fazer o login. Depois de logado, basta continuar e clicar em "Autorizar".

O processo de autorização é extremamente importante para garantirmos que somente o usuário com permissão em uma determinada loja tenha acesso às informações dela através do widget.

É esse processo que garante que nenhuma pessoa má intencionada tenha acesso aos dados sensíveis/confidenciais do seu cliente no iFood.

Perfis e permissões necessárias para autorizar o widget

Para realizar a autorização no Portal do Parceiro iFood é necessário que o usuário logado tenha acesso a todos os merchants informados no código de incorporação e ter um dos seguintes perfis:

  • "Administrador(a)"
  • "Dono(a)"
  • "Gestão da rede (antigo Master Franqueado)"
  • "Gestão estratégica de 2 ou mais lojas"
  • "Dono(a) da franquia (antigo Franqueado)"
  • "Franqueado Operação"
  • "Franqueado Gestão de Cardápio"
  • "Franqueado Gestão de Cardápio e Entrega"
  • "Financeiro"

Token da sessão do Widget e o Cache Local

Ao autorizar o widget, são gerados um accessToken e um refreshToken que ficarão armazenados no cache local. O próprio widget se encarrega de renovar o token quando ele estiver prestes a expirar, mas é super importante que esse cache local nunca seja apagado. Caso o cache seja apagado, o usuário terá que autorizar o widget novamente.

Validade da Sessão

O refreshToken tem validade de 7 dias. Caso o usuário fique mais de 7 dias sem acessar o Widget ele precisará fazer a autorização novamente

Logoff do usuário no seu aplicativo e a sessão do Widget

Quando um usuário do seu aplicativo faz logoff (numa eventual troca de turno), recomendamos que você mantenha a sessão do widget ativa. Para isso, não remova o código de incorporação da tela de login e não apague o cache. Com isso, quando um novo usuário logar no seu aplicativo ele já tem acesso ao widget sem precisar passar por todo o processo de autorização novamente.

Veja no vídeo abaixo como funciona o processo de autorização:

Dúvidas Comuns

É possível incluir de 1 a 10 merchants em uma sessão do widget. É necessário que o usuário que faça o processo de autorização tenha acesso a todos os merchants dessa lista, caso contrário não será possível autorizar o widget.

Múltiplas tabs

Não é possível ter instâncias do widget em várias tabs do mesmo navegador com merchants diferentes. Ao autenticar os merchants em uma instância, todas as outras instâncias (inclusive de todas as tabs do browser) irão perder a sessão automaticamente.

Isso não quer dizer que um widget não possa estar autorizado em vários merchants ao mesmo tempo, um widget pode ter sido autorizado por N merchants, e deve continuar funcionando normalmente para todos eles, desde que em máquinas separadas.

Hoje o processo de autorização deve ser feito uma vez por dispositivo, pois o resultado da autorização é apenas persistido localmente, logo ao autorizar o widget em uma máquina A, ao tentar abrir o mesmo widget com o mesmo merchant em uma máquina B, o usuário da máquina B deverá realizar o processo de autorização.

Problemas com perda de autorização

Conforme mencionado anteriormente, o widget permanecerá autorizado minimamente por 7 dias. Porém, em alguns casos, é possível que o widget não consiga salvar a sessão localmente causando a perda de sessão. Neste caso, será necessário realizar o processo de autorização novamente para voltar a utilizar o widget.

Veja a seguir como configurar o seu navegador para evitar problemas com perda de sessão.

O widget utiliza cookies para salvar a sessão localmente, por isso algumas configurações de privacidade dos browsers podem impedir seu correto funcionamento.

Veja a seguir como configurar o seu browser para evitar problemas com perda de sessão.

Navegue para chrome://settings/cookies:

  • A opção Bloquear cookies de terceiros na navegação anônima deve estar habilitada.

  • As opções Bloquear cookies de terceiros e Bloquear todos os cookies (não recomendado) irão impedir que o widget se mantenha autorizado. Por este motivo devem permanecer desabilitadas.

  • A opção Limpar cookies e dados de sites quando você fechar todas as janelas deve estar desabilitada.

Abra as configurações via: Safari > Preferências > Privacidade:

  • A opção Bloquear todos os cookies deve estar desabilitada.

Navegue para edge://settings/content/cookies:

  • A opção Permitir que os sites salvem e leiam dados de cookies (recomendado) deve estar habilitada.
  • A opção Bloquear cookies de terceiros, deve estar desabilitada.

Navegue para edge://settings/clearBrowsingDataOnClose:

  • A opção Cookies e dados do site deve estar desabilitada.

Navegue para about:preferences#privacy:

  • Nas opções de privacidade, a opção Normal deve estar habilitada.

Ainda nessa página, na sessão Cookies e dados de sites:

  • A opção Apagar cookies e dados de sites quando o Firefox for fechado deve estar desabilitada.

Caso ainda tenha problemas de perda de sessão, verifique se o seu navegador possui extensões ou plugins que fazem limpeza de cache, cookies ou histórico automaticamente, se possuir tente reiniciar seu navegador com todas as extensões desativadas.

Evite também realizar limpeza de dados de sites no seu navegador frequentemente.

Verifique também se há ferramentas de limpeza de sistema excluindo os cookies do navegador. Neste caso, configure a ferramenta para não limpar cookies do browser.

Em alguns casos é possível que o widget perca a sessão caso seja inicializado com parâmetros inválidos.

Por exemplo, digamos que na sua aplicação os parâmetros widgetId e merchantIds só estarão disponíveis após user.login(), que executa uma chamada async:

<script>
  // Errado: Widget é inicializado com parâmetros 
  // inválidos, excluindo a sessão do usuário:

  window.addEventListener('load', () => {
    // 1. Inicializar com parâmetros em branco 
    iFoodWidget.init({
      widgetId: '',
      merchantIds: [],
    });
  });

  // 2. Aguardar algum processo async para carregar
  // os dados do usuário no seu sistema...

  user.login().then(user => {
    // 3. Inicializar uma segunda vez com os parâmetros corretos
    // agora que o user está carregado.
    iFoodWidget.init({
        widgetId: user.widgetId,
        merchantIds: user.merchants,
    });
  });
</script>

Para corrigir o problema basta remover o primeiro init com os valores vazios. O widget suporta ser inicializado a qualquer momento durante o ciclo de vida da página. Ou seja, caso sua aplicação não tenha os parâmetros imediatamente, basta remover a inicialização de dentro do window.addEventListener e mover para onde essa informação é carregada:

<script>
  // Correto: widget é inicializado apenas uma vez com  
  // os parâmetros corretos.

  user.login().then(user => {
    iFoodWidget.init({
        widgetId: user.widgetId,
        merchantIds: user.merchants,
    });
  });
</script>

Caso o problema ainda não tenha sido resolvido:

  • Verifique se o dispositivo rodando o widget possui scripts ou processos automatizados que fazem limpeza de dados após uso.
  • Caso sua aplicação não seja web, mas usa uma WebView para fazer a integração com o widget, verifique se a implementação de WebView escolhida suporta ou está configurada para salvar cookies.
  • Verifique se o usuário está sempre usando o mesmo perfil/conta no navegador.