Cadastro do Portador

A interface de programação referente ao Cadastro do Portador é primariamente composta por consultas que retornam o tipo CardHolder e destes consultam-se os campos como nome, documentos, endereços, contatos e demais informações.

Feito para:  Estabelecimentos ComerciaisEmissoresAdquirentesFacilitadoresOutros Desenvolvedores

Primeiros passos

  1. Leia Introdução ao GraphQL, com exemplos reais da nossa API.

  2. Crie um usuário no portal do desenvolvedor.

  3. Cadastre sua primeira aplicação.

  4. Utilize o dashboard para acessar suas configurações de acesso.

  5. Para explorar rapidamente as APIs aqui na página de documentação, use o console de GraphQL, na seção de referências. Nele, você pode ver as consultas de exemplo, executá-las e alterá-las.

Primeiros passos na plataforma de Desenvolvedores Elo

Jaydson GomesDesenvolvedor Evangelista

O portador é um usuário do sistema (User) o qual possuí cartões. Este usuário é denomidado CardHolder e gerencia cartões (Card) e carteiras (Wallet). Um portador (CardHolder) pode cadastrar, consultar, editar e deletar seus cartões, como também pode associar seus cartões ás suas carteiras. Este pode ser uma pessoa física, que possua cartões, ou pessoa jurídica que possua cartões corporativos.

query {
    user {
        id
        username
        origin
        cardHolders {
            companyName, 
            companyLegalName, 
            cards { 
                edges { 
                    node { 
                        transactions(filter: { 
                            startTimestamp: "2017-11-21T00:00:00Z", 
                            endTimestamp: "2017-12-30T00:00:00Z",
                            includeMerchantCategories: [{ min: 1,max: 3 }, { min: 4, max: 10 }], 
                            excludeMerchantCategories: [{ min: 10, max: 10 }], 
                            status: APPROVED
                        }) 
                        {
                            pageInfo { hasPreviousPage },
                            edges { 
                                cursor, 
                                node { 
                                    id, 
                                    bin { 
                                        number, 
                                        isInternational, 
                                        product { 
                                            id, 
                                            name
                                        }, 
                                        country
                                    }, 
                                    status, 
                                    capture { id, name }, 
                                    currency, 
                                    value, 
                                    installments
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

Campo Origin
Este campo pode ser utilizado para identificar a origem da criação do usuário em questão ele deve ser definido na chamada de criação do usuário mutation createUser.

Essa seção tem como objetivo detalhar alguns processos e trazer o passo-a-passo para integração com itens da API de Cadastro de Portador ELO.

A plataforma ELO de API foi construída pensando em expor as mais diversas informações para os mais diversos clientes de API possíveis, sejam eles bancos, estabelecimentos comerciais, pessoas físicas ou qualquer outro consumidor.

Dado esse cenário, houve a necessidade de se utilizar um protocolo que pudesse ser flexível e ao mesmo tempo seguro para autenticar e autorizar acessos ao recursos e dados contidos e expostos via API.

O OAuth 2.0 é um protocolo de autorização que habilita aplicações terceiras a obter acesso limitado a um serviço web / HTTP.

O OAuth, sendo uma especificação, descreve de forma detalhada uma maneira de tratar cenários simples e complexos de segurança de API. Ele estabelece definições como:

  • Resource Owner: a entidade que é capaz de controlar o acesso a um recurso protegido. É o "dono do recurso", mas nem sempre é uma pessoa. Quando ele é uma pessoa ele é o usuário final.

  • Resource Server: o servidor que possui os recursos protegidos e recebe as requisições para acessar esses recursos.

  • Authorization Server: é um servidor que gera tokens de acesso para permitir que o consumidor acesse os recursos que o resource owner permitiu com o nível de acesso que o resource owner especificou.

  • Client: é a aplicação que acessa os recursos no resource server em nome do usuário. O client pode ser qualquer tipo de aplicação que faça isso. É o consumidor da API.

Oauth

Com essas definições, o OAuth estabelece que quando uma aplicação precisa acessar um recurso protegido ela deve obter primeiro um token de acesso (Access Token). Este é um token contendo as informações que caracterizam o acesso que o dono do recurso permitiu aos dados protegidos.

Todas as requisições realizadas junto à API da ELO deverão utilizar o protocolo HTTPS, e deverão ter em seus cabeçalhos os dados necessários para o acesso ao serviço. São eles:

  • client_id: Identificador gerado quando o desenvolvedor cria uma aplicação no portal e que pode ser encontrado nas configurações da dashboard da aplicação.

  • Authorization ou access_token: Aqui é um ponto importante que deve ter bastante atenção do desenvolvedor. Enquanto o usuário não realizou o login na API é obrigatório o envio do Authorization. Após o login o desenvolvedor deve enviar apenas o access_token obtido.

Authorization

O Authorization pode ser obtido concatenando o texto "Basic " ao resultado da codificação em Base 64 dos campos client_id e client_secret concatenados com :.

Abaixo um exemplo de pseudo-código para gerar o Authorization:

var authorization = "Basic " + base64(client_id + ":" + client_secret);

e a seguir temos um exemplo de Authorization já definido no header da requisição:

Authorization : Basic ZjkyMTIxNzMtZTcwNS0zNzNiLWE2OTgtNjE5MjNlMzc4MzU5OjAyYWI1Mjg4LTkyZGItM2FiMy05OWZkLWZhYzRhZjg1N2Q4MQ==

Para que seja possível iniciar a jornada dentro da plataforma de APIs da Elo, é necessário que um usuário seja criado. Para esse processo o desenvolvedor deverá usar a função createUser disponibilizada pela API. Esta função pode ser utilizada de duas maneiras:

  • O usuário utilizará o nome de usuário e senha como meio de autenticação.

  • O usuário utilizará uma rede social suportada pela plataforma da ELO como meio de autenticação.

A seguir é demonstrado uma visão geral desse processo.

Fluxo de criação de um usuário

fluxoCreateUser

Um exemplo da utilização da função createUser usando o nome de usuário e senha como autenticação é demonstrado a seguir.

Exemplo do corpo da requisição:

mutation{
  createUser(input:{
    clientMutationId: "123",
    username: "username",
    bcryptPassword: "$2a$12$oumE.pnRbsdi.c4KYsyNWOJoVyfi2jMKDe102Er5uGCdzd49SvE1Y",
    name: "name",
    firstName: "firstName",
    lastName: "lastName",
        contacts: [{
            type: PHONE
            context: "CASA"
            value: "+5519912345678"
        }]
    displayName: "displayName",
    legalIds:{
      cpf: "1234567890",
      rg:{
        number: "234567890",
        issuerOrganization: "SSP",
        issuerState: "SP",
        issueDate: "2020-12-03"
      }
    }
    origin: "Promoção cadastre sua conta Elo",
    originUrl: "www.dev.elo.com.br/promocao",
    originChanneRaw: "utm_campaing=sales_event",
    originChannel: "Facebook",
    localEvent: "Campinas"
  })
  {
    clientMutationId,
    id,
    name,
    oauthToken {
      accessToken
      refreshToken
    }
  }
}

Exemplo da resposta da API:

{
   "data": {
        "createUser": {
            "id": "89bd51d6-8eaf-31a5-bd2c-1fve81d17db4",
            "name": "name"
        },
      "oauthToken": {
        "accessToken": "89bd51d6-8eaf-31a5-bd2c-1fve81d17db4",
        "refreshToken": "ccc0fba7-fa8d-3e85-a19e-2dc725bbb33d"
      }
   }
}

No exemplo acima, o campo oauthToken contém os tokens necessários para o fluxo oAuth de autenticação:

  • accessToken, token que deve ser sempre utilizado caso o usuário faça alguma requisição para algum recurso da API;

  • refreshToken, token necessário para a renovação do accessToken.

No campo id, temos também o mesmo accessToken informado.

Nesse cenário não é necessário que o usuário faça login após a criação pois o mesmo já foi feito implicitamente pela função createUser e o token de acesso pode ser utilizado até sua expiração.

Já um exemplo da utilização da função createUser usando uma rede social é demonstrado a seguir.

Exemplo do corpo da requisição:

mutation{
  createUser(input:{
    clientMutationId: "123",
    username: "username",
    socialNetwork:{
      provider: "FACEBOOK",
      username: "usernameFacebook@gmail.com"
    },
    oauth:{
      accessToken: "EAACEdEose0cBAPZAVQLY5qPqEfqPPPviCy5NYbYBX7zLndQWDiUZBOBMC5Ry...",
      refreshToken: "",
      scopes: "email",
      expiryTimestamp: "2018-03-01T00:00:00Z"
    },
    name: "name",
    firstName: "firstName",
    lastName: "lastName",
    displayName: "displayName",
    legalIds:{
      cpf: "1234567890",
      rg:{
        number: "234567890",
        issuerOrganization: "SSP",
        issuerState: "SP",
        issueDate: "2020-12-03"
      }
    }
    origin: "Promoção cadastre sua conta Elo",
    originUrl: "www.dev.elo.com.br/promocao",
    originChanneRaw: "utm_campaing=sales_event",
    originChannel: "Facebook",
    localEvent: "Campinas"
  })
  {
    clientMutationId,
    id,
    name,
    oauthToken {
      accessToken
      refreshToken
    }
  }
}

A resposta da criação do usuário usando uma rede social é a mesma do exemplo anterior.

Campo Origin
Este campo permite identificar a origem da criação do usuário, ex.: uma promoção semanal, campanha de marketing... É possível fornecer uma String que poderá ser consultada nos dados do usuário.

Tipos de Usuário

Após a criação, um determinado usuário pode assumir 3 tipos distintos na plataforma da Elo, sendo eles:

  • Card Holder: Um usuário portador de um ou mais cartões Elo;

  • Card Issuer: Um usuário que emite cartões Elo;

  • Merchant: Um estabelecimento comercial que realiza transações com cartões Elo;

  • Acquirer: Um usuário que captura transações realizadas com cartões Elo em estabelecimentos;

Cada tipo possui sua forma de ser associado, com informações pertinentes a cada um. Um usuário só pode ter um tipo associado ao mesmo tempo, logo, se um usuário está associado a um CardHolder e tenta se associar a um Merchant um erro será retornado. Neste caso, é necessário remover a associação do CardHolder do usuário e, somente depois, realizar a associação ao novo tipo.

Para associar um CardHolder ao usuário basta utilizar a função createCardHolderForUser, a mutation abaixo é um exemplo de sua utilização. Por questão de segurança o campo userId não se refere ao real id do usuário, e sim ao seu access_token.

Exemplo do corpo da requisição:

mutation{
    createCardHolderForUser(input:{
        clientMutationId: "123",
        userId: "33744898-9844-4864-a0ca-046d50fdaf15",
        companyName: "companyName",
        companyLegalName: "companyLegalName",
        companylegalIds: {
            cnpj: "1234567890"
        }
    })
    {
        clientMutationId,
        user{
            id,
            verified,
            name,
            displayName
        },
        cardHolder{
            id,
            name,
            companyName,
            companyLegalName
        }
    }
}

Neste exemplo estamos criando o CardHolder e associando o mesmo ao usuário identificado pelo access_token, que é refletido no campo userId. Os dados retornados após a criação e associação do CardHolder ao usuário, serão os que foram definidos na parte inferior da mutation.

Para associar um CardIssuer ao usuário basta utilizar a função addCardIssuerToUser, a seguir temos a chamada para esta mutation como exemplo de utilização. Por questão de segurança o campo userId não se refere ao real id do usuário, e sim ao access_token do mesmo.

Exemplo do corpo da requisição:

mutation{
    addCardIssuerToUser(input:{
        clientMutationId: "123",
        userId: "97c7fb10-174c-4e23-8feb-926d1d23a035",
        cardIssuerId: "1b253372-8215-4567-a54d-4fa78dadf0f6"
    })
    {
        clientMutationId,
        user{
            id,
            verified,
            name,
            displayName
        },
        cardIssuer{
            id,
            name,
            legalName
        }
    }
}

Neste exemplo estamos associando um CardIssuer ao usuário identificado pelo access_token, que é refletido no campo userId. Os dados retornados após a associação do CardIssuer ao usuário, serão os que foram definidos na parte inferior da mutation.

Para associar um Mechant ao usuário basta utilizar a função addMerchantToUser, a seguir temos um exemplo de sua utilização. Por questão de segurança o campo userId não se refere ao real id do usuário, e sim ao access_token do mesmo.

Exemplo do corpo da requisição:

mutation{
    addMerchantToUser(input:{
        clientMutationId: "123",
        userId: "14991673-f5b9-43b8-8cb3-8da353b9b70c",
        merchantId: "b86eb0ef-0c21-4ea5-b407-9f113a229190"
    })
    {
        clientMutationId,
        user{
            id,
            verified,
            name,
            displayName
        },
        merchant{
            id,
            name,
            legalName
        }
    }
}

Neste exemplo estamos associando um Merchant ao usuário identificado pelo access_token, que é refletido no campo userId. Os dados retornados após à associação do Merchant ao usuário, serão os que foram definidos na parte inferior da mutation.

Para obter o id do Merchant, basta utilizar a Query Merchants(..). Essa consulta retorna os dados de cadastro de todos os Merchants sendo possível também a utilização de filtros para consultar Merchants específicos como mostra o exemplo.

query {
    merchants (
    filter: {
        legalIds:[
            {cnpj: "13941300000117"},
            {cnpj: "07513760000222"}
        ]
    })
    {
        edges {
            cursor
            node {
                id
                name
                legalName
                addresses {
                    context
                    city
                }
                legalIds {
                    cnpj {
                        number
                    }
                }
                categories {
                    id
                    iso
                    name
                }
            }
        }
    }
}

Para associar um usuário ao tipo Acquirer, basta utilizar a mutation addAcquirerToUser. Por questão de segurança o campo access_token no header da requisição é usado para identificar o usuário que está efetuando a operação.

mutation{
  addAcquirerToUser(
    input:{
      clientMutationId: "1234"
      acquirerId: "5d430aad-41ff-435c-99ec-69a8b8f584e9"
    }
  )
  {
    clientMutationId
    user{
      id
      username
    }
    acquirer{
      id
      name
      code
    }
  }
}

Outras interações

Para consultar um usuário basta utilizar uma query de usuário, como no exemplo abaixo.

query {
   user(id: "70fa9e70-1b41-3f68-8df9-b207d76929f6") {
        id,
        username
        cardHolders{
            id
            name
            companyName
        }
    }
}

Para atualizar um usuário basta utilizar a função updateUser, a seguir temos um exemplo de sua utilização. Por questão de segurança o campo id não se refere ao real id do usuário, e sim ao access_token do mesmo.

mutation {  
    updateUser(input:{
        id: "0c9cd95a-365e-40d3-89c2-63c35340a0fa",
        firstName: "firstName changed"
    }) {
        user{
            id
            firstName
        }
    }
}

Neste exemplo estamos atualizando o firstName (primeiro nome) do usuário, porém outros atributos também podem ser atualizados.

Para deletar um usuário basta utilizar a função deleteUser, a seguir temos um exemplo de sua utilização. Por questão de segurança o campo userId não se refere ao real id do usuário, e sim ao access_token do mesmo.

mutation {  
    deleteUser(input:{
        userId: "e29e5d4b-c5f6-45c9-90e0-26b21fed43f9"
    }) {
        userId
        username
        displayName
    }
}

Neste exemplo estamos deletando o usuário com identificação informada no campo userId.

O campo bcryptPassword presente no cadastro de usuário refere-se aos dados sensíveis de acesso do usuário à API. Estes dados são o nome de usuário e senha criptografados usando o algoritmo conhecido como bcrypt. Isso é feito para não se armazenar as senhas no sistema. Os passos para utilização desse algoritmo com os parâmetros requisitados pela API da ELO são descritos abaixo:

1º Passo: Gerar um salt a partir do nome de usuário:

  • Aplicar o algoritmo SHA256 no nome do usuário e reservar os 16 primeiros caracteres.

  • Aplicar a codificação Base64 sobre o resultado do item anterior utilizando o alfabeto customizado do algoritmo bcrypt. O alfabeto utilizado pelo bcrypt utiliza "." ao invés de "+" e começa com "./". Segue abaixo:

    ./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789

  • Concatenar o resultado do item anterior com o texto "$2a$12". Exemplo de resultado:

    $2a$12$N9qo8uLOickgx2ZMRZoMye

2º Passo: Aplicar o algoritmo bcrypt utilizando a senha do usuário e o salt gerado no primeiro passo:

  • Aplicar o algoritmo SHA256 na senha do usuário.

  • Aplicar a codificação Base64 sobre o resultado do item anterior.

  • Aplicar o algoritmo bcrypt utilizando o resultado do item anterior e o salt gerado no primeiro passo.

NOTA: O custo utilizado pelo algoritmo do bcrypt deve ser igual a 12.

O usuário pode complementar seu cadastro com suas informações de contato. Atualmente, é possível adicionar um contato para cada um dos tipos a seguir: EMAIL, PHONE e IM. Caso o usuário precise adicionar mais contatos, ele pode cadastrá-los utilizando o contato do tipo OTHER que não possui restrição de quantidade.

Os contatos informados para o usuário durante o cadastro, permanecem com status UNVERIFIED até que seja realizada a confirmação destes através de um verificationCode gerado pelo sistema. Existem duas formas do usuário gerar o código de verificação:

  • Na criação do usuário, informando o campo opcional verifyContact;

  • Após a criação do usuário, utilizando a mutation requestContactVerification.

Em ambos os casos, é possível verificar apenas os contatos do tipo EMAIL e PHONE.

Confirmação de contato na criação do usuário

Para verificar o contato neste momento, é necessário informar o campo verifyContact, um Enum que possui como valores:

  • PHONE, para a verificação ser realizada com o telefone do usuário

  • EMAIL, para a verificação ser feita pelo e-mail do usuário

Abaixo, temos um exemplo de como seria essa chamada:

mutation{
  createUser(input:{  
    verifyContact: PHONE, # Enum opcional, aceita os valores PHONE e EMAIL
    clientMutationId: "123",
    username: "username",
    bcryptPassword: "$2a$12$oumE.pnRbsdi.c4KYsyNWOJoVyfi2jMKDe102Er5uGCdzd49SvE1Y",
    name: "name",
    firstName: "firstName",
    lastName: "lastName",
        contacts: [{
            type: PHONE
            context: "CASA"
            value: "+5519912345678"
        }]
    displayName: "displayName",
    legalIds:{
      cpf: "1234567890",
      rg:{
        number: "234567890",
        issuerOrganization: "SSP",
        issuerState: "SP",
        issueDate: "2020-12-03"
      }
    }
    origin: "Promoção cadastre sua conta Elo"
  })
  {
    clientMutationId,
    id,
    name
  }
}

Confirmação de contato através da mutation requestContactVerification

Segue abaixo os passos para solicitação do verificationCode e confirmação do contato:

1º Passo: Realizar uma requisição de verificação de contato:

mutation{ 
  requestContactVerification(input:{ 
    clientMutationId: "123", 
    userId: "", 
    type: EMAIL, 
    value: "email@provedor.com" 
  }) { 
    clientMutationId 
    user{ 
      id 
      verified 
      username 
      name 
      contacts{ 
        type 
        value 
        verified 
      } 
    } 
    contact{ 
      type 
      value 
      verified 
    } 
  } 
} 

Exemplo da resposta da API:

{ 
  "data": { 
    "requestContactVerification": { 
      "clientMutationId": "123", 
      "user": { 
        "id": "fb9444fb-b9df-3cdd-a83e-808e0ce4b938", 
        "verified": "UNVERIFIED", 
        "username": "user1", 
        "name": "Nome Usuário", 
        "contacts": [ 
          { 
            "type": "EMAIL", 
            "value": "email@provedor.com", 
            "verified": "PENDING" 
          } 
        ] 
      }, 
      "contact": { 
        "type": "EMAIL", 
        "value": "email@provedor.com", 
        "verified": "PENDING" 
      } 
    } 
  } 
} 

Após esta etapa, o status de verificação do contato passa para PENDING e o usuário receberá no contato em verificação um verificationCode que deverá ser utilizado no próximo passo.

2º Passo: Efetivar a confirmação de contato:

mutation{ 
  contactVerification(input:{ 
    clientMutationId: "456", 
    userId: "", 
    type: EMAIL, 
    value: "email@provedor.com", 
    verificationCode: "5QI057" 
  }) 
  { 
    clientMutationId 
    user{ 
      id 
      verified 
      username 
      name 
      contacts{ 
        type 
        value 
        verified 
      } 
    } 
    contact{ 
      type 
      value 
      verified 
    } 
  } 
} 

Exemplo da resposta da API:

{ 
  "data": { 
    "contactVerification": { 
      "clientMutationId": "456", 
      "user": { 
        "id": "fb9444fb-b9df-3cdd-a83e-808e0ce4b938", 
        "verified": "VERIFIED", 
        "username": "user1", 
        "name": "Nome Usuário", 
        "contacts": { 
          { 
            "type": "EMAIL", 
            "value": "email@provedor.com", 
            "verified": "VERIFIED" 
          } 
        ] 
      }, 
      "contact": { 
        "type": "EMAIL", 
        "value": "email@provedor.com", 
        "verified": "VERIFIED" 
      } 
    } 
  } 
} 

Ao receber a resposta de sucesso, o contato tem seu status de verificação alterado para VERIFIED. Desta forma, pode-se garantir que o contato do usuário é um contato válido.

Para ter acesso às APIs da Elo, o usuário deve possuir um access_token válido e para isso ele deve ou efetuar login na plataforma, ou renovar o seu access_token.

Realizando o login

O processo de login pode ser realizado de duas formas:

  • Utilizando um nome de usuário e senha via createLoginSalt

  • Com uma rede social via socialNetworkOAuthLogin

Veja na figura abaixo os dois exemplos para a realização de login:

login

Caso o usuário queira utilizar o nome de usuário e senha ele primeiro deve fazer uso da chamada createLoginSalt. Essa função retorna um salt que deve ser utilizado para gerar o challenge que será enviado no processo de login (Mais detalhes sobre como obter o challenge seram descritos posteriormente). Um exemplo dessa chamada pode ser vista abaixo.

Exemplo do corpo da requisição:

mutation {
    createLoginSalt(input:{
        username: "UserNameToLogin"
    }) 
    {
        username, 
        salt
    }
}

Exemplo da resposta da API:

{
  "data": {
    "createLoginSalt": {
      "username": "UserNameToLogin",
      "salt": "$2a$05$J/dgZmXIN23mEZtvkxDYeO"
    }
  }
}

Na sequência é necessário fazer uso da chamada login. Esta requisição é necessária para dar acesso ao usuário às demais chamadas da API. Desta forma, no retorno dessa chamada é disponibilizado o access_token que identifica o usuário de forma única.

Exemplo do corpo da requisição:

mutation {
    login(input:{
        clientMutationId: "0123456789",
        username: "UserNameToLogin",
        challenge:"$2a$05$J/dgZmXIN23mEZtvkxDYeOtRsNEY4xMU9HHkcBVMpiUlFSFBuhtxy"
    }) 
    {
        clientMutationId,
        accessToken,
    oauthToken{
      accessToken,
      refreshToken
    }
    }
}

Exemplo da resposta da API:

{
   "data": {
       "login": {
           "clientMutationId": "0123456789",
           "accessToken": "b64a0e34-24c5-39eb-b457-0c7331d176f0", 
           "oauthToken": {
               "accessToken": "b64a0e34-24c5-39eb-b457-0c7331d176f0",
               "refreshToken": "4a474832-1b48-4ae3-9ad9-1d767a48ebe6"
           }
       }
   }
}

Caso o usuário queira utilizar uma rede social para se autenticar na API da Elo ele deverá fazer uso da chamada socialNetworkOAuthLogin. Assim como no fluxo descrito anteriormente, no retorno da função também é disponibilizado o access_token que identifica o usuário de forma única.

Exemplo do corpo da requisição:

mutation {
    socialNetworkOAuthLogin(input:{ 
        clientMutationId: "0123456789", 
        provider: "FACEBOOK", 
        username: "user.name@gmail.com",  
        accessToken:"AAECEdEose0cBANynsVcZChZBxB3ysAuxDeZC3ZB4eIzkUKJnvoaTO1Vf4gyj8sl9bFFNPlnGU0Qsnh2fys7gcymWE7lKL64ygGLCJAtgyJtNq4YSGBkdDZBcgnAGZBKaGiI6emZCap8WJYO8ex06ZAZB75IdWnDtPoGCF8yPQnW4JZALHgeL1A1o6ZC5nz5uLD2lnVoUpkxAr1CNQABCD"
    }) 
    {
        clientMutationId,
        accessToken
    }
}

Exemplo da resposta da API:

{
    "data": {
        "login": {
            "clientMutationId": "0123456789",
            "accessToken": "120faef6-5f31-3e74-afb2-864151c52880"
        }
    }
}

Renovando o accessToken

Já para atualizar o access_token, é preciso utilizar a mutation refreshAccessToken, descrita ao final desta sessão.

O campo challenge presente no login de usuário refere-se ao resultado do desafio (challenge) de login. É um hash utilizando o algoritmo bcrypt com salt (fornecido por createLoginSalt) e o conteúdo sendo o bcryptPassword (especificado em User).

Os passos são os mesmos da geração do bcryptPassword (na criação de usuário), porém com dois passos a mais.

Após gerar o bcryptPassword:

  • Gerar um salt a partir da função createLoginSalt.

  • Aplicar o algoritmo bcrypt utilizando o bcryptPassword e o salt gerado no item anterior.

NOTA: O resultado final deve estar no formato padrão, com prefixo, custo, salt e por fim o valor computado em Base64, totalizando 60 caracteres.

Exemplo de challenge: $2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy.

Através da mutation refreshAccessToken, é possível realizar o fluxo de Atualização do accessToken. Esse fluxo consiste no envio para a API do refreshToken que, após validar junto com o Authorization enviado no header da requisição, retornará um novo accessToken, e um novo refreshToken, como exemplificado a seguir:

mutation {
  refreshAccessToken(input: {
    clientMutationId: "860e72f2-d58f-4bee-ad3a-532085f6f3eb",
    refreshToken: "ccc0fba7-fa8d-3e85-a19e-2dc725bbb33d"
  }) {
    clientMutationId,
    oauthToken{
      accessToken,
      refreshToken
    }
  }
}

Exemplo da resposta da API:

{
  "data": {
    "refreshAccessToken": {
      "clientMutationId": "860e72f2-d58f-4bee-ad3a-532085f6f3eb",
      "oauthToken": {
        "accessToken": "ffd2b5cf-be8b-3a8a-802d-41983dea5872",
        "refreshToken": "88803449-7c41-3c3f-adb2-3b32ef1a85ff"
      }
    }
  }
}

Atenção! Após a chamada desta mutation, o accessToken e o refreshToken enviados na requisição serão revogados - passando a valer apenas os tokens do retorno da mutation.

Caso um usuário não lembre sua senha e precise fazer o reset, existe um fluxo de Reset de Senha que pode ser feito. O primeiro passo é solicitar o envio de um pedido de reset de senha. Isso é feito através da mutation requestPasswordReset.

Após a execução da mutation de solicitação, será enviado um e-mail ou um SMS para o contato especificado, com um token que será usado para realizar o reset da senha, através da mutation passwordReset.

Todos os casos de reset de senha são válidos apenas para contatos do tipo e-mail e phone.

Solicitando o envio de um pedido de reset de senha

Através da mutation requestPasswordReset é possível solicitar o reset de duas formas:

  • Enviando o campo email ou phone (mas nunca ambos), sendo os mesmos contatos enviados no momento do cadastro, e que receberão o token para o reset da senha

  • Enviando o enum type, que quando indicado EMAIL ou PHONE, enviará o token ao respectivo contato salvo no momento do cadastro do usuário

Abaixo, temos a primeira forma:

mutation {
    requestPasswordReset(input: {
        clientMutationId: "123456",
        legalId: {
            cpf: "12345678900"
        },
        email: "seu.email@provedor.com"
    }) {
        clientMutationId
        maskedEmail
    }
}

E a seguir, temos a solicitação de reset de senha através do enum type:

mutation {
    requestPasswordReset(input: {
        clientMutationId: "123456",
        legalId: {
            cpf: "12345678900"
        },
    type: EMAIL
    }) {
        clientMutationId
        maskedEmail
    }
}

Realizando o reset de senha

Após a chamada anterior e após o envio do token através do e-mail/SMS para o contato especificado, é preciso utilizá-lo através da mutation passwordReset, para fazer o reset da senha.

Da mesma forma, como na mutation anterior, é possível realizar de duas formas o reset de senha: ou enviando os campos de e-mail/telefone, ou informando o type - e, assim, refenciar o contato salvo na criação do usuário.

Abaixo, temos um exemplo com o envio do campo e-mail:

mutation {
    passwordReset(input: {
        clientMutationId: "1234567",
        legalId: {
            cpf: "12345678900"
        },
        email: "seu.email@provedor.com",
        bcryptPassword: "$2a$12$yOCCL/0cbkvc5Lj/.EfnKeHm3oBPq28rGYbs8ayG8tbRYw4qtXflW",
        token: "C68M59"
    }) {
        clientMutationId
        user {
            id
            verified
            username
            name
            firstName
        }
    }
}

Obs.: Lembrando que caso o token tenha sido solicitado usando phone (SMS), é preciso enviar o phone na requisição passwordReset; caso requestPasswordReset tenha sido solicitado usando email, se envia o campo email na passwordReset.

O bcryptPassword enviado nessa mutation precisa ser gerado com o mesmo username do usuário cadastrado e com a nova senha. Para saber como gerar esse campo, ver a seção BcryptPassword.

Para criar um cartão é necessário utilizar a função createCard. Esta requisição é responsável por criar um novo cartão associado ao usuário que o criou. Para poder fazer uso dessa função o usuário deve ser um portador (CardHolder). Abaixo é demonstrado uma visão geral do processo de criação de um cartão.

createCard fluxo1

Um exemplo da utilização do createCard pode ser visto abaixo.

mutation {
    createCard(input: {
        clientMutationId: "123",             
        sensitive:"eyJhbGciOiJFQ0RILUVTIiwiZW5jIjoiQTEyOENCQy1IUzI1NiIsImVway...",
        holderId: "9e5d64e4-409f-4900-b3b6-28319950fe5b",
        billingAddress: {
            context: "Casa",
            number: 123,
            country: "BRA",
            city: "Campinas",
            state: "São Paulo",
            zip: "1234",
            place: "via"
        }
    })
    {
        clientMutationId,
        card {
            id,
            last4,
            billingAddress{
            context,
            country,
            city
            }
        }
    }
}

Apoś a criação do cartão serão retornados os dados solicitados pelo usuário na parte inferior da mutation.

O campo sensitive é o conteúdo sensível (Número do cartão, Nome do portador, Vencimento, etc) gerado a partir de um processo de assinatura e criptografia, cujo payload foi assinado a partir do uso de uma a chave privada do usuário e na sequência criptografado fazendo uso de uma chave pública do servidor. Mais detalhes desse campo na seção Sensitive.

O campo holderId é o id do CardHolder que foi associado ao usuário. Logo não é o id (access_token) do usuário, e sim do CardHolder associado a ele.

Outras interações

Para consultar cartões utilizando filtros utiliza-se a query cards, abaixo segue um exemplo de utilização.

query {  
    cards(filter:{
        status:ACTIVE
    }) {
        edges{
            node{
                id
                last4
                expiry{
                    month
                    year
                }
            }
        }
    }
}

Neste exemplo estamos buscandos todos os cartões ativos. Outros filtros podem ser aplicados para esta consulta, como também pode ser solicitado outros retornos.

Para consultar cartão por identificador global único é utilizado a consulta node. Abaixo segue um exemplo de utilização.

query {  
    node(id: "b63dcf70-08ae-423f-9459-db580b3d6e95") {
        ... on Card {
            id
            last4
            status {
                status
            }
            bin {
                number
            }
        }
    }
}

Neste exemplo estamos solicitando uma consulta de nó (node) onde o identificador global único refere-se a um cartão. Outras informações de retorno podem ser solicitadas nesta requisição.

Também é possível listar os cartões pela consulta de usuário, como no exemplo abaixo.

query {  
    user {
        cardHolders{
            cards{
                edges{
                    node{
                        id
                        last4
                        expiry{
                            month
                            year
                        }
                    }
                }
            }
        }
    }
}

Nesta requisição estamos listando os cartões de um portador utilizando a query de usuário. Outras informações podem ser solicitadas no retorno desta consulta.

Para atualizar um cartão é utilizado a função updateCard. Abaixo segue um exemplo de utilização.

mutation {
    updateCard(input:{
        holderId: "d6f9605c-8da9-484a-bdb4-3e483db232ee",
        billingAddress:{
            country: "coutnry changed",
            city: "city changed",
            state: "SP changed",
            number: 32,
            place: "place changed"
        }
        status:SUSPENDED,
        sensitive: "eyJhbGciOiJFQ0RILUVTIiwiZW5jIjoiQTEyOENCQy1IUzI1NiIsImVway..."
    }) {
        card {
            id
            last4
            expiry{
                month
                year
            }
        }
    }
}

Neste exemplo estamos atualizando algumas informações do cartão - identificado pelo campo holderId. Além de alterarmos o endereço de cobrança do cartão (campo billingAddress) e seu status, será atualizado a data de validade e o nome impresso no cartão.

Atenção: Para ser válida a atualização, é preciso que o PAN do cartão seja igual ao do cartão criado previamente.

Para deletar um cartão é utilizado a função deleteCard. Abaixo segue um exemplo de utilização.

mutation {
    deleteCard(input:{
        cardId: "c049ac20-084b-46f1-ac03-817e855b5811"
    }) {
        cardId
        last4
        bin {
            number
        }
    }
}

Neste exemplo estamos deletando o cartão identificado pelo campo cardId, e solictando algumas informações do mesmo.

O campo sensitive presente no cadastro de cartão refere-se aos dados sensíveis de um cartão (número do cartão, código de verificação, validade e etc). Estes dados estarão assinados e criptografados para garantir sua segurança.

O primeiro passo na geração deste campo é ter os dados no formato JSON como descrito abaixo:

  • pan: O número da conta primária (Primary Account Number), também conhecido como "número do cartão" físico. Exemplo: "1234567890123456".

  • expiry: Data de validade do cartão, ou seja, quando ele expira. É um objeto composto pelas chaves month e year descritas a seguir. Exemplo: {"month": 2, "year": 2020}.

    month: Mês da validade do cartão. Número inteiro entre 1 (Janeiro) e 12 (Dezembro).
    year: Ano da validade do cartão. Número inteiro com 4 dígitos (2017, não 17).

  • name: Nome do portador do cartão. Exemplo: "João da Silva".

  • csc: Código de segurança do cartão (Card Security Code), usualmente impresso na parte de trás do cartão físico.

  • cscEntryTime: Data e horário quando o CSC (Código de Segurança do Cartão) foi digitado. É necessário quando o CSC é gerado por um chaveiro/token baseado em tempo. Deve estar no formato ISO 8601. Exemplo: "2017-06-01T12:00:00-03:00".

  • authCode: Código de autorização. Este código não é o CSC (Código de Segurança do Cartão) pois não está impresso no cartão. Exemplo: "AB123Z1Y".

  • authCodeEntryTime: Data e horário quando o código de autorização (authCode) foi digitado. Deve estar no formato ISO 8601. Exemplo: "2017-06-01T12:00:00-03:00".

NOTA: a autorização é feita com os campos csc ou authCode e seus respectivos horários de entrada. Apenas um deles deve ser especificado.

O segundo passo é assinar os dados utilizando JSON Web Signature (JWS) em formato compacto, e utilizando Elliptic Curve (EC) como algoritmo de assinatura.

O terceiro passo é criptografar os dados do passo anterior utilizando a chave pública do servidor, que pode ser obtida a partir da query:

query {
    serverPublicKey {
        key
    }
}

Tal criptografia será realizada utilizando JSON Web Encryption (JWE) em formato compacto, e EC como algoritmo de criptografia.

A estrutura de assinatura e criptografia segue a seguinte ideia:

JWE.Encrypt(recipient=ServerKey, format=compact,
     JWS.Sign(issuer=UserKey, format=compact,
         JSON.Stringify(CardSensitiveInput)
     )
)

O quarto passo é cadastrar a chave pública do cliente a qual foi utilizada para assinar os dados sensíveis. Desta forma o servidor poderá validar a assinatura do cliente no processo de descriptografia do campo sensitive. Abaixo segue um exemplo da mutation de cadastro de chave pública.

mutation {
    addPublicKeyToUser(input:{
        clientMutationId:"012", 
        userId:"bdc89491-f1f4-32f7-bad2-f44ae3b88aa6", 
        key:"{\"kty\":\"EC\", \"kid\":\"my-public-key-id-1\", \"x\":\"g_Sr4WwVDt5Qy3KonZyXqFwWykTR9KVMCt8Sx-dXSB8\",\"y\":\"ydSE-mUMtuhBTI_txDpd2ivb7e6FNzxq4e_18iHFZ2U\",\"crv\":\"P-256\"}",
        format:JWK
}) {
        clientMutationId, 
        user{
            id,
            firstName
            ,lastName
        }, 
        publicKey{
            key
        }
    }
}

NOTA: o quarto passo só é necessário caso a chave pública que assinou os dados sensíveis não tenha sido cadastrada anteriormente.

A carteira é uma forma do usuário organizar seus cartões. Para criar uma carteira utilizando a API da ELO basta que o usuário seja um portador (CardHolder) e faça uso da função CreateWallet. Um exemplo de utilização dessa função pode ser vista abaixo:

mutation { 
    createWallet(
        input: { 
            clientMutationId: "123", 
            cardHolderId: "fdf9f98e-a6ac-4878-ad45-cc133e4ca168", 
            name: "Carteira"
        }
    ) {
        clientMutationId, 
        wallet{ 
            id, 
            name, 
            holder{
                name, 
                firstName, 
                displayName
            }
        }
    }
}

Após a criação da carteira serão retornados seus dados e a partir deles é possível fazer seu gerenciamento adicionando ou removendo cartões. Abaixo temos um exemplo de cada operação possível com a carteira criada.

Adicionar um cartão à carteira:

mutation {
    addCardToWallet(
        input:{
            clientMutationId:"123", 
            walletId: "770d83de-f022-4c4e-b12d-e62f3d2d1d51", 
            cardId: "2fde85bf-6935-4e9b-8262-94d82e08e4bd"
        }
    ) { 
        clientMutationId, 
        wallet{ 
            id,
            name 
        }, 
        card{
            id
        }
    }
}

Remover cartão de uma carteira:

mutation{
    removeCardFromWallet(
        input:{
            clientMutationId: "012", 
            walletId: "770d83de-f022-4c4e-b12d-e62f3d2d1d51", 
            cardId: "2fde85bf-6935-4e9b-8262-94d82e08e4bd"}
    ) {
        clientMutationId, 
        wallet{
            name
        }, 
        card{
            id
        }
    }
}

Atualizar a carteira:

mutation{
  updateWallet(
      input: {
          clientMutationId: "123",
          walletId: "770d83de-f022-4c4e-b12d-e62f3d2d1d51",
          name: "Carteira Principal"
        }
    ) {
        wallet {
            id,
            name
        }
    }
}

NOTA: Só é possível atualizar o nome da carteira.

Remover a carteira:

mutation{
    deleteWallet(
        input:{
            clientMutationId: "012", 
            walletId: "770d83de-f022-4c4e-b12d-e62f3d2d1d51"
        }
    ) { 
        clientMutationId, 
        walletId, 
        name
    }
}

Termos de Uso podem ser adicionados ao usuário, isso siginifica que o mesmo aceitou tal termo. Para listar os termos de uso basta utilizar a query agreementTerms.

query{
  agreementTerms(filter:{
    nameContains: "",
    agreementTermIds: [
      "",
      ""
    ]
  })
  {
    pageInfo{
      hasPreviousPage
      hasNextPage
    }
    totalCount
    edges{
      cursor
      node{
        id
        title
        description
        url
      }
    }
  }
}

Obs: Filtros podem ser aplicados na consulta de termos de uso, mais detalhes podem ser encontrados no argumento filter AgreementTermFilterInput

Adicionar Termo de Uso ao usuário:

Para adicionar um termo de uso ao usuário utiliza-se a mutation addAgreementToUser.

mutation {
  addAgreementToUser(input: {
    clientMutationId: "012", 
    userId: "b1ca0944-7822-3538-920d-58b233154608", 
    agreementTermId: "e32a7918-eef5-41af-909b-f4c93cee2e22"
  }) {
    clientMutationId
    user {
      id
      username
      firstName
      lastName
      displayName
    }
    agreement {
      agreementTerm {
        id
        title
        description
        url
      }
    }
  }
}

Remover Termo de uso do usuário:

Para remover um termo de uso do usuário utiliza-se a mutation removeAgreementFromUser

mutation {
  removeAgreementFromUser(input: {
    clientMutationId: "013", 
    userId: "b1ca0944-7822-3538-920d-58b233154608", 
    agreementTermId: "e32a7918-eef5-41af-909b-f4c93cee2e22"
  }) {
    user {
      id
      firstName
      lastName
    }
    agreementTerm {
      id
      description
      url
    }
  }
}

Consulta

Consultar dados de portador utilizando a consulta de usuário

query {
   user(id: "70fa9e70-1b41-3f68-8df9-b207d76929f6") {
        id,
        username
        cardHolders{
            id
            name
            companyName
        }
    }
}

NOTA: o parâmetro id se refere ao access_token do usuário.

Dados de um portador via ID

Consultar o nome, CPF, RG e data de nascimento de um portador dado o identificador global único:

query {
   node(id: "B8B1582B-1C2C-406B-9FC3-ACA842049207") {
      ... on CardHolder {
         firstName
         lastName
         legalIds {
            cpf {
               number
            }
            rg {
               number
               issuerOrganization
               issuerState
               issueDate
            }
         }
         birthday
      }
   }
}

NOTA: o parâmetro id se refere ao identificador global único do portador (CardHolder).

  • Access_token:: Código de acesso disponibilizado pela API após a realização do login e que deve ser utilizado pelo desenvolvedor ao realizar as chamadas aos recursos disponibilizados. Ele é utilizado para validação do acesso e identificação do usuário que está realizando as operações na API.

  • Bcrypt: Algoritmo de criptografia do tipo hash utilizado para segurança de senhas (Wikipedia). No contexto desta API é o resultado do algoritmo bcrypt sobre o nome de usuário e senha.

  • BIN: Número de Identificação do Banco (Bank Identification Number). O BIN é relativo aos números iniciais de um cartão e identifica o emissor e produtos associados ao mesmo.

  • CardIssuer: Um usuário do tipo pessoa jurídica que emite cartões. Também conhecido como Emissor.

  • CardHolder: Um usuário do tipo pessoa física ou jurídica que possui cartões. Também conhecido como Portador.

  • Challenge: Resultado do algoritmo bcrypt aplicado sobre um salt gerado e o bcrypt do nome do usuário e senha.

  • Client_id: Identificador utilizado pela API para verificar e validar qual a aplicação está fazendo uso dos recursos disponibilizados. Sua geração é feita no momento que o desenvolvedor cria uma nova aplicação no portal de desenvolvedores.

  • Merchant: Um usuário do tipo pessoa jurídica que é um estabelecimento comercial e realiza transações com cartões.

  • PAN: Número da conta primária (Primary Account Number), também conhecido como "número do cartão".

  • Salt: Dado gerado de forma aleatório que é usado no algoritmo de criptografia junto da senha como uma forma de proteção evitando que o hash de dois dados iguais gerem o mesmo resultado.

  • Sensitive: Conteúdo sensível (Número do cartão, Nome do portador, Vencimento, etc) gerado a partir de um processo de assinatura e criptografia, cujo payload foi assinado a partir do uso de uma a chave privada do usuário e na sequência criptografado fazendo uso de uma chave pública do servidor.

  • Wallet: Carteira virtual utilizada para organizar cartões criados pelo portador dentro da API da ELO.