diff --git a/.gitignore b/.gitignore
index f83e8cf..ddacca5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
.idea
target
*.iml
+dependency-reduced-pom.xml
diff --git a/.travis.yml b/.travis.yml
index ce6845b..afb824f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,8 +1,8 @@
language: java
+dist: trusty
jdk:
- openjdk7
- - oraclejdk7
- oraclejdk8
install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V
diff --git a/CHANGELOG b/CHANGELOG
index db744df..3f09af0 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,4 +1,27 @@
-### 1.1.7 15-03-2017
+### versión 2.0.4 - 03-12-2024
+* Control bad request
+* Add validations recurrent
+
+### versión 2.0.3 - 03-11-2024
+* Add new test
+
+### versión 2.0.2 - 03-10-2024
+* Control erro
+
+### versión 2.0.1 - 18-18-2023
+* Add status code
+* Add encrypt RSA
+
+### versión 2.0.0 - 27-12-2022
+* Add Yape y Confirm Order
+
+### versión 1.1.9 - 31-05-2017
+* Add TimeOut Exception
+
+### versión 1.1.8 - 16-03-2017
+* Fixed url query params for List data
+
+### versión 1.1.7 - 15-03-2017
* Improved method List data for all resources
* Fixex Timeout for List data
* Added Enum CurrencyCode with the following values: PEN, USD
diff --git a/README.md b/README.md
index cec0133..865d75a 100644
--- a/README.md
+++ b/README.md
@@ -1,133 +1,216 @@
-# Culqi Java
+# Culqi-Java
[![Code Climate](https://codeclimate.com/github/culqi/culqi-java/badges/gpa.svg)](https://codeclimate.com/github/culqi/culqi-java)
[![Build Status](https://travis-ci.org/culqi/culqi-java.svg?branch=master)](https://travis-ci.org/culqi/culqi-java)
-Biblioteca de CULQI para el lenguaje Java, pagos simples en tu sitio web. Consume el Culqi API.
+Nuestra Biblioteca JAVA oficial, es compatible con la [v2.0](https://culqi.com/api/) del Culqi API, con el cual tendrás la posibilidad de realizar cobros con tarjetas de débito y crédito, Yape, PagoEfectivo, billeteras móviles y Cuotéalo con solo unos simples pasos de configuración.
+
+Nuestra biblioteca te da la posibilidad de capturar el `status_code` de la solicitud HTTP que se realiza al API de Culqi, así como el `response` que contiene el cuerpo de la respuesta obtenida.
+
| Versión actual|Culqi API|
|----|----|
-| 1.1.7 (2017-03-16) |[v2](https://culqi.com/api/)|
+| 2.0.4 |[v2.0](https://culqi.com/api/)|
+
## Requisitos
- Java 1.7+
-- Credenciales de comercio en Culqi (1).
+- Afiliate [aquí](https://afiliate.culqi.com/).
+- Si vas a realizar pruebas obtén tus llaves desde [aquí](https://integ-panel.culqi.com/#/registro), si vas a realizar transacciones reales obtén tus llaves desde [aquí](https://panel.culqi.com/#/registro).
+
+> Recuerda que para obtener tus llaves debes ingresar a tu CulqiPanel > Desarrollo > ***API Keys***.
+
+![alt tag](http://i.imgur.com/NhE6mS9.png)
+
+> Recuerda que las credenciales son enviadas al correo que registraste en el proceso de afiliación.
+
+* Para encriptar el payload debes generar un id y llave RSA ingresando a CulqiPanel > Desarrollo > RSA Keys.
+
+## Instalación
-## Ejemplos
+Instalación usando Maven:
+Solo necesita agregar el siguiente repositorio en el archivo pom.xml
-#### Inicialización
+```xml
+
+
+ jitpack.io
+ https://jitpack.io
+
+
+```
+
+Luego agregar la dependencia:
+
+```xml
+
+ com.github.culqi
+ culqi-java
+ v2.0.4
+
+```
+
+## Configuración
+
+Para empezar a enviar peticiones al API de Culqi debes configurar tu llave pública (pk), llave privada (sk).
+Para habilitar encriptación de payload debes configurar tu rsa_id y rsa_public_key.
```java
-Culqi culqi = new Culqi();
-culqi.public_key = "{LLAVE PUBLICA}";
-culqi.secret_key = "{LLAVE SECRETA}"
+culqi.public_key = "pk_test_889113cd74ecfc55";
+culqi.secret_key = "sk_test_LoSAl6rqTInlzPSJ";
+String rsaPublicKey = "-----BEGIN PUBLIC KEY-----\n"
+ + "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDADka0Pt4SuWlHRA6kcJIwDde\n"
+ + "o67OYBEgQDEelmmixs9AlB/1bv446XOOE8eTJSridll2ZAn2nze7Gl2vQs0yW+4A\n"
+ + "XmszJwugM0lxTDiPdTXdbrA4VXiXDG29VLQCAxt1+/c7bE84hMS6cymWgEjYoa6I\n"
+ + "xX8u0ncLyiRUdZC2cwIDAQAB\n"
+ + "-----END PUBLIC KEY-----";
+
+Sring rsaId = "5243bad7-1d88-49c0-9699-f8ae156da58f";
+
+JsonData jsondata = new JsonData();
```
-#### Crear Token
+### Encriptar payload
+
+Para encriptar el payload necesitas pasar como parámetro el rsaPublicKey y rsaId.
+
+Ejemplo
```java
-Map token = new HashMap();
-token.put("card_number", "4111111111111111");
-token.put("cvv", "123");
-token.put("email", "wm@wm.com");
-token.put("expiration_month", 9);
-token.put("expiration_year", 2020);
-Map token_created = culqi.token.create(token);
+protected Map createTokenEncrypt() throws Exception {
+ return init().token.create(jsondata.jsonToken(), rsaPublicKey, rsaId);
+}
+```
+
+
+## Servicios
+
+### Crear Token
+Antes de crear un Cargo o Card es necesario crear un `token` de tarjeta.
+Lo recomendable es generar los 'tokens' con [Culqi Checkout v4](https://docs.culqi.com/es/documentacion/checkout/v4/culqi-checkout/) o [Culqi JS v4](https://docs.culqi.com/es/documentacion/culqi-js/v4/culqi-js/) **debido a que es muy importante que los datos de tarjeta sean enviados desde el dispositivo de tus clientes directamente a los servidores de Culqi**, para no poner en riesgo los datos sensibles de la tarjeta de crédito/débito.
+
+> Recuerda que cuando interactúas directamente con el [API Token](https://apidocs.culqi.com/#tag/Tokens/operation/crear-token) necesitas cumplir la normativa de PCI DSS 3.2. Por ello, te pedimos que llenes el [formulario SAQ-D](https://listings.pcisecuritystandards.org/documents/SAQ_D_v3_Merchant.pdf) y lo envíes al buzón de riesgos Culqi.
+
+```java
+ protected Map createToken() throws Exception {
+ return init().token.create(jsondata.jsonToken());
+ }
```
-#### Crear Cargo
+### Crear Cargo
+
+Crear un cargo significa cobrar una venta a una tarjeta. Para esto previamente deberías generar el `token` y enviarlo en parámetro **source_id**.
+
+Los cargos pueden ser creados vía [API de cargo](https://apidocs.culqi.com/#tag/Cargos/operation/crear-cargo).
```java
-Map charge = new HashMap();
-Map metadata = new HashMap();
-metadata.put("oder_id", "124");
-charge.put("amount",1000);
-charge.put("capture", true);
-charge.put("currency_code",CurrencyCode.PEN);
-charge.put("description","Venta de prueba");
-charge.put("email","test@culqi.com");
-charge.put("installments", 0);
-charge.put("metadata", metadata);
-charge.put("source_id", token_created.get("id").toString());
-Map charge_created = culqi.charge.create(charge);
+protected Map createCharge() throws Exception {
+ String source_id = createToken().get("id").toString();
+ return init().charge.create(jsondata.jsonCharge(source_id));
+}
+```
+Para realizar un cargo recurrente, puedes utilizar el siguiente código:
+
+```java
+protected Map createCharge() throws Exception {
+ String source_id = createToken().get("id").toString();
+ Map customHeaders = new HashMap();
+ customHeaders.put("X-Charge-Channel", "recurrent");
+
+ return init().charge.create(jsondata.jsonCharge(source_id), customHeaders);
+}
```
-#### Crear Plan
+### Crear Devolución
+
+Solicita la devolución de las compras de tus clientes (parcial o total) de forma gratuita a través del API y CulqiPanel.
+
+Las devoluciones pueden ser creados vía [API de devolución](https://apidocs.culqi.com/#tag/Devoluciones/operation/crear-devolucion).
```java
-Map plan = new HashMap();
-Map metadata = new HashMap();
-metadata.put("oder_id", "124");
-plan.put("amount",1000);
-plan.put("currency_code",CurrencyCode.PEN);
-plan.put("interval","dias");
-plan.put("interval_count",30);
-plan.put("limit", 4);
-plan.put("metadata", metadata);
-plan.put("name", "plan-test");
-plan.put("trial_days", 15);
-Map plan_created = culqi.plan.create(plan);
-```
-
-#### Crear Cliente
+protected Map createRefund() throws Exception {
+ String charge_id = createCharge().get("id").toString();
+ return init().refund.create(jsondata.jsonRefund(charge_id));
+}
+```
+
+### Crear Cliente
+
+El **cliente** es un servicio que te permite guardar la información de tus clientes. Es un paso necesario para generar una [tarjeta](/es/documentacion/pagos-online/recurrencia/one-click/tarjetas).
+
+Los clientes pueden ser creados vía [API de cliente](https://apidocs.culqi.com/#tag/Clientes/operation/crear-cliente).
```java
-Map customer = new HashMap();
-customer.put("address","Av Lima 123");
-customer.put("address_city","Lima");
-customer.put("country_code","PE");
-customer.put("email","tst@culqi.com");
-customer.put("first_name","Test");
-customer.put("last_name","Cuqli");
-customer.put("phone_number",99004356);
-Map customer_created = culqi.customer.create(customer);
+ protected Map createCustomer() throws Exception {
+ return init().customer.create(jsondata.jsonCustomer());
+ }
```
-#### Crear Tarjeta
+### Crear Tarjeta
+
+La **tarjeta** es un servicio que te permite guardar la información de las tarjetas de crédito o débito de tus clientes para luego realizarles cargos one click o recurrentes (cargos posteriores sin que tus clientes vuelvan a ingresar los datos de su tarjeta).
+
+Las tarjetas pueden ser creadas vía [API de tarjeta](https://apidocs.culqi.com/#tag/Tarjetas/operation/crear-tarjeta).
```java
-Map card = new HashMap();
-card.put("customer_id",customer_created.get("id").toString());
-card.put("token_id",token_created.get("id").toString());
-Map card_created = culqi.card.create(card);
+protected Map createCard() throws Exception {
+ String customer_id = createCustomer().get("id").toString();
+ String token_id = createToken().get("id").toString();
+ return init().card.create(jsondata.jsonCard(customer_id,token_id));
+}
```
+### Crear Plan
-#### Crear Suscripción
+El plan es un servicio que te permite definir con qué frecuencia deseas realizar cobros a tus clientes.
+
+Un plan define el comportamiento de las suscripciones. Los planes pueden ser creados vía el [API de Plan](https://apidocs.culqi.com/#/planes#create) o desde el **CulqiPanel**.
```java
-Map subscription = new HashMap();
-subscription.put("card_id",card_created.get("id").toString());
-subscription.put("plan_id",plan_created.get("id").toString());
-Map suscription_created = culqi.subscription.create(subscription);
+protected Map createPlan() throws Exception {
+ return init().plan.create(jsondata.jsonPlan());
+}
```
-#### Crear Devolución
+### Crear Suscripción
+
+La suscripción es un servicio que asocia la tarjeta de un cliente con un plan establecido por el comercio.
+
+Las suscripciones pueden ser creadas vía [API de suscripción](https://apidocs.culqi.com/#tag/Suscripciones/operation/crear-suscripcion).
```java
-Map refund = new HashMap();
-refund.put("amount",900);
-refund.put("charge_id",charge_created.get("id").toString());
-refund.put("reason",Reason.solicitud_comprador);
-Map refund_created = culqi.refund.create(refund);
+ protected Map createSubscription() throws Exception {
+ String card_id = createCard().get("id").toString();
+ String plan_id = createPlan().get("id").toString();
+ return init().subscription.create(jsondata.jsonSubscription(card_id, plan_id));
+ }
```
-## Documentación
-¿Necesitas más información para integrar `culqi-java`? La documentación completa se encuentra en [https://culqi.com/docs/](https://culqi.com/docs/)
+### Crear Orden
+Es un servicio que te permite generar una orden de pago para una compra potencial.
+La orden contiene la información necesaria para la venta y es usado por el sistema de **PagoEfectivo** para realizar los pagos diferidos.
-## Changelog
+Las órdenes pueden ser creadas vía [API de orden](https://apidocs.culqi.com/#tag/Ordenes/operation/crear-orden).
-Todos los cambios en las versiones de esta biblioteca están listados en [CHANGELOG](CHANGELOG).
+```java
+ protected Map createSubscription() throws Exception {
+ String card_id = createCard().get("id").toString();
+ String plan_id = createPlan().get("id").toString();
+ return init().subscription.create(jsondata.jsonSubscription(card_id, plan_id));
+ }
+```
-## Dependencias para el desarrollo
-- [okhttp3](http://square.github.io/okhttp/)
-- [Jackson Core Databind](https://github.com/FasterXML/jackson-databind/wiki)
+## Build
+
+```bash
+mvn package -DskipTests
+```
## Testing
@@ -140,18 +223,179 @@ mvn test
Puede ejecutar estos unitarios independientemente
```bash
-mvn test -D test=CulqiCreateTest#test1ValidCreateToken
-mvn test -D test=CulqiCreateTest#test2ValidCreateCharge
-mvn test -D test=CulqiCreateTest#test3ValidCreatePlan
-mvn test -D test=CulqiCreateTest#test4ValidCreateCustomer
-mvn test -D test=CulqiCreateTest#test5ValidCreateCard
-mvn test -D test=CulqiCreateTest#test6ValidCreateSubscription
-mvn test -D test=CulqiCreateTest#test7ChargeCapture
+mvn test -D test=CulqiCreateTest#test01_createToken
+mvn test -D test=CulqiCreateTest#test02_createTokenEncrypt
+mvn test -D test=CulqiCreateTest#test04_createCharge
+mvn test -D test=CulqiCreateTest#test05_createPlan
+mvn test -D test=CulqiCreateTest#test06_createCustomer
+mvn test -D test=CulqiCreateTest#test07_createCard
+mvn test -D test=CulqiCreateTest#test08_createSubscription
+mvn test -D test=CulqiCreateTest#test09_chargeCapture
+```
+
+### Ejemplo Prueba Token
+
+```java
+@Test
+public void test01_createToken() throws Exception {
+ culqiCRUD.createToken().get("object").toString();
+ assertEquals("token", culqiCRUD.createToken().get("object").toString());
+}
+```
+
+### Ejemplo Prueba Cargo
+```java
+@Test
+public void test04_createCharge() throws Exception {
+ assertEquals("charge", culqiCRUD.createCharge().get("object").toString());
+}
+```
+
+## ¿Cómo instalar el jar de Culqi en un proyecto Maven?
+
+```bash
+mvn install:install-file -Dfile={dir}/culqi-java-1.1.8.jar -DgroupId=com.culqi -DartifactId=culqi-java -Dversion={version} -Dpackaging=jar
```
+
+Luego agregas la siguiente dependencia en el pom.xml
+
+```xml
+
+ com.culqi
+ culqi-java
+ {version}
+
+```
+
+## Documentación
+
+- [Referencia de Documentación](https://docs.culqi.com/)
+- [Referencia de API](https://apidocs.culqi.com/)
+- [Demo Checkout V4 + Culqi 3DS](https://github.com/culqi/culqi-java-demo-checkoutv4-culqi3ds)
+- [okhttp3](http://square.github.io/okhttp/)
+- [Jackson Core Databind](https://github.com/FasterXML/jackson-databind/wiki)
+- [Wiki](https://github.com/culqi/culqi-java/wiki)
+
+### Instalar Java
+Descarga Spring Tools Suite 4-4.21.0 archivo del siguiente link:
+
+```bash
+ https://cdn.spring.io/spring-tools/release/STS4/4.21.0.RELEASE/dist/e4.30/spring-tool-suite-4-4.21.0.RELEASE-e4.30.0-linux.gtk.x86_64.tar.gz
+```
+
+### Instalar jdk (Kit de Desarrollo de Java)
+Asegúrate de tener instalado el JDK 8 mediante los siguientes comandos:
+
+```bash
+sudo apt-get update
+sudo apt-get install openjdk-8-jdk
+```
+### Configurar Variables de Entorno para Java y Maven
+Edita el archivo .bashrc con el siguiente comando:
+
+```bash
+ #Abre el archivo .bashrc
+ nano ~/.bashrc
+```
+Añade las siguientes líneas al final del archivo:
+
+```bash
+ #Agrega las siguientes líneas al final del archivo:
+ JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
+ M2_HOME=/usr/share/maven
+ PATH=$PATH:$JAVA_HOME/bin:$M2_HOME/bin
+```
+Guarda los cambios y cierra el editor (Ctrl + o >> Enter >> Ctrl + x).
+
+### Instalar Maven
+Instala Maven con el siguiente comando
+
+```bash
+sudo apt-get install maven
+```
+
+
+### Como abrir el archvio SDK
+
+Abre Spring Tools Suite y selecciona:
+```bash
+ FILE >> IMPORT >> MAVEN >> EXISTING MAVEN PROJECTS
+```
+
+### Instalar Dependencias
+Haz clic derecho en la carpeta raíz del proyecto y selecciona:
+
+```bash
+ RUN AS >> MAVEN CLEAN
+ RUN AS >> MAVEN INSTALL
+```
+
+### Ejecutar Tests
+Haz clic derecho en la carpeta src/test/java y selecciona:
+
+```bash
+ RUN AS >> JUnit Test
+```
+Espera a que se ejecuten todas las pruebas unitarias y, luego, ejecuta cada prueba individualmente según las necesidades.
+
+```bash
+CulqiCreateTest:
+ test05_createPlan
+ test08_createSubscription
+
+CulqiDeleteTest:
+ test01_deleteSubscription
+ test02_deletePlan
+
+CulqiGetTest:
+ test06_findPlan
+ test07_findSubscription
+
+CulqiAllTest:
+ test04_allPlan
+ test06_allSubscriptions
+```
+Click derecho en el nombre del test_0** >> RUN
+
+### Donde Encontrar los ejemplos para Pruebas
+Dentro de la estructura del proyecto, encontrarás ejemplos de pruebas que puedes utilizar para verificar el funcionamiento del SDK. Sigue estos pasos para acceder y ejecutar los ejemplos:
+
+# Ubicación de los Ejemplos:
+* Haz clic derecho en la carpeta src/test/java.
+* Abre el archivo CulqiCRUD.java.
+* En la linea 27 puedes configurar el secreto:
+
+```bash
+ culqi.secret_key = "sk_live_************";
+```
+
+* Haz clic derecho en la carpeta src/test/java.
+* Abre el archivo JsonData.java.
+
+* Ejemplo de JSON:
+En el archivo JsonData.java, encontrarás ejemplos de datos en formato JSON que se utilizan en las pruebas. Puedes modificar estos datos según tus necesidades.
+
+```bash
+php examples/plan/02-create-plan.php
+ Crear Plan: jsonPlan
+ Actualizar Plan: jsonUpdatePlan
+ All Plan: jsonPlanFilter
+
+ Crear Subscription: jsonSubscription
+ Actualizar Subscription: jsonUpdateSubscription
+ All Subscription: jsonListSubscriptions
+```
+Modifica estos ejemplos según tus necesidades y asegúrate de tener configuradas correctamente tus credenciales de Culqi antes de ejecutar las pruebas.
+
+
+## Changelog
+
+Todos los cambios en las versiones de esta biblioteca están listados en [CHANGELOG](CHANGELOG).
+
## Autor
-Willy Aguirre ([@marti1125](https://github.com/marti1125) - Team Culqi)
+Team Culqi
## Licencia
diff --git a/README_EN.md b/README_EN.md
new file mode 100644
index 0000000..130b49a
--- /dev/null
+++ b/README_EN.md
@@ -0,0 +1,218 @@
+# Culqi Java
+
+[![Code Climate](https://codeclimate.com/github/culqi/culqi-java/badges/gpa.svg)](https://codeclimate.com/github/culqi/culqi-java)
+[![Build Status](https://travis-ci.org/culqi/culqi-java.svg?branch=master)](https://travis-ci.org/culqi/culqi-java)
+
+Library of CULQI for the Java language, simple payments in your website. Use the Culqi API.
+
+| Current version |Culqi API|
+|----|----|
+| 3.0.0 |[v3.0](https://culqi.com/api/)|
+
+## Requirements
+
+- Java 1.7+
+- Afiliate [aquí](https://afiliate.culqi.com/).
+- Si vas a realizar pruebas obtén tus llaves desde [aquí](https://integ-panel.culqi.com/#/registro), si vas a realizar transacciones reales obtén tus llaves desde [aquí](https://panel.culqi.com/#/registro).
+
+> Recuerda que para obtener tus llaves debes ingresar a tu CulqiPanel > Desarrollo > ***API Keys***.
+
+![alt tag](http://i.imgur.com/NhE6mS9.png)
+
+> Recuerda que las credenciales son enviadas al correo que registraste en el proceso de afiliación.
+
+## Installation
+
+Installation using Maven:
+Just need to add the following repository in the pom.xml
+
+```xml
+
+
+ jitpack.io
+ https://jitpack.io
+
+
+```
+
+Then add the dependency
+
+```xml
+
+ com.github.culqi
+ culqi-java
+ v1.1.9
+
+```
+
+## Examples
+
+#### Initialization
+
+```java
+Culqi culqi = new Culqi();
+culqi.public_key = "{PUBLIC_KEY}";
+culqi.secret_key = "{SECRET_KEY}"
+```
+
+#### Create Token
+
+```java
+Map token = new HashMap();
+token.put("card_number", "4111111111111111");
+token.put("cvv", "123");
+token.put("email", "wm@wm.com");
+token.put("expiration_month", 9);
+token.put("expiration_year", 2020);
+Map token_created = culqi.token.create(token);
+
+```
+
+#### Create Charge
+
+```java
+Map charge = new HashMap();
+Map antifraudDetails = new HashMap();
+antifraudDetails.put("address", "Calle Narciso de Colina 421 Miraflores");
+antifraudDetails.put("address_city", "LIMA");
+antifraudDetails.put("country_code", "PE");
+antifraudDetails.put("first_name", "Willy");
+antifraudDetails.put("last_name", "Aguirre");
+antifraudDetails.put("phone_number", "012767623");
+Map metadata = new HashMap();
+metadata.put("oder_id", "124");
+charge.put("amount",1000);
+charge.put("capture", true);
+charge.put("currency_code",CurrencyCode.PEN);
+charge.put("description","Sale Test");
+charge.put("email","test@culqi.com");
+charge.put("installments", 0);
+charge.put("antifraud_details", antifraudDetails);
+charge.put("metadata", metadata);
+charge.put("source_id", token_created.get("id").toString());
+Map charge_created = culqi.charge.create(charge);
+
+```
+
+#### Create Plan
+
+```java
+Map plan = new HashMap();
+Map metadata = new HashMap();
+metadata.put("oder_id", "124");
+plan.put("amount",1000);
+plan.put("currency_code",CurrencyCode.PEN);
+plan.put("interval","dias");
+plan.put("interval_count",30);
+plan.put("limit", 4);
+plan.put("metadata", metadata);
+plan.put("name", "plan-test");
+plan.put("trial_days", 15);
+Map plan_created = culqi.plan.create(plan);
+```
+
+#### Create Client
+
+```java
+Map customer = new HashMap();
+customer.put("address","Av Lima 123");
+customer.put("address_city","Lima");
+customer.put("country_code","PE");
+customer.put("email","tst@culqi.com");
+customer.put("first_name","Test");
+customer.put("last_name","Cuqli");
+customer.put("phone_number",99004356);
+Map customer_created = culqi.customer.create(customer);
+```
+
+#### Create Card
+
+```java
+Map card = new HashMap();
+card.put("customer_id",customer_created.get("id").toString());
+card.put("token_id",token_created.get("id").toString());
+Map card_created = culqi.card.create(card);
+```
+
+
+#### Create Subscription
+
+```java
+Map subscription = new HashMap();
+subscription.put("card_id",card_created.get("id").toString());
+subscription.put("plan_id",plan_created.get("id").toString());
+Map suscription_created = culqi.subscription.create(subscription);
+```
+
+#### Create Refund
+
+```java
+Map refund = new HashMap();
+refund.put("amount",900);
+refund.put("charge_id",charge_created.get("id").toString());
+refund.put("reason",Reason.solicitud_comprador);
+Map refund_created = culqi.refund.create(refund);
+```
+
+## Documentation
+Do you need more info about integration `culqi-java` The complete documentation is in [https://culqi.com/docs/](https://culqi.com/docs/)
+
+
+## Changelog
+
+All changes in the version of this library are listed in [CHANGELOG](CHANGELOG).
+
+## Dependence for the development
+
+- [okhttp3](http://square.github.io/okhttp/)
+- [Jackson Core Databind](https://github.com/FasterXML/jackson-databind/wiki)
+
+## Build
+
+```bash
+mvn package -DskipTests
+```
+
+## Testing
+
+You must have installed Maven to run the tests
+
+```bash
+mvn test
+```
+
+You can run these unit tests independently
+
+```bash
+mvn test -D test=CulqiCreateTest#test1ValidCreateToken
+mvn test -D test=CulqiCreateTest#test2ValidCreateCharge
+mvn test -D test=CulqiCreateTest#test3ValidCreatePlan
+mvn test -D test=CulqiCreateTest#test4ValidCreateCustomer
+mvn test -D test=CulqiCreateTest#test5ValidCreateCard
+mvn test -D test=CulqiCreateTest#test6ValidCreateSubscription
+mvn test -D test=CulqiCreateTest#test7ChargeCapture
+```
+
+## How install the Culqi's jar in a Maven project?
+
+```bash
+mvn install:install-file -Dfile={dir}/culqi-java-1.1.8.jar -DgroupId=com.culqi -DartifactId=culqi-java -Dversion={version} -Dpackaging=jar
+```
+
+The add the following dependency in the pom.xml
+
+```xml
+
+ com.culqi
+ culqi-java
+ {version}
+
+```
+
+## Author
+
+Willy Aguirre ([@marti1125](https://github.com/marti1125) - Team Culqi)
+
+## License
+
+The source code of culqi-java is distribuited under MIT License, check the file [LICENSE](https://github.com/culqi/culqi-java/blob/master/LICENSE).
diff --git a/pom.xml b/pom.xml
index 9c27a30..127838c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
com.culqi
culqi-java
- 1.1.7
+ 2.0.4
jar
Culqi Java
@@ -19,6 +19,10 @@
https://github.com/culqi/culqi-java/blob/master/LICENSE
+
+ 8
+ 8
+
Culqi
@@ -27,8 +31,8 @@
- Willy Aguirre
- willy.aguirre@culqi.com
+ José Calderón
+ jose.calderon@culqi.com
Culqi
http://culqi.com/
@@ -46,18 +50,28 @@
+
+ org.bouncycastle
+ bcpkix-jdk15on
+ 1.50
+
+
+ com.google.code.gson
+ gson
+ 2.8.9
+
+
+ org.json
+ json
+ 20230227
+
junit
junit
4.12
test
-
- org.projectlombok
- lombok
- 1.16.12
- provided
-
+
com.squareup.okhttp3
okhttp
@@ -66,7 +80,12 @@
com.fasterxml.jackson.core
jackson-databind
- 2.8.5
+ 2.9.9
+
+
+ org.springframework.data
+ spring-data-commons
+ 2.7.2
@@ -82,25 +101,42 @@
+
-
+
- maven-assembly-plugin
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 2.3
+
package
- single
+ shade
+
+
+
+
+ com.culqi.Culqi
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
-
- jar-with-dependencies
-
+
+ 8
+
+
-
\ No newline at end of file
+
diff --git a/src/main/java/com/culqi/Culqi.java b/src/main/java/com/culqi/Culqi.java
index 63c9eb1..c1da626 100644
--- a/src/main/java/com/culqi/Culqi.java
+++ b/src/main/java/com/culqi/Culqi.java
@@ -1,5 +1,16 @@
package com.culqi;
+import com.culqi.apioperation.service.Card;
+import com.culqi.apioperation.service.Charge;
+import com.culqi.apioperation.service.Customer;
+import com.culqi.apioperation.service.Event;
+import com.culqi.apioperation.service.Iin;
+import com.culqi.apioperation.service.Order;
+import com.culqi.apioperation.service.Plan;
+import com.culqi.apioperation.service.Refund;
+import com.culqi.apioperation.service.Subscription;
+import com.culqi.apioperation.service.Token;
+import com.culqi.apioperation.service.Transfer;
import com.culqi.model.*;
@@ -15,6 +26,8 @@ public class Culqi {
// Resources
public Token token = new Token();
+ public Order order = new Order();
+
public Charge charge = new Charge();
public Customer customer = new Customer();
@@ -35,4 +48,7 @@ public class Culqi {
public Culqi() {}
+ public static void main(String[] args) {
+ }
+
}
diff --git a/src/main/java/com/culqi/apioperation/All.java b/src/main/java/com/culqi/apioperation/All.java
index 7d7e30a..0d2fdef 100644
--- a/src/main/java/com/culqi/apioperation/All.java
+++ b/src/main/java/com/culqi/apioperation/All.java
@@ -1,13 +1,14 @@
package com.culqi.apioperation;
-import java.util.List;
import java.util.Map;
+import com.culqi.model.ResponseCulqi;
+
/**
* Created by culqi on 12/02/17.
*/
public interface All {
- Map list(Map params) throws Exception;
+ ResponseCulqi list(Map params) throws Exception;
}
diff --git a/src/main/java/com/culqi/apioperation/Create.java b/src/main/java/com/culqi/apioperation/Create.java
index 9f59aa3..0dd8ced 100644
--- a/src/main/java/com/culqi/apioperation/Create.java
+++ b/src/main/java/com/culqi/apioperation/Create.java
@@ -2,11 +2,13 @@
import java.util.Map;
+import com.culqi.model.ResponseCulqi;
+
/**
* Created by culqi on 12/02/17.
*/
public interface Create {
- Map create(Map body) throws Exception;
+ ResponseCulqi create(Map body) throws Exception;
}
diff --git a/src/main/java/com/culqi/apioperation/Delete.java b/src/main/java/com/culqi/apioperation/Delete.java
index aa83da6..f5f48d7 100644
--- a/src/main/java/com/culqi/apioperation/Delete.java
+++ b/src/main/java/com/culqi/apioperation/Delete.java
@@ -2,11 +2,13 @@
import java.util.Map;
+import com.culqi.model.ResponseCulqi;
+
/**
* Created by culqi on 12/02/17.
*/
public interface Delete {
- Map delete(String id) throws Exception;
+ ResponseCulqi delete(String id) throws Exception;
}
diff --git a/src/main/java/com/culqi/apioperation/Find.java b/src/main/java/com/culqi/apioperation/Find.java
index 49e9561..8f22c04 100644
--- a/src/main/java/com/culqi/apioperation/Find.java
+++ b/src/main/java/com/culqi/apioperation/Find.java
@@ -2,11 +2,13 @@
import java.util.Map;
+import com.culqi.model.ResponseCulqi;
+
/**
* Created by culqi on 12/02/17.
*/
public interface Find {
- Map get(String id) throws Exception;
+ ResponseCulqi get(String id) throws Exception;
}
diff --git a/src/main/java/com/culqi/apioperation/ObjectResult.java b/src/main/java/com/culqi/apioperation/ObjectResult.java
new file mode 100644
index 0000000..a3a6488
--- /dev/null
+++ b/src/main/java/com/culqi/apioperation/ObjectResult.java
@@ -0,0 +1,102 @@
+package com.culqi.apioperation;
+
+import com.culqi.model.ResponseCulqi;
+import com.culqi.util.EncryptAESRSA;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Created by culqi on 1/16/17.
+ */
+public class ObjectResult {
+
+ public ObjectResult(){}
+
+ ObjectMapper mapper = new ObjectMapper();
+
+ public ResponseCulqi list(String url, Object params) throws Exception {
+ String query = (params != null) ? mapper.writeValueAsString(params) : null;
+ ResponseCulqi response = new ResponseHelper().list(url, query);
+ return response;
+ }
+
+ public ResponseCulqi create(Map body, String url) throws Exception {
+ String jsonData = mapper.writeValueAsString(body);
+ ResponseCulqi response = new ResponseHelper().create(url, jsonData);
+ return response;
+ }
+
+ public ResponseCulqi create (Map body, String url, Map customHeaders) throws Exception {
+ String jsonData = mapper.writeValueAsString(body);
+ ResponseCulqi response = new ResponseHelper().create(url, jsonData, customHeaders);
+ return response;
+ }
+
+ public ResponseCulqi create(Map body, String url, String rsaPublicKey, String rsaId ) throws Exception {
+ String jsonData = mapper.writeValueAsString(body);
+
+ EncryptAESRSA encryptAESRSA = new EncryptAESRSA();
+ jsonData = encryptAESRSA.getJsonEncryptAESRSA(jsonData, rsaPublicKey);
+
+ ResponseCulqi response = new ResponseHelper().create(url, jsonData, rsaId);
+ System.out.println(jsonData);
+ System.out.println(response.getStatusCode());
+ return response;
+ }
+
+ public ResponseCulqi create(Map body, String url, String rsaPublicKey, String rsaId, Map customHeaders ) throws Exception {
+ String jsonData = mapper.writeValueAsString(body);
+
+ EncryptAESRSA encryptAESRSA = new EncryptAESRSA();
+ jsonData = encryptAESRSA.getJsonEncryptAESRSA(jsonData, rsaPublicKey);
+
+ ResponseCulqi response = new ResponseHelper().create(url, jsonData, rsaId, customHeaders);
+ System.out.println(jsonData);
+ System.out.println(response.getStatusCode());
+ return response;
+ }
+
+ public ResponseCulqi update(Map body, String url, String id) throws Exception {
+ String jsonData = mapper.writeValueAsString(body);
+ ResponseCulqi response = new ResponseHelper().update(url, jsonData, id);
+ return response;
+ }
+
+ public ResponseCulqi update(Map body, String url, String id, String rsaPublicKey, String rsaId) throws Exception {
+ String jsonData = mapper.writeValueAsString(body);
+
+ EncryptAESRSA encryptAESRSA = new EncryptAESRSA();
+ jsonData = encryptAESRSA.getJsonEncryptAESRSA(jsonData, rsaPublicKey);
+
+ ResponseCulqi response = new ResponseHelper().update(url, jsonData, id, rsaId);
+ return response;
+ }
+
+ public ResponseCulqi get_or_delete(String url, String id, boolean delete) throws Exception {
+ ResponseCulqi response = new ResponseHelper().get_or_delete(url, id, delete);
+ return response;
+ }
+
+ public ResponseCulqi capture(String url, String id) throws Exception {
+ ResponseCulqi response = new ResponseHelper().capture(url, id);
+ return response;
+ }
+
+ public ResponseCulqi capture(String url, String id, String rsaPublicKey, String rsaId) throws Exception {
+ Map body = new HashMap();
+ String jsonData = mapper.writeValueAsString(body);
+
+ EncryptAESRSA encryptAESRSA = new EncryptAESRSA();
+ jsonData = encryptAESRSA.getJsonEncryptAESRSA(jsonData, rsaPublicKey);
+
+ ResponseCulqi response = new ResponseHelper().capture(url, id, jsonData, rsaId);
+ return response;
+ }
+
+ public ResponseCulqi confirm(String url, String id) throws Exception {
+ ResponseCulqi response = new ResponseHelper().confirm(url, id);
+ return response;
+ }
+}
diff --git a/src/main/java/com/culqi/apioperation/ResponseHelper.java b/src/main/java/com/culqi/apioperation/ResponseHelper.java
new file mode 100644
index 0000000..4cb2ac6
--- /dev/null
+++ b/src/main/java/com/culqi/apioperation/ResponseHelper.java
@@ -0,0 +1,417 @@
+package com.culqi.apioperation;
+
+import com.culqi.Culqi;
+import com.culqi.model.Config;
+import com.culqi.model.ResponseCulqi;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import okhttp3.*;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Created by culqi on 1/16/17.
+ */
+public class ResponseHelper {
+
+ public ResponseHelper(){}
+
+ private static int GENERIC_ERROR = 502;
+ Config config = new Config();
+
+ OkHttpClient client = new OkHttpClient.Builder().connectTimeout(180, TimeUnit.SECONDS)
+ .readTimeout(180, TimeUnit.SECONDS).build();
+
+ public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
+
+ public ResponseCulqi list(String url, String params) {
+ String result = "";
+
+ try {
+ HttpUrl.Builder builder = HttpUrl.parse(Config.API_BASE).newBuilder();
+
+ if (url.contains("plans")) {
+ builder.addPathSegment("recurrent").addPathSegment("plans");
+ } else if (url.contains("subscriptions")) {
+ builder.addPathSegment("recurrent").addPathSegment("subscriptions");
+ } else {
+ String cleanUrl = url.replaceAll("^/+", "").replaceAll("/+$", "");
+ builder.addPathSegments(cleanUrl);
+ }
+
+ if (params != null) {
+ HashMap map = new HashMap();
+ String[] pairs = params.replace("{", "").replace("}", "").split(",");
+
+ for (int i = 0; i < pairs.length; i++) {
+ String pair = pairs[i];
+ String[] keyValue = pair.split(":");
+ map.put(keyValue[0].replace("\"",""), keyValue[1].replace("\"",""));
+ }
+
+ for (Map.Entry entry : map.entrySet()) {
+ builder.addQueryParameter(entry.getKey(), entry.getValue().toString());
+ }
+ }
+
+ String env = Config.X_CULQI_ENV_TEST;
+ if(Culqi.secret_key.contains("live")) {
+ env = Config.X_CULQI_ENV_LIVE;
+ }
+
+ HttpUrl urlquery = builder.build();
+ Request request = new Request.Builder()
+ .url(urlquery)
+ .header("Authorization","Bearer " + Culqi.secret_key)
+ .header("x-culqi-env", env)
+ .header("x-culqi-client", Config.X_CULQI_CLIENT)
+ .header("x-culqi-client-version", Config.X_CULQI_CLIENT_VERSION)
+ .header("x-api-version", Config.X_API_VERSION)
+ .build();
+
+ Response response = client.newCall(request).execute();
+
+ return responseCulqi(response.code(), response.body().string());
+ } catch (IOException e) {
+ result = exceptionError();
+ }
+ return responseCulqi(GENERIC_ERROR, result);
+ }
+
+ public ResponseCulqi create(String url, String jsonData) {
+ String result = "";
+ try {
+ String api_key = url.contains("tokens") || url.contains("confirm") ? Culqi.public_key : Culqi.secret_key;
+
+ String env = Config.X_CULQI_ENV_TEST;
+ if(api_key.contains("live")) {
+ env = Config.X_CULQI_ENV_LIVE;
+ }
+ String base_url = url.contains("tokens") ? config.API_SECURE : config.API_BASE;
+ url = (url.contains("plans") || url.contains("subscriptions")) ? url + "create" : url;
+
+ RequestBody body = RequestBody.create(JSON, jsonData);
+ Request request = new Request.Builder()
+ .url(base_url+url)
+ .header("Authorization", "Bearer " + api_key)
+ .header("Content-Type", "application/json")
+ .header("x-culqi-env", env)
+ .header("x-culqi-client", Config.X_CULQI_CLIENT)
+ .header("x-culqi-client-version", Config.X_CULQI_CLIENT_VERSION)
+ .header("x-api-version", Config.X_API_VERSION)
+ .post(body)
+ .build();
+
+ Response response = client.newCall(request).execute();
+ return responseCulqi(response.code(), response.body().string());
+ } catch (IOException e) {
+ result = exceptionError();
+ }
+ return responseCulqi(GENERIC_ERROR, result);
+ }
+
+ public ResponseCulqi create(String url, String jsonData, Map customHeaders) {
+ String result = "";
+ try {
+ String api_key = url.contains("tokens") || url.contains("confirm") ? Culqi.public_key : Culqi.secret_key;
+ String env = Config.X_CULQI_ENV_TEST;
+ if(api_key.contains("live")) {
+ env = Config.X_CULQI_ENV_LIVE;
+ }
+ String base_url = url.contains("tokens") ? config.API_SECURE : config.API_BASE;
+ url = (url.contains("plans") || url.contains("subscriptions")) ? url + "create" : url;
+ RequestBody body = RequestBody.create(JSON, jsonData);
+ Request.Builder builder = new Request.Builder()
+ .url(base_url+url)
+ .header("Authorization","Bearer " + api_key)
+ .header("Content-Type", "application/json")
+ .header("x-culqi-env", env)
+ .header("x-culqi-client", Config.X_CULQI_CLIENT)
+ .header("x-culqi-client-version", Config.X_CULQI_CLIENT_VERSION)
+ .header("x-api-version", Config.X_API_VERSION)
+ .post(body);
+ builder = addCustomHeadersToRequest(customHeaders, builder);
+ Request request = builder.build();
+ Response response = client.newCall(request).execute();
+ return responseCulqi(response.code(), response.body().string());
+ } catch (IOException e) {
+ result = exceptionError();
+ }
+ return responseCulqi(GENERIC_ERROR, result);
+ }
+
+ public ResponseCulqi create(String url, String jsonData, String rsaId) {
+ String result = "";
+ try {
+ String api_key = url.contains("tokens") || url.contains("confirm") ? Culqi.public_key : Culqi.secret_key;
+ String env = Config.X_CULQI_ENV_TEST;
+ if(api_key.contains("live")) {
+ env = Config.X_CULQI_ENV_LIVE;
+ }
+ String base_url = url.contains("tokens") ? config.API_SECURE : config.API_BASE;
+ url = (url.contains("plans") || url.contains("subscriptions")) ? url + "create" : url;
+ RequestBody body = RequestBody.create(JSON, jsonData);
+ Request request = new Request.Builder()
+ .url(base_url+url)
+ .header("Authorization","Bearer " + api_key)
+ .header("Content-Type", "application/json")
+ .header("x-culqi-rsa-id", rsaId)
+ .header("x-culqi-env", env)
+ .header("x-culqi-client", Config.X_CULQI_CLIENT)
+ .header("x-culqi-client-version", Config.X_CULQI_CLIENT_VERSION)
+ .header("x-api-version", Config.X_API_VERSION)
+ .post(body)
+ .build();
+ Response response = client.newCall(request).execute();
+ return responseCulqi(response.code(), response.body().string());
+ } catch (IOException e) {
+ result = exceptionError();
+ }
+ return responseCulqi(GENERIC_ERROR, result);
+ }
+
+ public ResponseCulqi create(String url, String jsonData, String rsaId, Map customHeaders) {
+ String result = "";
+ try {
+ String api_key = url.contains("tokens") || url.contains("confirm") ? Culqi.public_key : Culqi.secret_key;
+ String env = Config.X_CULQI_ENV_TEST;
+ if(api_key.contains("live")) {
+ env = Config.X_CULQI_ENV_LIVE;
+ }
+ String base_url = url.contains("tokens") ? config.API_SECURE : config.API_BASE;
+ url = (url.contains("plans") || url.contains("subscriptions")) ? url + "create" : url;
+ RequestBody body = RequestBody.create(JSON, jsonData);
+ Request.Builder builder = new Request.Builder()
+ .url(base_url+url)
+ .header("Authorization","Bearer " + api_key)
+ .header("x-culqi-rsa-id", rsaId)
+ .header("x-culqi-env", env)
+ .header("Content-Type", "application/json")
+ .header("Accept", "application/json")
+ .header("x-culqi-client", Config.X_CULQI_CLIENT)
+ .header("x-culqi-client-version", Config.X_CULQI_CLIENT_VERSION)
+ .header("x-api-version", Config.X_API_VERSION)
+ .post(body);
+ builder = addCustomHeadersToRequest(customHeaders, builder);
+ Request request = builder.build();
+ Response response = client.newCall(request).execute();
+ return responseCulqi(response.code(), response.body().string());
+ } catch (IOException e) {
+ result = exceptionError();
+ }
+ return responseCulqi(GENERIC_ERROR, result);
+ }
+
+ public ResponseCulqi update(String url, String jsonData, String id) {
+ String result = "";
+ try {
+ String env = Config.X_CULQI_ENV_TEST;
+ if(Culqi.secret_key.contains("live")) {
+ env = Config.X_CULQI_ENV_LIVE;
+ }
+ System.out.println(config.API_BASE+url+id);
+ RequestBody body = RequestBody.create(JSON, jsonData);
+ Request request = new Request.Builder()
+ .url(config.API_BASE+url+id)
+ .header("Authorization","Bearer " + Culqi.secret_key)
+ .header("x-culqi-env", env)
+ .header("x-culqi-client", Config.X_CULQI_CLIENT)
+ .header("x-culqi-client-version", Config.X_CULQI_CLIENT_VERSION)
+ .header("x-api-version", Config.X_API_VERSION)
+ .patch(body)
+ .build();
+ Response response = client.newCall(request).execute();
+ return responseCulqi(response.code(), response.body().string());
+ } catch (IOException e) {
+ result = exceptionError();
+ }
+ return responseCulqi(GENERIC_ERROR, result);
+ }
+
+ public ResponseCulqi update(String url, String jsonData, String id, String rsaId) {
+ String result = "";
+ try {
+ String env = Config.X_CULQI_ENV_TEST;
+ if(Culqi.secret_key.contains("live")) {
+ env = Config.X_CULQI_ENV_LIVE;
+ }
+ RequestBody body = RequestBody.create(JSON, jsonData);
+ Request request = new Request.Builder()
+ .url(config.API_BASE+url+id)
+ .header("Authorization","Bearer " + Culqi.secret_key)
+ .header("x-culqi-rsa-id", rsaId)
+ .header("x-culqi-env", env)
+ .header("x-culqi-client", Config.X_CULQI_CLIENT)
+ .header("x-culqi-client-version", Config.X_CULQI_CLIENT_VERSION)
+ .header("x-api-version", Config.X_API_VERSION)
+ .patch(body)
+ .build();
+ Response response = client.newCall(request).execute();
+ return responseCulqi(response.code(), response.body().string());
+ } catch (IOException e) {
+ result = exceptionError();
+ }
+ return responseCulqi(GENERIC_ERROR, result);
+ }
+
+ public ResponseCulqi get_or_delete(String url, String id, boolean delete) {
+ String result = "";
+ try {
+ String env = Config.X_CULQI_ENV_TEST;
+ if(Culqi.secret_key.contains("live")) {
+ env = Config.X_CULQI_ENV_LIVE;
+ }
+ Request.Builder builder = new Request.Builder();
+ builder.url(config.API_BASE + url + id);
+ System.out.println(config.API_BASE + url + id);
+ builder.header("Authorization","Bearer " + Culqi.secret_key)
+ .header("x-culqi-env", env)
+ .header("x-culqi-client", Config.X_CULQI_CLIENT)
+ .header("x-culqi-client-version", Config.X_CULQI_CLIENT_VERSION)
+ .header("x-api-version", Config.X_API_VERSION);
+ if (delete) {
+ builder.delete();
+ }
+ Request request = builder.build();
+ Response response = client.newCall(request).execute();
+ return responseCulqi(response.code(), response.body().string());
+ } catch (IOException e) {
+ result = exceptionError();
+ }
+ return responseCulqi(GENERIC_ERROR, result);
+ }
+
+ public ResponseCulqi capture(String url, String id) throws Exception {
+ String result = "";
+ try {
+ String env = Config.X_CULQI_ENV_TEST;
+ if(Culqi.secret_key.contains("live")) {
+ env = Config.X_CULQI_ENV_LIVE;
+ }
+ RequestBody body = RequestBody.create(JSON, "");
+ Request.Builder builder = new Request.Builder();
+ builder.url(config.API_BASE + url + id + "/capture/");
+ builder.header("Authorization", "Bearer " + Culqi.secret_key)
+ .header("x-culqi-env", env)
+ .header("x-culqi-client", Config.X_CULQI_CLIENT)
+ .header("x-culqi-client-version", Config.X_CULQI_CLIENT_VERSION)
+ .header("x-api-version", Config.X_API_VERSION);
+ builder.post(body);
+ Request request = builder.build();
+ Response response = client.newCall(request).execute();
+ return responseCulqi(response.code(), response.body().string());
+ } catch (IOException e) {
+ result = exceptionError();
+ }
+ return responseCulqi(GENERIC_ERROR, result);
+ }
+ public ResponseCulqi capture(String url, String id, String jsonData, String rsaId) throws Exception {
+ String result = "";
+ try {
+ String env = Config.X_CULQI_ENV_TEST;
+ if(Culqi.secret_key.contains("live")) {
+ env = Config.X_CULQI_ENV_LIVE;
+ }
+ RequestBody body = RequestBody.create(JSON, jsonData);
+ Request.Builder builder = new Request.Builder();
+ builder.url(config.API_BASE + url + id + "/capture/");
+ builder.header("Authorization", "Bearer " + Culqi.secret_key)
+ .header("x-culqi-env", env)
+ .header("x-culqi-client", Config.X_CULQI_CLIENT)
+ .header("x-culqi-rsa-id", rsaId)
+ .header("x-culqi-client-version", Config.X_CULQI_CLIENT_VERSION)
+ .header("x-api-version", Config.X_API_VERSION);
+ builder.post(body);
+ Request request = builder.build();
+ Response response = client.newCall(request).execute();
+ return responseCulqi(response.code(), response.body().string());
+ } catch (IOException e) {
+ result = exceptionError();
+ }
+ return responseCulqi(GENERIC_ERROR, result);
+ }
+
+ public ResponseCulqi confirm(String url, String id) throws Exception {
+ String result = "";
+ try {
+ String env = Config.X_CULQI_ENV_TEST;
+ if(Culqi.public_key.contains("live")) {
+ env = Config.X_CULQI_ENV_LIVE;
+ }
+ RequestBody body = RequestBody.create(JSON, "");
+ Request.Builder builder = new Request.Builder();
+ builder.url(config.API_BASE+url+id+"/confirm/");
+ builder.header("Authorization","Bearer " + Culqi.public_key)
+ .header("x-culqi-env", env)
+ .header("x-culqi-client", Config.X_CULQI_CLIENT)
+ .header("x-culqi-client-version", Config.X_CULQI_CLIENT_VERSION)
+ .header("x-api-version", Config.X_API_VERSION);
+ builder.post(body);
+ Request request = builder.build();
+ Response response = client.newCall(request).execute();
+ return responseCulqi(response.code(), response.body().string());
+ } catch (IOException e) {
+ result = exceptionError();
+ }
+ return responseCulqi(GENERIC_ERROR, result);
+ }
+
+ private Request.Builder addCustomHeadersToRequest(Map customHeaders, Request.Builder builder) {
+ for (Map.Entry entry : customHeaders.entrySet()) {
+ System.out.println("Adding header '" + entry.getKey() + "' with value = " + entry.getValue());
+ builder.header(entry.getKey(), entry.getValue());
+ }
+ return builder;
+ }
+
+ private String generateCurlCommand(Request request, String jsonData) {
+ StringBuilder curlCmd = new StringBuilder("curl -X ").append(request.method().toUpperCase() + " ");
+
+ // Añadimos la URL
+ curlCmd.append("\"").append(request.url().toString()).append("\" ");
+
+ // Añadimos los headers
+ for (String headerName : request.headers().names()) {
+ String headerValue = request.header(headerName);
+ curlCmd.append("-H \"").append(headerName).append(": ").append(headerValue).append("\" ");
+ }
+
+ // Añadimos el body (si es necesario)
+ if (jsonData != null && !jsonData.isEmpty()) {
+ curlCmd.append("-d '").append(jsonData).append("' ");
+ }
+
+ return curlCmd.toString();
+ }
+
+ private String exceptionError() {
+ String result = "";
+ Map errorResponse = new HashMap();
+ errorResponse.put("object", "error");
+ errorResponse.put("type", "internal");
+ errorResponse.put("charge_id", "ninguno");
+ errorResponse.put("code", "ninguno");
+ errorResponse.put("decline_code", "ninguno");
+ errorResponse.put("merchant_message", "El tiempo de espera ha sido excedido");
+ errorResponse.put("user_message", "El tiempo de espera ha sido excedido");
+ errorResponse.put("param", "ninguno");
+ try {
+ result = new ObjectMapper().writeValueAsString(errorResponse);
+ } catch (JsonProcessingException jx) {
+
+ }
+ return result;
+ }
+
+ private ResponseCulqi responseCulqi(int statusCode, String body) {
+ ResponseCulqi res = new ResponseCulqi();
+ res.setStatusCode(statusCode);
+ res.setBody(body);
+ System.out.println(res);
+ return res;
+ }
+
+}
diff --git a/src/main/java/com/culqi/apioperation/Update.java b/src/main/java/com/culqi/apioperation/Update.java
index cf729c0..b4fda92 100644
--- a/src/main/java/com/culqi/apioperation/Update.java
+++ b/src/main/java/com/culqi/apioperation/Update.java
@@ -2,11 +2,13 @@
import java.util.Map;
+import com.culqi.model.ResponseCulqi;
+
/**
* Created by culqi on 12/02/17.
*/
public interface Update {
- Map update(Map body, String id) throws Exception;
+ ResponseCulqi update(Map body, String id) throws Exception;
}
diff --git a/src/main/java/com/culqi/apioperation/service/Card.java b/src/main/java/com/culqi/apioperation/service/Card.java
new file mode 100644
index 0000000..88eb485
--- /dev/null
+++ b/src/main/java/com/culqi/apioperation/service/Card.java
@@ -0,0 +1,15 @@
+package com.culqi.apioperation.service;
+
+
+/**
+ * Created by culqi on 12/02/17.
+ */
+public class Card extends Generic {
+
+ private static final String URL = "/cards/";
+
+ public Card() {
+ super(URL);
+ }
+
+}
diff --git a/src/main/java/com/culqi/apioperation/service/Charge.java b/src/main/java/com/culqi/apioperation/service/Charge.java
new file mode 100644
index 0000000..2b7eff0
--- /dev/null
+++ b/src/main/java/com/culqi/apioperation/service/Charge.java
@@ -0,0 +1,26 @@
+package com.culqi.apioperation.service;
+
+import com.culqi.apioperation.ObjectResult;
+import com.culqi.model.ResponseCulqi;
+
+/**
+ * Created by culqi on 12/22/16.
+ */
+
+public class Charge extends Generic {
+
+ private static final String URL = "/charges/";
+
+ public Charge() {
+ super(URL);
+ }
+
+ public ResponseCulqi capture(String id) throws Exception {
+ return new ObjectResult().capture(this.URL, id);
+ }
+
+ public ResponseCulqi capture(String id, String rsaPublicKey, String rsaId) throws Exception {
+ return new ObjectResult().capture(this.URL, id, rsaPublicKey, rsaId);
+ }
+
+}
diff --git a/src/main/java/com/culqi/apioperation/service/Customer.java b/src/main/java/com/culqi/apioperation/service/Customer.java
new file mode 100644
index 0000000..7e218a9
--- /dev/null
+++ b/src/main/java/com/culqi/apioperation/service/Customer.java
@@ -0,0 +1,12 @@
+package com.culqi.apioperation.service;
+
+
+public class Customer extends Generic {
+
+ private static final String URL = "/customers/";
+
+ public Customer() {
+ super(URL);
+ }
+
+}
diff --git a/src/main/java/com/culqi/apioperation/service/Event.java b/src/main/java/com/culqi/apioperation/service/Event.java
new file mode 100644
index 0000000..13c3de7
--- /dev/null
+++ b/src/main/java/com/culqi/apioperation/service/Event.java
@@ -0,0 +1,12 @@
+package com.culqi.apioperation.service;
+
+
+public class Event extends Generic {
+
+ private static final String URL = "/events/";
+
+ public Event() {
+ super(URL);
+ }
+
+}
diff --git a/src/main/java/com/culqi/apioperation/service/Generic.java b/src/main/java/com/culqi/apioperation/service/Generic.java
new file mode 100644
index 0000000..7e5f875
--- /dev/null
+++ b/src/main/java/com/culqi/apioperation/service/Generic.java
@@ -0,0 +1,234 @@
+package com.culqi.apioperation.service;
+
+import java.io.IOException;
+import java.util.Map;
+
+import com.culqi.apioperation.All;
+import com.culqi.apioperation.Create;
+import com.culqi.apioperation.Find;
+import com.culqi.apioperation.ObjectResult;
+import com.culqi.model.ResponseCulqi;
+import com.culqi.util.validation.*;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class Generic implements All, Create, Find {
+
+ private String URL = "";
+
+ public Generic(String url) {
+ this.URL = url;
+ }
+
+ ObjectMapper mapper = new ObjectMapper();
+
+ public ResponseCulqi list(Map params) throws Exception {
+ params = (params == null || params.size() == 0) ? null : params;
+ Map validationResponse = verifyClassValidationList(params, this.URL);
+ if (validationResponse != null) {
+ ResponseCulqi response = new ResponseCulqi();
+ response.setStatusCode(400);
+ response.setBody(mapper.writeValueAsString(validationResponse));
+ return response;
+ }
+
+ String url = this.URL;
+ if (!url.contains("plans") || !url.contains("subscriptions")) {
+ url.replace("/", "");
+ }
+
+ return new ObjectResult().list(url, params);
+ }
+
+ public ResponseCulqi list() throws Exception {
+ return new ObjectResult().list(this.URL.replace("/",""), null);
+ }
+
+ public ResponseCulqi create(Map body) throws Exception {
+ Map validationResponse = verifyClassValidationCreate(body, this.URL);
+ if (validationResponse != null) {
+ ResponseCulqi response = new ResponseCulqi();
+ response.setStatusCode(400);
+ response.setBody(mapper.writeValueAsString(validationResponse));
+ return response;
+ }
+ return new ObjectResult().create(body, this.URL);
+ }
+
+ public ResponseCulqi create(Map body, Map customHeaders ) throws Exception {
+ Map validationResponse = verifyClassValidationCreate(body, this.URL);
+ if (validationResponse != null) {
+ ResponseCulqi response = new ResponseCulqi();
+ response.setStatusCode(400);
+ response.setBody(mapper.writeValueAsString(validationResponse));
+ return response;
+ }
+ return new ObjectResult().create(body, this.URL, customHeaders);
+ }
+
+ public ResponseCulqi create(Map body, String rsaPublicKey, String rsaId) throws Exception {
+ return new ObjectResult().create(body, this.URL, rsaPublicKey, rsaId);
+ }
+
+ public ResponseCulqi create(Map body, String rsaPublicKey, String rsaId, Map customHeaders ) throws Exception {
+ return new ObjectResult().create(body, this.URL, rsaPublicKey, rsaId, customHeaders);
+ }
+
+ public ResponseCulqi get(String id) throws Exception {
+ Map validationResponse = verifyClassValidationUpdate(id, this.URL);
+ if (validationResponse != null) {
+ ResponseCulqi response = new ResponseCulqi();
+ response.setStatusCode(400);
+ response.setBody(mapper.writeValueAsString(validationResponse));
+ return response;
+ }
+ return new ObjectResult().get_or_delete(this.URL, id, false);
+ }
+
+ public ResponseCulqi update(Map body, String id) throws Exception {
+ Map validationResponse = validatePayloadUpdate(id, this.URL, body);
+ if (validationResponse != null) {
+ ResponseCulqi response = new ResponseCulqi();
+ response.setStatusCode(400);
+ response.setBody(mapper.writeValueAsString(validationResponse));
+ return response;
+ }
+ return new ObjectResult().update(body, this.URL, id);
+ }
+
+ public ResponseCulqi update(Map body, String id, String rsaPublicKey, String rsaId)
+ throws Exception {
+ Map validationResponse = validatePayloadUpdate(id, this.URL, body);
+ if (validationResponse != null) {
+ ResponseCulqi response = new ResponseCulqi();
+ response.setStatusCode(400);
+ response.setBody(mapper.writeValueAsString(validationResponse));
+ return response;
+ }
+ return new ObjectResult().update(body, this.URL, id, rsaPublicKey, rsaId);
+ }
+
+ public ResponseCulqi delete(String id) throws Exception {
+ Map validationResponse = verifyClassValidationUpdate(id, this.URL);
+ if (validationResponse != null) {
+ ResponseCulqi response = new ResponseCulqi();
+ response.setStatusCode(400);
+ response.setBody(mapper.writeValueAsString(validationResponse));
+ return response;
+ }
+ return new ObjectResult().get_or_delete(this.URL, id, true);
+ }
+
+ private static Map verifyClassValidationCreate(Map body, String url) throws Exception {
+ try {
+ if (url.contains("tokens")) {
+ TokenValidation.create(body);
+ }
+ if (url.contains("charges")) {
+ ChargeValidation.create(body);
+ }
+ if (url.contains("refunds")) {
+ RefundValidation.create(body);
+ }
+ if (url.contains("plans")) {
+ PlanValidation.create(body);
+ }
+ if (url.contains("customers")) {
+ CustomerValidation.create(body);
+ }
+ if (url.contains("cards")) {
+ CardValidation.create(body);
+ }
+ if (url.contains("subscriptions")) {
+ SubscriptionValidation.create(body);
+ }
+ if (url.contains("orders")) {
+ OrderValidation.create(body);
+ }
+ } catch (CustomException e) {
+ return e.getErrorData();
+ }
+ return null;
+ }
+
+ private static Map validatePayloadUpdate(String id, String url, Map body)
+ throws Exception {
+ try {
+ if (url.contains("plans")) {
+ Helper.validateStringStart(id, "pln");
+ PlanValidation.update(body);
+ }
+ if (url.contains("subscriptions")) {
+ Helper.validateStringStart(id, "sxn");
+ SubscriptionValidation.update(body);
+ }
+ } catch (CustomException e) {
+ return e.getErrorData();
+ }
+ return null;
+ }
+
+ private static Map verifyClassValidationUpdate(String id, String url) throws Exception {
+ try {
+ if (url.contains("tokens")) {
+ Helper.validateStringStart(id, "tkn");
+ }
+ if (url.contains("charges")) {
+ Helper.validateStringStart(id, "chr");
+ }
+ if (url.contains("refunds")) {
+ Helper.validateStringStart(id, "ref");
+ }
+ if (url.contains("plans")) {
+ Helper.validateStringStart(id, "pln");
+ }
+ if (url.contains("customers")) {
+ Helper.validateStringStart(id, "cus");
+ }
+ if (url.contains("cards")) {
+ Helper.validateStringStart(id, "crd");
+ }
+ if (url.contains("subscriptions")) {
+ Helper.validateStringStart(id, "sxn");
+ }
+ if (url.contains("orders")) {
+ Helper.validateStringStart(id, "ord");
+ }
+ } catch (CustomException e) {
+ return e.getErrorData();
+ }
+ return null;
+ }
+
+ private static Map verifyClassValidationList(Map params, String url) throws Exception {
+ try {
+ if (url.contains("tokens")) {
+ TokenValidation.list(params);
+ }
+ if (url.contains("charges")) {
+ ChargeValidation.list(params);
+ }
+ if (url.contains("refunds")) {
+ RefundValidation.list(params);
+ }
+ if (url.contains("plans")) {
+ PlanValidation.list(params);
+ }
+ if (url.contains("customers")) {
+ CustomerValidation.list(params);
+ }
+ if (url.contains("cards")) {
+ CardValidation.list(params);
+ }
+ if (url.contains("subscriptions")) {
+ SubscriptionValidation.list(params);
+ }
+ if (url.contains("orders")) {
+ OrderValidation.list(params);
+ }
+ } catch (CustomException e) {
+ return e.getErrorData();
+ }
+ return null; // No validation errors
+ }
+
+}
diff --git a/src/main/java/com/culqi/apioperation/service/Iin.java b/src/main/java/com/culqi/apioperation/service/Iin.java
new file mode 100644
index 0000000..1bfbd6b
--- /dev/null
+++ b/src/main/java/com/culqi/apioperation/service/Iin.java
@@ -0,0 +1,11 @@
+package com.culqi.apioperation.service;
+
+
+public class Iin extends Generic {
+
+ private static final String URL = "/iins/";
+
+ public Iin() {
+ super(URL);
+ }
+}
diff --git a/src/main/java/com/culqi/apioperation/service/Order.java b/src/main/java/com/culqi/apioperation/service/Order.java
new file mode 100644
index 0000000..703812b
--- /dev/null
+++ b/src/main/java/com/culqi/apioperation/service/Order.java
@@ -0,0 +1,55 @@
+package com.culqi.apioperation.service;
+
+import java.util.Map;
+
+import com.culqi.apioperation.ObjectResult;
+import com.culqi.model.ResponseCulqi;
+import com.culqi.util.validation.CustomException;
+import com.culqi.util.validation.Helper;
+import com.culqi.util.validation.TokenValidation;
+
+/**
+ * Created by culqi on 12/22/16.
+ */
+
+public class Order extends Generic {
+
+ private static final String URL = "/orders/";
+
+ public Order() {
+ super(URL);
+ }
+
+ public ResponseCulqi confirm(String id) throws Exception {
+ Map validationResponse = verifyClassValidationConfirm(id);
+ if (validationResponse != null) {
+ ResponseCulqi response = new ResponseCulqi();
+ response.setStatusCode(400);
+ response.setBody(mapper.writeValueAsString(validationResponse));
+ return response;
+ }
+ return new ObjectResult().confirm(this.URL, id);
+ }
+
+ public ResponseCulqi confirm_order_type(Map body) throws Exception {
+ String id = (String)body.get("order_id");
+ Map validationResponse = verifyClassValidationConfirm(id);
+ if (validationResponse != null) {
+ ResponseCulqi response = new ResponseCulqi();
+ response.setStatusCode(400);
+ response.setBody(mapper.writeValueAsString(validationResponse));
+ return response;
+ }
+ return new ObjectResult().create(body, this.URL+"confirm");
+ }
+
+ private static Map verifyClassValidationConfirm(String id) throws Exception {
+ try {
+ Helper.validateStringStart(id, "ord");
+ } catch (CustomException e) {
+ return e.getErrorData();
+ }
+ return null;
+ }
+
+}
diff --git a/src/main/java/com/culqi/apioperation/service/Plan.java b/src/main/java/com/culqi/apioperation/service/Plan.java
new file mode 100644
index 0000000..7ec23ed
--- /dev/null
+++ b/src/main/java/com/culqi/apioperation/service/Plan.java
@@ -0,0 +1,11 @@
+package com.culqi.apioperation.service;
+
+
+public class Plan extends Generic {
+
+ private static final String URL = "/recurrent/plans/";
+
+ public Plan() {
+ super(URL);
+ }
+}
diff --git a/src/main/java/com/culqi/apioperation/service/Refund.java b/src/main/java/com/culqi/apioperation/service/Refund.java
new file mode 100644
index 0000000..f15be3c
--- /dev/null
+++ b/src/main/java/com/culqi/apioperation/service/Refund.java
@@ -0,0 +1,11 @@
+package com.culqi.apioperation.service;
+
+public class Refund extends Generic {
+
+ private static final String URL = "/refunds/";
+
+ public Refund() {
+ super(URL);
+ }
+
+}
diff --git a/src/main/java/com/culqi/apioperation/service/Subscription.java b/src/main/java/com/culqi/apioperation/service/Subscription.java
new file mode 100644
index 0000000..6914407
--- /dev/null
+++ b/src/main/java/com/culqi/apioperation/service/Subscription.java
@@ -0,0 +1,11 @@
+package com.culqi.apioperation.service;
+
+public class Subscription extends Generic {
+
+ private static final String URL = "/recurrent/subscriptions/";
+
+ public Subscription() {
+ super(URL);
+ }
+
+}
diff --git a/src/main/java/com/culqi/apioperation/service/Token.java b/src/main/java/com/culqi/apioperation/service/Token.java
new file mode 100644
index 0000000..16a0ad0
--- /dev/null
+++ b/src/main/java/com/culqi/apioperation/service/Token.java
@@ -0,0 +1,42 @@
+package com.culqi.apioperation.service;
+
+import java.util.Map;
+
+import com.culqi.apioperation.ObjectResult;
+import com.culqi.model.ResponseCulqi;
+import com.culqi.util.validation.*;
+
+/**
+ * Created by culqi on 12/21/16.
+ */
+
+public class Token extends Generic {
+
+ private static final String URL = "/tokens/";
+ private static final String URL_YAPE = "/tokens/yape";
+
+ public Token() {
+ super(URL);
+ }
+
+ public ResponseCulqi createYape(Map body) throws Exception {
+ Map validationResponse = verifyClassValidationYape(body);
+ if (validationResponse != null) {
+ ResponseCulqi response = new ResponseCulqi();
+ response.setStatusCode(400);
+ response.setBody(mapper.writeValueAsString(validationResponse));
+ return response;
+ }
+ return new ObjectResult().create(body, this.URL_YAPE);
+ }
+
+ private static Map verifyClassValidationYape(Map body) throws Exception {
+ try {
+ TokenValidation.createTokenYapeValidation(body);
+ } catch (CustomException e) {
+ return e.getErrorData();
+ }
+ return null;
+ }
+
+}
diff --git a/src/main/java/com/culqi/apioperation/service/Transfer.java b/src/main/java/com/culqi/apioperation/service/Transfer.java
new file mode 100644
index 0000000..cc41964
--- /dev/null
+++ b/src/main/java/com/culqi/apioperation/service/Transfer.java
@@ -0,0 +1,11 @@
+package com.culqi.apioperation.service;
+
+public class Transfer extends Generic {
+
+ private static final String URL = "/transfers/";
+
+ public Transfer() {
+ super(URL);
+ }
+
+}
diff --git a/src/main/java/com/culqi/model/Card.java b/src/main/java/com/culqi/model/Card.java
deleted file mode 100644
index f09500d..0000000
--- a/src/main/java/com/culqi/model/Card.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.culqi.model;
-
-import com.culqi.apioperation.*;
-import com.culqi.util.ObjectResult;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Created by culqi on 12/02/17.
- */
-public class Card implements All, Create, Delete, Find, Update {
-
- private static final String URL = "/cards/";
-
- public Map list(Map params) throws Exception {
- params = (params == null || params.size() == 0) ? null: params;
- return new ObjectResult().list(this.URL, params);
- }
-
- public Map list() throws Exception {
- return new ObjectResult().list(this.URL, null);
- }
-
- public Map create(Map body) throws Exception {
- return new ObjectResult().create(body, this.URL);
- }
-
- public Map get(String id) throws Exception {
- return new ObjectResult().get_or_delete(this.URL, id, false);
- }
-
- public Map delete(String id) throws Exception {
- return new ObjectResult().get_or_delete(this.URL, id, true);
- }
-
- public Map update(Map body, String id) throws Exception {
- return new ObjectResult().update(body, this.URL, id);
- }
-
-}
diff --git a/src/main/java/com/culqi/model/Charge.java b/src/main/java/com/culqi/model/Charge.java
deleted file mode 100644
index 23b0e94..0000000
--- a/src/main/java/com/culqi/model/Charge.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package com.culqi.model;
-
-import com.culqi.apioperation.All;
-import com.culqi.apioperation.Create;
-import com.culqi.apioperation.Find;
-import com.culqi.apioperation.Update;
-import com.culqi.util.ObjectResult;
-
-import java.util.Map;
-
-/**
- * Created by culqi on 12/22/16.
- */
-
-public class Charge implements All, Create, Find, Update {
-
- private static final String URL = "/charges/";
-
- public Map list(Map params) throws Exception {
- params = (params == null || params.size() == 0) ? null: params;
- return new ObjectResult().list(this.URL, params);
- }
-
- public Map list() throws Exception {
- return new ObjectResult().list(this.URL, null);
- }
-
- public Map create(Map body) throws Exception {
- return new ObjectResult().create(body, this.URL);
- }
-
- public Map get(String id) throws Exception {
- return new ObjectResult().get_or_delete(this.URL, id, false);
- }
-
- public Map update(Map body, String id) throws Exception {
- return new ObjectResult().update(body, this.URL, id);
- }
-
- public Map capture(String id) throws Exception {
- return new ObjectResult().capture(this.URL, id);
- }
-
-}
diff --git a/src/main/java/com/culqi/model/Config.java b/src/main/java/com/culqi/model/Config.java
index 1df025c..f9cf616 100644
--- a/src/main/java/com/culqi/model/Config.java
+++ b/src/main/java/com/culqi/model/Config.java
@@ -6,9 +6,16 @@
public class Config {
public static final String API_BASE = "https://api.culqi.com/v2";
+ public static final String API_SECURE = "https://secure.culqi.com/v2";
public static final String DOMAIN = "api.culqi.com";
public static final String PATH = "/v2";
+
+ public static final String X_CULQI_ENV_TEST = "test";
+ public static final String X_CULQI_ENV_LIVE = "live";
+ public static final String X_API_VERSION = "2";
+ public static final String X_CULQI_CLIENT = "culqi-java";
+ public static final String X_CULQI_CLIENT_VERSION = "2.0.4";
}
diff --git a/src/main/java/com/culqi/model/Customer.java b/src/main/java/com/culqi/model/Customer.java
deleted file mode 100644
index 021b1e0..0000000
--- a/src/main/java/com/culqi/model/Customer.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.culqi.model;
-
-import com.culqi.apioperation.*;
-import com.culqi.util.ObjectResult;
-
-import java.util.Map;
-
-/**
- * Created by culqi on 12/02/17.
- */
-public class Customer implements All, Create, Find, Update, Delete {
-
- private static final String URL = "/customers/";
-
- public Map list(Map params) throws Exception {
- params = (params == null || params.size() == 0) ? null: params;
- return new ObjectResult().list(this.URL, params);
- }
-
- public Map list() throws Exception {
- return new ObjectResult().list(this.URL, null);
- }
-
- public Map create(Map body) throws Exception {
- return new ObjectResult().create(body, this.URL);
- }
-
- public Map get(String id) throws Exception {
- return new ObjectResult().get_or_delete(this.URL, id, false);
- }
-
- public Map update(Map body, String id) throws Exception {
- return new ObjectResult().update(body, this.URL, id);
- }
-
- public Map delete(String id) throws Exception {
- return new ObjectResult().get_or_delete(this.URL, id, true);
- }
-
-}
diff --git a/src/main/java/com/culqi/model/Event.java b/src/main/java/com/culqi/model/Event.java
deleted file mode 100644
index 14bfef0..0000000
--- a/src/main/java/com/culqi/model/Event.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.culqi.model;
-
-import com.culqi.apioperation.All;
-import com.culqi.apioperation.Find;
-import com.culqi.util.ObjectResult;
-
-import java.util.Map;
-
-/**
- * Created by culqi on 12/02/17.
- */
-public class Event implements All, Find {
-
- private static final String URL = "/events/";
-
- public Map list(Map params) throws Exception {
- params = (params == null || params.size() == 0) ? null: params;
- return new ObjectResult().list(this.URL, params);
- }
-
- public Map list() throws Exception {
- return new ObjectResult().list(this.URL, null);
- }
-
- public Map get(String id) throws Exception {
- return new ObjectResult().get_or_delete(this.URL, id, false);
- }
-
-}
diff --git a/src/main/java/com/culqi/model/Iin.java b/src/main/java/com/culqi/model/Iin.java
deleted file mode 100644
index 3c2f12f..0000000
--- a/src/main/java/com/culqi/model/Iin.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.culqi.model;
-
-import com.culqi.apioperation.All;
-import com.culqi.apioperation.Find;
-import com.culqi.util.ObjectResult;
-
-import java.util.Map;
-
-/**
- * Created by culqi on 1/25/17.
- */
-public class Iin implements All, Find {
-
- private static final String URL = "/iins/";
-
- public Map list(Map params) throws Exception {
- params = (params == null || params.size() == 0) ? null: params;
- return new ObjectResult().list(this.URL, params);
- }
-
- public Map list() throws Exception {
- return new ObjectResult().list(this.URL, null);
- }
-
- public Map get(String id) throws Exception {
- return new ObjectResult().get_or_delete(this.URL, id, false);
- }
-}
diff --git a/src/main/java/com/culqi/model/Plan.java b/src/main/java/com/culqi/model/Plan.java
deleted file mode 100644
index fc698b1..0000000
--- a/src/main/java/com/culqi/model/Plan.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.culqi.model;
-
-import com.culqi.apioperation.*;
-import com.culqi.util.ObjectResult;
-
-import java.util.Map;
-
-/**
- * Created by culqi on 12/22/16.
- */
-
-public class Plan implements All, Create, Find, Update, Delete {
-
- private static final String URL = "/plans/";
-
- public Map list(Map params) throws Exception {
- params = (params == null || params.size() == 0) ? null: params;
- return new ObjectResult().list(this.URL, params);
- }
-
- public Map list() throws Exception {
- return new ObjectResult().list(this.URL, null);
- }
-
- public Map create(Map body) throws Exception {
- return new ObjectResult().create(body, this.URL);
- }
-
- public Map get(String id) throws Exception {
- return new ObjectResult().get_or_delete(this.URL, id, false);
- }
-
- public Map update(Map body, String id) throws Exception {
- return new ObjectResult().update(body, this.URL, id);
- }
-
-
- public Map delete(String id) throws Exception {
- return new ObjectResult().get_or_delete(this.URL, id, true);
- }
-}
diff --git a/src/main/java/com/culqi/model/Refund.java b/src/main/java/com/culqi/model/Refund.java
deleted file mode 100644
index 52a26d7..0000000
--- a/src/main/java/com/culqi/model/Refund.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.culqi.model;
-
-import com.culqi.apioperation.All;
-import com.culqi.apioperation.Create;
-import com.culqi.apioperation.Find;
-import com.culqi.apioperation.Update;
-import com.culqi.util.ObjectResult;
-
-import java.util.Map;
-
-/**
- * Created by culqi on 12/23/16.
- */
-
-public class Refund implements All, Create, Find, Update {
-
- private static final String URL = "/refunds/";
-
- public Map list(Map params) throws Exception {
- params = (params == null || params.size() == 0) ? null: params;
- return new ObjectResult().list(this.URL, params);
- }
-
- public Map list() throws Exception {
- return new ObjectResult().list(this.URL, null);
- }
-
- public Map create(Map body) throws Exception {
- return new ObjectResult().create(body, this.URL);
- }
-
- public Map get(String id) throws Exception {
- return new ObjectResult().get_or_delete(this.URL, id, false);
- }
-
- public Map update(Map body, String id) throws Exception {
- return new ObjectResult().update(body, this.URL, id);
- }
-
-}
diff --git a/src/main/java/com/culqi/model/ResponseCulqi.java b/src/main/java/com/culqi/model/ResponseCulqi.java
new file mode 100644
index 0000000..7f358bd
--- /dev/null
+++ b/src/main/java/com/culqi/model/ResponseCulqi.java
@@ -0,0 +1,37 @@
+package com.culqi.model;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class ResponseCulqi {
+
+ private int statusCode;
+ private String body;
+
+
+ public ResponseCulqi() {
+
+ }
+ public int getStatusCode() {
+ return statusCode;
+ }
+ public void setStatusCode(int statusCode) {
+ this.statusCode = statusCode;
+ }
+ public String getBody() {
+ return body;
+ }
+ public void setBody(String body) {
+ this.body = body;
+ }
+
+
+ @Override
+ public String toString() {
+ return "ResponseCulqi [statusCode=" + statusCode + ", body=" + body + "]";
+ }
+
+
+
+
+}
diff --git a/src/main/java/com/culqi/model/Subscription.java b/src/main/java/com/culqi/model/Subscription.java
deleted file mode 100644
index a4f7029..0000000
--- a/src/main/java/com/culqi/model/Subscription.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.culqi.model;
-
-import com.culqi.apioperation.*;
-import com.culqi.util.ObjectResult;
-
-import java.util.Map;
-
-/**
- * Created by culqi on 12/23/16.
- */
-
-public class Subscription implements All, Create, Find, Delete, Update {
-
- private static final String URL = "/subscriptions/";
-
- public Map list(Map params) throws Exception {
- params = (params == null || params.size() == 0) ? null: params;
- return new ObjectResult().list(this.URL, params);
- }
-
- public Map list() throws Exception {
- return new ObjectResult().list(this.URL, null);
- }
-
- public Map create(Map body) throws Exception {
- return new ObjectResult().create(body, this.URL);
- }
-
- public Map get(String id) throws Exception {
- return new ObjectResult().get_or_delete(this.URL, id, false);
- }
-
- public Map delete(String id) throws Exception {
- return new ObjectResult().get_or_delete(this.URL, id, true);
- }
-
- public Map update(Map body, String id) throws Exception {
- return new ObjectResult().update(body, this.URL, id);
- }
-
-}
diff --git a/src/main/java/com/culqi/model/Token.java b/src/main/java/com/culqi/model/Token.java
deleted file mode 100644
index a08f113..0000000
--- a/src/main/java/com/culqi/model/Token.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.culqi.model;
-
-import com.culqi.apioperation.All;
-import com.culqi.apioperation.Create;
-import com.culqi.apioperation.Find;
-import com.culqi.util.ObjectResult;
-
-import java.util.Map;
-
-/**
- * Created by culqi on 12/21/16.
- */
-
-public class Token implements All, Create, Find {
-
- private static final String URL = "/tokens/";
-
- public Map list(Map params) throws Exception {
- params = (params == null || params.size() == 0) ? null: params;
- return new ObjectResult().list(this.URL, params);
- }
-
- public Map list() throws Exception {
- return new ObjectResult().list(this.URL, null);
- }
-
- public Map create(Map body) throws Exception {
- return new ObjectResult().create(body, this.URL);
- }
-
- public Map get(String id) throws Exception {
- return new ObjectResult().get_or_delete(this.URL, id, false);
- }
-
-}
diff --git a/src/main/java/com/culqi/model/Transfer.java b/src/main/java/com/culqi/model/Transfer.java
deleted file mode 100644
index 76c113a..0000000
--- a/src/main/java/com/culqi/model/Transfer.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.culqi.model;
-
-import com.culqi.apioperation.All;
-import com.culqi.apioperation.Find;
-import com.culqi.util.ObjectResult;
-
-import java.util.Map;
-
-/**
- * Created by culqi on 1/25/17.
- */
-public class Transfer implements All, Find {
-
- private static final String URL = "/transfers/";
-
- public Map list(Map params) throws Exception {
- params = (params == null || params.size() == 0) ? null: params;
- return new ObjectResult().list(this.URL, params);
- }
-
- public Map list() throws Exception {
- return new ObjectResult().list(this.URL, null);
- }
-
- public Map get(String id) throws Exception {
- return new ObjectResult().get_or_delete(this.URL, id, false);
- }
-
-}
diff --git a/src/main/java/com/culqi/util/AESUtil.java b/src/main/java/com/culqi/util/AESUtil.java
new file mode 100644
index 0000000..1c5de9e
--- /dev/null
+++ b/src/main/java/com/culqi/util/AESUtil.java
@@ -0,0 +1,205 @@
+package com.culqi.util;
+
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.BadPaddingException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.spec.GCMParameterSpec;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.nio.charset.StandardCharsets;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.Arrays;
+import java.util.Base64;
+
+public class AESUtil {
+
+ public static final int GCM_TAG_LENGTH = 16;
+
+ public static String encryptCulqi(String input, SecretKey key, IvParameterSpec iv) throws InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, BadPaddingException, IllegalBlockSizeException {
+ String algorithm = "AES/CBC/PKCS5Padding";
+ return encrypt(algorithm, input, key, iv);
+ }
+
+ public static String encryptCulqiGCM(String input, SecretKey key, GCMParameterSpec iv) throws InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, BadPaddingException, IllegalBlockSizeException {
+ String algorithm = "AES/GCM/NoPadding";
+ return encryptGCM(algorithm, input, key, iv);
+ }
+
+ public static String encrypt(String algorithm, String input, SecretKey key, IvParameterSpec iv)
+ throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException,
+ InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
+ Cipher cipher = Cipher.getInstance(algorithm);
+ cipher.init(Cipher.ENCRYPT_MODE, key, iv);
+ byte[] cipherText = cipher.doFinal(input.getBytes());
+ return Base64.getEncoder()
+ .encodeToString(cipherText);
+ }
+
+ public static String encryptGCM(String algorithm, String input, SecretKey key,GCMParameterSpec iv)
+ throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException,
+ InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
+
+ Cipher cipher = Cipher.getInstance(algorithm);
+ cipher.init(Cipher.ENCRYPT_MODE, key, iv);
+ byte[] cipherText = cipher.doFinal(input.getBytes(StandardCharsets.UTF_8));
+ cipherText = Arrays.copyOfRange(cipherText, 0, cipherText.length - 16);
+
+ // Concatenate the IV and encrypted message
+ //byte[] ivAndEncryptedMessage = new byte[iv.getIV().length + cipherText.length];
+ //System.arraycopy(iv, 0, ivAndEncryptedMessage, 0, 12);
+ //System.arraycopy(encryptedMessage, 0, ivAndEncryptedMessage, iv.length, encryptedMessage.length);
+
+ return Base64.getEncoder()
+ .encodeToString(cipherText);
+ }
+
+ public static String decrypt(String algorithm, String cipherText, SecretKey key, IvParameterSpec iv)
+ throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException,
+ InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
+ Cipher cipher = Cipher.getInstance(algorithm);
+ cipher.init(Cipher.DECRYPT_MODE, key, iv);
+ byte[] plainText = cipher.doFinal(Base64.getDecoder()
+ .decode(cipherText));
+ return new String(plainText);
+ }
+
+ public static String decryptGCM(String algorithm, String cipherText, SecretKey key, GCMParameterSpec iv) throws Exception
+ {
+ // Get Cipher Instance
+ Cipher cipher = Cipher.getInstance(algorithm);
+ // Create SecretKeySpec
+ SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), "AES");
+ // Create GCMParameterSpec
+ //GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(16 * 8, IV);
+
+ // Initialize Cipher for DECRYPT_MODE
+ cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
+
+ byte[] plainText = cipher.doFinal(Base64.getDecoder()
+ .decode(cipherText));
+ return new String(plainText);
+ }
+
+ public static SecretKey generateKey(int n) throws NoSuchAlgorithmException {
+ KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
+ keyGenerator.init(n);
+ SecretKey key = keyGenerator.generateKey();
+ return key;
+ }
+
+ public static IvParameterSpec generateIv() {
+ byte[] iv = new byte[16];
+ new SecureRandom().nextBytes(iv);
+ return new IvParameterSpec(iv);
+ }
+
+ public static GCMParameterSpec generateIvGCM() {
+ byte[] iv = new byte[12];
+ new SecureRandom().nextBytes(iv);
+ return new GCMParameterSpec(GCM_TAG_LENGTH * 8,iv);
+ }
+
+ /*
+ public static SecretKey getKeyFromPassword(String password, String salt)
+ throws NoSuchAlgorithmException, InvalidKeySpecException {
+ SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
+ KeySpec spec = new PBEKeySpec(password.toCharArray(), salt.getBytes(), 65536, 256);
+ SecretKey secret = new SecretKeySpec(factory.generateSecret(spec)
+ .getEncoded(), "AES");
+ return secret;
+ }
+
+ public static void encryptFile(String algorithm, SecretKey key, IvParameterSpec iv,
+ File inputFile, File outputFile) throws IOException, NoSuchPaddingException,
+ NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException,
+ BadPaddingException, IllegalBlockSizeException {
+ Cipher cipher = Cipher.getInstance(algorithm);
+ cipher.init(Cipher.ENCRYPT_MODE, key, iv);
+ FileInputStream inputStream = new FileInputStream(inputFile);
+ FileOutputStream outputStream = new FileOutputStream(outputFile);
+ byte[] buffer = new byte[64];
+ int bytesRead;
+ while ((bytesRead = inputStream.read(buffer)) != -1) {
+ byte[] output = cipher.update(buffer, 0, bytesRead);
+ if (output != null) {
+ outputStream.write(output);
+ }
+ }
+ byte[] outputBytes = cipher.doFinal();
+ if (outputBytes != null) {
+ outputStream.write(outputBytes);
+ }
+ inputStream.close();
+ outputStream.close();
+ }
+
+ public static void decryptFile(String algorithm, SecretKey key, IvParameterSpec iv,
+ File encryptedFile, File decryptedFile) throws IOException, NoSuchPaddingException,
+ NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException,
+ BadPaddingException, IllegalBlockSizeException {
+ Cipher cipher = Cipher.getInstance(algorithm);
+ cipher.init(Cipher.DECRYPT_MODE, key, iv);
+ FileInputStream inputStream = new FileInputStream(encryptedFile);
+ FileOutputStream outputStream = new FileOutputStream(decryptedFile);
+ byte[] buffer = new byte[64];
+ int bytesRead;
+ while ((bytesRead = inputStream.read(buffer)) != -1) {
+ byte[] output = cipher.update(buffer, 0, bytesRead);
+ if (output != null) {
+ outputStream.write(output);
+ }
+ }
+ byte[] output = cipher.doFinal();
+ if (output != null) {
+ outputStream.write(output);
+ }
+ inputStream.close();
+ outputStream.close();
+ }
+
+ public static SealedObject encryptObject(String algorithm, Serializable object, SecretKey key,
+ IvParameterSpec iv) throws NoSuchPaddingException, NoSuchAlgorithmException,
+ InvalidAlgorithmParameterException, InvalidKeyException, IOException, IllegalBlockSizeException {
+ Cipher cipher = Cipher.getInstance(algorithm);
+ cipher.init(Cipher.ENCRYPT_MODE, key, iv);
+ SealedObject sealedObject = new SealedObject(object, cipher);
+ return sealedObject;
+ }
+
+ public static Serializable decryptObject(String algorithm, SealedObject sealedObject, SecretKey key,
+ IvParameterSpec iv) throws NoSuchPaddingException, NoSuchAlgorithmException,
+ InvalidAlgorithmParameterException, InvalidKeyException, ClassNotFoundException,
+ BadPaddingException, IllegalBlockSizeException, IOException {
+ Cipher cipher = Cipher.getInstance(algorithm);
+ cipher.init(Cipher.DECRYPT_MODE, key, iv);
+ Serializable unsealObject = (Serializable) sealedObject.getObject(cipher);
+ return unsealObject;
+ }
+
+ public static String encryptPasswordBased(String plainText, SecretKey key, IvParameterSpec iv)
+ throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException,
+ InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
+ Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+ cipher.init(Cipher.ENCRYPT_MODE, key, iv);
+ return Base64.getEncoder()
+ .encodeToString(cipher.doFinal(plainText.getBytes()));
+ }
+
+ public static String decryptPasswordBased(String cipherText, SecretKey key, IvParameterSpec iv)
+ throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException,
+ InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
+ Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
+ cipher.init(Cipher.DECRYPT_MODE, key, iv);
+ return new String(cipher.doFinal(Base64.getDecoder()
+ .decode(cipherText)));
+ }
+ */
+ ///
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/culqi/util/CountryCodes.java b/src/main/java/com/culqi/util/CountryCodes.java
new file mode 100644
index 0000000..427fbe3
--- /dev/null
+++ b/src/main/java/com/culqi/util/CountryCodes.java
@@ -0,0 +1,32 @@
+package com.culqi.util;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class CountryCodes {
+ /**
+ * Returns a list of country codes.
+ *
+ * @return a list of country codes
+ */
+ public static List getCountryCodes() {
+ return Arrays.asList(
+ "AD", "AE", "AF", "AG", "AI", "AL", "AM", "AO", "AQ", "AR", "AS", "AT", "AU", "AW", "AX", "AZ",
+ "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BL", "BM", "BN", "BO", "BQ", "BR", "BS",
+ "BT", "BV", "BW", "BY", "BZ", "CA", "CC", "CD", "CF", "CG", "CH", "CI", "CK", "CL", "CM", "CN",
+ "CO", "CR", "CU", "CV", "CW", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE",
+ "EG", "EH", "ER", "ES", "ET", "FI", "FJ", "FK", "FM", "FO", "FR", "GA", "GB", "GD", "GE", "GF",
+ "GG", "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", "GW", "GY", "HK", "HM",
+ "HN", "HR", "HT", "HU", "ID", "IE", "IL", "IM", "IN", "IO", "IQ", "IR", "IS", "IT", "JE", "JM",
+ "JO", "JP", "KE", "KG", "KH", "KI", "KM", "KN", "KP", "KR", "KW", "KY", "KZ", "LA", "LB", "LC",
+ "LI", "LK", "LR", "LS", "LT", "LU", "LV", "LY", "MA", "MC", "MD", "ME", "MF", "MG", "MH", "MK",
+ "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA",
+ "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NU", "NZ", "OM", "PA", "PE", "PF", "PG",
+ "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", "PW", "PY", "QA", "RE", "RO", "RS", "RU", "RW",
+ "SA", "SB", "SC", "SD", "SE", "SG", "SH", "SI", "SJ", "SK", "SL", "SM", "SN", "SO", "SR", "SS",
+ "ST", "SV", "SX", "SY", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", "TK", "TL", "TM", "TN", "TO",
+ "TR", "TT", "TV", "TW", "TZ", "UA", "UG", "UM", "US", "UY", "UZ", "VA", "VC", "VE", "VG", "VI",
+ "VN", "VU", "WF", "WS", "YE", "YT", "ZA", "ZM", "ZW"
+ );
+ }
+}
diff --git a/src/main/java/com/culqi/util/EncryptAESRSA.java b/src/main/java/com/culqi/util/EncryptAESRSA.java
new file mode 100644
index 0000000..b6aeea3
--- /dev/null
+++ b/src/main/java/com/culqi/util/EncryptAESRSA.java
@@ -0,0 +1,38 @@
+package com.culqi.util;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.GCMParameterSpec;
+
+import org.json.JSONObject;
+
+public class EncryptAESRSA {
+
+ public String getJsonEncryptAESRSA(String input, String rsaPublicKey) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, InvalidAlgorithmParameterException, BadPaddingException, IllegalBlockSizeException {
+
+ JSONObject jsonObject = new JSONObject();
+
+ SecretKey key = AESUtil.generateKey(256);
+ //IvParameterSpec ivParameterSpec = AESUtil.generateIv();
+ GCMParameterSpec gcmParameterSpec = AESUtil.generateIvGCM();
+
+ String encryptedData = AESUtil.encryptCulqiGCM(input, key, gcmParameterSpec);
+
+ RSAUtil rsaUtil = new RSAUtil();
+
+ String encryptedKey = rsaUtil.encriptarByte(key.getEncoded(), rsaPublicKey);
+ String encryptedIv = rsaUtil.encriptarByte(gcmParameterSpec.getIV(), rsaPublicKey);
+
+ jsonObject.put("encrypted_data", encryptedData);
+ jsonObject.put("encrypted_key", encryptedKey);
+ jsonObject.put("encrypted_iv", encryptedIv);
+
+ return jsonObject.toString();
+ }
+}
diff --git a/src/main/java/com/culqi/util/ObjectResult.java b/src/main/java/com/culqi/util/ObjectResult.java
deleted file mode 100644
index 7e71cfb..0000000
--- a/src/main/java/com/culqi/util/ObjectResult.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.culqi.util;
-
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Created by culqi on 1/16/17.
- */
-public class ObjectResult {
-
- public ObjectResult(){}
-
- ObjectMapper mapper = new ObjectMapper();
-
- public Map list(String url, Object params) throws Exception {
- String query = (params != null)? mapper.writeValueAsString(params) : null;
- String response = new ResponseHelper().list(url, query);
- return mapper.readValue(response.toString(), new TypeReference>(){});
- }
-
- public Map create(Map body, String url) throws Exception {
- String jsonData = mapper.writeValueAsString(body);
- String response = new ResponseHelper().create(url, jsonData);
- return mapper.readValue(response, new TypeReference>(){});
- }
-
- public Map update(Map body, String url, String id) throws Exception {
- String jsonData = mapper.writeValueAsString(body);
- String response = new ResponseHelper().update(url, jsonData, id);
- return mapper.readValue(response, new TypeReference>(){});
- }
-
- public Map get_or_delete(String url, String id, boolean delete) throws Exception {
- String response = new ResponseHelper().get_or_delete(url, id, delete);
- return mapper.readValue(response, new TypeReference>(){});
- }
-
- public Map capture(String url, String id) throws Exception {
- String response = new ResponseHelper().capture(url, id);
- return mapper.readValue(response, new TypeReference>(){});
- }
-
-}
diff --git a/src/main/java/com/culqi/util/RSAKeysLoader.java b/src/main/java/com/culqi/util/RSAKeysLoader.java
new file mode 100644
index 0000000..7af1c06
--- /dev/null
+++ b/src/main/java/com/culqi/util/RSAKeysLoader.java
@@ -0,0 +1,46 @@
+package com.culqi.util;
+
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.Security;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Base64;
+
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+
+public class RSAKeysLoader {
+
+ static {
+ Security.addProvider(new BouncyCastleProvider());
+ }
+
+ public RSAPublicKey getPublicKeyPKCS1Format(String publicKeyContent) throws NoSuchAlgorithmException, InvalidKeySpecException {
+
+ RSAPublicKey pubKey = null;
+
+ publicKeyContent = publicKeyContent.replace("-----BEGIN PUBLIC KEY-----\n", "")
+ .replace("-----END PUBLIC KEY-----", "")
+ .replaceAll("\\s+", "");
+
+ KeyFactory kf = KeyFactory.getInstance("RSA");
+ X509EncodedKeySpec keySpecX509 = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKeyContent));
+ pubKey = (RSAPublicKey) kf.generatePublic(keySpecX509);
+
+ return pubKey;
+ }
+
+ public RSAPrivateKey getPrivateKeyPKCS1Format(String privateKeyContent) throws NoSuchAlgorithmException, InvalidKeySpecException {
+
+ //privateKeyContent = privateKeyContent.replaceAll("\\n", "").replace("-----BEGIN RSA PRIVATE KEY-----", "").replace("-----END RSA PRIVATE KEY-----", "");
+ KeyFactory kf = KeyFactory.getInstance("RSA");
+
+ PKCS8EncodedKeySpec keySpecPKCS8 = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKeyContent));
+ RSAPrivateKey privKey = (RSAPrivateKey) kf.generatePrivate(keySpecPKCS8);
+ return privKey;
+ }
+
+}
diff --git a/src/main/java/com/culqi/util/RSAUtil.java b/src/main/java/com/culqi/util/RSAUtil.java
new file mode 100644
index 0000000..d59dfc7
--- /dev/null
+++ b/src/main/java/com/culqi/util/RSAUtil.java
@@ -0,0 +1,87 @@
+package com.culqi.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.MGF1ParameterSpec;
+import java.util.Base64;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.OAEPParameterSpec;
+import javax.crypto.spec.PSource;
+
+public class RSAUtil {
+
+
+ private static final Logger logger = LoggerFactory.getLogger(RSAUtil.class);
+
+ /*
+ public byte[] encriptar(String mensaje, String pubKey) {
+ try {
+
+ Cipher rsaCipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
+ RSAKeysLoader rsaKeysLoader = new RSAKeysLoader();
+ RSAPublicKey publicKeyRSA = rsaKeysLoader.getPublicKeyPKCS1Format(pubKey);
+
+ rsaCipher.init(Cipher.ENCRYPT_MODE, publicKeyRSA, new OAEPParameterSpec("SHA-256", "MGF1", new MGF1ParameterSpec("SHA-256"), PSource.PSpecified.DEFAULT));
+ //rsaCipher.init(Cipher.ENCRYPT_MODE, publicKeyRSA);
+
+ byte[] mensajeCifrado = rsaCipher.doFinal(mensaje.getBytes("UTF8"));
+ return mensajeCifrado;
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+ */
+ public String encriptarByte(byte[] mensaje, String pubKey) {
+ try {
+
+ Cipher rsaCipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
+ RSAKeysLoader rsaKeysLoader = new RSAKeysLoader();
+ RSAPublicKey publicKeyRSA = rsaKeysLoader.getPublicKeyPKCS1Format(pubKey);
+
+ rsaCipher.init(Cipher.ENCRYPT_MODE, publicKeyRSA, new OAEPParameterSpec("SHA-256", "MGF1", new MGF1ParameterSpec("SHA-256"), PSource.PSpecified.DEFAULT));
+ //rsaCipher.init(Cipher.ENCRYPT_MODE, publicKeyRSA);
+
+ byte[] mensajeCifrado = rsaCipher.doFinal(mensaje);
+ String mensajeCifrado64 = Base64.getEncoder().encodeToString(mensajeCifrado);
+ return mensajeCifrado64;
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /*
+ public String desencriptar(byte[] mensajeCifrado, String privKey) {
+ String mensajeDescifrado2 = null;
+ try {
+
+ //String privKey = privateKey;
+
+ Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
+
+ RSAKeysLoader rsaKeysLoader = new RSAKeysLoader();
+ RSAPrivateKey privateKeyRSA = rsaKeysLoader.getPrivateKeyPKCS1Format(privKey);
+
+ rsaCipher.init(Cipher.DECRYPT_MODE, privateKeyRSA);
+ byte[] mensajeDescifrado = rsaCipher.doFinal(mensajeCifrado);
+ mensajeDescifrado2 = new String(mensajeDescifrado, "UTF8");
+
+ System.out.println(mensajeDescifrado2);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return mensajeDescifrado2;
+ }
+
+ */
+}
+
diff --git a/src/main/java/com/culqi/util/ResponseHelper.java b/src/main/java/com/culqi/util/ResponseHelper.java
deleted file mode 100644
index 528dbb2..0000000
--- a/src/main/java/com/culqi/util/ResponseHelper.java
+++ /dev/null
@@ -1,114 +0,0 @@
-package com.culqi.util;
-
-import com.culqi.Culqi;
-import com.culqi.model.Config;
-import okhttp3.*;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Created by culqi on 1/16/17.
- */
-public class ResponseHelper {
-
- public ResponseHelper(){}
-
- Config config = new Config();
-
- OkHttpClient client = new OkHttpClient.Builder().connectTimeout(180, TimeUnit.SECONDS)
- .readTimeout(180, TimeUnit.SECONDS).build();
-
- public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
-
- public String list(String url, String params) throws Exception {
-
- HttpUrl.Builder builder = new HttpUrl.Builder();
-
- builder.scheme("https").host(Config.DOMAIN).addPathSegment(Config.PATH+url);
-
- if(params != null) {
-
- HashMap map = new HashMap();
-
- String[] pairs = params.replace("{","").replace("}","").split(",");
-
- for (int i=0;i data) throws Exception {
+ Helper.validateStringStart((String) data.get("customer_id"), "cus");
+ Helper.validateStringStart((String) data.get("token_id"), "tkn");
+ }
+
+ public static void list(Map data) throws Exception {
+ if (data.containsKey("card_brand")) {
+ List allowedBrandValues = Arrays.asList("Visa", "Mastercard", "Amex", "Diners");
+ Helper.validateValue((String) data.get("card_brand"), allowedBrandValues);
+ }
+
+ if (data.containsKey("card_type")) {
+ List allowedCardTypeValues = Arrays.asList("credito", "debito", "internacional");
+ Helper.validateValue((String) data.get("card_type"), allowedCardTypeValues);
+ }
+
+ if (data.containsKey("country_code")) {
+ List countryCodes = CountryCodes.getCountryCodes();
+ Helper.validateValue((String) data.get("country_code"), countryCodes);
+ }
+
+ if (data.containsKey("creation_date_from") && data.containsKey("creation_date_to")) {
+ Helper.validateDateFilter((String) data.get("creation_date_from"), (String) data.get("creation_date_to"));
+ }
+ }
+}
diff --git a/src/main/java/com/culqi/util/validation/ChargeValidation.java b/src/main/java/com/culqi/util/validation/ChargeValidation.java
new file mode 100644
index 0000000..f394ea3
--- /dev/null
+++ b/src/main/java/com/culqi/util/validation/ChargeValidation.java
@@ -0,0 +1,85 @@
+package com.culqi.util.validation;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import com.culqi.util.CountryCodes;
+
+public class ChargeValidation {
+ public static void create(Map data) throws Exception {
+ String email = (String) data.get("email");
+ if (!Helper.isValidEmail(email)) {
+ throw new CustomException("Invalid email.");
+ }
+ Object amountObj = data.get("amount");
+ Helper.validateAmountValue(amountObj);
+
+ Helper.validateCurrencyCode((String) data.get("currency_code").toString());
+
+ String sourceId = (String) data.get("source_id");
+
+ if (sourceId.startsWith("tkn")) {
+ Helper.validateStringStart(sourceId, "tkn");
+ } else if (sourceId.startsWith("ype")) {
+ Helper.validateStringStart(sourceId, "ype");
+ } else if (sourceId.startsWith("crd")) {
+ Helper.validateStringStart(sourceId, "crd");
+ } else {
+ throw new CustomException("Incorrect format. The format must start with tkn, ype, or crd.");
+ }
+ }
+
+ public static void list(Map data) throws Exception {
+ if (data.containsKey("currency_code")) {
+ Helper.validateCurrencyCode((String) data.get("currency_code").toString());
+ }
+ if (data.containsKey("amount")) {
+ Object amountObj = data.get("amount");
+ Helper.validateAmountValue(amountObj);
+ }
+ if (data.containsKey("min_amount")) {
+ Object amountObj = data.get("min_amount");
+ Helper.validateAmountValue(amountObj);
+ }
+ if (data.containsKey("max_amount")) {
+ Object amountObj = data.get("max_amount");
+ Helper.validateAmountValue(amountObj);
+ }
+ if (data.containsKey("installments")) {
+ Object amountObj = data.get("installments");
+ Helper.validateAmountValue(amountObj);
+ }
+ if (data.containsKey("min_installments")) {
+ Object amountObj = data.get("min_installments");
+ Helper.validateAmountValue(amountObj);
+ }
+ if (data.containsKey("max_installments")) {
+ Object amountObj = data.get("max_installments");
+ Helper.validateAmountValue(amountObj);
+ }
+ if (data.containsKey("email")) {
+ String email = (String) data.get("email");
+ if (!Helper.isValidEmail(email)) {
+ throw new CustomException("Invalid email.");
+ }
+ }
+ if (data.containsKey("card_brand")) {
+ List allowedBrandValues = Arrays.asList("Visa", "Mastercard", "Amex", "Diners");
+ Helper.validateValue((String) data.get("card_brand"), allowedBrandValues);
+ }
+
+ if (data.containsKey("card_type")) {
+ List allowedCardTypeValues = Arrays.asList("credito", "debito", "internacional");
+ Helper.validateValue((String) data.get("card_type"), allowedCardTypeValues);
+ }
+
+ if (data.containsKey("country_code")) {
+ List countryCodes = CountryCodes.getCountryCodes();
+ Helper.validateValue((String) data.get("country_code"), countryCodes);
+ }
+
+ if (data.containsKey("creation_date_from") && data.containsKey("creation_date_to")) {
+ Helper.validateDateFilter((String) data.get("creation_date_from"), (String) data.get("creation_date_to"));
+ }
+ }
+}
diff --git a/src/main/java/com/culqi/util/validation/CustomException.java b/src/main/java/com/culqi/util/validation/CustomException.java
new file mode 100644
index 0000000..b1fb16f
--- /dev/null
+++ b/src/main/java/com/culqi/util/validation/CustomException.java
@@ -0,0 +1,22 @@
+package com.culqi.util.validation;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class CustomException extends Exception {
+ private Map errorData;
+
+ public CustomException(String merchantMessage) {
+ super(merchantMessage);
+ errorData = new HashMap<>();
+ errorData.put("object", "error");
+ errorData.put("type", "param_error");
+ errorData.put("merchant_message", merchantMessage);
+ errorData.put("user_message", merchantMessage);
+ }
+
+ public Map getErrorData() {
+ return errorData;
+ }
+}
+
diff --git a/src/main/java/com/culqi/util/validation/CustomerValidation.java b/src/main/java/com/culqi/util/validation/CustomerValidation.java
new file mode 100644
index 0000000..badbb0f
--- /dev/null
+++ b/src/main/java/com/culqi/util/validation/CustomerValidation.java
@@ -0,0 +1,54 @@
+package com.culqi.util.validation;
+import java.util.List;
+import java.util.Map;
+
+import com.culqi.util.CountryCodes;
+
+public class CustomerValidation {
+ public static void create(Map data) throws Exception {
+ String first_name = (String) data.get("first_name");
+ String last_name = (String) data.get("last_name");
+ String address = (String) data.get("address");
+ String address_city = (String) data.get("address_city");
+ if (first_name == null || first_name.isEmpty()) {
+ throw new CustomException("first name is empty.");
+ }
+
+ if (last_name == null || last_name.isEmpty()) {
+ throw new CustomException("last name is empty.");
+ }
+
+ if (address == null || address.isEmpty()) {
+ throw new CustomException("address is empty.");
+ }
+
+ if (address_city == null || address_city.isEmpty()) {
+ throw new CustomException("address_city is empty.");
+ }
+
+ if (!(data.get("phone_number") instanceof String)) {
+ throw new CustomException("Invalid 'phone_number'. It should be a string.");
+ }
+
+ List countryCodes = CountryCodes.getCountryCodes();
+ Helper.validateValue((String) data.get("country_code"), countryCodes);
+
+ String email = (String) data.get("email");
+ if (!Helper.isValidEmail(email)) {
+ throw new CustomException("Invalid email.");
+ }
+ }
+
+ public static void list(Map data) throws Exception {
+ if (data.containsKey("email")) {
+ String email = (String) data.get("email");
+ if (!Helper.isValidEmail(email)) {
+ throw new CustomException("Invalid email.");
+ }
+ }
+ if (data.containsKey("country_code")) {
+ List countryCodes = CountryCodes.getCountryCodes();
+ Helper.validateValue((String) data.get("country_code"), countryCodes);
+ }
+ }
+}
diff --git a/src/main/java/com/culqi/util/validation/Helper.java b/src/main/java/com/culqi/util/validation/Helper.java
new file mode 100644
index 0000000..9a216f8
--- /dev/null
+++ b/src/main/java/com/culqi/util/validation/Helper.java
@@ -0,0 +1,336 @@
+package com.culqi.util.validation;
+
+import java.util.regex.Pattern;
+
+import com.google.gson.Gson;
+
+import java.util.regex.Matcher;
+import java.time.LocalDateTime;
+import java.time.Instant;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class Helper {
+ public void validateAmount(Object amount) throws Exception {
+ if (!(amount instanceof Integer || amount instanceof Float) ||
+ ((Number) amount).intValue() != ((Number) amount).doubleValue()) {
+ throw new CustomException("Invalid amount.");
+ }
+ }
+
+ public static boolean isValidCardNumber(String number) {
+ Pattern pattern = Pattern.compile("^\\d{13,19}$");
+ Matcher matcher = pattern.matcher(number);
+ return matcher.matches();
+ }
+
+ public static boolean isValidEmail(String email) {
+ Pattern pattern = Pattern.compile("^\\S+@\\S+\\.\\S+$");
+ Matcher matcher = pattern.matcher(email);
+ return matcher.matches();
+ }
+
+ public static void validateCurrencyCode(String currencyCode) throws Exception {
+ if (currencyCode == null || currencyCode.isEmpty()) {
+ throw new CustomException("Currency code is empty.");
+ }
+
+ List allowedValues = Arrays.asList("PEN", "USD");
+ if (!allowedValues.contains(currencyCode)) {
+ throw new CustomException("Currency code must be either \"PEN\" or \"USD\".");
+ }
+ }
+
+ public static void validateStringStart(String string, String start) throws Exception {
+ if (!(string.startsWith(start + "_test_") || string.startsWith(start + "_live_"))) {
+ throw new CustomException("Incorrect format. The format must start with " + start + "_test_ or " + start + "_live_");
+ }
+ }
+
+ public static void validateValue(String value, List allowedValues) throws Exception {
+ if (!allowedValues.contains(value)) {
+ System.err.println(value);
+ throw new CustomException("Invalid value. It must be one of " + allowedValues);
+ }
+ }
+
+ public static boolean isFutureDate(long expirationDate) {
+ LocalDateTime expDate = LocalDateTime.ofInstant(Instant.ofEpochSecond(expirationDate), java.time.ZoneId.systemDefault());
+ return expDate.isAfter(LocalDateTime.now());
+ }
+
+ public static void validateDateFilter(String dateFrom, String dateTo) throws CustomException {
+ int parsedDateFrom;
+ int parsedDateTo;
+
+ try {
+ parsedDateFrom = Integer.parseInt(dateFrom);
+ parsedDateTo = Integer.parseInt(dateTo);
+ } catch (NumberFormatException e) {
+ throw new CustomException("Invalid value. Date_from and Date_to must be integers.");
+ }
+
+ if (parsedDateTo < parsedDateFrom) {
+ throw new CustomException("Invalid value. Date_from must be less than Date_to.");
+ }
+ }
+ public static void validateAmountValue(Object amountObj) throws CustomException {
+ if (amountObj instanceof Integer) {
+ // Amount is already an integer, no further validation needed.
+ } else if (amountObj instanceof String) {
+ try {
+ int amount = Integer.parseInt((String) amountObj);
+ } catch (NumberFormatException e) {
+ throw new CustomException("Invalid 'amount'. It should be an integer or a string representing an integer.");
+ }
+ } else {
+ throw new CustomException("Invalid 'amount'. It should be an integer or a string representing an integer.");
+ }
+ }
+
+ public static boolean validValue(Object value, Boolean isInteger) {
+ if (isInteger) {
+ if (!(value instanceof Integer)) {
+ return false;
+ }
+ } else {
+ if (!(value instanceof String)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static boolean validateRangeParameters(Object value, Integer minValue, Integer maxValue, Boolean isInteger) {
+ Integer num = isInteger ? Integer.parseInt(value.toString()) : value.toString().length();
+ return num < minValue || num > maxValue;
+ }
+
+ public static void validateCurrency(String currency, int amount) throws CustomException {
+ validateEnumCurrency(currency);
+ Integer MIN_AMOUNT_PEN = 3;
+ Integer MAX_AMOUNT_PEN = 5000;
+ Integer MIN_AMOUNT_USD = 1;
+ Integer MAX_AMOUNT_USD = 1500;
+
+ int minAmountPublicApi = MIN_AMOUNT_PEN * 100;
+ int maxAmountPublicApi = MAX_AMOUNT_PEN * 100;
+
+ if (currency.equals("USD")) {
+ minAmountPublicApi = MIN_AMOUNT_USD * 100;
+ maxAmountPublicApi = MAX_AMOUNT_USD * 100;
+ }
+
+ boolean validAmount = amount >= minAmountPublicApi && amount <= maxAmountPublicApi;
+
+ if (!validAmount) {
+ if (currency.equals("USD")) {
+ throw new CustomException("El campo 'amount' admite valores en el rango 100 a 150000.");
+ }
+
+ throw new CustomException("El campo 'amount' admite valores en el rango 300 a 500000.");
+ }
+ }
+
+ public static void validateInitialCycles(Map initialCycles)
+ throws CustomException {
+ boolean hasInitialCharge = (boolean) initialCycles.get("has_initial_charge");
+ int payAmount = (int) initialCycles.get("amount");
+ int count = (int) initialCycles.get("count");
+
+ if (!validValue(payAmount, true)) {
+ throw new CustomException(
+ "El campo 'initial_cycles.amount' es inválido o está vacío, debe tener un valor numérico.");
+ }
+
+ if (hasInitialCharge) {
+
+ if (count < 1 || count > 9999) {
+ throw new CustomException(
+ "El campo 'initial_cycles.count' solo admite valores numéricos en el rango 1 a 9999.");
+ }
+
+ } else {
+ if (count < 0 || count > 9999) {
+ throw new CustomException(
+ "El campo 'initial_cycles.count' solo admite valores numéricos en el rango 0 a 9999.");
+ }
+
+ }
+ }
+
+ public static void validateEnumCurrency(String currency) throws CustomException {
+ List ENUM_CURRENCY = Arrays.asList("PEN", "USD");
+ if (!ENUM_CURRENCY.contains(currency) || !validValue(currency, false)) {
+ throw new CustomException(
+ "El campo 'currency' es inválido o está vacío, el código de la moneda en tres letras (Formato ISO 4217). Culqi actualmente soporta las siguientes monedas: ['PEN','USD'].");
+ }
+ }
+
+ public static String validateMetadataSchema(Map objMetadata) throws CustomException {
+ if (!(objMetadata instanceof Map) && !(objMetadata instanceof Object)) {
+ throw new CustomException("Enviaste el campo metadata con un formato incorrecto.");
+ }
+
+ for (Map.Entry entry : objMetadata.entrySet()) {
+ String key = entry.getKey();
+ Object value = entry.getValue();
+ int paramKey = key.length();
+ int paramValue = value.toString().length();
+
+ if (paramKey < 1 || paramKey > 30 || paramValue < 1 || paramValue > 2000) {
+ throw new CustomException("El objeto 'metadata' es inválido, límite key (1 - 30), value (1 - 200)");
+ }
+ }
+
+ if (objMetadata instanceof Map && objMetadata.size() > 20) {
+ throw new CustomException("Enviaste más de 20 parámetros en el metadata. El límite es 20.");
+ }
+
+ Map transformedMetadata = new HashMap<>();
+ for (Map.Entry entry : objMetadata.entrySet()) {
+ String key = entry.getKey();
+ Object value = entry.getValue();
+ transformedMetadata.put(key, value instanceof String ? (String) value : String.valueOf(value));
+ }
+
+ return new Gson().toJson(transformedMetadata);
+ }
+
+ public static void validatePayloadCreatePlan(Map data) throws CustomException {
+ // Define la lista de parámetros esperados
+ List expectedParameters = Arrays.asList(
+ "interval_unit_time",
+ "interval_count",
+ "amount",
+ "name",
+ "description",
+ "short_name",
+ "currency",
+ "metadata",
+ "initial_cycles",
+ "image");
+
+ // Verifica si hay parámetros adicionales
+ Set extraParameters = new HashSet<>(data.keySet());
+ extraParameters.removeAll(expectedParameters);
+
+ if (!extraParameters.isEmpty()) {
+ throw new CustomException("Parámetros adicionales no permitidos: " + String.join(", ", extraParameters));
+ }
+ }
+
+ public static void validatePayloadCreateSubscription(Map data) throws CustomException {
+ // Define la lista de parámetros esperados
+ List expectedParameters = Arrays.asList(
+ "card_id",
+ "plan_id",
+ "metadata",
+ "tyc");
+
+ // Verifica si hay parámetros adicionales
+ Set extraParameters = new HashSet<>(data.keySet());
+ extraParameters.removeAll(expectedParameters);
+
+ if (!extraParameters.isEmpty()) {
+ throw new CustomException("Parámetros adicionales no permitidos: " + String.join(", ", extraParameters));
+ }
+ }
+
+ public static void validatePayloadUpdatePlan(Map data) throws CustomException {
+ // Define la lista de parámetros esperados
+ List expectedParameters = Arrays.asList(
+ "name", "description", "short_name", "status", "image", "metadata");
+
+ // Verifica si hay parámetros adicionales
+ Set extraParameters = new HashSet<>(data.keySet());
+ extraParameters.removeAll(expectedParameters);
+
+ if (!extraParameters.isEmpty()) {
+ throw new CustomException("Parámetros adicionales no permitidos: " + String.join(", ", extraParameters));
+ }
+ }
+
+ public static void validatePayloadUpdateSubscription(Map data) throws CustomException {
+ // Define la lista de parámetros esperados
+ List expectedParameters = Arrays.asList(
+ "card_id", "metadata");
+
+ // Verifica si hay parámetros adicionales
+ Set extraParameters = new HashSet<>(data.keySet());
+ extraParameters.removeAll(expectedParameters);
+
+ if (!extraParameters.isEmpty()) {
+ throw new CustomException("Parámetros adicionales no permitidos: " + String.join(", ", extraParameters));
+ }
+ }
+
+ public static void validatePayloadFilterPlan(Map data) throws CustomException {
+ // Define la lista de parámetros esperados
+ List expectedParameters = Arrays.asList(
+ "status",
+ "min_amount",
+ "max_amount",
+ "creation_date_to",
+ "creation_date_from",
+ "limit",
+ "after",
+ "before");
+
+ // Verifica si hay parámetros adicionales
+ Set extraParameters = new HashSet<>(data.keySet());
+ extraParameters.removeAll(expectedParameters);
+
+ if (!extraParameters.isEmpty()) {
+ throw new CustomException("Parámetros adicionales no permitidos: " + String.join(", ", extraParameters));
+ }
+ }
+
+ public static void validatePayloadFilterSubscription(Map data) throws CustomException {
+ // Define la lista de parámetros esperados
+ List expectedParameters = Arrays.asList(
+ "status",
+ "plan_id",
+ "creation_date_to",
+ "creation_date_from",
+ "limit",
+ "after",
+ "before");
+
+ // Verifica si hay parámetros adicionales
+ Set