public async Task <HttpStatusCodeResult> ProcessCardcomRecurringPayment() { #region ### IPN Parameters ### /* * there are two events trigger this endpoint * 1. Set Recurring Payment (after purchase) * 2. Recurring Charge (dashboard) * * --- * * POST http://localhost:5015/Purchase/ProcessCardcomRecurringPayment * H Content-Type: application/x-www-form-urlencoded * AccountId=1046&RecurringId=20054&RecordType=MasterRecurring&TerminalNumber=118599&InternalDecription=My+Morning+Love&CreateDate=18%2f01%2f2021+00%2f00&NextDateToBill=18%2f02%2f2021+00%2f00&TotalNumOfBills=999999&NumOfPaymentsAlreadyCharged=0&IsActive=True&TimeIntervalId=1&FinalDebitCoinId=1&IsInvoiceCreate=True&IsPrintNumOfPayments=False&DepartmentId=0&UserId=0&IsByProducts=False&FlexItem.InvoiceDescription=My+Morning+Love&FlexItem.Price=29.9000&FlexItem.IsLinkTo=False&FlexItem.IsPriceIncludeVat=True&FlexItem.LinkToId=1&FlexItem.OpenRateForLinkTo=0.0000&IsReNewOrder=False&IsPrintBillMonth=False&ReturnValue=14.9%7c2%7c383%7cde3cd3ce-853d-44ed-b342-a75b3622bd62 * * Set Recurring Payment (after purchase) * -------------------------------------- * AccountId=1046 * RecurringId=20054 * RecordType=MasterRecurring * TerminalNumber=118599 * InternalDecription=My Morning Love * CreateDate=18/01/2021 00/00 * NextDateToBill=18/02/2021 00/00 * TotalNumOfBills=999999 * NumOfPaymentsAlreadyCharged=0 * IsActive=True * TimeIntervalId=1 * FinalDebitCoinId=1 * IsInvoiceCreate=True * IsPrintNumOfPayments=False * DepartmentId=0 * UserId=0 * IsByProducts=False * FlexItem.InvoiceDescription=My Morning Love * FlexItem.Price=29.9000 * FlexItem.IsLinkTo=False * FlexItem.IsPriceIncludeVat=True * FlexItem.LinkToId=1 * FlexItem.OpenRateForLinkTo=0.0000 * IsReNewOrder=False * IsPrintBillMonth=False * ReturnValue=14.9|2|383|de3cd3ce-853d-44ed-b342-a75b3622bd62 * * --- * * POST http://localhost:5015/Purchase/ProcessCardcomRecurringPayment * H Content-Type: application/x-www-form-urlencoded * AccountId=1007&RecurringId=20009&RowID=20&RecordType=DetailRecurring&Status=SUCCESSFUL&TerminalNumber=118599&CreateDate=18%2f01%2f2021+00%2f00&InvoiceDescription=My+Morning+Love&LastBillDate=18%2f01%2f2021+05%2f18&OriginalNextDateToBill=18%2f01%2f2021+00%2f00&FinalDebitCoinId=1&DepartmentId=0&IsInvoiceCreate=True&UserId=0&PaymentNum=2&IsReNewOrder=False&Quantity=1.00&IsIncludesVAT=True&VAT=0.170&Sum=29.90&SumNoVat=26&InternalDealNumber=81256468&ResposeCode=0&ProcessID=16&BillingAttempts=1&ActualBillingType=CreditCard&ReturnValue=29.9%7c2%7c31%7c * * Recurring Charge (dashboard) * ---------------------------- * AccountId=1007 * RecurringId=20009 * RowID=20 * RecordType=DetailRecurring * Status=SUCCESSFUL * TerminalNumber=118599 * CreateDate=18/01/2021 00/00 * InvoiceDescription=My Morning Love * LastBillDate=18/01/2021 05/18 * OriginalNextDateToBill=18/01/2021 00/00 * FinalDebitCoinId=1 * DepartmentId=0 * IsInvoiceCreate=True * UserId=0 * PaymentNum=2 * IsReNewOrder=False * Quantity=1.00 * IsIncludesVAT=True * VAT=0.170 * Sum=29.90 * SumNoVat=26 * InternalDealNumber=81256468 * ResposeCode=0 * ProcessID=16 * BillingAttempts=1 * ActualBillingType=CreditCard * ReturnValue=29.9|2|31| */ #endregion var step = 0; try { LoggerSingleton.Instance.Info("Cardcom", "Process-Recurring-Payment"); var formVariables = Helper.Form2Dictionary(Request); var type = formVariables["RecordType"]; step = 1; var raw = string.Join("&", formVariables.Select(x => $"{x.Key}={x.Value}")); step = 2; if (type == "MasterRecurring") { LoggerSingleton.Instance.Info("Cardcom", "Establish-Recurring-Payment", new List <string> { raw }); return(new HttpStatusCodeResult(HttpStatusCode.OK, "OK")); } // type: "DetailRecurring" LoggerSingleton.Instance.Info("Cardcom", "Recurring-Payment", new List <string> { raw }); var transactionsBLL = new TransactionsBLL(); var couponsBLL = new CouponsBLL(); var subscriptionsBLL = new SubscriptionsBLL(); step = 3; // Collect Transaction details var transaction = new Transaction(); transaction.Raw = transaction.RawDetails = raw; transaction.Code = formVariables["Status"]; transaction.StatusCode = formVariables["Status"] == "SUCCESSFUL" ? 0 : 100; transaction.CardStatusCode = 0; transaction.Token = ""; transaction.TokenExpiry = ""; transaction.TokenApprovalNumber = ""; transaction.CardOwnerId = ""; transaction.CardExpiry = ""; transaction.CardSuffix = ""; transaction.InvoiceStatusCode = 0; transaction.InvoiceNumber = ""; transaction.InvoiceType = 0; transaction.NumOfPayments = 1; step = 4; // Collect custom details // returnValue: PRICE|PACKAGE|USER_ID|COUPON (e.g: 39.90|3|1|98F41F8F-6F6C-4A0A-A7D4-D719A41A6BD7) var returnValue = formVariables["ReturnValue"].Trim(); var returnValueSlices = returnValue.Split('|'); transaction.Price = Convert.ToSingle(returnValueSlices[0]); transaction.PackageId = Convert.ToInt32(returnValueSlices[1]); transaction.SubscriptionId = Convert.ToInt32(returnValueSlices[2]); step = 5; var coupon = await couponsBLL.Find(returnValueSlices[3]); transaction.Coupon = coupon == null ? "" : coupon.Code.ToString(); step = 6; // Create Transaction Row var transactionId = await transactionsBLL.Save(transaction); if (transactionId <= 0) { throw new Exception($"Error while trying to save an incoming transaction ({transaction.Code})"); } transaction.RowId = transactionId; step = 7; if (transaction.StatusCode != 0) { step = 8; var success1 = await subscriptionsBLL.SaveRegistrationStep(transaction.SubscriptionId, "TransactionFailed"); if (!success1) { LoggerSingleton.Instance.Info("Cardcom", $"SaveRegistrationStep Failed For User #{transaction.SubscriptionId}"); } throw new Exception($"transaction code error. status-code {transaction.StatusCode} ({transaction.Code})"); } step = 9; var packageDetails = PackagesSingleton.Instance.GetPackage(transaction.PackageId); // calculate the valid-until, the Recurring Payments Start Date and the corresponding interval id DateTime?validUntil = packageDetails.ValidUntil; step = 10; // update ValidUntil var successValidUntil = await subscriptionsBLL.SaveValidUntil(transaction.SubscriptionId, validUntil); if (!successValidUntil) { LoggerSingleton.Instance.Info("Cardcom", "SaveValidUntil Failed", new List <string> { $"#{transaction.SubscriptionId}", }); } step = 11; return(new HttpStatusCodeResult(HttpStatusCode.OK, "OK")); } catch (Exception ex) { ex.Data.Add("step", step); ex.Data.Add("Method", "ProcessCardcomRecurringPayment"); LoggerSingleton.Instance.Error("Cardcom", ex); return(new HttpStatusCodeResult(HttpStatusCode.InternalServerError, ex.Message)); } }
public async Task <HttpStatusCodeResult> ProcessCardcomTransaction() { #region ### IPN Parameters ### /* * GET https://localhost:44373/Purchase/ProcessCardcomTransaction?terminalnumber=1000&lowprofilecode=2467a885-1f97-40d5-8b5f-42222ce64c80&Operation=2&DealRespone=0&DealResponse=0&TokenResponse=0&InvoiceResponseCode=0&OperationResponse=0&OperationResponseText=OK&ReturnValue=39.90%7c3%7c1%7c98F41F8F-6F6C-4A0A-A7D4-D719A41A6BD7 * * --- * * terminalnumber=1000 * lowprofilecode=2467a885-1f97-40d5-8b5f-42222ce64c80 * Operation=2 * DealResponse=0 * TokenResponse=0 * InvoiceResponseCode=0 * OperationResponse=0 * OperationResponseText=OK * ReturnValue=39.90|3|1|98F41F8F-6F6C-4A0A-A7D4-D719A41A6BD7 */ #endregion var step = 0; try { LoggerSingleton.Instance.Info("Cardcom", "Process-Transaction", new List <string> { $"QueryString: {Request.QueryString}" }); var transactionsBLL = new TransactionsBLL(); var couponsBLL = new CouponsBLL(); var subscriptionsBLL = new SubscriptionsBLL(); var cardcomManager = new CardcomManager(ConfigSingleton.Instance.CardcomTerminal, ConfigSingleton.Instance.CardcomUserName, TerminalNoCvv: ConfigSingleton.Instance.CardcomTerminalNoCvv); step = 1; // Collect basic details var transaction = new Transaction(); transaction.Raw = Request.QueryString?.ToString(); transaction.Code = Request.QueryString["lowprofilecode"]; transaction.StatusCode = Convert.ToInt32(Request.QueryString["OperationResponse"]); transaction.CardStatusCode = Convert.ToInt32(Request.QueryString["DealResponse"]); step = 2; // Collect extra details var detailsResponse = cardcomManager.GetTransactionDetails(transaction.Code); step = 3; if (Convert.ToInt32(detailsResponse.Details["ResponseCode"]) != 0) { throw new Exception($"Error while trying to get details. status-code {detailsResponse.Details["ResponseCode"]} ({transaction.Code})"); } step = 4; transaction.RawDetails = detailsResponse.Raw; transaction.Token = detailsResponse.Details["Token"] ?? ""; transaction.TokenExpiry = detailsResponse.Details["TokenExDate"] ?? ""; transaction.TokenApprovalNumber = detailsResponse.Details["TokenApprovalNumber"] ?? ""; transaction.CardOwnerId = detailsResponse.Details["CardOwnerID"] ?? ""; // fix format > MM (e.g: 7 to 07) var CardValidityMonth = detailsResponse.Details["CardValidityMonth"] ?? ""; if (CardValidityMonth.Length == 1) { CardValidityMonth = $"0{CardValidityMonth}"; } transaction.CardExpiry = $"{detailsResponse.Details["CardValidityYear"] ?? ""}{CardValidityMonth}"; transaction.CardSuffix = detailsResponse.Details["ExtShvaParams.CardNumber5"] ?? ""; transaction.InvoiceStatusCode = Convert.ToInt32(detailsResponse.Details["InvoiceResponseCode"]); transaction.InvoiceNumber = detailsResponse.Details["InvoiceNumber"] ?? ""; transaction.InvoiceType = Convert.ToInt32(detailsResponse.Details["InvoiceType"] ?? "0"); transaction.NumOfPayments = Convert.ToInt32(detailsResponse.Details["NumOfPayments"] ?? "1"); step = 5; // Collect custom details // returnValue: PRICE|PACKAGE|USER_ID|COUPON (e.g: 39.90|3|1|98F41F8F-6F6C-4A0A-A7D4-D719A41A6BD7) var returnValue = detailsResponse.Details["ReturnValue"].Trim(); var returnValueSlices = returnValue.Split('|'); transaction.Price = Convert.ToSingle(returnValueSlices[0]); transaction.PackageId = Convert.ToInt32(returnValueSlices[1]); transaction.SubscriptionId = Convert.ToInt32(returnValueSlices[2]); var coupon = await couponsBLL.Find(returnValueSlices[3]); transaction.Coupon = coupon == null ? "" : coupon.Code.ToString(); step = 6; // Create Transaction Row var transactionId = await transactionsBLL.Save(transaction); if (transactionId <= 0) { throw new Exception($"Error while trying to save an incoming transaction ({transaction.Code})"); } transaction.RowId = transactionId; step = 7; if (transaction.StatusCode != 0) { var success1 = await subscriptionsBLL.SaveRegistrationStep(transaction.SubscriptionId, "TransactionFailed"); if (!success1) { LoggerSingleton.Instance.Info("Cardcom", $"SaveRegistrationStep Failed For User #{transaction.SubscriptionId}"); } throw new Exception($"transaction code error. status-code {transaction.StatusCode} ({transaction.Code})"); } step = 8; // Update Coupon Capacity if (!string.IsNullOrEmpty(transaction.Coupon)) { var successCapacity = await couponsBLL.IncreaseCapacityInUse(Guid.Parse(transaction.Coupon)); if (!successCapacity) { LoggerSingleton.Instance.Info("Cardcom", "IncreaseCapacity Failed", new List <string> { $"#{transaction.SubscriptionId}", transaction.Coupon }); } } step = 9; var packageDetails = PackagesSingleton.Instance.GetPackage(transaction.PackageId); step = 10; // calculate the valid-until, the Recurring Payments Start Date and the corresponding interval id DateTime?validUntil = packageDetails.ValidUntil; var timeIntervalId = packageDetails.CardcomIntervalId; step = 11; // update ValidUntil var successValidUntil = await subscriptionsBLL.SaveValidUntil(transaction.SubscriptionId, validUntil); if (!successValidUntil) { LoggerSingleton.Instance.Info("Cardcom", "SaveValidUntil Failed", new List <string> { $"#{transaction.SubscriptionId}", }); } step = 12; var chargeDetails = new Entities.ChargeDetails { SubscriptionId = transaction.SubscriptionId, Token = transaction.Token, IsAutoRenewal = true, CardSuffix = transaction.CardSuffix, CardExpiry = transaction.CardExpiry, CardOwnerId = transaction.CardOwnerId, Code = transaction.Code }; // save charge details for this subscription var successChargeDetails = await subscriptionsBLL.SaveChargeDetails(chargeDetails); if (!successChargeDetails) { LoggerSingleton.Instance.Info("Cardcom", "SaveChargeDetails Failed", new List <string> { $"#{chargeDetails.SubscriptionId}", chargeDetails.Token }); } step = 13; // load subscription var subscription = await subscriptionsBLL.Get(transaction.SubscriptionId); step = 14; var responseCharge = cardcomManager.SetRecurringCharge( chargeDetails.Code, "My Morning Love", validUntil.Value, timeIntervalId, new List <CardcomIFrameSourceItem> { new CardcomIFrameSourceItem { Description = packageDetails.Name, Price = packageDetails.Price, Quantity = 1 } }, returnValue, new CardcomInvoiceDetails { CustomerId = subscription.Details.Id.ToString(), CustomerName = subscription.Details.FullName, Email = subscription.Details.Email, SendEmail = true } ); step = 15; if (responseCharge.Details["ResponseCode"] != "0") { LoggerSingleton.Instance.Info("Cardcom", $"SetRecurringCharge Failed With Code {responseCharge.Details["ResponseCode"]}"); await subscriptionsBLL.SaveAutoRenewal(transaction.SubscriptionId, false); // recurring charge has failed > mark user as AutoRenewal false } step = 16; chargeDetails.RecurringId = Convert.ToInt32(responseCharge.Details["Recurring0.RecurringId"]); successChargeDetails = await subscriptionsBLL.SaveChargeDetails(chargeDetails); if (!successChargeDetails) { LoggerSingleton.Instance.Info("Cardcom", "SaveChargeDetails (with RecurringId) Failed", new List <string> { $"#{chargeDetails.SubscriptionId}", chargeDetails.Token, responseCharge.Details["Recurring0.RecurringId"] }); } step = 17; var success2 = await subscriptionsBLL.SaveRegistrationStep(subscription.Details.Id, "Completed"); if (!success2) { LoggerSingleton.Instance.Info("Cardcom", $"SaveRegistrationStep Failed For User #{subscription.Details.Id}"); } return(new HttpStatusCodeResult(HttpStatusCode.OK, "OK")); } catch (Exception ex) { ex.Data.Add("step", step); ex.Data.Add("Method", "ProcessCardcomTransaction"); LoggerSingleton.Instance.Error("Cardcom", ex); return(new HttpStatusCodeResult(HttpStatusCode.InternalServerError, ex.Message)); } }
public async Task <string> ProcessCardcomTransaction() { #region ### IPN Parameters ### /* * GET https://localhost:44373/Purchase/ProcessCardcomTransaction?terminalnumber=1000&lowprofilecode=2467a885-1f97-40d5-8b5f-42222ce64c80&Operation=2&DealRespone=0&DealResponse=0&TokenResponse=0&InvoiceResponseCode=0&OperationResponse=0&OperationResponseText=OK&ReturnValue=39.90%7c3%7c1%7c98F41F8F-6F6C-4A0A-A7D4-D719A41A6BD7 * * --- * * terminalnumber=1000 * lowprofilecode=2467a885-1f97-40d5-8b5f-42222ce64c80 * Operation=2 * DealResponse=0 * TokenResponse=0 * InvoiceResponseCode=0 * OperationResponse=0 * OperationResponseText=OK * ReturnValue=39.90|3|1|98F41F8F-6F6C-4A0A-A7D4-D719A41A6BD7 */ #endregion var step = 0; var isTransactionFailed = false; var transaction = new Transaction(); var httpResult = ""; var transactionsBLL = new TransactionsBLL(); var couponsBLL = new CouponsBLL(); var subscriptionsBLL = new SubscriptionsBLL(); // [step-1: process request] try { LoggerSingleton.Instance.Info("Cardcom", "Process-Transaction", new List <string> { $"QueryString: {Request.QueryString}" }); // defaults transaction.StatusCode = 9999; transaction.StatusCodeDetails = 9999; transaction.StatusCodeChargeToken = 9999; transaction.StatusCodeRecurringCharge = 9999; transaction.InvoiceNumber = ""; var cardcomManager = new CardcomManager(ConfigSingleton.Instance.CardcomTerminal, ConfigSingleton.Instance.CardcomUserName, TerminalNoCvv: ConfigSingleton.Instance.CardcomTerminalNoCvv); step = 1; // Collect basic details transaction.Raw = Request.QueryString?.ToString(); transaction.Code = Request.QueryString["lowprofilecode"]; transaction.StatusCode = Convert.ToInt32(Request.QueryString["OperationResponse"]); transaction.CardStatusCode = Convert.ToInt32(Request.QueryString["DealResponse"]); step = 2; // Collect extra details var detailsResponse = cardcomManager.GetTransactionDetails(transaction.Code); step = 3; transaction.StatusCodeDetails = Convert.ToInt32(detailsResponse.Details["ResponseCode"]); transaction.RawDetails = detailsResponse.Raw; if (Convert.ToInt32(detailsResponse.Details["ResponseCode"]) != 0) { throw new Exception($"Error while trying to get details. status-code {detailsResponse.Details["ResponseCode"]} ({transaction.Code})"); } step = 4; transaction.Token = detailsResponse.Details["Token"] ?? ""; transaction.TokenExpiry = detailsResponse.Details["TokenExDate"] ?? ""; transaction.TokenApprovalNumber = detailsResponse.Details["TokenApprovalNumber"] ?? ""; transaction.CardOwnerId = detailsResponse.Details["CardOwnerID"] ?? ""; // fix format > MM (e.g: 7 to 07) var CardValidityMonth = detailsResponse.Details["CardValidityMonth"] ?? ""; if (CardValidityMonth.Length == 1) { CardValidityMonth = $"0{CardValidityMonth}"; } transaction.CardExpiry = $"{detailsResponse.Details["CardValidityYear"] ?? ""}{CardValidityMonth}"; transaction.CardSuffix = detailsResponse.Details["ExtShvaParams.CardNumber5"] ?? ""; transaction.NumOfPayments = Convert.ToInt32(detailsResponse.Details["NumOfPayments"] ?? "1"); step = 5; // Collect custom details // returnValue: PRICE|PACKAGE|USER_ID|COUPON (e.g: 39.90|3|1|98F41F8F-6F6C-4A0A-A7D4-D719A41A6BD7) var returnValue = detailsResponse.Details["ReturnValue"].Trim(); var returnValueSlices = returnValue.Split('|'); transaction.Price = Convert.ToSingle(returnValueSlices[0]); transaction.PackageId = Convert.ToInt32(returnValueSlices[1]); transaction.SubscriptionId = Convert.ToInt32(returnValueSlices[2]); var coupon = await couponsBLL.Find(returnValueSlices[3]); transaction.Coupon = coupon == null ? "" : coupon.Code.ToString(); step = 6; // load package var packageDetails = PackagesSingleton.Instance.GetPackage(transaction.PackageId); step = 7; // load subscription var subscription = await subscriptionsBLL.Get(transaction.SubscriptionId); step = 8; /* * we have two states to handle: * 1. free week -> no charge + recurring-charge with a 1 week delay * 2. coupon -> immediate charge + recurring-charge with a week/month delay (depending on the acquired package) */ var isFreeWeek = coupon == null; /// isFreeWeek = false; // disabled if (isFreeWeek) { transaction.Price = 0; } else { // actual charge using generated TOKEN var responseCharge = cardcomManager.ChargeWithToken( transaction.Token, transaction.CardExpiry, transaction.CardOwnerId, new List <CardcomIFrameSourceItem> { new CardcomIFrameSourceItem { Description = $"#{packageDetails.Id} {packageDetails.Name}", Price = transaction.Price, Quantity = 1 } }, returnValue, transaction.NumOfPayments, InvoiceDetails: new CardcomInvoiceDetails { CustomerId = subscription.Details.Id.ToString(), CustomerName = subscription.Details.FirstName, Email = subscription.Details.Email, SendEmail = true } ); step = 9; transaction.StatusCodeChargeToken = Convert.ToInt32(responseCharge.Details["ResponseCode"]); transaction.RawChargeToken = responseCharge.Raw; if (Convert.ToInt32(responseCharge.Details["ResponseCode"]) != 0) { throw new Exception($"Error while trying to charge with token {transaction.Token}. status-code {responseCharge.Details["ResponseCode"]} ({transaction.Code})"); } step = 10; transaction.CardStatusCode = 0; // update the card status code // add invoice details transaction.InvoiceStatusCode = Convert.ToInt32(responseCharge.Details["InvoiceResponse.ResponseCode"]); transaction.InvoiceNumber = responseCharge.Details["InvoiceResponse.InvoiceNumber"] ?? ""; transaction.InvoiceType = Convert.ToInt32(responseCharge.Details["InvoiceResponse.InvoiceType"] ?? "0"); } step = 11; if (transaction.StatusCode != 0) { var success1 = await subscriptionsBLL.SaveRegistrationStep(transaction.SubscriptionId, "TransactionFailed"); if (!success1) { LoggerSingleton.Instance.Info("Cardcom", $"SaveRegistrationStep Failed For User #{transaction.SubscriptionId}"); } throw new Exception($"transaction code error. status-code {transaction.StatusCode} ({transaction.Code})"); } step = 12; // Update Coupon Capacity if (!string.IsNullOrEmpty(transaction.Coupon)) { var successCapacity = await couponsBLL.IncreaseCapacityInUse(Guid.Parse(transaction.Coupon)); if (!successCapacity) { LoggerSingleton.Instance.Info("Cardcom", "IncreaseCapacity Failed", new List <string> { $"#{transaction.SubscriptionId}", transaction.Coupon }); } } step = 13; // calculate the valid-until, the Recurring Payments Start Date and the corresponding interval id DateTime?validUntil = packageDetails.ValidUntil; var timeIntervalId = packageDetails.CardcomIntervalId; step = 14; if (isFreeWeek) { validUntil = DateTime.Now.AddDays(7); } step = 15; // update ValidUntil var successValidUntil = await subscriptionsBLL.SaveValidUntil(transaction.SubscriptionId, validUntil); if (!successValidUntil) { LoggerSingleton.Instance.Info("Cardcom", "SaveValidUntil Failed", new List <string> { $"#{transaction.SubscriptionId}", }); } step = 16; var chargeDetails = new Entities.ChargeDetails { SubscriptionId = transaction.SubscriptionId, Token = transaction.Token, IsAutoRenewal = packageDetails.IsReccuringPayment, CardSuffix = transaction.CardSuffix, CardExpiry = transaction.CardExpiry, CardOwnerId = transaction.CardOwnerId, Code = transaction.Code }; // save charge details for this subscription var successChargeDetails = await subscriptionsBLL.SaveChargeDetails(chargeDetails); if (!successChargeDetails) { LoggerSingleton.Instance.Info("Cardcom", "SaveChargeDetails Failed", new List <string> { $"#{chargeDetails.SubscriptionId}", chargeDetails.Token }); } step = 17; // add a transaction var transactionId = await transactionsBLL.Save(transaction); if (transactionId <= 0) { throw new Exception($"Error while trying to save an incoming transaction ({transaction.Code})"); } transaction.RowId = transactionId; step = 18; // set recurring-charge if (packageDetails.IsReccuringPayment) { step = 19; var responseRecurringCharge = cardcomManager.SetRecurringCharge( chargeDetails.Code, "My Morning Love", validUntil.Value, timeIntervalId, new List <CardcomIFrameSourceItem> { new CardcomIFrameSourceItem { Description = packageDetails.Name, Price = packageDetails.Price, Quantity = 1 } }, returnValue, new CardcomInvoiceDetails { CustomerId = subscription.Details.Id.ToString(), CustomerName = subscription.Details.FullName, Email = subscription.Details.Email, SendEmail = true } ); step = 20; transaction.StatusCodeRecurringCharge = Convert.ToInt32(responseRecurringCharge.Details["ResponseCode"]); transaction.RawRecurringCharge = responseRecurringCharge.Raw; if (responseRecurringCharge.Details["ResponseCode"] != "0") { await subscriptionsBLL.SaveAutoRenewal(transaction.SubscriptionId, false); // recurring charge has failed > mark user as AutoRenewal false throw new Exception($"Error while trying to set Recurring Charge. status-code {responseRecurringCharge.Details["ResponseCode"]} ({transaction.Code})"); } step = 20; chargeDetails.RecurringId = Convert.ToInt32(responseRecurringCharge.Details["Recurring0.RecurringId"]); successChargeDetails = await subscriptionsBLL.SaveChargeDetails(chargeDetails); if (!successChargeDetails) { LoggerSingleton.Instance.Info("Cardcom", "SaveChargeDetails (with RecurringId) Failed", new List <string> { $"#{chargeDetails.SubscriptionId}", chargeDetails.Token, responseRecurringCharge.Details["Recurring0.RecurringId"] }); } } step = 21; httpResult = "OK"; } catch (Exception ex) { isTransactionFailed = true; ex.Data.Add("step", step); ex.Data.Add("Method", "ProcessCardcomTransaction"); LoggerSingleton.Instance.Error("Cardcom", ex); httpResult = ex.Message; } step = 22; // [step-2: update transaction] try { // Create Transaction Row var transactionId = await transactionsBLL.Save(transaction); if (transactionId <= 0) { throw new Exception($"Error while trying to save an incoming transaction ({transaction.Code})"); } transaction.RowId = transactionId; } catch (Exception ex) { isTransactionFailed = true; ex.Data.Add("step", step); ex.Data.Add("Method", "ProcessCardcomTransaction"); LoggerSingleton.Instance.Error("Cardcom", ex); httpResult = ex.Message; } step = 23; // [step-3: mark registration state] try { var success = await subscriptionsBLL.SaveRegistrationStep(transaction.SubscriptionId, isTransactionFailed? "TransactionFailed" : "Completed"); if (!success) { LoggerSingleton.Instance.Info("Cardcom", $"SaveRegistrationStep Failed For User #{transaction.SubscriptionId}"); } } catch (Exception ex) { ex.Data.Add("step", step); ex.Data.Add("Method", "ProcessCardcomTransaction"); LoggerSingleton.Instance.Error("Cardcom", ex); httpResult = ex.Message; } Response.StatusCode = httpResult == "OK" ? (int)HttpStatusCode.OK : (int)HttpStatusCode.InternalServerError; return(httpResult); ///return new HttpStatusCodeResult(HttpStatusCode.OK, "OK"); /// return httpStatusCodeResult; }