NEQUI
  • Colombia

  • Panamá

  • Cómo usar el SDK
  • Creación de un cliente
  • Servicio para reversar una transacción
  • Servicio para consulta de suscripción

Consumo del API de Reversos en Java o Android

Cómo usar el SDK

Para poder consumir el API de Nequi en su proyecto Java debe agregar el SDK como una dependencia de maven, el id del artefacto cambia según si el ambiente es QA o producción.

Por favor incluya en la parte de dependencias de su pom.xml lo siguiente:

  • Ambiente de pruebas o QA:
    
        <dependency>
            <groupId>com.nequi</groupId>
            <artifactId>nequi-api-client-qa</artifactId>
            <version>1.0.2</version>
        </dependency>
    
  • Ambiente de producción:
    
        <dependency>
            <groupId>com.nequi</groupId>
            <artifactId>nequi-api-client</artifactId>
            <version>1.0.2</version>
        </dependency>
    

Si no va a usar el artefacto de maven sino que el equipo de NEQUI le entregó los jars requeridos, agregue estos al classpath de su proyecto; o en caso que  tenga las fuentes del SDK de Java en un .zip, descomprímalo y en la raíz donde se encuentra el archivo pom.xml ejecute el comando mvn install para instalar el paquete en su repositorio local de maven.

Creación de un cliente

Ya teniendo el SDK integrado en nuestro proyecto, lo siguiente para consumir el API de NEQUI es instanciar un nuevo cliente mediante el objeto ApiClientFactory y la interfaz NequiGatewayClient que representa el contrato de servicio con las operaciones que se pueden hacer sobre el API de Nequi.

Para este proceso va a necesitar el apiKey, accessKey y secretKey que le ha suministrado el equipo de Nequi como sus credenciales de acceso al API para poder configurar la autorización mediante alguno de los múltiples proveedores que ofrece AWS (mediante Variables de entorno, archivos de propiedades, AWS Security Token Service, etc.) o alguna estrategia que usted desee crear. Para este ejemplo vamos a utilizar un proveedor que nos expone el SDK de Nequi llamado BasicAWSCredentialsProvider.

En el siguiente código en java podemos ver un ejemplo de cómo instanciar un cliente del API:


//Se inicializa la fábrica de clientes
ApiClientFactory factory = new ApiClientFactory();
//Se instancia el proveedor de credenciales
AWSCredentialsProvider credenetialsProvider = new BasicAWSCredentialsProvider(ACCESS_KEY,SECRET_KEY);
//Se setea el api key
factory.apiKey(API_KEY);
//Se asigna el proveedor de credenciales a la fábrica de clientes
factory.credentialsProvider(credenetialsProvider);
//Se instancia un nuevo cliente del api a partir del contrato establecido por 
//NequiSubscriptionsGatewayClient
NequiGatewayClient apiClient = factory.build(NequiGatewayClient.class);

 

Ya con el contrato o interfaz NequiGatewayClient instanciada podemos ejecutar de manera sincrónica el método para realizar reversos:

    
        public interface NequiGatewayClient {    
            JsonObject servicesReverseServicesReverseTransactionPost(JsonObject body);
        }
    

 

Como se puede ver en la anterior imagen, cada método o servicio del API recibe un JsonObject que representa el cuerpo de la petición que requiere el servicio y retorna un JsonObject que representa la respuesta del servicio.

Servicio para reversar una transacción

El servicio para reversar una transacción  expuesto en el api permite a partir de un tipo de transacción, del identificador y valor de la transacción, del celular de un cliente y del tipo y número de identificación del comercio, reversar una transacción en Nequi.
Este servicio se recomienda usar en el caso cuando el sistema integrado con el API no recibe una respuesta, timeout, o hay un fallo en la comunicación con el API.

De los métodos que ofrece el NequiGatewayClient vamos a utilizar servicesReverseServicesReverseTransactionPost para reversar una transacción.

En código Java sería de la siguiente forma:


  //Inicialización del cliente API
  ApiClientFactory factory = new ApiClientFactory();
  AWSCredentialsProvider credenetialsProvider = new BasicAWSCredentialsProvider(ACCESS_KEY, SECRET_KEY);
  factory.apiKey(_API_KEY);
  factory.credentialsProvider(credenetialsProvider);
  NequiGatewayClient apiClient = factory.build(NequiGatewayClient.class);
  String phone_number = “3995426589”;
  String value = “100”;
  String messageId = “123456”;
  String code = “123456789”;
  String type = “cashin”;
  //Consumo del servicio, retorna un JsonObject con la respuesta del servicio
  JsonObject response = apiClient.servicesReverseServicesReverseTransactionPost(BodyUtils. getBodyReversionQR(phone_number, value, messageId, code, type));

 

Si analizamos el anterior código primero se inicializa el cliente y luego se invoca el servicio. Además, en este ejemplo también se usa un método estático, BodyUtils.getBodyReversionQR, para generar el cuerpo de la petición, este método debería retornar un JsonObject con la siguiente estructura:


  {
    "RequestMessage": {
      "RequestHeader": {
        "Channel": CONSUMER_ID, //ID del consumidor para trazabilidad
        "RequestDate": DATE, //Timestamp completo, con milisegundos precisión 3
        "MessageID": ID, //Identificador único de la transacción, timestamp o alguno único
        "ClientID": NUMBER //Identificador de la terminal, nodo o servidor
            "Destination": {
          "ServiceName": "ReverseServices", //Servicio que se quiere consumir
          "ServiceOperation": "reverseTransaction", //Operación del servicio a consumir
          "ServiceRegion": "C001", //Región a la que pertenece el servicio, para panamá P001
          "ServiceVersion": "1.0.0" //Versión del servicio
        }
      },
      "RequestBody": {
        "any": {
          "reversionRQ": {
            "phoneNumber": NUMBER, //Número de celular del cliente NEQUI
            "value": VALUE, //Valor de la transacción
            "code": CODE, //Combinación del tipo y número de identificación del comercio
            "messageId": MESSAGEID //Identificador de la transacción a reversar   
            "type": TYPE, //Tipo de la transacción
          }
        }
      }
    }
  }

Para construir las cabeceras del cuerpo de la petición o  RequestHeader va a necesitar el Channel que le ha sido suministrado por Nequi, generar un datestamp a partir de la fecha en que se realiza la petición para la propiedad RequestDate y definir una forma única de identificar la transacción mediante un alfanumérico de 10 para asignar al campo MessageID. Un ejemplo de la codificación del método sería:


//Canal entregado por el equipo de Nequi
public static final String CHANNEL = "MF-001";
public static JsonObject getBodyGenerateQR(String phone, String value, String messageId, String code, String type) {
  //Fecha de la petición
  Date d = new Date();
  String date = new SimpleDateFormat("yyyy-MM-dd:HH-mm-ss").format(d);
  String miliseconds = Long.toString(System.currentTimeMillis());
  String input = 
    "{\"RequestMessage\":{"
      + "\"RequestHeader\":{"
        //Canal
        + "\"Channel\":\""+CHANNEL+"\","
        //Fecha de la petición
        + "\"RequestDate\":\""+date+"\","
        //Identificador único de la transacción
        + "\"MessageID\":\""+miliseconds.substring(miliseconds.length()-9)+"\","                                
        + "\"ClientID\":\""+ phone+ "\""
        + ", \"Destination\": {"                    
          +  "\"ServiceName\": \"ReverseServices\""
          +", \"ServiceOperation\": \"reverseTransaction \""
          +", \"ServiceRegion\": \"C001\""
          +", \"ServiceVersion\": \"1.0.0\""
        + "}"
      + "},"
      + "\"RequestBody\":{"
        + "\"any\":{"
          + "\"reversionRQ\":{"
            + "\"messageId\":\""+ messageId + "\","
            + "\"code\":\""+ code + "\","
            + "\"type\":\""+ type + "\","
            + "\"phoneNumber\":\""+ phone + "\","
            + "\"value\":\"" + value + "\""
          + "}"
        + "}"
      + "}"
    + "}}";
  return gson.fromJson(input, JsonObject.class);
}

 

En el atributo type se debe enviar el siguiente valor según la transacción a reversar:

  • Recarga = cashin
  • Retiro = cashout
  • Pago con QR o Push = payment
  • Pago Débito Automático o con Suscripción  = automaticPayment

Al consumir el anterior servicio en el response de la petición se puede verificar si fue exitoso u ocurrió algún error en el atributo Status. Cuando el atributo StatusCode es igual a 0 significa que la transacción se reverso correctamente y en caso contrario ha ocurrido un error y más detalle de este se puede ver en el atributo  StatusDesc. La estructura de respuesta del servicio es la siguiente:


{
  "ResponseMessage": {
    "ResponseHeader": {
      "Channel": CONSUMER_ID, //ID del consumidor para trazabilidad
      "ResponseDate": DATE, //Fecha de respuesta
      "Status": {
        "StatusCode": "0",
        "StatusDesc": "SUCCESS"
      },
      "MessageID": ID, //Identificador único de la transacción, timestamp o alguno único
      "ClientID": NUMBER, //Identificador de la terminal, nodo o servidor
      //Datos técnicos que no deberían ser procesados o almacenados
      "Destination": {
        "ServiceName": "ReverseServices", //Nombre del Servicio
        "ServiceOperation": "reverseTransaction" //Nombre de la operación
              "ServiceRegion": "C001", //Región a la que pertenece el servicio, para panamá P001
        "ServiceVersion": "1.0.0" //Versión del servicio
      }
    },
    "ResponseBody": {
      "any": {
        "reversionRS": {}
      }
    }
  }
}

 

Cuando la operación del servicio falla, no el consumo HTTP del servicio REST, sino la operación de negocio, el campo StatusCode será diferente de cero y por consiguiente en ResponseBody.any no vendrá el objeto  cashOutRS sino que any  será un elemento o cadena vacía..

Servicio para consulta de suscripción

El servicio para consulta de suscripción permite a partir de un celular de un usuario Nequi, el tipo y número de identificación de un comercio y el último token que se tenga de esa suscripción, consultar los datos de dicha suscripción principalmente el estado que define si ya fue aprobada, rechazada, expirada o si sigue pendiente.

De los métodos que ofrece el NequiSubscriptionsGatewayClient vamos a utilizar servicesSubscriptionpaymentserviceGetsubscriptionPost para consultar una suscrpción.

En código Java seria de la siguiente forma:


//Inicialización del cliente API
ApiClientFactory factory = new ApiClientFactory();
AWSCredentialsProvider credenetialsProvider = new BasicAWSCredentialsProvider(ACCESS_KEY, SECRET_KEY);
factory.apiKey(_API_KEY);
factory.credentialsProvider(credenetialsProvider);
NequiSubscriptionsGatewayClient apiClient = factory.build(NequiSubscriptionsGatewayClient.class);
String phone_number =”3993457689”;
String token =”AWSDERRGTTGFD”;
String code = “12345”; 
//Consumo del servicio, retorna un JsonObject con la respuesta del servicio
JsonObject response = apiClient.servicesSubscriptionpaymentserviceGetsubscriptionPost(BodyUtils.getBodyGetSubscription(phone_number, code, token));

 

Si analizamos el anterior código primero se inicializa el cliente y luego se invoca el servicio. Además, en este ejemplo también se usa un método estático, BodyUtils.getBodyGetSubscription, para generar el cuerpo de la petición, este método debería retornar un JsonObject con la siguiente estructura:


{
  "RequestMessage": {
    "RequestHeader": {
      "Channel": CONSUMER_ID, //ID del consumidor para trazabilidad
      "RequestDate": DATE, //Timestamp completo, con milisegundos precisión 3
      "MessageID": ID, //Identificador único de la transacción, timestamp o alguno único
      "ClientID": NUMBER //Identificador de la terminal o servidor
          "Destination": {
        "ServiceName": " SubscriptionPaymentService", //Servicio que se quiere consumir
        "ServiceOperation": "getSubscription", //Operación del servicio a consumir
        "ServiceRegion": "C001", //Región a la que pertenece el servicio, para panamá P001
        "ServiceVersion": "1.0.0" //Versión del servicio
      }
    },
    "RequestBody": {
      "any": {
        "getSubscriptionRQ": {
          "phoneNumber": STRING, //Número de celular del cliente
          "code": STRING, //Combinación del tipo y número de identificación del comercio
          "token": STRING //Último token retornado por el servicio de nueva suscripción 
        }
      }
    }
  }
}

 

Para construir las cabeceras del cuerpo de la petición o  RequestHeader va a necesitar el Channel que le ha sido suministrado por Nequi, generar un datestamp a partir de la fecha en que se realiza la petición para la propiedad RequestDate y definir una forma única de identificar la transacción mediante un alfanumérico de 10 para asignar al campo MessageID. Un ejemplo de la codificación del método sería:


//Canal entregado por el equipo de Nequi
public static final String CHANNEL = "MF-001";
public static JsonObject getBodyGetSubscription(String phone, String code, String token) {
  //Fecha de la petición
  Date d = new Date();
  String date = new SimpleDateFormat("yyyy-MM-dd:HH-mm-ss").format(d);
  String miliseconds = Long.toString(System.currentTimeMillis());
  String input = 
    "{\"RequestMessage\":{"
      + "\"RequestHeader\":{"
        //Canal
        + "\"Channel\":\""+CHANNEL+"\","
        //Fecha de la petición
        + "\"RequestDate\":\""+date+"\","
        //Identificador único de la transacción
        + "\"MessageID\":\""+miliseconds.substring(miliseconds.length()-9)+"\","
        //Identificador de la terminal
        + "\"ClientID\":\"12345\""
        + ", \"Destination\": {"                    
          +     "\"ServiceName\": \"SubscriptionPaymentService\""
          +", \"ServiceOperation\": \"getSubscription\""
          +    ", \"ServiceRegion\": \"C001\""
          +    ", \"ServiceVersion\": \"1.0.0\""
        + "}"
      + "},"
      + "\"RequestBody\":{"
        + "\"any\":{"
          + "\"getSubscriptionRQ\":{"
            + "\"phoneNumber\":\""+ phone + "\","
            + "\"code\":\""+ code + "\","    
            + "\"token\":\"" + token + "\""
          + "}"
        + "}"
      + "}"
    + "}}";
  return gson.fromJson(input, JsonObject.class);
}

 

Llegado el caso que el consumo del servicio sea exitoso, el JsonObject que retorna el método trae los datos de la suscripción, la estructura de la respuesta es similar a la siguiente:


{
  "ResponseMessage": {
    "ResponseHeader": {
      "Channel": CONSUMER_ID, //ID del consumidor para trazabilidad
      "ResponseDate": DATE, //Fecha de respuesta
      "Status": {
        "StatusCode": "0",
        "StatusDesc": "SUCCESS"
      },
      "MessageID": ID, //Identificador único de la transacción, timestamp o alguno único
      "ClientID": NUMBER, //Identificador de la terminal o servidor
      //Datos técnicos que no deberían ser procesados o almacenados
      "Destination": {
        "ServiceName": "SubscriptionPaymentService", //Nombre del Servicio
        "ServiceOperation": "getSubscription" //Nombre de la operación
              "ServiceRegion": "C001", //Región a la que pertenece el servicio, para panamá P001
        "ServiceVersion": "1.0.0" //Versión del servicio
      }
    },
    "ResponseBody": {
      "any": {
        //Presente solo cuando StatusCode es igual a cero
        "getSubscriptionRS": {
          "dateCreated": STRING, //Fecha de generación de la suscripción,
          "name": STRING, //Nombre del comercio asociado a la suscripción
          "status": STRING //Estado de la suscripción
        }
      }
    }
  }
}

 

Cuando la operación del servicio falla, no el consumo HTTP del servicio REST, sino la operación de negocio, el campo StatusCode será diferente de cero y por consiguiente en ResponseBody.any no vendrá el objeto  getSubscriptionRS sino que any  será un elemento o cadena vacía.

 

Si tiene dudas técnicas sobre la implementación y uso del API de NEQUI para notificaciones revise el código de la aplicación de ejemplo que se le entregó con esta guía o póngase en contacto con el equipo de NEQUI.