Inheritance: IPaymentValidation
示例#1
0
 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));
 }
示例#2
0
        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);
        }
示例#3
0
        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);
        }
示例#4
0
        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);
        }
示例#5
0
        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);
            }
        }
示例#11
0
 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);
        }
示例#13
0
        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;
        }
示例#14
0
        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);
            }
        }
示例#15
0
 public void Process_Should_Return_Status_Code()
 {
     Payment payment = new Payment { TransactionType = TransactionType.Recurring, PaymentInterval = 1 };
     var result = provider.Process(payment);
     Assert.IsNotNull(result);
 }
示例#16
0
 public static void AddCampaignInfo(Payment payment)
 {
     payment.Campaign = EntityHelpers.GetValidCampaign();
     payment.Owner = EntityHelpers.GetValidUserProfile();
     payment.Organization = EntityHelpers.GetValidOrganization();
 }
示例#17
0
        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);
        }
示例#20
0
        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;
 }
示例#22
0
        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);
        }
示例#23
0
        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 });
        }
示例#24
0
 public void Process_Should_Return_Status_Code()
 {
     Payment payment = new Payment();
     var result = provider.Process(payment);
     Assert.AreNotEqual(result.ResponseCode, 0);
 }
示例#25
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);
        }