0 purchases
enzona
Descripción #
Esta librería es un SDK (aún en desarrollo) que tiene como objetivo facilitar el uso de las APIs de ENZONA, de manera tal que el desarrollador solo tenga que concentrarse en la lógica de negocio de su proyecto.
APIs disponibles #
API
Dispnible
PaymentAPI
✅
QRAPI
☑️
ClaimAPI
☑️
XMET_AccountAPI
☑️
XMET_AccountingOperationAPI
☑️
Primeros pasos #
Antes de comenzar a usar este SDK es recomendado que primero revise la documentación oficial proporcionada por el equipo de ENZONA para que conozca el ambiente de pruebas (bulevar/api sandbox) y tenga el conocimiento base de los flujos y funcionamiento de las APIs.
Vea este simple tutorial
Acceda a la documentación y ejemplos oficiales desde el api sandbox
Para usar este SDK #
Lo primero es añadir enzona como una dependencia más de su proyecto, para esto puede usar el comando:
Para proyectos puramente en Dart
dart pub add enzona
copied to clipboard
Para proyectos en Flutter
flutter pub add enzona
copied to clipboard
Este comando añadirá enzona al pubspec.yaml de su proyecto.
Finalmente solo tiene que ejecutar:
dart pub get ó flutter pub get según el tipo de proyecto para descargar la dependencia a su pub-cache
¿Cómo usar este SDK? #
Muy simple, solo construya una instancia de este SDK de Enzona así: #
final enzona = Enzona(
apiUrl: apiUrl, //Url base de las APIs de ENZONA (https://api.enzona.net ó https://apisandbox.enzona.net)
accessTokenUrl: accessTokenUrl, //Opcionalmente. Url del endpoint de autenticación OAuth2 (https://api.enzona.net/token ó https://apisandbox.enzona.net/token), esta Url en caso de no pasarse se asume automáticamente la Url: '$apiUrl/token'
consumerKey: consumerKey, //El Consumer Key del Comercio para el cual se desea acceder a las APIs de ENZONA
consumerSecret: consumerSecret, //El Consumer Secret del Comercio para el cual se desea acceder a las APIs de ENZONA
scopes: scopes, //El alcance que tendrá el token de autenticacón
timeout: Duration(seconds: 30), //Opcionalmente el tiempo de espera antes de abortar una petición al API
httpClient: HttpClient(), //Opcionalmente una instancia de HttpClient para tener control sobre las peticiones http, como la validación de certificados, etc.
);
copied to clipboard
Y luego la inicialízela así:
await enzona.init();
copied to clipboard
Y listo ya tiene acceso a las APIs de ENZONA...
En la mayoría de los casos con una instancia simple como esta bastará:
final enzona = Enzona(
apiUrl: apiUrl,
consumerKey: consumerKey,
consumerSecret: consumerSecret,
scopes: scopes,
);
copied to clipboard
¿Cómo funciona la autenticación? #
Las APIs de ENZONA implementan una variante de OAuth2 (sin renovación de token) para la autenticación, (ver documentación). Este SDK implementa autenticación OAuth2 y además se encarga de renovar el token automáticamente sin que el desarrollador se tenga que preocupar por eso, en cada petición a las APIs se comprueba la validez del token y si este ha expirado, se procede a re-autenticar, y se continua con la petición original.
De igual forma es posible renovar el token manualmente así como obtener las credenciales de autenticación.
if(enzona.credentials.isExpired) {
final credentials = await enzona.refreshCredentials();
print(credentials.accessToken);
}
copied to clipboard
Detalles a tener en cuenta #
En aras de reducir posibles errores en el manejo de nombres de propiedades, filtros y valores:
Se usa la clase Params donde se definen todos los nombres de propiedades y filtros usados en el SDK.
Se usa la clase StatusCode donde se definen todos los códigos de estado de las transacciones.
Se usa la clase Order para definir el tipo de orden a la hora de filtrar un listado.
Ejemplo:
final filters = <String, dynamic> {
Params.pageIndex: 0,
Params.pageSize: 5,
Params.order: Order.desc,
};
final response = await enzona.paymentAPI.getPayments(filters: filters);
if(response.isSuccessful && (response.body?.isNotEmpty ?? false)) {
final payment = response.body![0];
if(payment.statusCode == StatusCode.confirmada){
print(payment.amount?.total);
}
copied to clipboard
¿Cómo usar el PaymentAPI? #
Desde una instancia del sdk puede acceder a las APIs disponibles, entre estas el API de pagos. Tenga en cuenta que el scope (alcance) que haya usado para la autenticación es lo que determina a qué APIs podrá acceder con el token generado.
Funciones disponibles PaymentAPI #
Función
Soportada
Listar/filtrar pagos
✅
Obtener detalles de un pago
✅
Crear un pago
✅
Completar un pago
✅
Cancelar un pago
✅
Listar/filtrar devoluciones
✅
Obtener detalles de una devolución
✅
Realizar una devolución completa
✅
Realizar una devolución parcial
✅
Listar/filtrar pagos #
final response = await enzona.paymentAPI.getPayments(
pageIndex: 0,
pageSize: 5,
merchantUUID: merchantUUID,
merchantOp: merchantOp,
enzonaOp: enzonaOp,
status: StatusCode.confirmada,
startDate: DateTime.now().subtract(Duration(days: 7)),
endDate: DateTime.now(),
order: Order.desc,
);
if(response.isSuccessful && (response.body?.isNotEmpty ?? false)) {
print('totalCount: ${response.headers[Pagination.totalCountHeader]}');
for(var payment in response.body!) {
print('id: ${payment.transactionUUID}, statusCode: ${payment.statusCode}');
}
}
copied to clipboard
Pagination.totalCountHeader se refiere a la cantidad total de pagos que existen, este valor se obtiene de los headers del response. Útil para cuando se quiere mostrar un paginado por pasos.
Además de poder especificar los filtros directamente como en el ejemplo anterior, se puede también especificar un Map de filtros con cualquier combinación de filtros:
final filters = <String, dynamic> {
Params.pageIndex: 0,
Params.pageSize: 5,
Params.merchantUUID: merchantUUID,
Params.merchantOp: merchantOp,
Params.enzonaOp: enzonaOp,
Params.status: StatusCode.confirmada,
Params.startDate: DateTime.now().subtract(Duration(days: 7)),
Params.endDate: DateTime.now(),
Params.order: Order.desc,
};
final response = await enzona.paymentAPI.getPayments(
filters: filters
);
if(response.isSuccessful && (response.body?.isNotEmpty ?? false)) {
print('totalCount: ${response.headers[Pagination.totalCountHeader]}');
for(var payment in response.body!) {
print('id: ${payment.transactionUUID}, statusCode: ${payment.statusCode}');
}
}
copied to clipboard
Obtener detalles de un pago #
final response = await enzona.paymentAPI.getPayment(transactionUUID: transactionUUID);
if(response.isSuccessful) {
final payment = response.body;
print('id: ${payment?.transactionUUID}, statusCode: ${payment?.statusCode}');
}
copied to clipboard
Crear un pago #
Muy importante haber estudiado la documentación oficial sugerida en los Primero pasos para entender bien cómo funciona el flujo de crear un pago.
Para crear un pago tenemos disponible la clase PaymentRequest donde se definen valores requeridos y algunos otros opcionales.
final payment = PaymentRequest(
returnUrl: "http://url.to.return.after.payment.confirmation",
cancelUrl: "http://url.to.return.after.payment.cancellation",
merchantOpId: PaymentRequest.generateRandomMerchantOpId(),
currency: "CUP",
amount: PaymentAmount(
total: 33,
details: PaymentAmountDetails(
shipping: 1,
tax: 0,
discount: 2,
tip: 4,
),
),
items: [
PaymentItem(
name: "Payment Item 1",
description: "Some item description",
quantity: 2,
price: 15,
tax: 0,
)
],
description: "This is an example payment description",
);
final response = await enzona.paymentAPI.createPayment(data: payment);
if(response.isSuccessful) {
final createdPayment = response.body;
print('id: ${createdPayment?.transactionUUID}, statusCode: ${createdPayment?.statusCode}');
}
copied to clipboard
Como debe saber una vez creado un pago se debe proceder a confirmarlo, para esto se usa una URL de confirmación que apunta a la plataforma de ENZONA desde donde el usuario puede autenticarse y confirmar el pago. Esta URL de confirmación se puede obtener simplemente con:
String? confirmationUrl = payment.confirmationUrl;
launch(confirmationUrl); //El proceso de lanzar la URL en el navegador no se maneja en este SDK
copied to clipboard
Para un manejo adecuado de la confirmación de un pago use enzona_flutter
Completar un pago #
A partir de un pago confirmado se puede proceder a completarlo.
final response = await enzona.paymentAPI.completePayment(transactionUUID: payment.transactionUUID!);
if(response.isSuccessful) {
final completedPayment = response.body;
print('id: ${completedPayment?.transactionUUID}, statusCode: ${completedPayment?.statusCode}');
} else if(response.error is ErrorResponse &&
(response.error as ErrorResponse).code == StatusCode.transaccionNoConfirmada) {
final errorResponse = response.error as ErrorResponse;
print('Mensaje de error: ${errorResponse.message}. El pago debe confirmarse antes de proceder completarse');
}
copied to clipboard
Cancelar un pago #
A partir de un pago confirmado se puede proceder a cancelarlo.
final response = await enzona.paymentAPI.cancelPayment(transactionUUID: payment.transactionUUID!);
if(response.isSuccessful) {
final cancelledPayment = response.body;
print('id: ${cancelledPayment?.transactionUUID}, statusCode: ${cancelledPayment?.statusCode}');
} else {
print('Hubo un error y no se pudo cancelar el pago.');
}
copied to clipboard
Listar/filtrar devoluciones #
final response = await enzona.paymentAPI.getRefunds(
pageIndex: 0,
pageSize: 5,
merchantUUID: merchantUUID,
transactionUUID: transactionUUID,
commerceRefundId: commerceRefundId,
status: StatusCode.aceptada,
startDate: DateTime.now().subtract(Duration(days: 7)),
endDate: DateTime.now(),
order: Order.desc,
);
if(response.isSuccessful && (response.body?.isNotEmpty ?? false)) {
print('totalCount: ${response.headers[Pagination.totalCountHeader]}');
for(var refund in response.body!) {
print('id: ${refund.transactionUUID}, statusCode: ${refund.statusCode}');
}
}
copied to clipboard
Pagination.totalCountHeader se refiere a la cantidad total de devoluciones que existen, este valor se obtiene de los headers del response. Útil para cuando se quiere mostrar un paginado por pasos.
Además de poder especificar los filtros directamente como en el ejemplo anterior, se puede también especificar un Map de filtros con cualquier combinación de filtros:
final filters = <String, dynamic> {
pageIndex: 0,
pageSize: 5,
merchantUUID: merchantUUID,
transactionUUID: transactionUUID,
commerceRefundId: commerceRefundId,
status: StatusCode.aceptada,
startDate: DateTime.now().subtract(Duration(days: 7)),
endDate: DateTime.now(),
order: Order.desc,
};
final response = await enzona.paymentAPI.getRefunds(
filters: filters
);
if(response.isSuccessful && (response.body?.isNotEmpty ?? false)) {
print('totalCount: ${response.headers[Pagination.totalCountHeader]}');
for(var refund in response.body!) {
print('id: ${refund.transactionUUID}, statusCode: ${refund.statusCode}');
}
}
copied to clipboard
Obtener detalles de una devolución #
final response = await enzona.paymentAPI.getRefund(transactionUUID: transactionUUID);
if(response.isSuccessful) {
final refund = response.body;
print('id: ${refund?.transactionUUID}, statusCode: ${refund?.statusCode}');
}
copied to clipboard
Realizar una devolución completa #
final response = await enzona.paymentAPI.refundPayment(transactionUUID: transactionUUID);
if(response.isSuccessful) {
final refund = response.body;
print('id: ${refund?.transactionUUID}, statusCode: ${refund?.statusCode}');
}
copied to clipboard
Realizar una devolución parcial #
final refund = Refund(
amount: PaymentAmount(
total: 5,
),
description: 'This is a partial refund'
);
final response = await enzona.paymentAPI.refundPayment(transactionUUID: transactionUUID, data: refund);
if(response.isSuccessful) {
final refund = response.body;
print('id: ${refund?.transactionUUID}, statusCode: ${refund?.statusCode}');
}
copied to clipboard
Agradecimientos a #
Janier Treto
Contribución #
Si encuentra algún problema no dude en abrir un ISSUE, siéntase libre de hacer fork, mejorar el SDK y hacer pull request.
For personal and professional use. You cannot resell or redistribute these repositories in their original state.
There are no reviews.