public async Task <Result <CreditCardVoidResult> > Void(CreditCardVoidMoneyRequest request, CreditCardPaymentInfo paymentInfo, string maskedNumber, MoneyAmount moneyAmount, string referenceCode, UserInfo user, int agentId) { return(await VoidInPayfort() .Tap(WriteAuditLog)); Task <Result <CreditCardVoidResult> > VoidInPayfort() => _payfortService.Void(request); Task WriteAuditLog(CreditCardVoidResult voidResult) { var eventData = new CreditCardLogEventData($"Void money for the payment '{referenceCode}'", voidResult.ExternalCode, voidResult.Message, paymentInfo.InternalReferenceCode); return(_creditCardAuditService.Write(CreditCardEventType.Void, maskedNumber, moneyAmount.Amount, user, eventData, referenceCode, agentId, moneyAmount.Currency)); } }
public async Task <Result <Payment> > Create(string paymentId, string paymentOrderReference, string bookingReferenceCode, MoneyAmount price, string ipAddress) { var now = _dateTimeProvider.UtcNow(); var info = new CreditCardPaymentInfo(customerIp: ipAddress, externalId: paymentId, message: string.Empty, authorizationCode: string.Empty, expirationDate: string.Empty, internalReferenceCode: paymentOrderReference); var payment = new Payment { Amount = price.Amount, Currency = price.Currency, AccountNumber = string.Empty, Created = now, Modified = now, Status = PaymentStatuses.Created, Data = JsonConvert.SerializeObject(info), PaymentMethod = PaymentTypes.CreditCard, PaymentProcessor = PaymentProcessors.NGenius, ReferenceCode = bookingReferenceCode }; _context.Payments.Add(payment); await _context.SaveChangesAsync(); await _bookingPaymentCallbackService.ProcessPaymentChanges(payment); return(payment); }
public async Task <Result <CreditCardCaptureResult> > Capture(CreditCardCaptureMoneyRequest request, CreditCardPaymentInfo paymentInfo, string maskedNumber, Currencies currency, UserInfo user, int agentId) { return(await CaptureInPayfort() .Tap(WriteAuditLog)); Task <Result <CreditCardCaptureResult> > CaptureInPayfort() => _payfortService.Capture(request); Task WriteAuditLog(CreditCardCaptureResult captureResult) { var eventData = new CreditCardLogEventData($"Capture money for the payment '{request.MerchantReference}'", captureResult.ExternalCode, captureResult.Message, paymentInfo.InternalReferenceCode); return(_creditCardAuditService.Write(CreditCardEventType.Capture, maskedNumber, request.Amount, user, eventData, request.MerchantReference, agentId, currency)); } }
/// <summary> /// Gets the card information. /// </summary> /// <param name="paymentInfo">The payment information.</param> /// <returns></returns> private Card GetCard(CreditCardPaymentInfo cc) { var card = new Card(); card.accountNumber = cc.Number.AsNumeric(); card.expirationMonth = cc.ExpirationDate.Month.ToString("D2"); card.expirationYear = cc.ExpirationDate.Year.ToString("D4"); card.cvNumber = cc.Code.AsNumeric(); card.cvIndicator = "1"; if (cc.CreditCardTypeValue != null) { switch (cc.CreditCardTypeValue.Value) { case "Visa": card.cardType = "001"; break; case "MasterCard": card.cardType = "002"; break; case "American Express": card.cardType = "003"; break; case "Discover": card.cardType = "004"; break; case "Diners": card.cardType = "005"; break; case "Carte Blanche": card.cardType = "006"; break; case "JCB": card.cardType = "007"; break; default: card.cardType = string.Empty; break; } } return(card); }
public async Task <Result <CreditCardRefundResult> > Refund(CreditCardRefundMoneyRequest request, CreditCardPaymentInfo paymentInfo, string maskedNumber, string referenceCode, UserInfo user, int agentId) { return(await RefundInPayfort() .Tap(WriteAuditLog)); async Task <Result <CreditCardRefundResult> > RefundInPayfort() => request.Amount.IsGreaterThan(0m) ? await _payfortService.Refund(request) : new CreditCardRefundResult(default, default, request.MerchantReference);
public async Task <Result <CreditCardRefundResult> > Refund(CreditCardRefundMoneyRequest request, CreditCardPaymentInfo paymentInfo, PaymentProcessors paymentProcessor, string maskedNumber, string referenceCode, int paymentId, ApiCaller apiCaller, int agentId) { return(await RefundInPayfort() .Tap(WriteAuditLog)); async Task <Result <CreditCardRefundResult> > RefundInPayfort() { return(request.Amount.IsGreaterThan(0m) ? paymentProcessor == PaymentProcessors.Payfort ? await _payfortService.Refund(request) : await _nGeniusRefundService.Refund(paymentId, request.Amount.ToMoneyAmount(request.Currency), paymentInfo.ExternalId, request.MerchantReference) : new CreditCardRefundResult(default, default, request.MerchantReference));
public async Task <Result <CreditCardCaptureResult> > Capture(CreditCardCaptureMoneyRequest request, CreditCardPaymentInfo paymentInfo, PaymentProcessors paymentProcessor, string maskedNumber, Currencies currency, ApiCaller apiCaller, int agentId) { return(await Capture() .Tap(WriteAuditLog)); Task <Result <CreditCardCaptureResult> > Capture() { return(paymentProcessor switch { PaymentProcessors.Payfort => _payfortService.Capture(request), PaymentProcessors.NGenius => _nGeniusPaymentService.Capture(paymentInfo.ExternalId, paymentInfo.InternalReferenceCode, request.Amount.ToMoneyAmount(request.Currency)), _ => throw new NotSupportedException($"Payment processor `{nameof(paymentProcessor)}` not supported") });
/// <summary> /// Performs the third step of adding a new payment schedule /// </summary> /// <param name="financialGateway">The financial gateway.</param> /// <param name="resultQueryString">The result query string from step 2.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> /// <exception cref="System.ArgumentNullException">tokenId</exception> public FinancialScheduledTransaction AddScheduledPaymentStep3(FinancialGateway financialGateway, string resultQueryString, out string errorMessage) { errorMessage = string.Empty; try { var rootElement = GetRoot(financialGateway, "complete-action"); rootElement.Add(new XElement("token-id", resultQueryString.Substring(10))); XDocument xdoc = new XDocument(new XDeclaration("1.0", "UTF-8", "yes"), rootElement); var result = PostToGateway(financialGateway, xdoc); if (result == null) { errorMessage = "Invalid Response from NMI!"; return(null); } if (result.GetValueOrNull("result") != "1") { errorMessage = result.GetValueOrNull("result-text"); return(null); } var scheduledTransaction = new FinancialScheduledTransaction(); scheduledTransaction.IsActive = true; scheduledTransaction.GatewayScheduleId = result.GetValueOrNull("subscription-id"); scheduledTransaction.FinancialGatewayId = financialGateway.Id; scheduledTransaction.FinancialPaymentDetail = new FinancialPaymentDetail(); string ccNumber = result.GetValueOrNull("billing_cc-number"); if (!string.IsNullOrWhiteSpace(ccNumber)) { // cc payment var curType = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CREDIT_CARD); scheduledTransaction.FinancialPaymentDetail.CurrencyTypeValueId = curType != null ? curType.Id : (int?)null; scheduledTransaction.FinancialPaymentDetail.CreditCardTypeValueId = CreditCardPaymentInfo.GetCreditCardType(ccNumber.Replace('*', '1').AsNumeric())?.Id; scheduledTransaction.FinancialPaymentDetail.AccountNumberMasked = ccNumber.Masked(true); string mmyy = result.GetValueOrNull("billing_cc-exp"); if (!string.IsNullOrWhiteSpace(mmyy) && mmyy.Length == 4) { scheduledTransaction.FinancialPaymentDetail.ExpirationMonthEncrypted = Encryption.EncryptString(mmyy.Substring(0, 2)); scheduledTransaction.FinancialPaymentDetail.ExpirationYearEncrypted = Encryption.EncryptString(mmyy.Substring(2, 2)); } } else { // ach payment var curType = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_ACH); scheduledTransaction.FinancialPaymentDetail.CurrencyTypeValueId = curType != null ? curType.Id : (int?)null; scheduledTransaction.FinancialPaymentDetail.AccountNumberMasked = result.GetValueOrNull("billing_account_number").Masked(true); } GetScheduledPaymentStatus(scheduledTransaction, out errorMessage); return(scheduledTransaction); } catch (WebException webException) { string message = GetResponseMessage(webException.Response.GetResponseStream()); errorMessage = webException.Message + " - " + message; return(null); } catch (Exception ex) { errorMessage = ex.Message; return(null); } }
/// <summary> /// Performs the final step of a three-step charge. /// </summary> /// <param name="financialGateway">The financial gateway.</param> /// <param name="resultQueryString">The result query string from step 2.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public FinancialTransaction ChargeStep3(FinancialGateway financialGateway, string resultQueryString, out string errorMessage) { errorMessage = string.Empty; try { var rootElement = GetRoot(financialGateway, "complete-action"); rootElement.Add(new XElement("token-id", resultQueryString.Substring(10))); XDocument xdoc = new XDocument(new XDeclaration("1.0", "UTF-8", "yes"), rootElement); var result = PostToGateway(financialGateway, xdoc); if (result == null) { errorMessage = "Invalid Response from NMI!"; return(null); } if (result.GetValueOrNull("result") != "1") { errorMessage = result.GetValueOrNull("result-text"); string resultCodeMessage = GetResultCodeMessage(result); if (resultCodeMessage.IsNotNullOrWhiteSpace()) { errorMessage += string.Format(" ({0})", resultCodeMessage); } // write result error as an exception ExceptionLogService.LogException(new Exception($"Error processing NMI transaction. Result Code: {result.GetValueOrNull( "result-code" )} ({resultCodeMessage}). Result text: {result.GetValueOrNull( "result-text" )}. Card Holder Name: {result.GetValueOrNull( "first-name" )} {result.GetValueOrNull( "last-name" )}. Amount: {result.GetValueOrNull( "total-amount" )}. Transaction id: {result.GetValueOrNull( "transaction-id" )}. Descriptor: {result.GetValueOrNull( "descriptor" )}. Order description: {result.GetValueOrNull( "order-description" )}.")); return(null); } var transaction = new FinancialTransaction(); transaction.TransactionCode = result.GetValueOrNull("transaction-id"); transaction.ForeignKey = result.GetValueOrNull("customer-vault-id"); transaction.FinancialPaymentDetail = new FinancialPaymentDetail(); string ccNumber = result.GetValueOrNull("billing_cc-number"); if (!string.IsNullOrWhiteSpace(ccNumber)) { // cc payment var curType = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CREDIT_CARD); transaction.FinancialPaymentDetail.NameOnCardEncrypted = Encryption.EncryptString($"{result.GetValueOrNull( "billing_first-name" )} {result.GetValueOrNull( "billing_last-name" )}"); transaction.FinancialPaymentDetail.CurrencyTypeValueId = curType != null ? curType.Id : (int?)null; transaction.FinancialPaymentDetail.CreditCardTypeValueId = CreditCardPaymentInfo.GetCreditCardType(ccNumber.Replace('*', '1').AsNumeric())?.Id; transaction.FinancialPaymentDetail.AccountNumberMasked = ccNumber.Masked(true); string mmyy = result.GetValueOrNull("billing_cc-exp"); if (!string.IsNullOrWhiteSpace(mmyy) && mmyy.Length == 4) { transaction.FinancialPaymentDetail.ExpirationMonthEncrypted = Encryption.EncryptString(mmyy.Substring(0, 2)); transaction.FinancialPaymentDetail.ExpirationYearEncrypted = Encryption.EncryptString(mmyy.Substring(2, 2)); } } else { // ach payment var curType = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_ACH); transaction.FinancialPaymentDetail.CurrencyTypeValueId = curType != null ? curType.Id : (int?)null; transaction.FinancialPaymentDetail.AccountNumberMasked = result.GetValueOrNull("billing_account-number").Masked(true); } transaction.AdditionalLavaFields = new Dictionary <string, object>(); foreach (var keyVal in result) { transaction.AdditionalLavaFields.Add(keyVal.Key, keyVal.Value); } return(transaction); } catch (WebException webException) { string message = GetResponseMessage(webException.Response.GetResponseStream()); errorMessage = webException.Message + " - " + message; return(null); } catch (Exception ex) { errorMessage = ex.Message; return(null); } }
/// <summary> /// Gets the payment information. /// </summary> /// <param name="parameters">The parameters.</param> /// <param name="person">The person.</param> /// <param name="rockContext">The rock context.</param> /// <param name="totalAmount">The total amount.</param> /// <param name="paymentDetail">The payment detail.</param> /// <returns></returns> private PaymentInfo GetPaymentInfo(PaymentParameters parameters, Person person, RockContext rockContext, decimal totalAmount, FinancialPaymentDetail paymentDetail) { PaymentInfo paymentInfo = null; if (parameters.AccountType.ToLower() == "credit") { if (parameters.ExpirationMonth < 1 || parameters.ExpirationMonth > 12) { GenerateResponse(HttpStatusCode.BadRequest, "ExpirationMonth is required and must be between 1 and 12 for credit transactions"); } var currentDate = DateTime.Now; var maxYear = currentDate.Year + 30; if (parameters.ExpirationYear < currentDate.Year || parameters.ExpirationYear > maxYear) { GenerateResponse(HttpStatusCode.BadRequest, string.Format("ExpirationYear is required and must be between {0} and {1} for credit transactions", currentDate.Year, maxYear)); } if (parameters.ExpirationYear <= currentDate.Year && parameters.ExpirationMonth < currentDate.Month) { GenerateResponse(HttpStatusCode.BadRequest, "The ExpirationMonth and ExpirationYear combination must not have already elapsed for credit transactions"); } if (string.IsNullOrWhiteSpace(parameters.Street1) || string.IsNullOrWhiteSpace(parameters.City) || string.IsNullOrWhiteSpace(parameters.State) || string.IsNullOrWhiteSpace(parameters.PostalCode)) { GenerateResponse(HttpStatusCode.BadRequest, "Street1, City, State, and PostalCode are required for credit transactions"); } paymentInfo = new CreditCardPaymentInfo() { Number = parameters.AccountNumber, Code = parameters.CCV ?? string.Empty, ExpirationDate = new DateTime(parameters.ExpirationYear, parameters.ExpirationMonth, 1), BillingStreet1 = parameters.Street1 ?? string.Empty, BillingStreet2 = parameters.Street2 ?? string.Empty, BillingCity = parameters.City ?? string.Empty, BillingState = parameters.State ?? string.Empty, BillingPostalCode = parameters.PostalCode ?? string.Empty, BillingCountry = parameters.Country ?? "USA" }; } else { if (string.IsNullOrWhiteSpace(parameters.RoutingNumber)) { GenerateResponse(HttpStatusCode.BadRequest, "RoutingNumber is required for ACH transactions"); return(null); } paymentInfo = new ACHPaymentInfo() { BankRoutingNumber = parameters.RoutingNumber, BankAccountNumber = parameters.AccountNumber, AccountType = parameters.AccountType.ToLower() == "checking" ? BankAccountType.Checking : BankAccountType.Savings }; } paymentInfo.Amount = totalAmount; paymentInfo.FirstName = parameters.FirstName ?? person.FirstName; paymentInfo.LastName = parameters.LastName ?? person.LastName; paymentInfo.Email = parameters.Email ?? person.Email; paymentInfo.Phone = parameters.PhoneNumber ?? string.Empty; paymentInfo.Street1 = parameters.Street1 ?? string.Empty; paymentInfo.Street2 = parameters.Street2 ?? string.Empty; paymentInfo.City = parameters.City ?? string.Empty; paymentInfo.State = parameters.State ?? string.Empty; paymentInfo.PostalCode = parameters.PostalCode ?? string.Empty; paymentInfo.Country = parameters.Country ?? "USA"; if (paymentInfo.CreditCardTypeValue != null) { paymentDetail.CreditCardTypeValueId = paymentInfo.CreditCardTypeValue.Id; } if (paymentInfo.CurrencyTypeValue != null) { paymentDetail.CurrencyTypeValueId = paymentInfo.CurrencyTypeValue.Id; } return(paymentInfo); }