NEQUI
  • Colombia

  • Panamá

  • Cómo usar el SDK
  • Creación de un cliente
  • Autenticación en Nequi Conecta
  • Servicio para generar código de pago mediante QR
  • Servicio de Pago sin Registro
  • Servicio para validar pago

Consumo del API de Pagos 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-payments-sdk-qa</artifactid>
          <version>2.0.0</version>
      </dependency>
  • Ambiente de producción:
      <dependency>
          <groupid>com.nequi</groupid>
          <artifactid>nequi-payments-sdk</artifactid>
          <version>2.0.0</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 NequiPaymentsGatewayClient 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 la clase NequiAuth.

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 setea el api key
factory.apiKey(API_KEY);
//Se instancia un nuevo cliente del api a partir del contrato establecido por NequiPaymentsGatewayClient
NequiPaymentsGatewayClient apiClient = factory.build(NequiPaymentsGatewayClient.class);

Ya con el contrato o interfaz NequiPaymentsGatewayClient instanciada podemos ejecutar de manera sincrónica cualquiera de los siguientes métodos:


public interface NequiPaymentsGatewayClient {
    JsonObject servicesPaymentserviceCancelqrpaymentPost(JsonObject body, String authorization);
    JsonObject servicesPaymentserviceCancelunregisteredpaymentPost(JsonObject body, String authorization);
    JsonObject servicesPaymentserviceGeneratecodeqrPost(JsonObject body, String authorization);
    JsonObject servicesPaymentserviceGetstatuspaymentPost(JsonObject body, String authorization);
    JsonObject servicesPaymentserviceUnregisteredpaymentPost(JsonObject body, String authorization);
    JsonObject servicesReverseservicesReversetransactionPost(JsonObject body, String authorization);
    JsonObject servicesStaticqrservicesCreatependingpaymentPost(JsonObject body, String authorization);
    JsonObject servicesStaticqrservicesGetinfoPost(JsonObject body, String authorization);
    JsonObject servicesStaticqrservicesGetpendingpaymentPost(JsonObject body, String authorization);
    JsonObject servicesStaticqrservicesGetstatuspaymentPost(JsonObject body, String authorization);
    JsonObject servicesStaticqrservicesReversepaymentPost(JsonObject body, String authorization);
}

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

Autenticación en Nequi Conecta

Todos los servicios ofrecidos por el API necesitan de un token de autenticación, el cuál podrá obtener mediante la clase NequiAuth. Dicha autenticación se puede hacer mediante 2 medios:

1. Variables de entorno: Esta es la opción recomendada, siempre que pueda suministrar las variables de entorno tal cual se mencionan a continuación:

  • NEQUI_CLIENT_ID: Proveida por Conecta Nequi en la sección de credenciales.
  • NEQUI_CLIENT_SECRET: Proveida por Conecta Nequi en la sección de credenciales.
  • NEQUI_AUTH_URI: Es la URI del endpoint que debe consumir para autenticarse, para producción es "https://oauth.nequi.com/oauth2/token"(sin las comillas).
  • NEQUI_AUTH_GRANT_TYPE: Tipo de acceso a los recursos del API, el valor recomendado es "client_credentials"(sin las comillas).

Una vez listas las variables de entorno, basta con instanciar la clase de la siguiente forma:

Ejemplo

NequiAuth nequiAuth = NequiAuth.getInstance().fromEnvVars();

2. Asignación manual de los datos: Con este mecanismo podrá asignar manualmente los valores que se necesitan para autenticarse usando alguno de los siguientes métodos de la clase NequiAuth:

  • NequiAuth.getInstance().with: Este método recibe los siguientes valores:
    • String clientId: Proveida por Conecta Nequi en la sección de credenciales.
    • String clientSecret: Proveida por Conecta Nequi en la sección de credenciales.
    • String authUri: Es la URI del endpoint que debe consumir para autenticarse, para producción es "https://oauth.nequi.com/oauth2/token"(sin las comillas).
    • String authGranType: Tipo de acceso a los recursos del API, el valor recomendado es "client_credentials"(sin las comillas).

Ejemplos:

// Opción 1: Se omite el argumento "authGranType" para que tome el valor por defecto
NequiAuth nequiAuth = NequiAuth.getInstance().with("myClientId", "myClienteSecret", "https://oauth.sandbox.nequi.com/oauth2/token");

// Opción 2: Se pasan todos los argumentos necesarios
NequiAuth nequiAuth = NequiAuth.getInstance().with("myClientId", "myClienteSecret", "https://oauth.sandbox.nequi.com/oauth2/token", "client_credentials");
  • Usando los métodos .withXYZ: La clase NequiAuth cuenta con 4 métodos concatenables que permiten asignar los valores manualmente:
    • .withClientId(String clientId)
    • .withClientSecret(String clientSecret)
    • .withAuthUri(String authUri)
    • .withAuthGranType(String authGranType)

Ejemplos:

// Opción 1: Se instancia pasando cada dato en particular
NequiAuth nequiAuth = NequiAuth.getInstance()
    .withClientId("myClientId")
    .withClientSecret("myClientSecret")
    .withAuthUri("https://oauth.sandbox.nequi.com/oauth2/token")
    .withAuthGranType("client_credentials");

// Opción 2: Se instancia a partir de las variables de entorno, pero se puede sobre-escribir cualquier valor
NequiAuth nequiAuth = NequiAuth.getInstance().fromEnvVars()
    .withClientId("myClientId")
    .withClientSecret("myClientSecret");

Una vez instanciada la clase NequiAuth, puede obtener un token de autorización usando el método .getToken();, el cual puede recibir un flag que indica si se desea obtener concatenado el tipo de token y el token(el resultado es la cabecera HTTP "Authorization" ya lista); o si solo se desea el token. Si no se pasa el flag, por defecto será true.

Ejemplo:

// Retorna el tipo de token y el token concatenados, lo que conforma la cabecera HTTP "Authorization"
// Se obtiene el mismo resultado que invocar nequiAuth.getToken(true);
String token = nequiAuth.getToken();

 

Servicio para generar código de pago mediante QR

El servicio para generar código de pago mediante QR expuesto en el api permite a partir del celular de un cliente merchant y un valor a cobrar, crear una solicitud o código de pago, que al concatenar con el string "bancadigital-" conforman la cadena con la cual se puede crear un código QR que puede ser leído desde la aplicación móvil NEQUI para concretar el pago.

De los métodos que ofrece el NequiPaymentsGatewayClient vamos a utilizar servicesPaymentserviceGeneratecodeqrPost para consumir el servicio que genera claves para la creación de QR.

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


//Inicialización del cliente API
ApiClientFactory factory = new ApiClientFactory();
factory.apiKey(_API_KEY);
//Se instancia un nuevo cliente
NequiPaymentsGatewayClient apiClient = factory.build(NequiPaymentsGatewayClient.class);
//Se instancia la clase para autenticarse
NequiAuth auth = NequiAuth.getInstance().fromEnvVars();

Long phone_number = 123;
Integer value = 100;
//Consumo del servicio, retorna un JsonObject con la respuesta del servicio
JsonObject response = apiClient.servicesPaymentserviceGeneratecodeqrPost(BodyUtils.getBodyGenerateQR(phone_number, value), auth.getToken());

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.getBodyGenerateQR, 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 //Número de celular del merchant ó identificador de la terminal
            "Destination": {
                "ServiceName": "PaymentsService", //Servicio que se quiere consumir 
                "ServiceOperation": "generateCodeQR", //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": {
                "generateCodeQRRQ": {                   
                    "code": "CC_CEDULA", //Cédula
                    "value": VALUE //Valor del pago a cobrar,
                    "reference1": "reference1",
                    "reference2": "reference2",
                    "reference3": "reference3",
                    "tipValue": TIP, //Valor de la propina (solo para Panamá) 
                    "taxValue": TAX  //Valor del impuesto (solo para Panamá) 

                }
            }
        }
    }
}

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 para pagos con QR
public static final String CHANNEL = "PQR03-C001";
// Construye a partir del celular y valor para generar un codigo de pago el
// mensaje de entrada del servicio de generacion de QR
public static JsonObject getBodyGenerateQR(String code, Integer value,String reference1,String reference2,String reference3) {
    //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)+"\","
            //Número de celular del merchant ó identificador de la terminal
            + "\"ClientID\":\""+ phone+ "\""
            + ", \"Destination\": {"
                +    "\"ServiceName\": \"PaymentsService\""
                +    ", \"ServiceOperation\": \"generateCodeQR\""
                +    ", \"ServiceRegion\": \"C001\""
                +    ", \"ServiceVersion\": \"1.0.0\""
            + "}"
        + "},"
        + "\"RequestBody\":{"
            + "\"any\":{"
                + "\"generateCodeQRRQ\":{"
                    + "\"code\":\""+ code+ "\","
                    + "\"value\":\"" + value + "\""+ "\","
                    + "\"reference1\":\"" + reference1+ "\""+ "\","
                    + "\"reference2\":\"" + reference2+ "\""+ "\","
                    + "\"reference3\":\"" + reference3+ "\""+ "\","
                + "}"
            + "}"
        + "}"
    + "}}";
    return gson.fromJson(input, JsonObject.class);
}

Llegado el caso que el consumo del servicio sea exitoso, el JsonObject que retorna el método trae internamente el código requerido para generar el QR, es un atributo con nombre codeQR, 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, //Número de celular del merchant ó identificador de la terminal
            //Datos técnicos que no deberían ser procesados o almacenados
            "Destination": {
                "ServiceName": "PaymentsService", // Nombre del Servicio
                "ServiceOperation": "generateCodeQR" //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
                "generateCodeQRRS": {
                    "codeQR": CODIGO_QR //Esta es la variable que nos interesa
                }
            }
        }
    }
}

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 generateCodeQRRS sino que any  será un elemento o cadena vacía.

Servicio de Pago sin Registro

El servicio de pago sin registro  expuesto en el api permite a partir del celular de un cliente NEQUI, un valor a cobrar y el tipo y número de identificación de un comercio al que se le va a pagar, crear una solicitud de pago sin registro que envía una notificación push al celular para que el cliente confirme el pago desde la aplicación móvil de NEQUI.

De los métodos que ofrece el NequiPaymentsGatewayClient vamos a utilizar servicesPaymentserviceUnregisteredpaymentPost para enviar una solicitud de pago a un cliente NEQUI.

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

//Inicialización del cliente API 
ApiClientFactory factory = new ApiClientFactory(); 
factory.apiKey(_API_KEY); 
//Se instancia un nuevo cliente 
NequiPaymentsGatewayClient apiClient = factory.build(NequiPaymentsGatewayClient.class);
//Se instancia la clase para autenticarse
NequiAuth auth = NequiAuth.getInstance().fromEnvVars();

Long phone_number = 123;
Integer value = 100;
String code = "12345";
 
//Consumo del servicio, retorna un JsonObject con la respuesta del servicio
JsonObject response = apiClient. servicesPaymentserviceUnregisteredpaymentPost(BodyUtils.getBodyUnregisteredPayment(phone_number,value, code), auth.getToken());

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.getBodyUnregisteredPayment, 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 //Número de celular del merchant ó identificador de la terminal
            "Destination": {
                "ServiceName": "PaymentsService", //Servicio que se quiere consumir
                "ServiceOperation": "unregisteredPayment", //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": {
                "unregisteredPaymentRQ": {
                    //Número de celular del cliente
                    "phoneNumber": NUMBER,
                    "code": CODE, //Combinación del tipo y número de identificación del comercio
                    "value": VALUE //Valor del pago a cobrar,
                    "reference1": "reference1",  
                    "reference2": "reference2",   
                    "reference3": "reference3"
                }
            }
        }
    }
}

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 para pagos con PUSH o sin registro
public static final String CHANNEL = "PNP04-C001";
// Construye a partir del celular y valor el cuerpo para consumir el servicio de pago sin
// registro. Tener en la cuenta el atributo code, este representa el tipo y número de identificación del comercio
public static JsonObject getBodyUnregisteredPayment(Long phone, Integer value, String code,String reference1,String reference2,String reference3) {
    //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)+"\","
                //Número de celular del merchant ó identificador de la terminal
                + "\"ClientID\":\""+ phone+ "\""
                + ", \"Destination\": {"
                    +    "\"ServiceName\": \"PaymentsService\""
                    +", \"ServiceOperation\": \" unregisteredPayment\""
                    +    ", \"ServiceRegion\": \"C001\""
                    +    ", \"ServiceVersion\": \"1.0.0\""
                + "}"
            + "},"
            + "\"RequestBody\":{"
                + "\"any\":{"
                    + "\"generateCodeQRRQ\":{"
                        + "\"phoneNumber\":\""+ phone + "\","
                        + "\"code\":\""+ code + "\","
                        + "\"value\":\"" + value + "\""+ "\","
                        + "\"reference1\":\"" + reference1+ "\""+ "\"," 
                        + "\"reference2\":\"" + reference2+ "\""+ "\"," 
                        + "\"reference3\":\"" + reference3+ "\""
                    + "}"
                + "}"
            + "}"
        + "}}";
    return gson.fromJson(input, JsonObject.class);
}

Llegado el caso que el consumo del servicio sea exitoso, el JsonObject que retorna el método trae internamente el identificador de la transacción, es un atributo con nombre transactionId, 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, //Número de celular del merchant ó identificador de la terminal
            //Datos técnicos que no deberían ser procesados o almacenados
            "Destination": {
                "ServiceName": "PaymentsService", // Nombre del Servicio
                "ServiceOperation": "unregisteredPayment" //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
                "unregisteredPaymentRS": {
                    "transactionId": TRANSACTION_ID //Esta es la variable que nos interesa
                }
            }
        }
    }
}

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  unregisteredPaymentRS sino que any será un elemento o cadena vacía.

Servicio para validar pago

El servicio para validar pagos, expuesto en el api permite a partir del código QR, no una imagen sino el código que responde el servicio de QR, o a partir del transactionId que retorna el servicio de pago sin registro validar si el pago ya fue realizado desde alguna cuenta NEQUI.

De las funciones que ofrece el NequiPaymentsGatewayClient vamos a utilizar servicesPaymentserviceGetstatuspaymentPost para consumir el servicio que valida el estado de un pago.

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

//Inicialización del cliente API
ApiClientFactory factory = new ApiClientFactory();
factory.apiKey(_API_KEY);
//Se instancia un nuevo cliente
NequiPaymentsGatewayClient apiClient = factory.build(NequiPaymentsGatewayClient.class);
//Se instancia la clase para autenticarse
NequiAuth auth = NequiAuth.getInstance().fromEnvVars();

String code = "1234";
Long phone_number = 123;
 
//Consumo del servicio, retorna un JsonObject con la respuesta del servicio
JsonObject response = apiClient. servicesPaymentserviceGetstatuspaymentPost(BodyUtils. getBodyGetStatusPayment(phone_number, code), auth.getToken());

En el anterior ejemplo primero se inicializa el cliente y luego se invoca el servicio, si la respuesta es exitosa y el estado del pago es igual a 35, significa que el pago ya está realizado.

Además, en este ejemplo también se usa un método que no está implementado en el ejemplo, BodyUtils.getBodyGetStatusPayment, para generar el cuerpo de la petición, esta función 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, //Número de celular del merchant ó identificador de la terminal (QR) o celular del cliente al que se le va a requerir el pago (Pago sin registro)
            "Destination": {
                "ServiceName": "PaymentsService", //Servicio que se quiere consumir
                "ServiceOperation": "getStatusPayment", //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": {
                "getStatusPaymentRQ": {
                    " codeQR ": NUMBER //Código del pago sea QR o transactionId
                }
            }
        }
    }
}

Al igual que en los servicios anteriores 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 mediante un alfanumérico de 10 para asignar al campo MessageID. Un ejemplo de la codificación del método sería:

// Canal para pagos con QR
public static final String CHANNEL = "PQR03-C001"; // Si es con  PUSH PNP04-C001
//Construye a partir de un código de pago qr o transactionId el mensaje de entrada del
//servicio de validación de pago
public static JsonObject getBodyValidatePayment(Long phone_number, String code) {
    Date d = new Date();
    String date = new SimpleDateFormat("yyyy-MM-dd:HH-mm-ss").format(d);
    tring miliseconds = Long.toString(System.currentTimeMillis());
    String input =
        "{\"RequestMessage\":{"
            + "\"RequestHeader\":{"
                //Canal
                + "\"Channel\":\""+CHANNEL+"\","
                //Feha de la petición
                + "\"RequestDate\":\""+date+"\","
                //Identificador único de la transacción
                + "\"MessageID\":\""+miliseconds.substring(miliseconds.length()-9)+"\","
                + "\"ClientID\":\""+phone_number+ "\""
                + ", \"Destination\": {"
                    + "\"ServiceName\": \"PaymentsService\""
                    + ", \"ServiceOperation\": \"getStatusPayment\""
                    + ", \"ServiceRegion\": \"C001\""
                    + ", \"ServiceVersion\": \"1.0.0\""
                + "}"
            + "},"
            + "\"RequestBody\":{"
                + "\"any\":{"
                    + "\"getStatusPaymentRQ\":{"
                        + "\"codeQR\":\"" + code + "\""
                    + "}"
                + "}"
            + "}"
        + "}}";
    return gson.fromJson(input, JsonObject.class);
}

Llegado el caso que el consumo del servicio sea exitoso, el response de la petición o el retorno del método trae internamente el estado del pago, el cual es igual a 35 cuando ya se realizó el pago por parte de algún cliente NEQUI. El estado es un atributo con nombre status y  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, //Número de celular del merchant ó identificador de la terminal
            //Datos técnicos que no deberían ser procesados o almacenados
            "Destination": {
                "ServiceName": "PaymentsService",
                "ServiceOperation": "getStatusPayment",
                "ServiceRegion": "C001", //Región a la que pertenece el servicio, para panamá P001
                "ServiceVersion": "1.0.0"
            }
        },
        "ResponseBody": {
            "any": {
                //Presente solo cuando StatusCode es igual a cero
                "getStatusPaymentRS": {
                    "status": STATUS, //Estado del pago, si es igual a 35 es porque esta completo
                    "phoneNumber": CELL, //Numero del cliente que pago
                    "date": DATE, //Fecha del pago
                    "name": NAME, //Nombre del cliente merchant
                    "trnId": ID, //Id de la transacción
                    "value": VALUE, //Valor pagado
                    "tipValue": TIP, //Valor de la propina (solo en Panamá) 
                    "taxValue": TAX, //Valor del impuesto (solo en Panamá) 
                    "originMoney": [{
                        "name": NAME, //Nombre del origen o bolsillo de dónde provino el dinero
                        "value": VALUE, //Valor debitado
                        "pocketType": POCKET, //Tipo de bolsillo
                    }]
                }
            }
        }
    }
}

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  getStatusPaymentRS 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 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.