public static void LogError(Payment payment, PaymentResponse response) { var context = HttpContext.Current; var log = ErrorLog.GetDefault(context); var ex = new ApplicationException(string.Format("{0} {1}'s donation of {2:C} was unable to be processed. Error Code: {3}. Description: {4}", payment.FirstName, payment.LastName, payment.Amount, response.ResponseCode, response.ReasonText)); log.Log(new Error(ex, context)); }
public void Process_Should_Return_Approved_When_Valid_Payment_Is_Given() { Payment payment = new Payment { FirstName = "Johnny", LastName = "Appleseed", AddressLine1 = "123 My St", City = "New York", State = "NY", ZipCode = "12345", PaymentType = PaymentType.CC, AccountNumber = "4111111111111111", Expiration = new DateTime(2015, 1, 1), Cid = "123", Amount = TestHelpers.GetAmount() }; var result = provider.Process(payment); Assert.AreEqual(PaymentResponseCode.Approved, result.ResponseCode); }
public void Process_Should_Return_Approved_When_Valid_ECheck_Is_Given() { Payment payment = new Payment { FirstName = "Johnny", LastName = "Appleseed", AddressLine1 = "123 My St", City = "New York", State = "NY", ZipCode = "12345", AccountNumber = "4111111111111111", RoutingNumber = "122105278", PaymentType = PaymentType.ECheck, CheckNumber = "1234", Amount = TestHelpers.GetAmount() }; var result = provider.Process(payment); Assert.AreEqual(PaymentResponseCode.Approved, result.ResponseCode); }
public void Process_Invalid_Should_Return_Error() { Payment payment = new Payment { FirstName = "Johnny", LastName = "Appleseed", AddressLine1 = "123 My St", City = "New York", State = "NY", ZipCode = "12345", PaymentType = PaymentType.CC, AccountNumber = "42", Expiration = new DateTime(2015, 1, 1), Cid = "123", Amount = TestHelpers.GetAmount(), TransactionType = TransactionType.Recurring, SubscriptionStart = DateTime.Now }; var result = provider.Process(payment); Assert.AreEqual(PaymentResponseCode.Error, result.ResponseCode); }
public void Process_Invalid_Echeck_Should_Return_Error() { Payment payment = new Payment { FirstName = "Johnny", LastName = "Appleseed", AddressLine1 = "123 My St", City = "New York", State = "NY", ZipCode = "12345", PaymentType = PaymentType.ECheck, NameOnAccount = "Johnny Appleseed", AccountNumber = "42", BankName = "Some Bank", RoutingNumber = "123456789", CheckType = CheckType.Checking, Amount = TestHelpers.GetAmount(), TransactionType = TransactionType.Recurring, SubscriptionStart = DateTime.Now.AddDays(1) }; var result = provider.Process(payment); Assert.AreEqual(PaymentResponseCode.Error, result.ResponseCode); }
private void PopulateSubscription(ARBCreateSubscriptionRequest request, Payment payment) { ARBSubscriptionType sub = new ARBSubscriptionType(); creditCardType creditCard = new creditCardType(); bankAccountType bankAccount = new bankAccountType(); sub.name = string.Format("{0} {1} Subscription", payment.FirstName, payment.LastName); if (payment.PaymentType == PaymentType.CC) { creditCard.cardNumber = payment.AccountNumber; creditCard.expirationDate = payment.GetFormattedDate(); // required format for API is YYYY-MM sub.payment = new paymentType { Item = creditCard }; } else { bankAccount.accountNumber = payment.AccountNumber; bankAccount.accountTypeSpecified = true; bankAccount.bankName = payment.BankName; bankAccount.routingNumber = payment.RoutingNumber; bankAccount.accountType = GetAccountType(payment); bankAccount.nameOnAccount = payment.NameOnAccount; sub.payment = new paymentType { Item = bankAccount }; } sub.billTo = new nameAndAddressType { firstName = payment.FirstName, lastName = payment.LastName }; sub.paymentSchedule = new paymentScheduleType { startDate = payment.SubscriptionStart, startDateSpecified = true, totalOccurrences = 12, totalOccurrencesSpecified = true }; sub.amount = payment.Amount; sub.amountSpecified = true; sub.paymentSchedule.interval = new paymentScheduleTypeInterval { length = 1, unit = ARBSubscriptionUnitEnum.months }; sub.customer = new customerType { email = payment.Email }; PopulateMerchantAuthentication(request); request.subscription = sub; }
private bankAccountTypeEnum GetAccountType(Payment payment) { switch (payment.CheckType) { case CheckType.Savings: return bankAccountTypeEnum.savings; case CheckType.BusinessChecking: return bankAccountTypeEnum.businessChecking; case CheckType.Checking: default: return bankAccountTypeEnum.checking; } }
private SubscriptionResponse CreateSubscription(Payment payment) { var createRequest = new ARBCreateSubscriptionRequest(); PopulateSubscription(createRequest, payment); object response = null; XmlDocument xmldoc; bool bResult = PostRequest(createRequest, out xmldoc); if (bResult) { ProcessXmlResponse(xmldoc, out response); } return ProcessResponse(response); }
private Dictionary<string, string> BuildAimRequest(Payment payment) { var postValues = new Dictionary<string, string> { { "x_login", LoginID }, { "x_tran_key", TransactionKey }, { "x_delim_data", "TRUE" }, { "x_delim_char", RESPONSE_DELIMITER }, { "x_relay_response", "FALSE" }, { "x_type", "AUTH_CAPTURE" }, { "x_method", payment.PaymentType.ToString() }, { "x_amount", payment.Amount.ToString(CultureInfo.InvariantCulture) }, { "x_description", payment.ToString() }, { "x_first_name", payment.FirstName }, { "x_last_name", payment.LastName }, { "x_address", payment.AddressLine1 }, { "x_state", payment.State }, { "x_zip", payment.ZipCode } }; if (payment.PaymentType == PaymentType.CC) { postValues.Add("x_card_num", payment.AccountNumber); postValues.Add("x_exp_date", payment.GetFormattedDate()); postValues.Add("x_card_code", payment.Cid); } else // ECheck { postValues.Add("x_bank_aba_code", payment.RoutingNumber); postValues.Add("x_bank_acct_num", payment.AccountNumber); postValues.Add("x_bank_acct_type", payment.CheckType.ToString()); postValues.Add("x_bank_name", payment.BankName); postValues.Add("x_bank_acct_name", string.Format("{0} {1}", payment.FirstName, payment.LastName)); postValues.Add("x_echeck_type", "WEB"); postValues.Add("x_bank_check_number", payment.CheckNumber); postValues.Add("x_recurring_billing", "NO"); } // NOTE: From the Authorize.net API documentation: // Additional fields can be added here as outlined in the AIM integration // guide at: http://developer.authorize.net AppendCustomFields(postValues, payment); return postValues; }
private void AppendCustomFields(IDictionary<string, string> postValues, Payment payment) { postValues.Add("x-donor-comments", payment.Comments != null ? payment.Comments.Substring(0, 255) : string.Empty); if (payment.Campaign != null) { var campaign = payment.Campaign; postValues.Add("x-campaign-id", campaign.CampaignID.ToString(CultureInfo.InvariantCulture)); postValues.Add("x-campaign-title", campaign.Title); } if (payment.Owner != null) { var userProfile = payment.Owner; postValues.Add("x-campaign-owner-name", userProfile.FullName); postValues.Add("x-campaign-owner-id", userProfile.UserProfileID.ToString(CultureInfo.InvariantCulture)); postValues.Add("x-campaign-owner-email", userProfile.Email); } if (payment.Organization != null) { postValues.Add("x-organization-name", payment.Organization.Name); } }
public void Process_Should_Return_Reason_Code() { Payment payment = new Payment(); var result = provider.Process(payment); Assert.Greater(result.ReasonCode, 0); }
/// <summary> /// Process method to call from production. Will pass an "isTest" value of false to the Process(payment, isTest) overload. /// </summary> /// <param name="payment">Payment object to pass to Authorize.net gateway</param> /// <returns>PaymentResponse object containing Authorize.net's response information</returns> public PaymentResponse Process(Payment payment) { if (payment.TransactionType == TransactionType.Recurring) { return ProcessRecurring(payment); } return ProcessOneTime(payment); }
private CampaignDonor GetDonation(Payment payment) { UserProfile userProfile = null; var donation = Mapper.Map<Payment, CampaignDonor>(payment); PopulateDisplayName(donation); if (User.Identity.IsAuthenticated) { userProfile = userProfileRepository.FindUserProfileByEmail(User.Identity.Name).FirstOrDefault(); } else { userProfile = userProfileRepository.FindUserProfileByEmail(payment.Email).FirstOrDefault(); } if (userProfile != null) { if (userProfile.CampaignDonors == null) { userProfile.CampaignDonors = new List<CampaignDonor>(); } UpdateUserProfile(userProfile, donation); userProfile.CampaignDonors.Add(donation); } return donation; }
public void Process_Multiple_Valid_Should_Result_In_All_Success() { for (int i = 0; i < 10; i++) { Payment payment = new Payment { FirstName = "Payment " + i, LastName = "Appleseed", AddressLine1 = "123 My St", City = "New York", State = "NY", ZipCode = "12345", PaymentType = PaymentType.CC, AccountNumber = "4111111111111111", Expiration = new DateTime(2015, 1, 1), Cid = "123", Amount = TestHelpers.GetAmount(), TransactionType = TransactionType.Recurring, SubscriptionStart = DateTime.Now.AddDays(1) }; var result = provider.Process(payment); Assert.AreEqual(PaymentResponseCode.Approved, result.ResponseCode); } }
public void Process_Should_Return_Status_Code() { Payment payment = new Payment { TransactionType = TransactionType.Recurring, PaymentInterval = 1 }; var result = provider.Process(payment); Assert.IsNotNull(result); }
public static void AddCampaignInfo(Payment payment) { payment.Campaign = EntityHelpers.GetValidCampaign(); payment.Owner = EntityHelpers.GetValidUserProfile(); payment.Organization = EntityHelpers.GetValidOrganization(); }
private static Payment GetPayment(UserProfile userProfile) { Payment payment; if (userProfile != null) { payment = Mapper.Map<UserProfile, Payment>(userProfile); payment.NameOnAccount = userProfile.FullName; } else { payment = new Payment(); } return payment; }
public PaymentResponse Process(Payment payment) { throw new NotImplementedException(); }
/// <summary> /// Provides a hook into Authorize.net's AIM (one time) card processing API /// </summary> /// <param name="payment">Payment object to pass to Authorize.net gateway</param> /// <returns>PaymentResponse object containing Authorize.net's response information</returns> private PaymentResponse ProcessOneTime(Payment payment) { var postValues = BuildAimRequest(payment); StringBuilder postString = new StringBuilder(); foreach (var field in postValues) { if (postString.Length > 0) { postString.Append("&"); } postString.AppendFormat("{0}={1}", field.Key, field.Value); } // create an HttpWebRequest object to communicate with Authorize.net HttpWebRequest request = (HttpWebRequest) WebRequest.Create(ApiUrl); request.Method = "POST"; request.ContentLength = postString.Length; request.ContentType = "application/x-www-form-urlencoded"; using (StreamWriter myWriter = new StreamWriter(request.GetRequestStream())) { myWriter.Write(postString.ToString()); myWriter.Close(); } string responseString; HttpWebResponse response = (HttpWebResponse) request.GetResponse(); using (StreamReader responseStream = new StreamReader(response.GetResponseStream())) { responseString = responseStream.ReadToEnd(); responseStream.Close(); } // NOTE: From the Authorize API documentation: // individual elements of the array could be accessed to read certain response // fields. For example, response_array[0] would return the Response Code, // response_array[2] would return the Response Reason Code. // for a list of response fields, please review the AIM Implementation Guide var responseArray = responseString.Split('|'); var responseCode = (PaymentResponseCode) int.Parse(responseArray [0]); var reasonCode = int.Parse(responseArray [2]); var reasonText = responseArray [3]; return new PaymentResponse(responseCode, reasonCode, reasonText); }
public void Process_Should_Return_Error_When_Invalid_Payment_Is_Given() { Payment payment = new Payment { AccountNumber = "42", Expiration = new DateTime(2015, 1, 1), Amount = TestHelpers.GetAmount() }; var result = provider.Process(payment); Assert.AreNotEqual(PaymentResponseCode.Approved, result.ResponseCode); }
private PaymentResponse ProcessRecurring(Payment payment) { payment.SubscriptionStart = DateTime.Now.AddDays(1); var response = CreateSubscription(payment); PaymentResponse paymentResponse = new PaymentResponse(response.ResponseCode.ToUpper() == "OK" ? PaymentResponseCode.Approved : PaymentResponseCode.Error, -1, string.Join("|", response.Messages.ToArray())); return paymentResponse; }
private void SetUpController(MockRepository mocks, Payment payment = null, bool isPaymentApproved = true) { var mailer = mocks.DynamicMock<IDonateMailer>(); MailerBase.IsTestModeEnabled = true; var paymentProviderFactory = mocks.DynamicMock<IPaymentProviderFactory>(); var paymentProvider = mocks.StrictMock<IPaymentProvider>(); if (payment != null) { PaymentResponse response = isPaymentApproved ? new PaymentResponse(PaymentResponseCode.Approved, -1, string.Empty) : new PaymentResponse(PaymentResponseCode.Error, -1, string.Empty); Expect.Call(paymentProviderFactory.GetPaymentProvider(PaymentGatewayType.PayPal)).IgnoreArguments() .Return(paymentProvider); Expect.Call(paymentProvider.Process(payment)).IgnoreArguments().Return(response); } controller = new DonateController(campaignRepository, userProfileRepository, mailer, paymentProviderFactory, campaignDonorRepository) { OrganizationRepository = organizationRepository }; var context = MockRepository.GenerateStub<HttpContextBase>(); var request = MockRepository.GenerateStub<HttpRequestBase>(); context.Stub(x => x.Request).Return(request); context.User = new GenericPrincipal(new GenericIdentity("goodEmail"), null); controller.ControllerContext = new ControllerContext(context, new RouteData(), controller); }
public ActionResult ProcessDonation(Payment model, string slug = "") { var urlSlug = slug; if (ModelState.IsValid) { using (new UnitOfWorkScope()) { var campaign = campaignRepository.GetCampaignByUrlSlug(slug); if (campaign == null) { campaign = campaignRepository.GetDefaultCampaign(); } else if (!campaign.IsActive) { TempData["UserFeedback"] = "Sorry, this campaign is inactive and can no longer receive donations."; return RedirectToAction("Index", "Campaign", new { slug = urlSlug }); } else // We know it's OK to process campaign donation. Add campaign info to Payment to pass through to payment gateway for reconciliation. { var userProfile = campaign.UserProfile; model.Notes = string.Format("Apply payment to {0} Campaign owned by {1} {2}", campaign.Title, userProfile.FirstName, userProfile.LastName); } var provider = GetPaymentProvider(); var result = provider.Process(model); if (result.ResponseCode == PaymentResponseCode.Approved) { var donation = GetDonation(model); if (campaign.CampaignDonors == null) { campaign.CampaignDonors = new List<CampaignDonor>(); } donation.Approved = true; campaign.CampaignDonors.Add(donation); campaignRepository.Save(); var viewModel = SendNotifications(campaign, donation, model); TempData["Donation"] = viewModel; return RedirectToAction("ThankYou"); } Logger.LogError(model, result); TempData["PaymentGatewayError"] = result.ReasonText; } } TempData["Payment"] = model; return RedirectToAction("Index", new { slug = urlSlug }); }
public void Process_Should_Return_Status_Code() { Payment payment = new Payment(); var result = provider.Process(payment); Assert.AreNotEqual(result.ResponseCode, 0); }
private DonationDetailsModel SendNotifications(Campaign campaign, CampaignDonor donation, Payment payment) { // Send receipt of payment to user var mailerModel = Mapper.Map<CampaignDonor, DonationDetailsModel>(donation); mailerModel.Title = campaign.Title; mailerModel.UrlSlug = campaign.UrlSlug; mailerModel.PaymentType = payment.PaymentType == PaymentType.CC ? "Credit/Debit Card" : "Electronic Check"; mailerModel.TransactionType = payment.TransactionType; var organization = campaign.Organization; var bcc = organization.GetSetting(OrgSettingKeys.DONATION_NOTIFICATION_ADDRESS); if (bcc != null) { mailerModel.DonorNotificationEmail = bcc.Value; } donateMailer.UserDonation(mailerModel).SendAsync(); // Send notification to campaign owner mailerModel.Email = campaign.UserProfile.Email; donateMailer.CampaignDonation(mailerModel).SendAsync(); return mailerModel; }
private void SetUpPaymentResponse(Payment payment, bool isPaymentApproved = true) { var paymentProvider = mocks.StrictMock<IPaymentProvider>(); PaymentResponse response = isPaymentApproved ? new PaymentResponse(PaymentResponseCode.Approved, -1, string.Empty) : new PaymentResponse(PaymentResponseCode.Error, -1, string.Empty); Expect.Call(paymentProviderFactory.GetPaymentProvider(PaymentGatewayType.PayPal)).IgnoreArguments() .Return(paymentProvider); Expect.Call(paymentProvider.Process(payment)).IgnoreArguments().Return(response); }