
-
Colombia
-
Panamá
Colombia
Panamá
Para poder consumir el API de Suscripciones 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:
<dependency> <groupId>com.nequi</groupId> <artifactId>
nequi-subscriptions-api-sdk-qa</artifactId> <version>2.0.0</version> </dependency>
<dependency> <groupId>com.nequi</groupId> <artifactId>
nequi-subscriptions-api-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.
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 NequiSubscriptionsGatewayClient 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 NequiSubscriptionsGatewayClientNequiSubscriptionsGatewayClient apiClient = factory.build(NequiSubscriptionsGatewayClient.class);
Ya con el contrato o interfaz NequiSubscriptionsGatewayClient instanciada podemos ejecutar de manera sincrónica cualquiera de los siguientes métodos:
public interface NequiSubscriptionsGatewayClient { JsonObject
servicesSubscriptionpaymentserviceAutomaticpaymentPost(JsonObject body,
String authorization); JsonObject
servicesSubscriptionpaymentserviceGetsubscriptionPost(JsonObject body,
String authorization); JsonObject
servicesSubscriptionpaymentserviceNewsubscriptionPost(JsonObject body,
String authorization); JsonObject
servicesSubscriptionpaymentserviceGetstatuspaymentPost(JsonObject body,
String authorization); JsonObject
servicesReverseservicesReversetransactionPost(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.
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:
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:
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");
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();
El servicio para crear una nueva suscripción envía una solicitud a un cliente Nequi mediante una notificación PUSH para suscribirse a un comercio con el objetivo de permitirle a éste realizar pagos o débitos automáticos de esa cuenta Nequi. El usuario cuenta con la posibilidad de aprobarla o rechazarla.
De los métodos que ofrece el NequiNotificationGateWayClient vamos a utilizar servicesSubscriptionpaymentserviceNewsubscriptionPost para consumir el servicio para crear una nueva suscripción.
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
NequiSubscriptionsGatewayClient apiClient = factory.build(NequiSubscriptionsGatewayClient.class);
//Se instancia la clase para autenticarse
NequiAuth auth = NequiAuth.getInstance().fromEnvVars();
String phone_number = "3996581361";
String code = "123456789";
String name = "Prueba";
//Consumo del servicio, retorna un JsonObject con la respuesta del servicio
JsonObject response = apiClient.servicesSubscriptionpaymentserviceNewsubscriptionPost(BodyUtils.getNewSubscription(phone_number, code, name), 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.getNewSubscription, 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 o canal 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": "SubscriptionPaymentService", //Servicio que se quiere consumir "ServiceOperation": "newSubscription", //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": { "newSubscriptionRQ": { "phoneNumber": STRING, //Número de celular del cliente Nequi "code": STRING, //C
ombinación del tipo y número de identificación del comercio"name": STRING //Nombre del comercio con el cual se desea aparezca en el PUSH } } } } }
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 suscripciones public static final String CHANNEL = "PDA05-C001"; //Construye a partir del celular, t
ipo y número de identificación del comercioy nombre el mensaje de entrada del servicio de nueva //suscripción public static JsonObject getNewSubscription(String phoneNumber, String code, String name) { //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 o servidor + "\"ClientID\":\"123\"" + ", \"Destination\": {" +"\"ServiceName\":\"SubscriptionPaymentService\"" + ", \"ServiceOperation\": \"newSubscription\"" + ", \"ServiceRegion\": \"C001\"" + ", \"ServiceVersion\": \"1.0.0\"" + "}" + "}," + "\"RequestBody\":{" + "\"any\":{" + "\"newSubscriptionRQ\":{" + "\"phoneNumber\":\""+ phoneNumber + "\"," + "\"code\":\"" + code + "\"," + "\"name\":\"" + name + "\"" + "}" + "}" + "}" + "}}"; 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 token requerido para poder usar por primera vez el servicio de pago automático, el token debería ser almacenado porque no hay ningún otro servicio que lo retorne nuevamente por temas de seguridad, si lo pierde tendría que consumir de nuevo este servicio y esperar que el usuario apruebe la suscripción. La estructura de la respuesta del servicio 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": "newSubscription" //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
"newSubscriptionRS": {
"token": STRING //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 newSubscriptionRS sino que any será un elemento o cadena vacía.
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();
factory.apiKey(_API_KEY);
//Se instancia un nuevo cliente
NequiSubscriptionsGatewayClient apiClient = factory.build(NequiSubscriptionsGatewayClient.class);
//Se instancia la clase para autenticarse
NequiAuth auth = NequiAuth.getInstance().fromEnvVars();
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), 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.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, //C
ombinació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 para pagos con suscripciones
public static final String CHANNEL = "PDA05-C001";
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.
Los posibles estados que puede tener una suscripción son los siguientes:
Solo cuando es aceptada el servicio de pago automático podrá funcionar.
El servicio para realizar un pago automático permite a partir de un celular de un usuario Nequi, el tipo y número de identificación de un comercio, un valor a pagar y el último token que se tenga de esa suscripción, realizar un pago o débito automático o en línea de la cuenta del usuario Nequi.
El método que vamos a utilizar para los pagos automáticos es servicesSubscriptionpaymentserviceAutomaticpaymentPost.
En código Java seria de la siguiente forma:
//Inicialización del cliente API
ApiClientFactory factory = new ApiClientFactory();
factory.apiKey(_API_KEY);
//Se instancia un nuevo cliente
NequiSubscriptionsGatewayClient apiClient = factory.build(NequiSubscriptionsGatewayClient.class);
//Se instancia la clase para autenticarse
NequiAuth auth = NequiAuth.getInstance().fromEnvVars();
String phone_number = "3993457689";
String token = "AWSDERRGTTGFD";
String code = "12345";
String value = "1";
//Consumo del servicio, retorna un JsonObject con la respuesta del servicio
JsonObject response = apiClient.servicesSubscriptionpaymentserviceAutomaticpaymentPost(BodyUtils.getBodyAutomaticPayment(phone_number, code, token, 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.getBodyAutomaticPayment, 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": "automaticPayment", //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": { "automaticPaymentRQ": { "phoneNumber": STRING, //Número de celular del cliente "code": STRING, //C
ombinación del tipo y número de identificación del comercio"valor": STRING, //Valor a cobrar "token": STRING, //Último token de la suscripción "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 suscripciones
public static final String CHANNEL = "PDA05-C001";
public static JsonObject getBodyAutomaticPayment(String phone, String code, String value, String token,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)+"\","
//Identificador de la terminal
+ "\"ClientID\":\"12345\""
+ ", \"Destination\": {"
+ "\"ServiceName\": \"SubscriptionPaymentService\""
+", \"ServiceOperation\": \"automaticPayment\""
+ ", \"ServiceRegion\": \"C001\""
+ ", \"ServiceVersion\": \"1.0.0\""
+ "}"
+ "},"
+ "\"RequestBody\":{"
+ "\"any\":{"
+ "\"automaticPaymentRQ\":{"
+ "\"phoneNumber\":\""+ phone + "\","
+ "\"code\":\""+ code + "\","
+ "\"value\":\""+ value + "\","
+ "\"token\":\"" + token + "\","
+ "\"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 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": "automaticPayment" //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
"automaticPaymentRS": {
"transactionId ": STRING, //Identificador de la transacción que se usa en el
//servicio de validación o consulta de estado de pago,
"token": STRING, //Nuevo token para usar en los servicios que lo requieren
}
}
}
}
}
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 automaticPaymentRS sino que any será un elemento o cadena vacía.
El servicio para validar pagos, expuesto en el api permite a partir del transactionId que retorna el servicio de pago automático validar si el pago ya fue realizado desde la cuenta NEQUI. Este servicio es útil por si se necesita verificar si el pago fue correcto o no, aunque el servicio de pago automático ya retorna si fue exitoso o no, este es una opción adicional para verificar el pago.
De las funciones que ofrece el NequiSubscriptionsGatewayClient usaremos servicesSubscriptionpaymentserviceGetstatuspaymentPost para consumir el servicio que valida el estado de un pago.
En código Java seria de la siguiente forma:
//Inicialización del cliente API ApiClientFactory factory = new ApiClientFactory(); factory.apiKey(_API_KEY); //Se instancia un nuevo cliente NequiSubscriptionsGatewayClient apiClient = factory.build(NequiSubscriptionsGatewayClient.class); //Se instancia la clase para autenticarse NequiAuth auth = NequiAuth.getInstance().fromEnvVars();
String code = "1234"; //Consumo del servicio, retorna un JsonObject con la respuesta del servicio JsonObject response = apiClient. servicesSubscriptionpaymentserviceGetstatuspaymentPost(BodyUtils. getBodyGetStatusPayment(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, si es 34 fue rechazado y si es 33 ya expiró.
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, //Identificador de la terminal
"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 ": STRING //transactionId retornado por el servicio de pago automático
}
}
}
}
}
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 suscripciones
public static final String CHANNEL = "PDA05-C001";
//Construye a partir de un transactionId el mensaje de entrada del
//servicio de validación de pago
public static JsonObject getBodyGetStatusPayment(String code) {
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+"\","
//Feha de la petición
+ "\"RequestDate\":\""+date+"\","
//Identificador único de la transacción
+ "\"MessageID\":\""+miliseconds.substring(miliseconds.length()-9)+"\","
+ "\"ClientID\":\"12345\""
+ ", \"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, //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": CEL, //Numero del cliente que pago
"date": DATE, //Fecha del pago
"name": NAME, //Nombre del cliente merchant o comercio
"trnId": ID, //Id de la transacción
"value": VALUE, //Valor pagado
"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.
Para consumir este servicio recomendamos las siguientes dos estrategias:
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.