using CPSAPIModels;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Runtime.InteropServices;
using System.Timers;
namespace CPSConnector
{
public class CPSConnector
{
public event TokenNotRefreshedEventHandler TokenNotRefreshed;
///
/// Crea un nuevo conector CPS
///
/// Url de la API CPS. Existente para posibles futuras necesidades
/// Tiempo de expiración del token usado para autenticar las peticiones. Existente para posibles futuras necesidades
public CPSConnector(string CPSApiUrl = "https://www.cloudpaymentservice.com/api", int accessTokenExpirySeconds = CPSConnector.accessTokenExpirySeconds)
{
this.CPSApiUrl = CPSApiUrl;
this.timer = new Timer((accessTokenExpirySeconds - RefreshTokenOffset) * 1000);
this.timer.Elapsed += timerElapsedEvent;
this.timer.Enabled = false;
this.timer.AutoReset = true;
}
///
/// Certifica el estado de conexión con la API CPS.
///
/// Descripción ampliada del error cuando el resultado de la petición no ha sido satisfactorio.
/// Código de estado HTTP que informa sobre el resultado de la petición.
public HttpStatusCode Ping(ref string APIError)
{
string Resource = "/ping";
string Method = "GET";
string ResponseContent = null;
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
this.ExecuteRequest(null, Method, Resource, ref httpStatusCode, ref ResponseContent, null, null, false);
if (httpStatusCode != HttpStatusCode.OK)
{
APIError = ResponseContent;
}
return httpStatusCode;
}
#region Session
///
/// Inicia sesión sobre un terminal CPS.
///
/// Petición a enviar.
/// Descripción ampliada del error cuando el resultado de la petición no ha sido satisfactorio.
/// Código de estado HTTP que informa sobre el resultado de la petición.
public HttpStatusCode Login(CPSAPIModels.LoginRequest request, ref string APIError)
{
string Resource = "/login";
string Method = "POST";
string ResponseContent = null;
CPSAPIModels.LoginResponse response = new CPSAPIModels.LoginResponse();
if (request == null)
{
APIError = "Invalid login request";
return HttpStatusCode.BadRequest;
}
if (response == null)
{
APIError = "Invalid login response";
return HttpStatusCode.BadRequest;
}
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
response = (LoginResponse)this.ExecuteRequest(request, Method, Resource, ref httpStatusCode, ref ResponseContent, response.GetType(), request.ResponseTimeOut, false);
if (httpStatusCode != HttpStatusCode.OK)
{
APIError = ResponseContent;
}
else
{
UpdateTokens(response.AccessToken, response.RefreshToken);
this.ResponseTimeOut = request.ResponseTimeOut;
this.CPSAPIVersion = request.CPSAPIVersion;
}
return httpStatusCode;
}
///
/// Finaliza sesión sobre un terminal CPS
///
public void Logout()
{
timer.Stop();
this._AccessToken = null;
this._RefreshToken = null;
}
///
/// Inicia una transacción sobre un terminal CPS con el modo compartido activado.
///
/// Respuesta recibida.
/// Descripción ampliada del error cuando el resultado de la petición no ha sido satisfactorio.
/// Código de estado HTTP que informa sobre el resultado de la petición.
public HttpStatusCode StartTransaction(ref CPSAPIModels.StartTransactionResponse response, ref string APIError)
{
string Resource = "/starttransaction";
string Method = "GET";
string ResponseContent = null;
if (response == null)
{
APIError = "Invalid start transaction response";
return HttpStatusCode.BadRequest;
}
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
response = (StartTransactionResponse)this.ExecuteRequest(null, Method, Resource, ref httpStatusCode, ref ResponseContent, response.GetType(), null);
if (httpStatusCode != HttpStatusCode.OK)
{
APIError = ResponseContent;
}
return httpStatusCode;
}
///
/// Finaliza una transacción sobre un terminal CPS con el modo compartido activado.
///
/// Respuesta recibida.
/// Descripción ampliada del error cuando el resultado de la petición no ha sido satisfactorio.
/// Código de estado HTTP que informa sobre el resultado de la petición.
public HttpStatusCode EndTransaction(ref CPSAPIModels.EndTransactionResponse response, ref string APIError)
{
string Resource = "/endtransaction";
string Method = "GET";
string ResponseContent = null;
if (response == null)
{
APIError = "Invalid end transaction response";
return HttpStatusCode.BadRequest;
}
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
response = (EndTransactionResponse)this.ExecuteRequest(null, Method, Resource, ref httpStatusCode, ref ResponseContent, response.GetType(), null);
if (httpStatusCode != HttpStatusCode.OK)
{
APIError = ResponseContent;
}
return httpStatusCode;
}
#endregion
#region Terminal
///
/// Devuelve información acerca del terminal CPS.
///
/// Petición a enviar.
/// Respuesta recibida.
/// Descripción ampliada del error cuando el resultado de la petición no ha sido satisfactorio.
/// Código de estado HTTP que informa sobre el resultado de la petición.
public HttpStatusCode TerminalInfo(CPSAPIModels.TerminalInfoRequest request, ref CPSAPIModels.TerminalInfoResponse response, ref string APIError)
{
string Resource = "/terminalinfo";
string Method = "POST";
string ResponseContent = null;
if (request == null)
{
APIError = "Invalid terminal info request";
return HttpStatusCode.BadRequest;
}
if (response == null)
{
APIError = "Invalid terminal info response";
return HttpStatusCode.BadRequest;
}
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
response = (TerminalInfoResponse)this.ExecuteRequest(request, Method, Resource, ref httpStatusCode, ref ResponseContent, response.GetType(), request.ResponseTimeOut);
if (httpStatusCode != HttpStatusCode.OK)
{
APIError = ResponseContent;
}
return httpStatusCode;
}
///
/// Devuelve el actual estado operacional del terminal CPS.
///
/// Petición a enviar.
/// Respuesta recibida.
/// Descripción ampliada del error cuando el resultado de la petición no ha sido satisfactorio.
/// Código de estado HTTP que informa sobre el resultado de la petición.
public HttpStatusCode TerminalOperationalStatus(TerminalOperationalStatusRequest request, ref TerminalOperationalStatusResponse response, ref string APIError)
{
string Resource = "/terminaloperationalstatus";
string Method = "POST";
string ResponseContent = null;
if (request == null)
{
APIError = "Invalid terminal operational status request";
return HttpStatusCode.BadRequest;
}
if (response == null)
{
APIError = "Invalid terminal operational status response";
return HttpStatusCode.BadRequest;
}
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
response = (TerminalOperationalStatusResponse)this.ExecuteRequest(request, Method, Resource, ref httpStatusCode, ref ResponseContent, response.GetType(), request.ResponseTimeOut);
if (httpStatusCode != HttpStatusCode.OK)
{
APIError = ResponseContent;
}
return httpStatusCode;
}
///
/// Reinicia el terminal CPS.
///
/// Petición a enviar.
/// Respuesta recibida.
/// Descripción ampliada del error cuando el resultado de la petición no ha sido satisfactorio.
/// Código de estado HTTP que informa sobre el resultado de la petición.
public HttpStatusCode Restart(RestartRequest request, ref RestartResponse response, ref string APIError)
{
string Resource = "/restart";
string Method = "POST";
string ResponseContent = null;
if (request == null)
{
APIError = "Invalid restart request";
return HttpStatusCode.BadRequest;
}
if (response == null)
{
APIError = "Invalid restart response";
return HttpStatusCode.BadRequest;
}
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
response = (RestartResponse)this.ExecuteRequest(request, Method, Resource, ref httpStatusCode, ref ResponseContent, response.GetType(), request.ResponseTimeOut);
if (httpStatusCode != HttpStatusCode.OK)
{
APIError = ResponseContent;
}
return httpStatusCode;
}
///
/// Establece el idioma del terminal CPS.
///
/// Petición a enviar.
/// Respuesta recibida.
/// Descripción ampliada del error cuando el resultado de la petición no ha sido satisfactorio.
/// Código de estado HTTP que informa sobre el resultado de la petición.
public HttpStatusCode SetLanguage(SetLanguageRequest request, ref SetLanguageResponse response, ref string APIError)
{
string Resource = "/setlanguage";
string Method = "POST";
string ResponseContent = null;
if (request == null)
{
APIError = "Invalid set language request";
return HttpStatusCode.BadRequest;
}
if (response == null)
{
APIError = "Invalid set language response";
return HttpStatusCode.BadRequest;
}
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
response = (SetLanguageResponse)this.ExecuteRequest(request, Method, Resource, ref httpStatusCode, ref ResponseContent, response.GetType(), request.ResponseTimeOut);
if (httpStatusCode != HttpStatusCode.OK)
{
APIError = ResponseContent;
}
return httpStatusCode;
}
///
/// Finaliza la operación en curso en el terminal CPS. Permite la extracción del Tag en determinadas operaciones.
///
/// Petición a enviar.
/// Respuesta recibida.
/// Descripción ampliada del error cuando el resultado de la petición no ha sido satisfactorio.
/// Código de estado HTTP que informa sobre el resultado de la petición.
public HttpStatusCode EndCurrentOperation(EndCurrentOperationRequest request, ref EndCurrentOperationResponse response, ref string APIError)
{
string Resource = "/endcurrentoperation";
string Method = "POST";
string ResponseContent = null;
if (request == null)
{
APIError = "Invalid end current operation request";
return HttpStatusCode.BadRequest;
}
if (response == null)
{
APIError = "Invalid end current operation response";
return HttpStatusCode.BadRequest;
}
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
response = (EndCurrentOperationResponse)this.ExecuteRequest(request, Method, Resource, ref httpStatusCode, ref ResponseContent, response.GetType(), request.ResponseTimeOut);
if (httpStatusCode != HttpStatusCode.OK)
{
APIError = ResponseContent;
}
return httpStatusCode;
}
///
/// Inicia una operación de lectura de Tag en el terminal CPS.
///
/// Petición a enviar.
/// Respuesta recibida.
/// Descripción ampliada del error cuando el resultado de la petición no ha sido satisfactorio.
/// Código de estado HTTP que informa sobre el resultado de la petición.
public HttpStatusCode TagReading(TagReadingRequest request, ref TagReadingResponse response, ref string APIError)
{
string Resource = "/tagreading";
string Method = "POST";
string ResponseContent = null;
if (request == null)
{
APIError = "Invalid tag reading request";
return HttpStatusCode.BadRequest;
}
if (response == null)
{
APIError = "Invalid tag reading response";
return HttpStatusCode.BadRequest;
}
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
response = (TagReadingResponse)this.ExecuteRequest(request, Method, Resource, ref httpStatusCode, ref ResponseContent, response.GetType(), request.ResponseTimeOut);
if (httpStatusCode != HttpStatusCode.OK)
{
APIError = ResponseContent;
}
return httpStatusCode;
}
///
/// Activa/desactiva el modo configuración en el terminal CPS.
///
/// Petición a enviar.
/// Respuesta recibida.
/// Descripción ampliada del error cuando el resultado de la petición no ha sido satisfactorio.
/// Código de estado HTTP que informa sobre el resultado de la petición.
public HttpStatusCode ConfigurationMode(ConfigurationModeRequest request, ref ConfigurationModeResponse response, ref string APIError)
{
string Resource = "/configurationmode";
string Method = "POST";
string ResponseContent = null;
if (request == null)
{
APIError = "Invalid configuration mode request";
return HttpStatusCode.BadRequest;
}
if (response == null)
{
APIError = "Invalid configuration mode response";
return HttpStatusCode.BadRequest;
}
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
response = (ConfigurationModeResponse)this.ExecuteRequest(request, Method, Resource, ref httpStatusCode, ref ResponseContent, response.GetType(), request.ResponseTimeOut);
if (httpStatusCode != HttpStatusCode.OK)
{
APIError = ResponseContent;
}
return httpStatusCode;
}
///
/// Activa/desactiva el modo autónomo en el terminal CPS.
///
/// Petición a enviar.
/// Respuesta recibida.
/// Descripción ampliada del error cuando el resultado de la petición no ha sido satisfactorio.
/// Código de estado HTTP que informa sobre el resultado de la petición.
public HttpStatusCode StandaloneMode(StandaloneModeRequest request, ref StandaloneModeResponse response, ref string APIError)
{
string Resource = "/standalonemode";
string Method = "POST";
string ResponseContent = null;
if (request == null)
{
APIError = "Invalid standalone mode request";
return HttpStatusCode.BadRequest;
}
if (response == null)
{
APIError = "Invalid standalone mode response";
return HttpStatusCode.BadRequest;
}
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
response = (StandaloneModeResponse)this.ExecuteRequest(request, Method, Resource, ref httpStatusCode, ref ResponseContent, response.GetType(), request.ResponseTimeOut);
if (httpStatusCode != HttpStatusCode.OK)
{
APIError = ResponseContent;
}
return httpStatusCode;
}
#endregion
#region Payment
///
/// Devuelve el total cobrado por el terminal CPS desde el último cierre.
///
/// Petición a enviar.
/// Respuesta recibida.
/// Descripción ampliada del error cuando el resultado de la petición no ha sido satisfactorio.
/// Código de estado HTTP que informa sobre el resultado de la petición.
public HttpStatusCode CheckTotalPaymentAmount(CheckTotalPaymentAmountRequest request, ref CheckTotalPaymentAmountResponse response, ref string APIError)
{
string Resource = "/checktotalpaymentamount";
string Method = "POST";
string ResponseContent = null;
if (request == null)
{
APIError = "Invalid check total payment amount request";
return HttpStatusCode.BadRequest;
}
if (response == null)
{
APIError = "Invalid check total payment amount response";
return HttpStatusCode.BadRequest;
}
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
response = (CheckTotalPaymentAmountResponse)this.ExecuteRequest(request, Method, Resource, ref httpStatusCode, ref ResponseContent, response.GetType(), request.ResponseTimeOut);
if (httpStatusCode != HttpStatusCode.OK)
{
APIError = ResponseContent;
}
return httpStatusCode;
}
///
/// Inicializa a 0 el total cobrado por el terminal CPS.
///
/// Petición a enviar.
/// Respuesta recibida.
/// Descripción ampliada del error cuando el resultado de la petición no ha sido satisfactorio.
/// Código de estado HTTP que informa sobre el resultado de la petición.
public HttpStatusCode Closure(ClosureRequest request, ref ClosureResponse response, ref string APIError)
{
string Resource = "/closure";
string Method = "POST";
string ResponseContent = null;
if (request == null)
{
APIError = "Invalid closure request";
return HttpStatusCode.BadRequest;
}
if (response == null)
{
APIError = "Invalid closure response";
return HttpStatusCode.BadRequest;
}
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
response = (ClosureResponse)this.ExecuteRequest(request, Method, Resource, ref httpStatusCode, ref ResponseContent, response.GetType(), request.ResponseTimeOut);
if (httpStatusCode != HttpStatusCode.OK)
{
APIError = ResponseContent;
}
return httpStatusCode;
}
///
/// Inicia una operación de cobro sobre el terminal CPS.
///
/// Petición a enviar.
/// Respuesta recibida.
/// Descripción ampliada del error cuando el resultado de la petición no ha sido satisfactorio.
/// Código de estado HTTP que informa sobre el resultado de la petición.
public HttpStatusCode Payment(PaymentRequest request, ref PaymentResponse response, ref string APIError)
{
string Resource = "/payment";
string Method = "POST";
string ResponseContent = null;
if (request == null)
{
APIError = "Invalid payment request";
return HttpStatusCode.BadRequest;
}
if (response == null)
{
APIError = "Invalid payment response";
return HttpStatusCode.BadRequest;
}
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
response = (PaymentResponse)this.ExecuteRequest(request, Method, Resource, ref httpStatusCode, ref ResponseContent, response.GetType(), request.ResponseTimeOut);
if (httpStatusCode != HttpStatusCode.OK)
{
APIError = ResponseContent;
}
return httpStatusCode;
}
///
/// Inicia una operación de devolución de cobro (incluidas las recargas) sobre el terminal CPS.
///
/// Petición a enviar.
/// Respuesta recibida.
/// Descripción ampliada del error cuando el resultado de la petición no ha sido satisfactorio.
/// Código de estado HTTP que informa sobre el resultado de la petición.
public HttpStatusCode PaymentRefund(PaymentRefundRequest request, ref PaymentRefundResponse response, ref string APIError)
{
string Resource = "/paymentrefund";
string Method = "POST";
string ResponseContent = null;
if (request == null)
{
APIError = "Invalid payment refund request";
return HttpStatusCode.BadRequest;
}
if (response == null)
{
APIError = "Invalid payment refund response";
return HttpStatusCode.BadRequest;
}
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
response = (PaymentRefundResponse)this.ExecuteRequest(request, Method, Resource, ref httpStatusCode, ref ResponseContent, response.GetType(), request.ResponseTimeOut);
if (httpStatusCode != HttpStatusCode.OK)
{
APIError = ResponseContent;
}
return httpStatusCode;
}
///
/// Inicia una operación de preautorización de cobro sobre el terminal CPS.
///
/// Petición a enviar.
/// Respuesta recibida.
/// Descripción ampliada del error cuando el resultado de la petición no ha sido satisfactorio.
/// Código de estado HTTP que informa sobre el resultado de la petición.
public HttpStatusCode PaymentPreauthorization(PaymentPreauthorizationRequest request, ref PaymentPreauthorizationResponse response, ref string APIError)
{
string Resource = "/paymentpreauthorization";
string Method = "POST";
string ResponseContent = null;
if (request == null)
{
APIError = "Invalid payment preauthorization request";
return HttpStatusCode.BadRequest;
}
if (response == null)
{
APIError = "Invalid payment preauthorization response";
return HttpStatusCode.BadRequest;
}
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
response = (PaymentPreauthorizationResponse)this.ExecuteRequest(request, Method, Resource, ref httpStatusCode, ref ResponseContent, response.GetType(), request.ResponseTimeOut);
if (httpStatusCode != HttpStatusCode.OK)
{
APIError = ResponseContent;
}
return httpStatusCode;
}
///
/// Inicia una operación de confirmación de preautorización sobre el terminal CPS.
///
/// Petición a enviar.
/// Respuesta recibida.
/// Descripción ampliada del error cuando el resultado de la petición no ha sido satisfactorio.
/// Código de estado HTTP que informa sobre el resultado de la petición.
public HttpStatusCode PaymentConfirmation(PaymentConfirmationRequest request, ref PaymentConfirmationResponse response, ref string APIError)
{
string Resource = "/paymentconfirmation";
string Method = "POST";
string ResponseContent = null;
if (request == null)
{
APIError = "Invalid payment confirmation request";
return HttpStatusCode.BadRequest;
}
if (response == null)
{
APIError = "Invalid payment confirmation response";
return HttpStatusCode.BadRequest;
}
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
response = (PaymentConfirmationResponse)this.ExecuteRequest(request, Method, Resource, ref httpStatusCode, ref ResponseContent, response.GetType(), request.ResponseTimeOut);
if (httpStatusCode != HttpStatusCode.OK)
{
APIError = ResponseContent;
}
return httpStatusCode;
}
///
/// Inicia una operación de recarga sobre el terminal CPS.
///
/// Petición a enviar.
/// Respuesta recibida.
/// Descripción ampliada del error cuando el resultado de la petición no ha sido satisfactorio.
/// Código de estado HTTP que informa sobre el resultado de la petición.
public HttpStatusCode Recharge(RechargeRequest request, ref RechargeResponse response, ref string APIError)
{
string Resource = "/recharge";
string Method = "POST";
string ResponseContent = null;
if (request == null)
{
APIError = "Invalid recharge request";
return HttpStatusCode.BadRequest;
}
if (response == null)
{
APIError = "Invalid recharge response";
return HttpStatusCode.BadRequest;
}
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
response = (RechargeResponse)this.ExecuteRequest(request, Method, Resource, ref httpStatusCode, ref ResponseContent, response.GetType(), request.ResponseTimeOut);
if (httpStatusCode != HttpStatusCode.OK)
{
APIError = ResponseContent;
}
return httpStatusCode;
}
///
/// Inicia una operación de consulta de saldo financiero disponible sobre el terminal CPS.
///
/// Petición a enviar.
/// Respuesta recibida.
/// Descripción ampliada del error cuando el resultado de la petición no ha sido satisfactorio.
/// Código de estado HTTP que informa sobre el resultado de la petición.
public HttpStatusCode AvailableFinancialBalance(AvailableFinancialBalanceRequest request, ref AvailableFinancialBalanceResponse response, ref string APIError)
{
string Resource = "/availablefinancialbalance";
string Method = "POST";
string ResponseContent = null;
if (request == null)
{
APIError = "Invalid available financial balance request";
return HttpStatusCode.BadRequest;
}
if (response == null)
{
APIError = "Invalid available financial balance response";
return HttpStatusCode.BadRequest;
}
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
response = (AvailableFinancialBalanceResponse)this.ExecuteRequest(request, Method, Resource, ref httpStatusCode, ref ResponseContent, response.GetType(), request.ResponseTimeOut);
if (httpStatusCode != HttpStatusCode.OK)
{
APIError = ResponseContent;
}
return httpStatusCode;
}
///
/// Inicia una operación de expedición de efectivo sobre el terminal CPS.
///
/// Petición a enviar.
/// Respuesta recibida.
/// Descripción ampliada del error cuando el resultado de la petición no ha sido satisfactorio.
/// Código de estado HTTP que informa sobre el resultado de la petición.
public HttpStatusCode CashExpedition(CashExpeditionRequest request, ref CashExpeditionResponse response, ref string APIError)
{
string Resource = "/cashexpedition";
string Method = "POST";
string ResponseContent = null;
if (request == null)
{
APIError = "Invalid cash expedition request";
return HttpStatusCode.BadRequest;
}
if (response == null)
{
APIError = "Invalid cash expedition response";
return HttpStatusCode.BadRequest;
}
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
response = (CashExpeditionResponse)this.ExecuteRequest(request, Method, Resource, ref httpStatusCode, ref ResponseContent, response.GetType(), request.ResponseTimeOut);
if (httpStatusCode != HttpStatusCode.OK)
{
APIError = ResponseContent;
}
return httpStatusCode;
}
#endregion
#region Discounts
///
/// Inicia una operación de consulta de descuentos aplicables a una venta en el terminal CPS.
///
/// Petición a enviar.
/// Respuesta recibida.
/// Descripción ampliada del error cuando el resultado de la petición no ha sido satisfactorio.
/// Código de estado HTTP que informa sobre el resultado de la petición.
public HttpStatusCode DiscountsChecking(DiscountsCheckingRequest request, ref DiscountsCheckingResponse response, ref string APIError)
{
string Resource = "/discountschecking";
string Method = "POST";
string ResponseContent = null;
if (request == null)
{
APIError = "Invalid discounts checking request";
return HttpStatusCode.BadRequest;
}
if (response == null)
{
APIError = "Invalid discounts checking response";
return HttpStatusCode.BadRequest;
}
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
response = (DiscountsCheckingResponse)this.ExecuteRequest(request, Method, Resource, ref httpStatusCode, ref ResponseContent, response.GetType(), request.ResponseTimeOut);
if (httpStatusCode != HttpStatusCode.OK)
{
APIError = ResponseContent;
}
return httpStatusCode;
}
///
/// Inicia una operación de consolidación de descuentos aplicables a una venta en el terminal CPS.
///
/// Petición a enviar.
/// Respuesta recibida.
/// Descripción ampliada del error cuando el resultado de la petición no ha sido satisfactorio.
/// Código de estado HTTP que informa sobre el resultado de la petición.
public HttpStatusCode DiscountsConsolidation(DiscountsConsolidationRequest request, ref DiscountsConsolidationResponse response, ref string APIError)
{
string Resource = "/discountsconsolidation";
string Method = "POST";
string ResponseContent = null;
if (request == null)
{
APIError = "Invalid discounts consolidation request";
return HttpStatusCode.BadRequest;
}
if (response == null)
{
APIError = "Invalid discounts consolidation response";
return HttpStatusCode.BadRequest;
}
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
response = (DiscountsConsolidationResponse)this.ExecuteRequest(request, Method, Resource, ref httpStatusCode, ref ResponseContent, response.GetType(), request.ResponseTimeOut);
if (httpStatusCode != HttpStatusCode.OK)
{
APIError = ResponseContent;
}
return httpStatusCode;
}
///
/// Inicia una operación anulación de descuentos consolidados a una venta en el terminal CPS.
///
/// Petición a enviar.
/// Respuesta recibida.
/// Descripción ampliada del error cuando el resultado de la petición no ha sido satisfactorio.
/// Código de estado HTTP que informa sobre el resultado de la petición.
public HttpStatusCode ConsolidatedDiscountsAnulation(ConsolidatedDiscountsAnulationRequest request, ref ConsolidatedDiscountsAnulationResponse response, ref string APIError)
{
string Resource = "/consolidateddiscountsanulation";
string Method = "POST";
string ResponseContent = null;
if (request == null)
{
APIError = "Invalid consolidated discounts anulation request";
return HttpStatusCode.BadRequest;
}
if (response == null)
{
APIError = "Invalid consolidated discounts anulation response";
return HttpStatusCode.BadRequest;
}
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
response = (ConsolidatedDiscountsAnulationResponse)this.ExecuteRequest(request, Method, Resource, ref httpStatusCode, ref ResponseContent, response.GetType(), request.ResponseTimeOut);
if (httpStatusCode != HttpStatusCode.OK)
{
APIError = ResponseContent;
}
return httpStatusCode;
}
#endregion
#region Loyalty
///
/// Inicia una operación de concesión de puntos por venta sobre el terminal CPS.
///
/// Petición a enviar.
/// Respuesta recibida.
/// Descripción ampliada del error cuando el resultado de la petición no ha sido satisfactorio.
/// Código de estado HTTP que informa sobre el resultado de la petición.
public HttpStatusCode AwardPoints(AwardPointsRequest request, ref AwardPointsResponse response, ref string APIError)
{
string Resource = "/awardpoints";
string Method = "POST";
string ResponseContent = null;
if (request == null)
{
APIError = "Invalid award points request";
return HttpStatusCode.BadRequest;
}
if (response == null)
{
APIError = "Invalid award points response";
return HttpStatusCode.BadRequest;
}
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
response = (AwardPointsResponse)this.ExecuteRequest(request, Method, Resource, ref httpStatusCode, ref ResponseContent, response.GetType(), request.ResponseTimeOut);
if (httpStatusCode != HttpStatusCode.OK)
{
APIError = ResponseContent;
}
return httpStatusCode;
}
///
/// Inicia una operación de anulación de puntos concedidos sobre el terminal CPS.
///
/// Petición a enviar.
/// Respuesta recibida.
/// Descripción ampliada del error cuando el resultado de la petición no ha sido satisfactorio.
/// Código de estado HTTP que informa sobre el resultado de la petición.
public HttpStatusCode AwardedPointsAnulation(AwardedPointsAnulationRequest request, ref AwardedPointsAnulationResponse response, ref string APIError)
{
string Resource = "/awardedpointsanulation";
string Method = "POST";
string ResponseContent = null;
if (request == null)
{
APIError = "Invalid awarded points anulation request";
return HttpStatusCode.BadRequest;
}
if (response == null)
{
APIError = "Invalid awarded points anulation response";
return HttpStatusCode.BadRequest;
}
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
response = (AwardedPointsAnulationResponse)this.ExecuteRequest(request, Method, Resource, ref httpStatusCode, ref ResponseContent, response.GetType(), request.ResponseTimeOut);
if (httpStatusCode != HttpStatusCode.OK)
{
APIError = ResponseContent;
}
return httpStatusCode;
}
///
/// Inicia una operación de consulta de saldo de puntos sobre el terminal CPS.
///
/// Petición a enviar.
/// Respuesta recibida.
/// Descripción ampliada del error cuando el resultado de la petición no ha sido satisfactorio.
/// Código de estado HTTP que informa sobre el resultado de la petición.
public HttpStatusCode AvailablePointsBalance(AvailablePointsBalanceRequest request, ref AvailablePointsBalanceResponse response, ref string APIError)
{
string Resource = "/availablepointsbalance";
string Method = "POST";
string ResponseContent = null;
if (request == null)
{
APIError = "Invalid available points balance request";
return HttpStatusCode.BadRequest;
}
if (response == null)
{
APIError = "Invalid available points balance response";
return HttpStatusCode.BadRequest;
}
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
response = (AvailablePointsBalanceResponse)this.ExecuteRequest(request, Method, Resource, ref httpStatusCode, ref ResponseContent, response.GetType(), request.ResponseTimeOut);
if (httpStatusCode != HttpStatusCode.OK)
{
APIError = ResponseContent;
}
return httpStatusCode;
}
///
/// Inicia una operación de canjeo de puntos sobre el terminal CPS.
///
/// Petición a enviar.
/// Respuesta recibida.
/// Descripción ampliada del error cuando el resultado de la petición no ha sido satisfactorio.
/// Código de estado HTTP que informa sobre el resultado de la petición.
public HttpStatusCode RedeemPoints(RedeemPointsRequest request, ref RedeemPointsResponse response, ref string APIError)
{
string Resource = "/redeempoints";
string Method = "POST";
string ResponseContent = null;
if (request == null)
{
APIError = "Invalid redeem points request";
return HttpStatusCode.BadRequest;
}
if (response == null)
{
APIError = "Invalid redeem points response";
return HttpStatusCode.BadRequest;
}
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
response = (RedeemPointsResponse)this.ExecuteRequest(request, Method, Resource, ref httpStatusCode, ref ResponseContent, response.GetType(), request.ResponseTimeOut);
if (httpStatusCode != HttpStatusCode.OK)
{
APIError = ResponseContent;
}
return httpStatusCode;
}
///
/// Inicia una operación de anulación de canjeo de puntos sobre el terminal CPS.
///
/// Petición a enviar.
/// Respuesta recibida.
/// Descripción ampliada del error cuando el resultado de la petición no ha sido satisfactorio.
/// Código de estado HTTP que informa sobre el resultado de la petición.
public HttpStatusCode RedeemedPointsAnulation(RedeemedPointsAnulationRequest request, ref RedeemedPointsAnulationResponse response, ref string APIError)
{
string Resource = "/redeemedpointsanulation";
string Method = "POST";
string ResponseContent = null;
if (request == null)
{
APIError = "Invalid redeemed points anulation request";
return HttpStatusCode.BadRequest;
}
if (response == null)
{
APIError = "Invalid redeemed points anulation response";
return HttpStatusCode.BadRequest;
}
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
response = (RedeemedPointsAnulationResponse)this.ExecuteRequest(request, Method, Resource, ref httpStatusCode, ref ResponseContent, response.GetType(), request.ResponseTimeOut);
if (httpStatusCode != HttpStatusCode.OK)
{
APIError = ResponseContent;
}
return httpStatusCode;
}
///
/// Inicia una operación de obtención de catálogo de regalos canjeables sobre el terminal CPS.
///
/// Petición a enviar.
/// Respuesta recibida.
/// Descripción ampliada del error cuando el resultado de la petición no ha sido satisfactorio.
/// Código de estado HTTP que informa sobre el resultado de la petición.
public HttpStatusCode GetRedeemablePresents(GetRedeemablePresentsRequest request, ref GetRedeemablePresentsResponse response, ref string APIError)
{
string Resource = "/getredeemablepresents";
string Method = "POST";
string ResponseContent = null;
if (request == null)
{
APIError = "Invalid get redeemable presents request";
return HttpStatusCode.BadRequest;
}
if (response == null)
{
APIError = "Invalid get redeemable presents response";
return HttpStatusCode.BadRequest;
}
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
response = (GetRedeemablePresentsResponse)this.ExecuteRequest(request, Method, Resource, ref httpStatusCode, ref ResponseContent, response.GetType(), request.ResponseTimeOut);
if (httpStatusCode != HttpStatusCode.OK)
{
APIError = ResponseContent;
}
return httpStatusCode;
}
#endregion
#region Private Properties
private const int accessTokenExpirySeconds = 300;
private const int RefreshTokenOffset = 30;
private string CPSApiUrl;
private string _AccessToken;
private string _RefreshToken;
private bool _RefreshingToken = false;
private Timer timer;
private uint ResponseTimeOut;
private CPSAPIVersion CPSAPIVersion;
private void timerElapsedEvent(Object source, ElapsedEventArgs e)
{
int WaitSecondsBetweenRetries = 5;
int MaxRetries = RefreshTokenOffset / WaitSecondsBetweenRetries;
int Retry = 1;
List APIErrors = new List();
try
{
_RefreshingToken = true;
CPSAPIModels.RefreshTokenRequest request = new CPSAPIModels.RefreshTokenRequest();
request.CPSAPIVersion = this.CPSAPIVersion;
request.AccessToken = this._AccessToken;
request.RefreshToken = this._RefreshToken;
string APIError = null;
CPSAPIModels.RefreshTokenResponse response = new CPSAPIModels.RefreshTokenResponse();
HttpStatusCode RefreshTokenHttpStatusCode = RefreshToken(request, ref response, ref APIError);
while (RefreshTokenHttpStatusCode != HttpStatusCode.OK && Retry<=MaxRetries)
{
APIErrors.Add("Retry Number: " + Retry.ToString() + " Datetime: "+DateTime.Now.ToString()+" - APIError: " + APIError);
System.Threading.Thread.Sleep(WaitSecondsBetweenRetries*1000);
Retry += 1;
response = new CPSAPIModels.RefreshTokenResponse();
APIError = null;
RefreshTokenHttpStatusCode = RefreshToken(request, ref response, ref APIError);
}
}
catch
{
}
finally
{
_RefreshingToken = false;
}
if (Retry > MaxRetries)
{
this.OnTokenNotRefreshed(new TokenNotRefreshedEventArgs(String.Join(System.Environment.NewLine, APIErrors)));
}
}
protected void OnTokenNotRefreshed(TokenNotRefreshedEventArgs e)
{
if (TokenNotRefreshed != null)
{
TokenNotRefreshed(this, e);
}
}
private object ExecuteRequest(object Request, string RequestMethod, string Resource, ref HttpStatusCode httpStatusCode, ref string ResponseContent, Type ResponseType, uint? ResponseTimeOut, bool AuthorizationNeeded = true)
{
object Response = null;
string JSONRequest = null;
string RequestContentType = null;
if (Request != null)
{
JSONRequest = JSONSerialization(Request);
RequestContentType = "application/json";
}
string ResponseContentType = null;
uint TimeOut = this.ResponseTimeOut;
if (ResponseTimeOut.HasValue)
TimeOut = ResponseTimeOut.Value;
httpStatusCode = Execute_HTTP_Command(this.CPSApiUrl + Resource, RequestMethod, ref ResponseContent, ref ResponseContentType, TimeOut, JSONRequest, RequestContentType, AuthorizationNeeded, Request != null && Request.GetType()!=typeof(CPSAPIModels.RefreshTokenRequest));
if (httpStatusCode == HttpStatusCode.OK)
{
if (ResponseContent != null && ResponseType != null && ResponseContentType.Contains("application/json"))
{
Response = JSONDeserialization(ResponseContent, ResponseType);
}
}
return Response;
}
private string JSONSerialization(object JSONObject)
{
MemoryStream Stream = new MemoryStream();
DataContractJsonSerializer ser = new DataContractJsonSerializer(JSONObject.GetType());
ser.WriteObject(Stream, JSONObject);
Stream.Position = 0;
StreamReader reader = new StreamReader(Stream, System.Text.Encoding.UTF8);
return reader.ReadToEnd();
}
private object JSONDeserialization(string Serialization, Type Type)
{
byte[] SerializationAsBytes = new System.Text.UTF8Encoding().GetBytes(Serialization);
System.IO.MemoryStream Stream = new System.IO.MemoryStream(SerializationAsBytes);
Stream.Position = 0;
DataContractJsonSerializer ser = new DataContractJsonSerializer(Type);
return ser.ReadObject(Stream);
}
private HttpStatusCode Execute_HTTP_Command(string url, string RequestMethod, ref string ResponseContent, ref string ResponseContentType, uint TimeOut = 100, string RequestContent = null, string RequestContentType = null, bool AuthorizationNeeded = true, bool WaitRefreshingToken = true)
{
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(ValidateServerCertificate);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
if (TimeOut == 0)
request.Timeout = System.Threading.Timeout.Infinite;
else
request.Timeout = (int)TimeOut * 1000;
request.Method = RequestMethod;
if (AuthorizationNeeded)
{
while (WaitRefreshingToken && this._RefreshingToken)
{
System.Threading.Thread.Sleep(150);
}
request.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + this._AccessToken);
}
HttpWebResponse response = null;
try
{
if (!String.IsNullOrEmpty(RequestContent))
{
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
Byte[] byteArray = encoding.GetBytes(RequestContent);
request.ContentLength = byteArray.Length;
request.ContentType = RequestContentType;
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
}
response = (HttpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream, System.Text.Encoding.UTF8);
ResponseContentType = response.ContentType;
ResponseContent = reader.ReadToEnd();
httpStatusCode = response.StatusCode;
}
catch (System.Net.WebException Ex)
{
if (Ex.Response != null && Ex.Response.GetType().Equals(typeof(HttpWebResponse)))
{
httpStatusCode = ((HttpWebResponse)(Ex.Response)).StatusCode;
}
}
finally
{
if (response!=null)
{
response.Close();
}
}
return httpStatusCode;
}
private bool ValidateServerCertificate(Object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
return true;
}
private void UpdateTokens(string accessToken, string refreshToken)
{
timer.Stop();
this._AccessToken = accessToken;
this._RefreshToken = refreshToken;
timer.Start();
}
private HttpStatusCode RefreshToken(CPSAPIModels.RefreshTokenRequest request, ref CPSAPIModels.RefreshTokenResponse response, ref string APIError)
{
string Resource = "/refreshtoken";
string Method = "POST";
string ResponseContent = null;
if (request == null)
{
APIError = "Invalid refresh token request";
return HttpStatusCode.BadRequest;
}
if (response == null)
{
APIError = "Invalid refresh token response";
return HttpStatusCode.BadRequest;
}
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;
response = (RefreshTokenResponse)this.ExecuteRequest(request, Method, Resource, ref httpStatusCode, ref ResponseContent, response.GetType(), null, false);
if (httpStatusCode != HttpStatusCode.OK)
{
APIError = ResponseContent;
}
else
{
UpdateTokens(response.AccessToken, response.RefreshToken);
}
return httpStatusCode;
}
#endregion
}
public delegate void TokenNotRefreshedEventHandler(object sender, TokenNotRefreshedEventArgs e);
public class TokenNotRefreshedEventArgs : System.EventArgs
{
private string _APIErrors;
public string APIErrors
{
get
{
return _APIErrors;
}
}
public TokenNotRefreshedEventArgs(string APIErrors)
{
this._APIErrors = APIErrors;
}
}
}