# Guia de Integração do Biometric Pix Com o Biometric Pix da Belvo, coletar pagamentos de usuários torna-se simples, eliminando a necessidade de os usuários navegarem até sua instituição financeira para aprovar cada solicitação de pagamento individualmente. Neste guia, vamos conduzi-lo por cada etapa, desde o registro do dispositivo até a iniciação bem-sucedida de uma solicitação de pagamento. Pré-requisitos Por favor, certifique-se de ter concluído todas as etapas em nosso artigo dedicado de pré-requisitos antes de continuar este guia. Nós suportamos o Modo Escuro! 🤩 Nosso hosted widget Biometric Pix não só suporta o Modo Escuro, mas também personalização adicional de cores. Para mais detalhes, confira nosso artigo dedicado a Branding e Customização (Biometric Pix Widget) (*Em breve*). ## Fluxo Geral No diagrama abaixo, você pode ver o fluxo geral de inscrição e pagamento: 1. Seu usuário seleciona pagar com Biometric Pix. 2. Você gera um access token (com os detalhes necessários para a inscrição e pagamento) e o anexa à URL do widget. 3. Você redireciona seu usuário para a URL do widget. 4. Seu usuário passa pelo processo de inscrição e pagamento dentro do widget. 1. Você receberá eventos de webhook detalhando o status da inscrição, pagamento e cobrança. 5. Seu usuário é redirecionado de volta para sua aplicação. 6. Você recebe um webhook de transação confirmando que o pagamento foi processado. E é isso! Todo o processo de inscrição e pagamento requer apenas **uma** chamada POST para a API da Belvo! O restante é gerenciado pelo Biometric Pix Widget. ## Gerar um `access_token` Recomendamos sempre enviar as informações de inscrição e pagamento Para facilitar o seu fluxo de trabalho, recomendamos que você sempre envie os objetos `enrollment` e `payment_intent`. Isso permitirá que o widget lide com todo o fluxo para você (novas inscrições, inscrições existentes e pagamentos). O access token é válido apenas por 30 minutos. Para gerar um access token para o Biometric Pix widget que fará tanto a inscrição do dispositivo quanto o pagamento, você precisará fazer uma chamada POST para `/api/payments/br/token` com o seguinte payload: ```json { "use_cases": ["ENROLLMENT", "PAYMENT_INTENT"], "widget": { "enrollment": { "type": "open_finance_biometric_pix", "external_id": "recommended_uuid", "details": { "name": "optional_name_for_enrollment", "customer": { "identifier": "user_CPF", "name": "Gustavo Veloso", "external_id": "recommended_uuid" } } }, "payment_intent": { "amount": "amount_as_string", "external_id": "recommended_uuid", "description": "internal_description", "statement_description": "description_to_display", "allowed_payment_method_types": ["open_finance_biometric_pix"], "payment_method_details": { "open_finance_biometric_pix": { "beneficiary_bank_account": "registered_bank_account_belvo_id" } } }, "callback_urls": { "success": "url_to_redirect_user_after_success", "exit": "url_to_redirect_user_after_exit_or_error" }, "top_tier_institutions": [ "nubank_retail", "picpay_retail", "mercadopago_retail", "itau_retail"], "branding": {}, // Veja nosso artigo dedicado a branding e customização "theme": [] // Veja nosso artigo dedicado a branding e customização } } ``` ### `use_cases` ```json Parâmetro de Casos de Uso { "use_cases": ["ENROLLMENT", "PAYMENT_INTENT"], // [!code highlight] "widget": { } } ``` No parâmetro use_cases, você precisa fornecer o propósito do widget. Você pode escolher o seguinte: - `ENROLLMENT`: Use esta opção se você deseja inscrever o dispositivo do seu usuário na rede Biometric Pix ou listar as inscrições anteriores dos seus usuários. - `PAYMENT_INTENT`: Use esta opção se você deseja criar um pagamento para o seu usuário usando o Biometric Pix. Se você passar ambos os casos de uso (recomendado), o widget primeiro inscreverá o usuário e, em seguida, guiará seu usuário pelo pedido de pagamento também. ### `enrollment` O objeto de enrollment contém informações chave que são necessárias para inscrever o dispositivo do usuário com sua instituição. ```json Enrollment Object { "use_cases": ["ENROLLMENT", "PAYMENT_INTENT"], "widget": { "enrollment": { "type": "open_finance_biometric_pix", "external_id": "recommended_uuid", "details": { "name": "optional_name_for_enrollment", "customer": { "identifier": "user_CPF", "name": "Gustavo Veloso", "external_id": "recommended_uuid" } } }, } } ``` | Parâmetro | Obrigatório | Descrição | | --- | --- | --- | | `type` | sim | O tipo de enrollment. Para pagamentos Biometric Pix no 🇧🇷 Brasil, isso deve ser configurado como `open_finance_biometric_pix`. | | `external_id` | altamente recomendado | Um identificador único adicional para o recurso para fins internos. Recomendamos usar este campo para armazenar seu próprio identificador único para cada recurso (cliente, conta bancária, intenção de pagamento ou enrollment). Isso pode ser útil para rastrear o recurso em seu sistema e para fins de depuração. | | `details.name` | opcional | Use o parâmetro name para fornecer um nome opcional, legível por humanos, para o enrollment. | | `details.customer` | sim | No objeto customer, você precisa fornecer:- O CPF do seu usuário no parâmetro `identifier` (obrigatório). - O `name` do seu usuário (opcional, mas altamente recomendado). - Um `external_id` único adicional para fins internos, útil para rastrear o recurso em seu sistema e para fins de depuração (opcional, mas altamente recomendado). | ### `payment_intent` O objeto `payment_intent` contém todas as informações necessárias para realizar o pagamento. ```json Payment Intent Object { "use_cases": ["ENROLLMENT", "PAYMENT_INTENT"], "widget": { "enrollment": { "type": "open_finance_biometric_pix", "external_id": "recommended_uuid", "details": { "name": "optional_name_for_enrollment", "customer": { "identifier": "user_CPF", "name": "Gustavo Veloso", "external_id": "recommended_uuid" } } }, "payment_intent": { "amount": "amount_as_string", "external_id": "recommended_uuid", "description": "internal_description", "statement_description": "description_to_display", "allowed_payment_method_types": ["open_finance_biometric_pix"], "payment_method_details": { "open_finance_biometric_pix": { "beneficiary_bank_account": "registered_bank_account_belvo_id" } } }, } } ``` | Parâmetro | Obrigatório | Descrição | | --- | --- | --- | | `amount` | sim | No parâmetro `amount`, você precisa fornecer o valor do pagamento como uma string. | | `external_id` | altamente recomendado | Um identificador único adicional para o recurso para fins internos. Recomendamos usar este campo para armazenar seu próprio identificador único para cada recurso (cliente, conta bancária, intenção de pagamento ou inscrição). Isso pode ser útil para rastrear o recurso em seu sistema e para fins de depuração. | | `description` | sim | No parâmetro `description`, você precisa fornecer uma descrição do pagamento para seus propósitos internos. | | `statement_description` | altamente recomendado | No parâmetro opcional `statement_description`, você precisa fornecer uma descrição que aparecerá no extrato bancário do cliente (altamente recomendado). Se você não usar o parâmetro `statement_description`, o valor de `description` será usado como a descrição do extrato. | | `allowed_payment_method_types` | sim | O parâmetro `allowed_payment_method_types` indica qual método de pagamento deve ser usado. Para pagamentos Biometric Pix no Brasil, isso deve ser configurado como `["open_finance_biometric_pix"]`. | | `payment_method_details` | sim | No objeto `payment_method_details`, você fornece informações adicionais necessárias para processar um pagamento na rede Open Finance. Especificamente, você fornecerá a `beneficiary_bank_account` no objeto `open_finance_biometric_pix`.- No parâmetro obrigatório `beneficiary_bank_account`, você precisa fornecer o ID da conta bancária que receberá os fundos do pagamento. | ### `callback_urls` No objeto `callback_urls` (obrigatório), você deve adicionar links para onde seu usuário deve ser redirecionado. No caso de um erro durante o cadastro ou pagamento, o usuário será redirecionado para a URL de `exit`. Se o cadastro ou pagamento for bem-sucedido, o usuário será redirecionado para a URL de `success`. ```json Callback URLs Object { "use_cases": ["ENROLLMENT", "PAYMENT_INTENT"], "widget": { "enrollment": { "type": "open_finance_biometric_pix", "external_id": "recommended_uuid", "details": { "name": "optional_name_for_enrollment", "customer": { "identifier": "user_CPF", "name": "Gustavo Veloso", "external_id": "recommended_uuid" } } }, "payment_intent": { "amount": "amount_as_string", "external_id": "recommended_uuid", "description": "internal_description", "statement_description": "description_to_display", "allowed_payment_method_types": ["open_finance_biometric_pix"], "payment_method_details": { "open_finance_biometric_pix": { "beneficiary_bank_account": "registered_bank_account_belvo_id" } } }, "callback_urls": { "success": "url_to_redirect_user_after_success", "exit": "url_to_redirect_user_after_exit_or_error" }, "top_tier_institutions": [ "nubank_retail", "picpay_retail", "mercadopago_retail", "itau_retail"], "branding": { "color_scheme": "LIGHT", "company_name": "ACME" }, "theme": [] // Veja nosso artigo dedicado a branding e personalização } } ``` | Parâmetro | Obrigatório | Descrição | | --- | --- | --- | | `success` | sim | A URL para a qual seu usuário é redirecionado quando conclui com sucesso o cadastro ou pagamento. | | `exit` | sim | A URL para a qual seu usuário é redirecionado quando sai do processo do widget ou encontra um erro. A `exit_url` é usada nos seguintes casos específicos: **Saídas iniciadas pelo usuário:** - O usuário fecha ou sai manualmente do widget antes de concluir o processo de cadastro ou pagamento **Condições de erro:** - Um erro `token_not_valid` é retornado pela API da Belvo (token de acesso expirado ou inválido) - O widget é aberto em um dispositivo que não suporta a tecnologia WebAuthn Quando redirecionado para a URL de saída devido a um erro, parâmetros de consulta serão anexados para fornecer detalhes do erro. Abaixo está um exemplo de um erro `token_not_valid`: ``` Example Error Callback Structure https:///?error=token_not_valid&error_description=Authorization+header+is+missing+or+invalid. ``` | Erro de Token Não Válido no Widget No caso de um erro de token não válido, seu usuário verá a seguinte mensagem no widget (em português): "Sessão expirada: Sua sessão expirou, para realizar a conexão de conta você precisará iniciar novamente o processo." ### `top_tier_institutions` ```json Parâmetro Top Tier Institutions { "use_cases": ["ENROLLMENT", "PAYMENT_INTENT"], "widget": { // Outros parâmetros... "top_tier_institutions": [ "nubank_retail", "picpay_retail", "mercadopago_retail", "itau_retail"] } } ``` No parâmetro `top_tier_institutions`, você pode fornecer uma lista de instituições que serão inicialmente exibidas no widget (os usuários ainda poderão buscar por outras instituições). Você pode selecionar entre 1 a 5 instituições da lista disponível. As instituições serão exibidas na ordem em que você as fornecer no array. Se você não passar este parâmetro, o widget exibirá todas as instituições disponíveis. Para uma lista de instituições disponíveis, consulte o parâmetro top_tier_institutions em nossa Referência de API. ### `branding` e `theme` ```json Parâmetros de Branding e Tema { "use_cases": ["ENROLLMENT", "PAYMENT_INTENT"], "widget": { "enrollment": { "type": "open_finance_biometric_pix", "external_id": "recommended_uuid", "details": { "name": "optional_name_for_enrollment", "customer": { "identifier": "user_CPF", "name": "Gustavo Veloso", "external_id": "recommended_uuid" } } }, "payment_intent": { "amount": "amount_as_string", "external_id": "recommended_uuid", "description": "internal_description", "statement_description": "description_to_display", "allowed_payment_method_types": ["open_finance_biometric_pix"], "payment_method_details": { "open_finance_biometric_pix": { "beneficiary_bank_account": "registered_bank_account_belvo_id" } } }, "callback_urls": { "success": "url_to_redirect_user_after_success", "exit": "url_to_redirect_user_after_exit_or_error" }, "top_tier_institutions": [ "nubank_retail", "picpay_retail", "mercadopago_retail", "itau_retail"], "branding": { "color_scheme": "LIGHT", "company_name": "ACME" }, // Veja nosso artigo dedicado a branding e customização "theme": [] // Veja nosso artigo dedicado a branding e customização } } ``` #### `branding` No objeto `branding`, é possível adicionar personalizações adicionais ao widget para atender às necessidades da sua marca ou aplicação. | Parâmetro | Obrigatório | Descrição | | --- | --- | --- | | `color_scheme` | sim | No parâmetro `color_scheme` você define se o widget deve estar no modo `LIGHT` (padrão) ou `DARK`. Se você quiser personalizar ainda mais as cores desses modos, consulte o parâmetro `theme`. | | `company_name` | sim | O nome da sua empresa. | #### `theme` Você pode opcionalmente adicionar as cores da sua marca ao widget usando o parâmetro `theme`. Para mais informações sobre onde essas cores aparecerão no widget, confira o guia de branding do Biometric Pix dedicado. Nossa API retornará com o seguinte payload: ```json { "refresh": "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MjMzNDY1MDY5MiwiaWF0IjoxNzEyNTcwNjkyLCJqdGkiOiIxMDAxMTg4NDU4Y2M0ZTlhOThmMDA4MmU3MDU3YzBmNyIsInVzZXJfaWQiOiI2ZTliZTg4NC00NzgxLTQxNDMtYjY3My1hY2EwMjQ3NWVlOGMiLCJvcmdhbml6YXRpb25fbmFtZSI6IkRvbWluaWsgQ2hvbGV3c2tpJ3MgdGVhbSIsIm9yZ2FuaXphdGlvbl9pZCI6IjZlOWJlODg0LTQ3ODEtNDE0My1iNjczLWFjYTAyNDc1ZWU4YyIsInNjb3BlcyI6WyJyZWFkX2luc3RpdHV0aW9ucyIsIndyaXRlX2xpbmtzIl0sImVudmlyb25tZW50Ijoic2FuZGJveCIsImFwaV91cmwiOiJzYW5kYm94LmJlbHZvLmNvbSIsImNyZWRlbnRpYWxzX3N0b3JhZ2UiOiIzMGQiLCJzdGFsZV9pbiI6IjM2NWQiLCJmZXRjaF9yZXNvdXJjZXMiOlsiQUNDT1VOVFMiLCJUUkFOU0FDVElPTlMiLCJPV05FUlMiXSwiaXNzIjoic2FuZGJveC5iZWx2by5jb20ifQ.X43VAc6c37U0JbiYgSd_r4SESjvGOuMgOpK5_DbuMHF7seATr7atO1QiUGwxdwBlEHo9ECST_9QKiHjv7G2czg", "access": "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzEyNTcxODkyLCJpYXQiOjE3MTI1NzA2OTIsImp0aSI6ImFiNjRmYjkyZmY1ZjQ0MTU4N2IwM2Y2MDJhMzhhMjNhIiwidXNlcl9pZCI6IjZlOWJlODg0LTQ3ODEtNDE0My1iNjczLWFjYTAyNDc1ZWU4YyIsIm9yZ2FuaXphdGlvbl9uYW1lIjoiRG9taW5payBDaG9sZXdza2kncyB0ZWFtIiwib3JnYW5pemF0aW9uX2lkIjoiNmU5YmU4ODQtNDc4MS00MTQzLWI2NzMtYWNhMDI0NzVlZThjIiwic2NvcGVzIjpbInJlYWRfaW5zdGl0dXRpb25zIiwid3JpdGVfbGlua3MiXSwiZW52aXJvbm1lbnQiOiJzYW5kYm94IiwiYXBpX3VybCI6InNhbmRib3guYmVsdm8uY29tIiwiY3JlZGVudGlhbHNfc3RvcmFnZSI6IjMwZCIsInN0YWxlX2luIjoiMzY1ZCIsImZldGNoX3Jlc291cmNlcyI6WyJBQ0NPVU5UUyIsIlRSQU5TQUNUSU9OUyIsIk9XTkVSUyJdLCJpc3MiOiJzYW5kYm94LmJlbHZvLmNvbSJ9.2Irt1KCEKo6V17Y-N3zWeX3AchEvCrUWa_AlWoZ2gIIBhHvghHGkXtupOOrXKVqW9kTCOBE77-1riyyblUo4fw" } ``` ## Anexar token à URL do widget Assim que você receber o token de acesso, basta anexar o valor do parâmetro `access` à seguinte URL: ```curl Biometric Pix URL https://pix-biometria.pay.belvo.com/?access_token={access_token} ## Exemplo https://pix-biometria.pay.belvo.com/?access_token=eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MjMzNDY1MDY5MiwiaWF0IjoxNzEyNTcwNjkyLCJqdGkiOiIxMDAxMTg4NDU4Y2M0ZTlhOThmMDA4MmU3MDU3YzBmNyIsInVzZXJfaWQiOiI2ZTliZTg4NC00NzgxLTQxNDMtYjY3My1hY2EwMjQ3NWVlOGMiLCJvcmdhbml6YXRpb25fbmFtZSI6IkRvbWluaWsgQ2hvbGV3c2tpJ3MgdGVhbSIsIm9yZ2FuaXphdGlvbl9pZCI6IjZlOWJlODg0LTQ3ODEtNDE0My1iNjczLWFjYTAyNDc1ZWU4YyIsInNjb3BlcyI6WyJyZWFkX2luc3RpdHV0aW9ucyIsIndyaXRlX2xpbmtzIl0sImVudmlyb25tZW50Ijoic2FuZGJveCIsImFwaV91cmwiOiJzYW5kYm94LmJlbHZvLmNvbSIsImNyZWRlbnRpYWxzX3N0b3JhZ2UiOiIzMGQiLCJzdGFsZV9pbiI6IjM2NWQiLCJmZXRjaF9yZXNvdXJjZXMiOlsiQUNDT1VOVFMiLCJUUkFOU0FDVElPTlMiLCJPV05FUlMiXSwiaXNzIjoic2FuZGJveC5iZWx2by5jb20ifQ.X43VAc6c37U0JbiYgSd_r4SESjvGOuMgOpK5_DbuMHF7seATr7atO1QiUGwxdwBlEHo9ECST_9QKiHjv7G2czg ``` ## Redirecionar usuário para a URL Em sua aplicação, redirecione seu usuário para a URL que você formou na etapa anterior. Isso carregará o widget e seu usuário será guiado através do processo de inscrição e pagamento. ## Fluxos de inscrição do widget Abaixo você pode ver o processo que seu usuário passará no widget para completar o processo de inscrição. ### Notificações de webhook Durante o fluxo de inscrição, você receberá as seguintes notificações de webhook: | Código do Webhook | Tipo (Recurso) | Descrição | Disparo | | --- | --- | --- | --- | | `OBJECT_CREATED` | CUSTOMERS | No caso de o CPF que você enviou para o seu usuário ainda não ter sido registrado para sua conta em nosso sistema, criaremos o cliente e notificaremos via webhook, fornecendo a você o `customer.id`. Recomendamos que você armazene este ID com o usuário associado em seu banco de dados. | O usuário selecionou sua instituição e foi redirecionado para ela. | | `OBJECT_CREATED` | ENROLLMENTS | Assim que iniciarmos o processo de inscrição e criá-lo em nosso sistema, notificamos você via webhook e fornecemos o `enrollment.id`. Recomendamos que você armazene este ID com o usuário associado em seu banco de dados. **Nota 1**: Para associar a inscrição com seu usuário, por favor, verifique o `details.metadata.{provided_key}` para o identificador único que você forneceu para a sessão do widget. **Nota 2**: Um usuário pode ter várias inscrições (para cada instituição e para cada dispositivo). Em outras palavras, há uma relação de 1:N entre o cliente e o número de inscrições associadas ao cliente. | O usuário selecionou sua instituição e foi redirecionado para ela. | | `STATUS_UPDATE` | ENROLLMENTS | Quando o usuário é redirecionado de sua instituição de volta para o widget, você receberá uma notificação `STATUS_UPDATE`, indicando se o processo de inscrição foi bem-sucedido ou não. Você pode receber um dos seguintes eventos de webhook: `SUCCEEDED` `FAILED` Para mais detalhes, veja nossa seção dedicada a Webhooks de Inscrições. | O usuário é redirecionado de volta para o widget. | ## Fluxo de Pagamento do Widget Abaixo você pode ver o processo que seu usuário passará no widget para completar o processo de inscrição. ### Notificações de webhook Durante o fluxo de pagamento, você receberá as seguintes notificações de webhook: | Código do Webhook | Tipo (Recurso) | Descrição | Disparo | | --- | --- | --- | --- | | `OBJECT_CREATED` | PAYMENT_INTENTS | Assim que iniciamos o processo de pagamento e o criamos em nosso sistema, notificamos você via webhook e fornecemos o `payment_intent.id`. **Nota**: Para associar a intenção de pagamento ao seu usuário (ou inscrição), verifique o `details.metadata.{provided_key}` para o identificador único que você forneceu para a sessão do widget. | O usuário selecionou qual inscrição usar e clicou em continuar. | | `OBJECT_CREATED` | CHARGES | Assim que iniciamos o processo de pagamento e o criamos em nosso sistema, notificamos você via webhook e fornecemos o `charge.id`. | O usuário selecionou qual inscrição usar e clicou em continuar. | | `STATUS_UPDATE` | PAYMENT_INTENTS | Durante o processo do widget e pagamento, você receberá os seguintes webhooks `STATUS_UPDATE` para a intenção de pagamento: `REQUIRES_ACTION` `PROCESSING` `SUCCEEDED` `FAILED` | Você receberá os eventos `REQUIRES_ACTION` e `PROCESSING` ao mesmo tempo que `OBJECT_CREATED`. Os dois últimos você recebe quando o pagamento é concluído com sucesso ou falha. | | `STATUS_UPDATE` | CHARGES | Durante o processo do widget e pagamento, você receberá os seguintes webhooks `STATUS_UPDATE` para a cobrança: `SUCCEEDED` `FAILED` | Quando o pagamento é concluído com sucesso ou falha. | | `OBJECT_CREATED` | TRANSACTIONS | Assim que a intenção de pagamento e a cobrança associada forem processadas com sucesso, a Belvo criará uma Transação. | A transação foi processada com sucesso pela instituição. | ## Realizando pagamentos subsequentes Para realizar pagamentos subsequentes para o usuário, você pode usar o mesmo payload `access_token` como em Etapa 1 - Gerar um access_token. Nosso widget detectará automaticamente se o usuário possui algum cadastro existente e, se sim, iniciará imediatamente o widget no Fluxo de Pagamento do Widget.