/// <summary> /// Cancels the payment from the payment provider. This is often used when you need to call external services to handle the cancel process. /// </summary> /// <param name="payment">The payment.</param> /// <param name="status">The status.</param> /// <returns></returns> protected override bool CancelPaymentInternal(Payment payment, out string status) { var paymentMethod = payment.PaymentMethod; long accountNumber = Convert.ToInt64(paymentMethod.DynamicProperty <string>().AccountNumber.ToString()); var key = paymentMethod.DynamicProperty <string>().Key; int transactionNumber; if (!int.TryParse(payment.TransactionId, out transactionNumber)) { throw new FormatException(string.Format("Could not convert: {0} to an int.", payment.TransactionId)); } var preHash = accountNumber.ToString() + transactionNumber; var hash = Md5Computer.GetPreHash(preHash, key); var xml = GetPxOrderSoapClient(payment.PaymentMethod).Cancel2(accountNumber, transactionNumber, hash); var message = new PayExXmlMessage(xml); if (message.StatusCode && message.TransactionStatus == 4 && message.OriginalTransactionNumber.ToString() == payment.TransactionId) { payment.TransactionId = message.TransactionNumber.ToString(); payment.Save(); status = PaymentMessages.CancelSuccess; return(true); } status = PaymentMessages.CancelFailed + ": " + message.ErrorDescription; return(false); }
/// <summary> /// Processed the callback received from the payment provider. /// </summary> /// <param name="payment">The payment.</param> public override void ProcessCallback(Payment payment) { if (payment.PaymentStatus.PaymentStatusId != (int)PaymentStatusCode.PendingAuthorization) { return; } int transactionid = GetTransactionIdFromHttpRequestThrowsExceptionIfNotInt(); var paymentStatus = PaymentStatusCode.Authorized; if (payment.PaymentMethod.DynamicProperty <bool>().UseMd5) { var parameters = new Dictionary <string, string>(); foreach (var key in HttpContext.Current.Request.QueryString.AllKeys.Where(x => x != "hash")) { parameters.Add(key, HttpContext.Current.Request.QueryString[key]); } string md5Key = payment.PaymentMethod.DynamicProperty <string>().Key; var calculatedMd5Key = Md5Computer.GetPreMd5Key(parameters, md5Key); const string format = "When using md5 \"{0}\" cannot be null or empty."; var md5ReceivedFromEPay = GetParameter("hash", format); if (!md5ReceivedFromEPay.Equals(calculatedMd5Key)) { paymentStatus = PaymentStatusCode.Declined; } } payment.PaymentStatus = PaymentStatus.Get((int)paymentStatus); payment.TransactionId = transactionid.ToString(); ProcessPaymentRequest(new PaymentRequest(payment.PurchaseOrder, payment)); }
/// <summary> /// Refunds the payment from the payment provider. This is often used when you need to call external services to handle the refund process. /// </summary> /// <param name="payment">The payment.</param> /// <param name="status">The status.</param> /// <returns></returns> protected override bool RefundPaymentInternal(Payment payment, out string status) { var paymentMethod = payment.PaymentMethod; long accountNumber = Convert.ToInt64(paymentMethod.DynamicProperty <string>().AccountNumber.ToString()); string key = paymentMethod.DynamicProperty <string>().Key.ToString(); var amount = payment.Amount.ToCents(); var transactionRef = int.Parse(payment.TransactionId); var hashInput = accountNumber + "" + transactionRef + "" + amount + "" + payment.ReferenceId; var preHash = Md5Computer.GetPreHash(hashInput, key); var xml = GetPxOrderSoapClient(payment.PaymentMethod).Credit3(accountNumber, transactionRef, amount, payment.ReferenceId, preHash); var message = new PayExXmlMessage(xml); if (message.StatusCode && message.TransactionStatus == 2) { status = PaymentMessages.RefundSuccess; payment.TransactionId = message.TransactionNumber.ToString(); return(true); } status = PaymentMessages.RefundFailed + ": " + message.ErrorDescription; return(false); }
/// <summary> /// Acquires the payment from the payment provider. This is often used when you need to call external services to handle the acquire process. /// </summary> /// <param name="payment">The payment.</param> /// <param name="status">The status.</param> /// <returns></returns> protected override bool AcquirePaymentInternal(Payment payment, out string status) { var paymentMethod = payment.PaymentMethod; long accountNumber = Convert.ToInt64(paymentMethod.DynamicProperty <string>().AccountNumber.ToString()); var key = paymentMethod.DynamicProperty <string>().Key; int transactionNumber; if (!int.TryParse(payment.TransactionId, out transactionNumber)) { throw new Exception(string.Format("Could not convert: {0} to an int.", payment.TransactionId)); } var amount = Convert.ToInt32(payment.Amount * 100); var referenceId = payment.ReferenceId; var preHash = accountNumber.ToString() + transactionNumber + amount + referenceId; var hash = Md5Computer.GetPreHash(preHash, key); var xml = GetPxOrderSoapClient(payment.PaymentMethod).Capture3(accountNumber, transactionNumber, amount, referenceId, hash); var message = new PayExXmlMessage(xml); if (message.StatusCode && message.TransactionStatus == 6) { payment.TransactionId = message.TransactionNumber.ToString(); status = PaymentMessages.AcquireSuccess; return(true); } status = PaymentMessages.AcquireFailed + ": " + message.ErrorDescription; return(false); }
/// <summary> /// Processed the callback received from the payment provider. /// </summary> /// <param name="payment">The payment.</param> public override void ProcessCallback(Payment payment) { Guard.Against.PaymentNotPendingAuthorization(payment); Guard.Against.NoHttpContext(_webRuntimeInspector); Guard.Against.MissingParameterInResponse("orderRef"); var paymentMethod = payment.PaymentMethod; var acceptUrl = paymentMethod.DynamicProperty <string>().AcceptUrl; var cancelUrlForPaymentMethod = paymentMethod.DynamicProperty <string>().CancelUrl; long accountNumber = Convert.ToInt64(paymentMethod.DynamicProperty <string>().AccountNumber.ToString()); var key = paymentMethod.DynamicProperty <string>().Key; string orderReference = GetOrderReferenceFromRequest(); string hash = Md5Computer.GetPreHash(accountNumber + orderReference, key); PayExXmlMessage completeResponseMessage = CompletePayment(payment, accountNumber, orderReference, hash); Guard.Against.ResponseWasNotOk(completeResponseMessage, payment); Guard.Against.PaymentAlreadyCompleted(completeResponseMessage, payment); if (TransactionStatusNotAuthorized(completeResponseMessage)) { HandleDeclinedResponse(payment, cancelUrlForPaymentMethod); } else { HandleAuthorizedResponse(payment, acceptUrl, completeResponseMessage.TransactionNumber.ToString()); } }
/// <summary> /// Processed the callback received from the payment provider. /// </summary> /// <param name="payment">The payment.</param> public override void ProcessCallback(Payment payment) { string abortUrl = payment.PaymentMethod.DynamicProperty <string>().AbortUrl; string successUrl = payment.PaymentMethod.DynamicProperty <string>().SuccessUrl; string failureUrl = payment.PaymentMethod.DynamicProperty <string>().FailureUrl; string txType = payment.PaymentMethod.DynamicProperty <string>().TxType; if (payment.PaymentStatus.PaymentStatusId != (int)PaymentStatusCode.PendingAuthorization) { return; } HttpRequest request = HttpContext.Current.Request; IList <string> list = GetSignatureParameterList(request, payment.GetSagePaymentInfo(FieldCode.SecurityKey), payment.PaymentMethod); string vpsSignature = Md5Computer.VpsSignature(list).ToUpper(); var orgVpsSignature = request["VPSSignature"]; if (string.IsNullOrEmpty(orgVpsSignature)) { throw new Exception("VPSSignature is null in the HttpRequest."); } if (!vpsSignature.Equals(orgVpsSignature)) { throw new Exception(string.Format("VPS Signatures are not equal, Calculated Signature: {0}, From HttpRequest: {1}.", vpsSignature, orgVpsSignature)); } string vpsTxId = request["VPSTxId"]; string txAuthNo = request["TxAuthNo"]; if (string.IsNullOrEmpty(vpsTxId)) { throw new ArgumentException(@"vpsTxId must be present in query string."); } var statusCodeString = request["Status"]; if (string.IsNullOrEmpty(statusCodeString)) { throw new Exception("NullOrEmptystatus response from SagePay."); } var status = GetStatus(statusCodeString); var authNo = GetHttpRequestValueUrlDecoded(request, "TxAuthNo"); var txId = GetHttpRequestValueUrlDecoded(request, "VPSTxId"); payment.SetSagePaymentInfo(FieldCode.VPSTxId, txId); payment.SetSagePaymentInfo(FieldCode.TxAuthNo, authNo); IDictionary <string, string> results = new Dictionary <string, string>(); switch (status) { case SagePayStatusCode.Ok: case SagePayStatusCode.Registered: case SagePayStatusCode.Authenticated: if (txType.Equals("PAYMENT", StringComparison.InvariantCultureIgnoreCase)) { payment.PaymentStatus = PaymentStatus.Get((int)PaymentStatusCode.Acquired); } else { payment.PaymentStatus = PaymentStatus.Get((int)PaymentStatusCode.Authorized); } ProcessPaymentRequest(new PaymentRequest(payment.PurchaseOrder, payment)); results.Add("Status", "OK"); results.Add("RedirectURL", new Uri(_absoluteUrlService.GetAbsoluteUrl(successUrl)).AddOrderGuidParameter(payment.PurchaseOrder).ToString()); results.Add("StatusDetail", "All went well."); break; case SagePayStatusCode.Error: results.Add("Status", "INVALID"); results.Add("RedirectURL", new Uri(_absoluteUrlService.GetAbsoluteUrl(failureUrl)).AddOrderGuidParameter(payment.PurchaseOrder).ToString()); results.Add("StatusDetail", string.Format("Error: {0}.", status)); break; case SagePayStatusCode.Malformed: case SagePayStatusCode.Invalid: case SagePayStatusCode.Unknown: case SagePayStatusCode.Rejected: results.Add("Status", "OK"); results.Add("RedirectURL", new Uri(_absoluteUrlService.GetAbsoluteUrl(failureUrl)).AddOrderGuidParameter(payment.PurchaseOrder).ToString()); results.Add("StatusDetail", string.Format("Error: {0}.", status)); break; case SagePayStatusCode.Abort: results.Add("Status", "OK"); results.Add("RedirectURL", new Uri(_absoluteUrlService.GetAbsoluteUrl(abortUrl)).AddOrderGuidParameter(payment.PurchaseOrder).ToString()); results.Add("StatusDetail", string.Format("Error: {0}.", status)); break; default: throw new ArgumentOutOfRangeException(); } payment.Save(); WriteResponse(results); }
public override Payment RequestPayment(PaymentRequest paymentRequest) { var paymentMethod = paymentRequest.PaymentMethod; string callBackUrl = paymentMethod.DynamicProperty <string>().CallbackUrl; string cancelUrlForPaymentMethod = paymentMethod.DynamicProperty <string>().CancelUrl; long accountNumber = Convert.ToInt64(paymentMethod.DynamicProperty <string>().AccountNumber.ToString()); string key = paymentMethod.DynamicProperty <string>().Key; if (paymentRequest.Payment == null) { paymentRequest.Payment = CreatePayment(paymentRequest); } var vatRate = Convert.ToInt32(paymentRequest.Payment.PurchaseOrder.OrderLines.First().VATRate * 100) * 100; var price = paymentRequest.Payment.Amount.ToCents(); const string purchaseOperation = "AUTHORIZATION"; var isoCode = paymentRequest.PurchaseOrder.BillingCurrency.ISOCode; var productNumber = paymentRequest.Payment.ReferenceId; var clientIpAddress = HttpContext.Current.Request.UserHostAddress; const string description = "Sum"; var returnUrl = _callbackUrl.GetCallbackUrl(callBackUrl, paymentRequest.Payment); const string creditcard = "CREDITCARD"; var clientLanguage = LocalizationContext.CurrentCultureCode; string cancelUrl = AbstractPageBuilder.GetAbsoluteUrl(cancelUrlForPaymentMethod); string value = accountNumber + purchaseOperation + price + "" + isoCode + vatRate + productNumber + productNumber + description + clientIpAddress + "" + "" + "" + returnUrl + creditcard + "" + cancelUrl + clientLanguage; var preHash = Md5Computer.GetPreHash(value, key); var pxOrderSoapClient = GetPxOrderSoapClient(paymentMethod); string xml = pxOrderSoapClient.Initialize7( accountNumber, purchaseOperation, price, "", isoCode, vatRate, productNumber, productNumber, description, clientIpAddress, "", "", "", returnUrl, creditcard, "", cancelUrl, clientLanguage, preHash ); var message = new PayExXmlMessage(xml); if (!message.StatusCode) { throw new Exception(string.Format("The webservice returned: {0}.", xml)); } // To avoid Thread being aborted exception allow the request to complete before redirecting. HttpContext.Current.Response.Redirect(message.RedirectUrl); return(paymentRequest.Payment); }