Realizar um Pix Cash-Out por QR Code Dinâmico

Essa funcionalidade, deve ser utilizada sempre que um usuário da sua aplicação deseja realizar o pagamento de um QR Code Pix dinâmico.

Desta forma o caso de uso pode ser:

Como Fintech quero disponibilizar para os meus usuários a possibilidade de realizar pagamentos de QR Codes dinâmicos, para qualquer instituição financeira, uma vez que ele scanear, ou digitar o copia e cola, onde será retirado o saldo de sua conta e usado para pagar o emissor do QR Code.

Por que usar um QR Code dinâmico?

  • Apresenta em seu escopo um rol extenso de campos passíveis de configuração por parte do recebedor.

  • Permite a realização de pagamento imediato ou com vencimento.

  • É usado uma única vez para uma transação específica.

  • Além do valor, permite a inserção de mais informações na modalidade com vencimento, como as regras de cálculo de juros, multa, descontos, entre outras.

  • É recomendado para recebedores que demandem funcionalidades facilitadoras do processo de conciliação, da integração de sistemas e da automatização de processos.

  • É gerada por meio da integração via API Pix. Segundo define o BCB, é possível gerar um único QR Code ou proporcionar uma geração em lote, necessária, por exemplo, para empresas prestadoras de serviço que desejam gerar faturas para toda sua base de clientes. Por isso, o QR Code Pix agiliza os processos das empresas, principalmente dos comércios.


Passos para Integrar

  1. Converter QR Code no formato EMV
  2. Realizar autenticação na API - [API Reference]
  3. Consultar Informações do QR Code a partir do código EMV- [API Reference]
  4. Validar o Tipo de QR Code
    1. Se, QR Code = Immediate (Collection = 1), Consultar URL - [API Reference]
    2. Se, QR Code = Duedate (Collection = 2), Consultar URL - [API Reference]
  5. Consultar Chave vinculada ao QR Code - [API Reference]
  6. Realizar o Pix Cash Out - [API Reference]
  7. Receber o Webhook com Status do Pix

Caso seja necessário você pode consultar o status do Pix manualmente.



Decodificando QR Code

Para iniciar o processo de pagamento de um QR Code é necessário realizar sua leitura, portanto, é preciso decodificar ele, onde é gerado um código EMV (padrão criado para leitura de QR Code Pix no Brasil, nos sistemas financeiros geralmente é nomeado de Pix Copia e Cola). Para isso, basta utilizar API Retorna as informações do QR Code a partir de um EMV.

Modelo de request:

curl --location --request POST 'https://sandbox.openfinance.celcoin.dev/pix/v1/emv' \
--header 'accept: application/json' \
--header 'Content-Type: application/json-patch+json' \
--header 'Authorization: Bearer {access_token}' \
--data-raw '{
  "emv":  "00020101021226930014br.gov.bcb.pix2571api-h.developer.celcoin.com.br/v1/p/v2/0223b7626a7247e58a35cfadb1c18ba85204000053039865802BR5907Celcoin6007Barueri61080120100562070503***6304CB07"
}'

Modelo de retorno:

{
    "type": "2",
    "collection": "1",
    "payloadFormatIndicator": "01",
    "merchantAccountInformation": {
        "url": "https://api-h.developer.btgpactual.com/v1/p/v2/0223b7626a7247e58a35cfadb1c18ba8",
        "gui": "br.gov.bcb.pix",
        "key": null,
        "additionalInformation": null,
        "withdrawalServiceProvider": null
    },
    "merchantCategoryCode": 0,
    "transactionCurrency": 986,
    "transactionAmount": 0.0,
    "countryCode": "BR",
    "merchantName": "Celcoin",
    "merchantCity": "Barueri",
    "postalCode": "01201005",
    "initiationMethod": "12",
    "transactionIdentification": "***"
}

A propriedade type representa o tipo do QR Code, portanto deve ser validado se o que você está consultando é estático (representado pelo valor 1) ou dinâmico (2), fora isso, a propriedade collection determina se ele é immediate (imediato, representando pelo 1) ou duedate (com data de vencimento definida, representando pelo 2), é importante saber qual é o tipo e a collection do qrcode, pois isso irá definir como seguir com as integrações para a execução do pagamento.

Estrutura dos dados retornados:

CampoDescrição
typeTipo do QR Code (1 = estático, 2 = dinâmico)
collectionInforma se o QRCode dinâmico é COB (1) ou COBV (2)
payloadFormatIndicatorIndicador de formato de carga útil
merchantAccountInformationInformações sobre a cobrança atrelada ao QR Code
merchantCategoryCodeNúmero de quatro dígitos, listado na ISO 18245
transactionCurrencyCódigo da moeda corrente
transactionAmountValor da transação
countryCodeCódigo do país
merchantNameNome do emissor da cobrança
merchantCityCidade do emissor da cobrança
postalCodeCEP
initiationMethodRepresenta o tipo de pagamento
transactionIdentificationIdentificação da transação

O fluxo abaixo explica como dar continuidade no pagamento de QR Codes dinâmicos.

🚧

Recomendamos que seja armazenado temporariamente, ou em sua aplicação a propriedade url do objeto merchantAccountInformation, pois o seu valor será utilizado em requisições futuras para executar o pagamento do QR Code.

Caso você não tenha um EMV de um QR Code dinâmico immediate, para realizar os testes, basta criar um QR Code Location com a API da Celcoin Criar um QR Code (Location) e em seguida criar uma cobrança immediate coma API Criar nova cobrança imediata. Abaixo segue um modelo de request para criar o QR Code:

curl --location --request POST 'https://sandbox.openfinance.celcoin.dev/pix/v1/location' \
--header 'accept: application/json' \
--header 'Content-Type: application/json-patch+json' \
--header 'Authorization: Bearer {access_token}' \
--data-raw '{
  "clientRequestId": "9b26edb7cf254db09f5449c94bf13abc",
  "type": "COB",
  "merchant": {
    "postalCode": "01201005",
    "city": "Barueri",
    "merchantCategoryCode": "0000",
    "name": "Celcoin Pagamentos"
  }
}'

Abaixo segue um modelo de request para criar a cobrança imediata:

curl --location --request POST 'https://sandbox.openfinance.celcoin.dev/pix/v1/collection/immediate' \
--header 'accept: application/json' \
--header 'Content-Type: application/json-patch+json' \
--header 'Authorization: Bearer {access_token}' \
--data-raw '{
    "clientRequestId": "14232341231",
    "payerQuestion": "Não pagável após vencimento.",
    "key": "[email protected]",
    "locationId": 12730559,
    "debtor": {
        "name": "Fulano de Tal",
        "cnpj": "33188542046"
    },
    "amount": {
        "original": 15.00,
        "changeType": 0
    },
    "calendar": {
        "expiration": 86400
    },
    "additionalInformation": [
        {
            "value": "Assinatura de serviço",
            "key": "Produto 1"
        }
    ]
}'

Para criar QR Code dinâmico com vencimento veja mais detalhes nesse artigo.

📘

É importante ser usado a chave [email protected] em ambiente sandbox para conseguir finalizar seus testes, caso contrário será apresentado erro na hora de realizar a consulta da chave DICT.


Tipos de QR Code dinâmico

Como explicado anteriormente, quando falamos de QR Codes dinâmicos sabemos que é possível ter dois tipos, o imediato (immediate) e com data de vencimento (duedate). Uma vez que sua aplicação sabe qual é seu tipo, é necessário consultar a url que foi retornada na chamada de consulta EMV, porém cada QR Code tem uma API distinta para realizar essa busca, sendo immediate a API Carrega, valida e analisa a carga de json de uma Cobrança imediata (COB) e duedate a API Carrega, valida e analisa a carga de json de uma Cobrança com Vencimento (COBV). Vamos usar um QR Code Immediate para exemplificar as requisições.

🚧

Atenção

Perceba que deve ser removido o "https://" da url para realizar a requisição do payload, caso contrário a API da Celcoin não irá reconhecer a requisição.

Modelo de request:

curl --location --request GET 'https://sandbox.openfinance.celcoin.dev/pix/v1/collection/immediate/payload/api-h.developer.btgpactual.com%2Fv1%2Fp%2Fv2%2F0223b7626a7247e58a35cfadb1c18ba8' \
--header 'accept: application/json' \
--header 'Authorization: Bearer {access_token}'

Perceba que a propriedade url retornada na chamada de consulta EMV, deve ser encodada usando o padrão URL-encoded format, apenas dessa forma nossa api irá conseguir ler a url e retornar as informações do QR Code.

Para testar e entender o formato, recomendamos que use o link, para testar o processo de conversão da url disponibilizada em nossa api de consulta do EMV.

Criamos a GIF abaixo que mostra como realizamos a conversão e simulação da chamada em nossa api.

Modelo de retorno:

{
    "status": "ATIVA",
    "infoAdicionais": null,
    "txid": "kk6g232xel65a0daee4dd13kk9162847",
    "chave": "[email protected]",
    "solicitacaoPagador": "Aniversário do Jr.",
    "valor": {
        "original": "25.25",
        "abatimento": null,
        "desconto": null,
        "multa": null,
        "juros": null,
        "final": null,
        "modalidadeAlteracao": 0,
        "retirada": null
    },
    "calendario": {
        "criacao": "2022-03-07T12:23:36Z",
        "expiracao": 86400,
        "apresentacao": "2022-03-07T12:33:22Z",
        "validadeAposVencimento": 0
    },
    "revisao": 0
}

Consultar chaves Pix Externa (DICT)

Para realizar o pagamento de um QR Code é necessário consultar os dados bancários cadastrados na chave Pix que retornou da consulta EMV. Sendo assim, se faz necessário realizar uma consulta no DICT na API Retorna as informações do DICT utilizando uma chave cadastrada no Pix, onde será retornado algumas informações que são obrigatórias ao realizar um pagamento.

cURL da chamada

curl --location --request GET 'https://sandbox.openfinance.celcoin.dev/celcoin-baas-pix-dict-webservice/v1/pix/dict/entry/external/[email protected]' \
--header 'accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{token}}'

Exemplo de retorno

👍

Sucesso 200

{
  "version": "1.0.0",
  "status": "SUCCESS",
  "body": {
    "keyType": "string",
    "key": "string",
    "account": {
      "participant": "30306294",
      "branch": "0001",
      "account": "10545584",
      "accountType": "TRAN",
      "createDate": "2020-11-03T06:30:00-03:00"
    },
    "owner": {
      "type": "NATURAL_PERSON",
      "documentNumber": "34335125070",
      "name": "Carlos Henrique da Silva"
    },
    "endtoEndId": "string",
    "statistics": {
      "lastUpdated": "2023-03-08T11:01:26.101Z",
      "counters": [
        {
          "type": "string",
          "by": "string",
          "d3": "string",
          "d30": "string",
          "m6": "string"
        }
      ]
    }
  }
}

Error 400

{
  "version": "1.0.0",
  "status": "ERROR",
  "error": {
    "errorCode": "CBE177",
    "message": "Operação não permitida. Conta esta bloqueada"
  }
}

Tabela de errorCode

CodeMessage
CBE091É necessário informar pelo menos um dos campos: id, clientCode, ou endtoendId.
CBE039Account invalido.
CBE175Cadastro de chave não permitido. Verifique o formato da chave informada
CBE041Account possui tamanho maximo de 20 caracteres
CBE174O Campo key não pode ultrapassar 77 caracteres
CBE176Operação não permitida. Conta esta encerrada
CBE177Operação não permitida. Conta esta bloqueada
CBE190Operação Não permitida. Chave não esta vinculada a essa conta.

Transferência Pix Cash-Out a partir de QR Code Dinâmico

JSON de exemplo

{
  "amount": 25.55,
  "clientCode": "1458854",
  "transactionIdentification": "dc8cf02b81b54bd59323453b207e704a",
  "endToEndId": "E3030629420200808185300887639654",
  "initiationType": "DYNAMIC_QRCODE",
  "paymentType": "IMMEDIATE",
  "urgency": "HIGH",
  "transactionType": "TRANSFER",
  "debitParty": {
    "account": "444444"
  },
  "creditParty": {
    "bank": "30306294",
    "key": "5244f4e-15ff-413d-808d-7837652ebdc2",
    "account": "10545584",
    "branch": "10545584",
    "taxId": "11122233344",
    "name": "Celcoin",
    "accountType": "CACC"
  },
  "remittanceInformation": "Texto de mensagem"
}

cURL da chamada

curl --location --request POST 'https://sandbox.openfinance.celcoin.dev/baas-wallet-transactions-webservice/v1/pix/payment' \
--header 'accept: application/json' \
--header 'Authorization: Bearer {{token}}' \
--header 'Content-Type: application/json' \
--data-raw '{
  "amount": 25.55,
  "clientCode": "1458854",
  "transactionIdentification": "dc8cf02b81b54bd59323453b207e704a",
  "endToEndId": "E3030629420200808185300887639654",
  "initiationType": "DYNAMIC_QRCODE",
  "paymentType": "IMMEDIATE",
  "urgency": "HIGH",
  "transactionType": "TRANSFER",
  "debitParty": {
    "account": "444444"
  },
  "creditParty": {
    "bank": "30306294",
    "key": "5244f4e-15ff-413d-808d-7837652ebdc2",
    "account": "10545584",
    "branch": "10545584",
    "taxId": "11122233344",
    "name": "Celcoin",
    "accountType": "CACC"
  },
  "remittanceInformation": "Texto de mensagem"
}'

Descrição dos campos

CampoDescriçãoTipo Campo
amount*Valor da transação.
clientCode*Identificador único da transação gerado pelo cliente.
transactionIdentificationIdentificador único retornado durante a leitura do BRCode.Se initiationType igual a MANUAL ou DICT, esse campo não deve ser informado,

Se initiationType igual a STATIC_QRCODE, esse campo se torna obrigatório e com tamanho maximo permitido de 25 caracteres.

Se initiationType igual a DYNAMIC_QRCODE, esse campo se torna obrigatório e com tamanho maximo permitido entre 26 a 35 caracteres.
endToEndIdIdentificador ponta-a-ponta associado ao pagamento.Se initiationType igual a MANUAL, esse campo não deve ser informado pois o mesmo sera gerado pela Celcoin.

Se initiationType diferente de MANUAL, esse campo deve ser recuperado pelo endpoint /pix/dict/{key}.
initiationTypeTipo de iniciação do pagamentoMANUAL: Pagamento via dados transacionais da conta. (creditParty.key, endToEndId, e transactionIdentification, não devem ser informados).

DICT: Pagamento via chave. (Campos obrigatórios : creditParty.key, e endToEndId.transactionIdentification não deve ser informado).

STATIC_QRCODE: Pagamento via BRCode estatico. (Campos obrigatórios : creditParty.key, endToEndId, e transactionIdentification).

DYNAMIC_QRCODE: Pagamento via BRCode dinamico. (Campos obrigatórios : creditParty.key, endToEndId, e transactionIdentification).
paymentTypeTipo de pagamentoIMMEDIATE: Usado para pagamentos imediatos.
FRAUD: Usado para pagamento por suspeita de fraude.
SCHEDULED: Usado apenas para pagamentos agendados.
urgencyDetermina a urgência do pagamentoHIGH - usado para pagamentos imediatos.
NORMAL - usado para pagamentos agendados.
transactionTypeTipo da transação PixTRANSFER: Usado para pagamentos imediatos.
debitPartyObjeto
account*Número da conta de origem (Quem irá pagar).
creditPartyObjeto
bank*Identificador do Banco de destino (ISPB - Identificador de Sistema de Pagamentos Brasileiro).
key*Chave Pix.
accountNúmero da Conta de destino (Quem irá receber).
branchNúmero da agência de destino.
taxIdNúmero do documento (CPF ou CNPJ) da conta de destino.
name*Nome da conta de destino
accountTypeTipo de Conta Pix.CACC - Normal ou contas digitais
TRAN - Conta de pagamentos
SLRY - Conta salario
SVGS - Conta poupança
remittanceInformationDetermina um texto a ser apresentado ao pagador para que ele possa inserir uma informação correlacionada, em formato livre, para ser enviada ao destinatário. Se presente durante a leitura do Dynamic BRCode deve ser preservado e informado aqui.

Campo com * são obrigatórios na chamada

Exemplo de retorno

🚧

Atenção!!

Caso ocorra algum erro da família 5xx ao tentar realizar um pagamento, ou transfêrencia Pix e, ao consultar nossa api o status da transação esteja PROCESSING, recomendamos que aguarde até receber o disparo do gatilho com o novo status da transação. Sendo assim, não recomendamos o cancelamento da transação, pois o mesmo pode acarretar problemas em sua integração.

👍

Sucesso 200

{
  "status": "PROCESSING",
  "version": "1.0.0",
  "body": {
    "id": "34fee7bc-4d40-4605-9af8-398ed7d0d6b5",
    "amount": 0,
    "clientCode": "1458854",
    "transactionIdentification": "dc8cf02b81b54bd59323453b207e704a",
    "endToEndId": "E3030629420200808185300887639654",
    "initiationType": "STATIC_QRCODE",
    "paymentType": "IMMEDIATE",
    "urgency": "HIGH",
    "transactionType": "TRANSFER",
    "debitParty": {
      "account": "444444",
      "branch": "1",
      "taxId": "11122233344",
      "name": "Celcoin",
      "accountType": "CACC"
    },
    "creditParty": {
      "bank": "30306294",
      "key": "5244f4e-15ff-413d-808d-7837652ebdc2",
      "account": "10545584",
      "branch": "1",
      "taxId": "11122233344",
      "name": "Celcoin",
      "accountType": "CACC"
    },
    "remittanceInformation": "Texto de mensagem"
  }
}

Error 400

{
  "version": "1.0.0",
  "status": "ERROR",
  "error": {
    "errorCode": "CBE039",
    "message": "Account invalido.."
  }
}

Tabela de errorCode

CodeMessage
CBE001ClientCode é obrigatório.
CBE093ClientCode possui tamanho maximo de 200 caracteres.
CBE094amount é obrigatório.
CBE095amount invalido.Favor verificar a formatação do campo e deve ser maior que 0.
CBE100Existe um lançamento idêntico pendente.Favor aguarde para realizar esta operação para evitar duplicidade.
CBE101Já existe um lançamento com o mesmo clientCode. Favor realizar uma nova operação.
CBE102Lançamento de debito não permitido.Valor ultrapassa o limite maximo permitido por operação.
CBE107debitParty é obrigatório.
CBE108debitparty.account é obrigatório.
CBE109debitparty.account invalido.
CBE110debitparty.account possui tamanho maximo de 20 caracteres.
CBE115creditParty é obrigatório.
CBE116creditparty.account é obrigatório.
CBE117creditparty.account invalido.
CBE118creditparty.account possui tamanho maximo de 20 caracteres.
CBE119creditParty.branch é obrigatório.
CBE120creditParty.branch invalido.
CBE121creditParty.taxId é obrigatório.
CBE122creditParty.taxId invalido.
CBE123Transação não permitida.Conta com saldo insuficiente.
CBE124Lançamento não permitido.debit.account esta encerrada.
CBE126creditParty.bank é obrigatório e deve existir na lista de participantes Pix.
CBE127creditParty.name é obrigatório e possui tamanho maximo de 120 caracteres.
CBE128creditParty.accountType não foi informado ou é invalido.
CBE129remittanceInformation possui tamanho máximo de 140 caracteres.
CBE130initiationType invalido.
CBE131paymentType invalido.
CBE132urgency invalido.
CBE133transactionType invalido.
CBE134Campo transactionIdentification é de uso exclusivo para pagamentos de QRCodes. InitiationType STATIC_QRCODE ou DYNAMIC_QRCODE.
CBE135Campo transactionIdentification é de preenchimento obrigatório para pagamentos de QRCodes. InitiationType DYNAMIC_QRCODE.
CBE136Quando initiationType igual a STATIC_QRCODE o campo transactionIdentification não pode ultrapassar 25 caracteres.
CBE137Quando initiationType igual a DYNAMIC_QRCODE o campo transactionIdentification não pode ultrapassar 35 caracteres.
CBE139Já existe uma transação com o mesmo endToEndId. Favor realizar uma nova operação.
CBE139Quando initiationType igual a DICT os campos endToEndId e credityParty.key se tornam obrigatórios.
CBE140Quando initiationType igual a STATIC_QRCODE o campo credityParty.key se torna obrigatório.
CBE141Quando initiationType igual a DYNAMIC_QRCODE o campo credityParty.key se torna obrigatório.
CBE142Quando initiationType igual a MANUAL o campo credityParty.key não deve ser informado.
CBE143Quando paymentType está preenchido com Valor SCHEDULED, o campo urgency deve ser preenchido com valor NORMAL.
CBE144Quando paymentType está preenchido com Valor IMMEDIATE ou FRAUD, o campo urgency deve ser preenchido com valor HIGH.
CBE145Tipo de iniciação de pagamento não permitido.Para mais informações, entre em contato com o nosso suporte.
CBE146endToEndId invalido.
CBE159Lançamento não permitido.Sua conta esta bloqueada.

Recebendo notificações automáticas (Webhook)

Oferecemos a opção de configurar webhooks para receber notificações automáticas sempre que um pagamento via Pix Cash-out for realizado. Esses webhooks são um meio eficiente de receber atualizações em tempo real sobre as transações realizadas.

Para mais informações sobre a configuração e utilização dos webhooks, consulte a documentação específica disponível.

Evento: pix-payment-out

Link Documentação: Modelos de Webhooks do BaaS


Em caso de dúvidas adicionais, nossa equipe de suporte estará disponível para ajudar.