예제 #1
0
        /// <summary>
        /// Adds a credit card profile to the user and returns the profile ID
        /// </summary>
        /// <returns></returns>
        public string AddCreditCard(string profileID, string cardNumber, int expirationMonth, int expirationYear, string cardCode, Address billToAddress)
        {
            // Get the expiration date.
            DateTime dt = DateTime.Parse(expirationMonth.ToString() + "-1-" + expirationYear.ToString());
            DateTime expDate = new DateTime(dt.Year, dt.Month, 1).AddMonths(1).AddDays(-1);
            string sExpDate = expDate.ToString("yyyy-MM");
            // Make sure the card has not expired.
            if (expDate <= DateTime.Now)
                throw new Exception("The credit card expiration date \"" + sExpDate + "\" is expired.");

            var req = new createCustomerPaymentProfileRequest();

            req.customerProfileId = profileID;
            req.paymentProfile = new customerPaymentProfileType();
            req.paymentProfile.payment = new paymentType();

            var card = new creditCardType();
            if (!String.IsNullOrEmpty(cardCode)) card.cardCode = cardCode;
            card.cardNumber = cardNumber;
            card.expirationDate = sExpDate;
            req.paymentProfile.payment.Item = card;

            if (billToAddress != null)
                req.paymentProfile.billTo = billToAddress.ToAPIType();

            var response = (createCustomerPaymentProfileResponse)_gateway.Send(req);

            return response.customerPaymentProfileId;
        }
        public void CreateSubscription()
        {
            var random = new AnetRandom();
            var counter = random.Next(1, (int)(Math.Pow(2, 24)));
            var amount = ComputeRandomAmount();
            var email = string.Format("user.{0}@authorize.net", counter);

            //check ApiLoginid / TransactionKey
            var sError = CheckApiLoginTransactionKey();
            Assert.IsTrue(sError == "", sError);

            const string responseString = "<?xml version=\"1.0\" encoding=\"utf-8\"?><ARBCreateSubscriptionResponse xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"AnetApi/xml/v1/schema/AnetApiSchema.xsd\"><messages><resultCode>Ok</resultCode><message><code>I00001</code><text>Successful.</text></message></messages><subscriptionId>2010573</subscriptionId></ARBCreateSubscriptionResponse>";
            LocalRequestObject.ResponseString = responseString;

            var target = new SubscriptionGateway(ApiLogin, TransactionKey);

            var billToAddress = new Address { First = "SomeOneCool", Last = "MoreCoolPerson" };
            ISubscriptionRequest subscription = SubscriptionRequest.CreateMonthly(email, "ARB Subscription Test", amount, 1);
            subscription.CardNumber = "4111111111111111";
            subscription.CardExpirationMonth = 3;
            subscription.CardExpirationYear = Convert.ToInt32(DateTime.Now.AddYears(3).ToString("yyyy"));
            subscription.BillingAddress = billToAddress;

            ISubscriptionRequest actual = target.CreateSubscription(subscription);

            Assert.NotNull(actual);
            Assert.AreEqual(subscription.Amount, actual.Amount);
            Assert.AreEqual(subscription.CardNumber, actual.CardNumber);
            Assert.AreEqual(subscription.SubscriptionName, actual.SubscriptionName);

            _sMonthlySubscriptionId = actual.SubscriptionID;
            Assert.IsTrue(0 < _sMonthlySubscriptionId.Trim().Length);
            Assert.IsTrue(0 < long.Parse(_sMonthlySubscriptionId));
        }
        public virtual string AddShippingAddress(string customerProfileId, AuthorizeNet.Address address)
        {
            try
            {
                return(_authorizeTokenExService.AddShippingAddress(customerProfileId, address));
            }
            catch (System.Exception ex)
            {
                if (!ex.Message.Contains("E00039"))
                {
                    throw new PaymentException(PaymentException.ErrorType.ProviderError, string.Empty, ex.Message, ex);
                }

                var customer = _authorizeTokenExService.GetCustomer(customerProfileId);
                if (customer != null)
                {
                    var shippingAddress = customer.ShippingAddresses.FirstOrDefault(sa =>
                                                                                    sa.First == address.First &&
                                                                                    sa.Last == address.Last &&
                                                                                    sa.City == address.City &&
                                                                                    sa.Country == address.Country &&
                                                                                    sa.Fax == address.Fax &&
                                                                                    sa.Phone == address.Phone &&
                                                                                    sa.State == address.State &&
                                                                                    sa.Street == address.Street &&
                                                                                    sa.Zip == address.Zip);

                    return(shippingAddress?.ID);
                }

                throw new PaymentException(PaymentException.ErrorType.ProviderError, string.Empty, ex.Message, ex);
            }
        }
예제 #4
0
        private AuthorizeNetSDK.Address CreateBillingAddress(Transaction t)
        {
            var address = new AuthorizeNetSDK.Address
            {
                First   = t.Customer.FirstName,
                Last    = t.Customer.LastName,
                Company = t.Customer.Company,
                Street  = t.Customer.Street,
                City    = t.Customer.City
            };

            var country = t.Customer.CountryData;

            address.Country = country != null ? country.IsoNumeric : t.Customer.CountryName;

            // TODO: Add code to make sure we've got the correct state format
            if (!string.IsNullOrWhiteSpace(t.Customer.RegionName))
            {
                address.State = t.Customer.RegionName;
            }

            address.Zip   = t.Customer.PostalCode;
            address.Phone = t.Customer.Phone;
            return(address);
        }
        public void CreateSubscriptionTest_zeroTrial()
        {
            var random = new AnetRandom();
            var counter = random.Next(1, (int)(Math.Pow(2, 24)));
            var amount = ComputeRandomAmount();
            var email = string.Format("user.{0}@authorize.net", counter);

            const string responseString = "<?xml version=\"1.0\" encoding=\"utf-8\"?><ARBCreateSubscriptionResponse xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"AnetApi/xml/v1/schema/AnetApiSchema.xsd\"><messages><resultCode>Ok</resultCode><message><code>I00001</code><text>Successful.</text></message></messages><subscriptionId>2074569</subscriptionId></ARBCreateSubscriptionResponse>";
            LocalRequestObject.ResponseString = responseString;

            var target = new SubscriptionGateway(ApiLogin, TransactionKey);

            var billToAddress = new Address { First = "SomeOneCool", Last = "MoreCoolPerson" };
            ISubscriptionRequest subscription = SubscriptionRequest.CreateMonthly(email, "ARB Subscription Test", amount, 10);
            subscription.CardNumber = "4111111111111111";
            subscription.CardExpirationMonth = 3;
            subscription.CardExpirationYear = Convert.ToInt32(DateTime.Now.AddYears(3).ToString("yyyy"));
            subscription.BillingAddress = billToAddress;

            //setting Trial amount/ Trial Ocurances to 0 
            subscription.SetTrialPeriod(3, 0M);

            ISubscriptionRequest actual = null;
            actual = target.CreateSubscription(subscription);
            Assert.NotNull(actual);
        }
예제 #6
0
 /// <summary>
 /// Adds a shipping address to the request.
 /// </summary>
 /// <param name="add">The address to ship to</param>
 /// <returns></returns>
 public SubscriptionRequest WithShippingAddress(Address add) {
     this.ShippingAddress = add;
     return this;
 }
예제 #7
0
 /// <summary>
 /// Adds a full billing address - which is required for a credit card.
 /// </summary>
 /// <param name="add">The add.</param>
 /// <returns></returns>
 public SubscriptionRequest WithBillingAddress(Address add) {
     this.BillingAddress = add;
     return this;
 }
예제 #8
0
        public void TestSdkUpgradeCustomerOrder()
        {
            var random = new AnetRandom();
            var counter = random.Next(1, (int)(Math.Pow(2, 24)));
            const int maxAmount = 10000;// 214747;
            var amount = new decimal(counter > maxAmount ? (counter % maxAmount) : counter);
            var email = string.Format("user.{0}@authorize.net", counter);
            var description = string.Format("Description for Customer: {0}", counter);
            var merchantCustomerId = string.Format("CustomerId: {0}", counter);
            const string cardNumber = "4111111111111111";
            const string  cvv = "";
            var address = new Address
                {
                    First = string.Format("FName:{0}", counter),
                    Last = string.Format("LName:{0}", counter),
                    Company = "Visa",
                    Street = "123 Elm Street",
                    City = "Bellevue",
                    State = "WA",
                    Country = "US",
                    Zip = "98006"
                };

            //Save the customer first
            var gw = new CustomerGateway(ApiLogin, TransactionKey);

            var customer = gw.CreateCustomer(email, description, merchantCustomerId);
            var creditCardToken = gw.AddCreditCard(customer.ProfileID, cardNumber, DateTime.UtcNow.Month, DateTime.UtcNow.AddYears(1).Year, cvv, address);

            //Create order
            var order = new Order(customer.ProfileID, creditCardToken, "")
                {
                    Amount = amount,
                    CardCode = cvv,
                    ExtraOptions = "x_duplicate_window=0"
                };

            var result = (GatewayResponse)gw.AuthorizeAndCapture(order);
            Assert.IsNotNull(result, "GateWay response for Order AuthCapture is null");

            var buffer = new StringBuilder();

            buffer.Append( "IGateWayResponse->");
            buffer.AppendFormat( "  SplitTenderId:{0}", result.SplitTenderId);
            buffer.AppendFormat( ", MD5Hash:{0}", result.MD5Hash);
            buffer.AppendFormat( ", CCVResponse:{0}", result.CCVResponse);
            buffer.AppendFormat( ", Code:{0}", result.Code);
            buffer.AppendFormat( ", TransactionType:{0}", result.TransactionType);
            buffer.AppendFormat( ", AuthorizationCode:{0}", result.AuthorizationCode);
            buffer.AppendFormat( ", Method:{0}", result.Method);
            buffer.AppendFormat( ", Amount:{0}", result.Amount);
            buffer.AppendFormat( ", Tax:{0}", result.Tax);
            buffer.AppendFormat( ", TransactionID:{0}", result.TransactionID);
            buffer.AppendFormat( ", InvoiceNumber:{0}", result.InvoiceNumber);
            buffer.AppendFormat( ", Description:{0}", result.Description);
            buffer.AppendFormat( ", ResponseCode:{0}", result.ResponseCode);
            buffer.AppendFormat( ", CardNumber:{0}", result.CardNumber);
            buffer.AppendFormat( ", CardType:{0}", result.CardType);
            buffer.AppendFormat( ", CAVResponse:{0}", result.CAVResponse);
            buffer.AppendFormat( ", AVSResponse:{0}", result.AVSResponse);
            buffer.AppendFormat( ", SubCode:{0}", result.SubCode);
            buffer.AppendFormat( ", Message:{0}", result.Message);
            buffer.AppendFormat( ", Approved:{0}", result.Approved);
            buffer.AppendFormat( ", Declined:{0}", result.Declined);
            buffer.AppendFormat( ", Error:{0}", result.Error);
            buffer.AppendFormat( ", HeldForReview:{0}", result.HeldForReview);
            buffer.AppendFormat( ", FirstName:{0}", result.FirstName);
            buffer.AppendFormat( ", LastName:{0}", result.LastName);
            buffer.AppendFormat( ", Email:{0}", result.Email);
            buffer.AppendFormat( ", Company:{0}", result.Company);
            buffer.AppendFormat( ", Address:{0}", result.Address);
            buffer.AppendFormat( ", City:{0}", result.City);
            buffer.AppendFormat( ", State:{0}", result.State);
            buffer.AppendFormat( ", ZipCode:{0}", result.ZipCode);
            buffer.AppendFormat( ", Country:{0}", result.Country);
            buffer.AppendFormat( ", ShipFirstName:{0}", result.ShipFirstName);
            buffer.AppendFormat( ", ShipLastName:{0}", result.ShipLastName);
            buffer.AppendFormat( ", ShipCompany:{0}", result.ShipCompany);
            buffer.AppendFormat( ", ShipAddress:{0}", result.ShipAddress);
            buffer.AppendFormat( ", ShipCity:{0}", result.ShipCity);
            buffer.AppendFormat( ", ShipState:{0}", result.ShipState);
            buffer.AppendFormat( ", ShipZipCode:{0}", result.ShipZipCode);
            buffer.AppendFormat( ", ShipCountry:{0}", result.ShipCountry);

            Console.WriteLine(buffer);

            Assert.IsNotNull(result.MD5Hash);
            Assert.IsNotNullOrEmpty(result.TransactionType);
            Assert.IsNotNullOrEmpty(result.AuthorizationCode);
            Assert.IsNotNullOrEmpty(result.Method);
            Assert.AreEqual("CC", result.Method);
            Assert.IsNotNullOrEmpty(result.TransactionID);
            Assert.AreEqual("1", result.ResponseCode);
            Assert.AreEqual( "XXXX1111", result.CardNumber);
            Assert.AreEqual( "Visa", result.CardType);
            Assert.AreEqual("This transaction has been approved.", result.Message);
            Assert.IsTrue(result.Approved);
            Assert.IsFalse(result.Declined);
        }
예제 #9
0
        public void StoreInVault(int peopleId, string type, string cardNumber, string expires, string cardCode,
            string routing, string account, bool giving)
        {
            var person = db.LoadPersonById(peopleId);
            var paymentInfo = person.PaymentInfo();
            if (paymentInfo == null)
            {
                paymentInfo = new PaymentInfo();
                person.PaymentInfos.Add(paymentInfo);
            }

            var billToAddress = new AuthorizeNet.Address
            {
                First = paymentInfo.FirstName ?? person.FirstName,
                Last = paymentInfo.LastName ?? person.LastName,
                Street = paymentInfo.Address ?? person.PrimaryAddress,
                City = paymentInfo.City ?? person.PrimaryCity,
                State = paymentInfo.State ?? person.PrimaryState,
                Country = paymentInfo.Country ?? person.PrimaryCountry,
                Zip = paymentInfo.Zip ?? person.PrimaryZip,
                Phone = paymentInfo.Phone ?? person.HomePhone ?? person.CellPhone
            };

            Customer customer;

            if (paymentInfo.AuNetCustId == null) // create a new profilein Authorize.NET CIM
            {
                // NOTE: this can throw an error if the email address already exists...
                // TODO: Authorize.net needs to release a new Nuget package, because they don't have a clean way to pass in customer ID (aka PeopleId) yet... the latest code has a parameter for this, though
                //       - we could call UpdateCustomer after the fact to do this if we wanted to
                customer = CustomerGateway.CreateCustomer(person.EmailAddress, person.Name);
                customer.ID = peopleId.ToString();

                paymentInfo.AuNetCustId = customer.ProfileID.ToInt();
            }
            else
            {
                customer = CustomerGateway.GetCustomer(paymentInfo.AuNetCustId.ToString());
            }

            customer.BillingAddress = billToAddress;
            var isSaved = CustomerGateway.UpdateCustomer(customer);
            if (!isSaved)
                throw new Exception($"UpdateCustomer failed to save for {peopleId}");

            if (type == PaymentType.Ach)
            {
                SaveECheckToProfile(routing, account, paymentInfo, customer);

                paymentInfo.MaskedAccount = Util.MaskAccount(account);
                paymentInfo.Routing = Util.Mask(new StringBuilder(routing), 2);
            }
            else if (type == PaymentType.CreditCard)
            {
                var normalizeExpires = DbUtil.NormalizeExpires(expires);
                if (normalizeExpires == null)
                    throw new ArgumentException($"Can't normalize date {expires}", nameof(expires));

                var expiredDate = normalizeExpires.Value;

                SaveCreditCardToProfile(cardNumber, cardCode, expiredDate, paymentInfo, customer);

                paymentInfo.MaskedCard = Util.MaskCC(cardNumber);
                paymentInfo.Expires = expires;
            }
            else
                throw new ArgumentException($"Type {type} not supported", nameof(type));

            if (giving)
                paymentInfo.PreferredGivingType = type;
            else
                paymentInfo.PreferredPaymentType = type;

            db.SubmitChanges();
        }
 /// <summary>
 /// Adds a bank account profile to the user and returns the profile ID
 /// </summary>
 /// <returns></returns>
 public string AddECheckBankAccount(string profileID, BankAccountType bankAccountType, string bankRoutingNumber,
                                    string bankAccountNumber,
                                    string personNameOnAccount, string bankName, EcheckType eCheckType,
                                    Address billToAddress)
 {
     return AddECheckBankAccount(profileID,
                                 new BankAccount()
                                     {
                                         accountTypeSpecified = true,
                                         accountType = bankAccountType,
                                         routingNumber = bankRoutingNumber,
                                         accountNumber = bankAccountNumber,
                                         nameOnAccount = personNameOnAccount,
                                         bankName = bankName,
                                         echeckTypeSpecified = true,
                                         echeckType = eCheckType
                                     }, billToAddress);
 }
예제 #11
0
        /// <summary>
        /// Updates a shipping address for a user.
        /// </summary>
        /// <param name="profileID">The profile ID.</param>
        /// <param name="address">The address.</param>
        /// <returns></returns>
        public bool UpdateShippingAddress(string profileID, Address address)
        {
            var req = new updateCustomerShippingAddressRequest();

            req.customerProfileId = profileID;
            req.address = address.ToAPIExType();
            var response = (updateCustomerShippingAddressResponse)_gateway.Send(req);

            return true;
        }
예제 #12
0
        /// <summary>
        /// Adds a Shipping Address to the customer profile
        /// </summary>
        public string AddShippingAddress(string profileID, Address address)
        {
            var req = new createCustomerShippingAddressRequest();

            req.address = address.ToAPIType();
            req.customerProfileId = profileID;
            var response = (createCustomerShippingAddressResponse)_gateway.Send(req);

            return response.customerAddressId;
        }
 public override string AddCreditCard(string customerProfileId, string cardNumber, int expMonth, int expYear,
                                      string cscNumber, AuthorizeNet.Address address)
 {
     return(AddCreditCard(customerProfileId, cardNumber, expMonth, expYear));
 }
        /// <summary>
        /// Adds a bank account profile to the user and returns the profile ID
        /// </summary>
        /// <returns></returns>
        public string AddECheckBankAccount(string profileID, BankAccount bankAccount, Address billToAddress)
        {
            var req = new createCustomerPaymentProfileRequest();

            req.customerProfileId = profileID;
            req.paymentProfile = new customerPaymentProfileType();
            req.paymentProfile.payment = new paymentType();

            var bankAcct = new bankAccountType()
                {
                    accountTypeSpecified = bankAccount.accountTypeSpecified,
                    accountType = (bankAccountTypeEnum)Enum.Parse(typeof(bankAccountTypeEnum), bankAccount.accountType.ToString(), true),
                    routingNumber = bankAccount.routingNumber,
                    accountNumber = bankAccount.accountNumber,
                    nameOnAccount = bankAccount.nameOnAccount,
                    bankName = bankAccount.bankName,
                    echeckTypeSpecified = bankAccount.echeckTypeSpecified,
                    echeckType = (echeckTypeEnum)Enum.Parse(typeof(echeckTypeEnum), bankAccount.echeckType.ToString(), true)
                };
 
            req.paymentProfile.payment.Item = bankAcct;

            if (billToAddress != null)
                req.paymentProfile.billTo = billToAddress.ToAPIType();

            req.validationModeSpecified = true;
            req.validationMode = this._mode;

            var response = (createCustomerPaymentProfileResponse) _gateway.Send(req);

            return response.customerPaymentProfileId;
        }
        public void CreateSubscriptionTest_eCheck()
        {
            const string responseString = "<?xml version=\"1.0\" encoding=\"utf-8\"?><ARBCreateSubscriptionResponse xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"AnetApi/xml/v1/schema/AnetApiSchema.xsd\"><messages><resultCode>Ok</resultCode><message><code>I00001</code><text>Successful.</text></message></messages><subscriptionId>2074569</subscriptionId></ARBCreateSubscriptionResponse>";
            LocalRequestObject.ResponseString = responseString;

            var target = new SubscriptionGateway(ApiLogin, TransactionKey);

            ISubscriptionRequest subscription = SubscriptionRequest.CreateMonthly("*****@*****.**",
                                                                                  "ARB Subscription Test eCheck", _mAmount,
                                                                                  12);
            subscription.eCheckBankAccount = new BankAccount
                {
                    accountTypeSpecified = true,
                    accountType = BankAccountType.Checking,
                    routingNumber = "125000024",
                    accountNumber = "123456",
                    nameOnAccount = "Sue Zhu",
                    echeckTypeSpecified = true,
                    echeckType = EcheckType.WEB
                };

            var billToAddress = new Address {First = "Sue", Last = "Zhu"};
            subscription.BillingAddress = billToAddress;

            ISubscriptionRequest actual = target.CreateSubscription(subscription);

            Assert.AreEqual(subscription.Amount, actual.Amount);
            Assert.AreEqual(subscription.eCheckBankAccount.accountNumber, actual.eCheckBankAccount.accountNumber);
            Assert.AreEqual(subscription.SubscriptionName, actual.SubscriptionName);

            Assert.IsTrue(actual.SubscriptionID.Trim().Length > 0);
            Assert.IsTrue(0 < long.Parse(actual.SubscriptionID));
        }
예제 #16
0
        public void StoreInVault(int peopleId, string type, string cardNumber, string expires, string cardCode,
                                 string routing, string account, bool giving)
        {
            var person      = db.LoadPersonById(peopleId);
            var paymentInfo = person.PaymentInfo();

            if (paymentInfo == null)
            {
                paymentInfo = new PaymentInfo();
                person.PaymentInfos.Add(paymentInfo);
            }

            var billToAddress = new AuthorizeNet.Address
            {
                First   = paymentInfo.FirstName ?? person.FirstName,
                Last    = paymentInfo.LastName ?? person.LastName,
                Street  = paymentInfo.Address ?? person.PrimaryAddress,
                City    = paymentInfo.City ?? person.PrimaryCity,
                State   = paymentInfo.State ?? person.PrimaryState,
                Country = paymentInfo.Country ?? person.PrimaryCountry,
                Zip     = paymentInfo.Zip ?? person.PrimaryZip,
                Phone   = paymentInfo.Phone ?? person.HomePhone ?? person.CellPhone
            };

            Customer customer;

            if (paymentInfo.AuNetCustId == null) // create a new profilein Authorize.NET CIM
            {
                // NOTE: this can throw an error if the email address already exists...
                // TODO: Authorize.net needs to release a new Nuget package, because they don't have a clean way to pass in customer ID (aka PeopleId) yet... the latest code has a parameter for this, though
                //       - we could call UpdateCustomer after the fact to do this if we wanted to
                customer    = CustomerGateway.CreateCustomer(person.EmailAddress, person.Name);
                customer.ID = peopleId.ToString();

                paymentInfo.AuNetCustId = customer.ProfileID.ToInt();
            }
            else
            {
                customer = CustomerGateway.GetCustomer(paymentInfo.AuNetCustId.ToString());
            }

            customer.BillingAddress = billToAddress;
            var isSaved = CustomerGateway.UpdateCustomer(customer);

            if (!isSaved)
            {
                throw new Exception($"UpdateCustomer failed to save for {peopleId}");
            }

            if (type == PaymentType.Ach)
            {
                SaveECheckToProfile(routing, account, paymentInfo, customer);

                paymentInfo.MaskedAccount = Util.MaskAccount(account);
                paymentInfo.Routing       = Util.Mask(new StringBuilder(routing), 2);
            }
            else if (type == PaymentType.CreditCard)
            {
                var normalizeExpires = DbUtil.NormalizeExpires(expires);
                if (normalizeExpires == null)
                {
                    throw new ArgumentException($"Can't normalize date {expires}", nameof(expires));
                }

                var expiredDate = normalizeExpires.Value;

                SaveCreditCardToProfile(cardNumber, cardCode, expiredDate, paymentInfo, customer);

                paymentInfo.MaskedCard = Util.MaskCC(cardNumber);
                paymentInfo.Expires    = expires;
            }
            else
            {
                throw new ArgumentException($"Type {type} not supported", nameof(type));
            }

            if (giving)
            {
                paymentInfo.PreferredGivingType = type;
            }
            else
            {
                paymentInfo.PreferredPaymentType = type;
            }

            db.SubmitChanges();
        }
예제 #17
0
        public ActionResult AddCard(AddCard model)
        {
            if (ModelState.IsValid)
            {
                var transaction = new Transaction(IsolationLevel.ReadCommitted, "add card");
                try
                {
                    CustomerGateway cg;
                    var             customer = EnsureProfile(out cg);

                    var addr = new AuthorizeNet.Address
                    {
                        First   = model.FirstName,
                        Last    = model.LastName,
                        Street  = model.AddressLine1 + Environment.NewLine + model.AddressLine2,
                        State   = model.State,
                        Country = model.Country,
                        City    = model.City,
                        Zip     = model.Zip
                    };

                    // save the customer profile for the currently logged on user
                    var creditCard = new CreditCardEntity()
                    {
                        FirstName     = model.FirstName,
                        LastName      = model.LastName,
                        AccountNumber = model.CardNumber.Substring(model.CardNumber.Length - 4, 4),
                        Address       = model.AddressLine1
                    };

                    creditCard.AuthorizeId = cg.AddCreditCard(
                        customer.ProfileID,
                        model.CardNumber,
                        model.CardMonth,
                        model.CardYear,
                        model.SecurityCode,
                        addr);
                    transaction.Add(creditCard);
                    creditCard.Save();

                    var userCard = new UserCreditCardEntity
                    {
                        UserId       = Membership.GetUser().GetUserEntity().UserId,
                        CreditCardId = creditCard.CreditCardId
                    };
                    transaction.Add(userCard);
                    userCard.Save();

                    transaction.Commit();

                    return(new EmptyResult());
                }
                catch (Exception ex)
                {
                    transaction.Rollback();
                    // try to get all profiles from authorize.net
                    if (ex.Message.Contains("duplicate"))
                    {
                        ForceResync();
                    }
                    else
                    {
                        ModelState.AddModelError("", Purchase.AddCard_Error);
                    }
                    Log.Error(Purchase.AddCard_Error, ex);
                }
                finally
                {
                    transaction.Dispose();
                }
            }

            Response.StatusCode             = 417;
            Response.TrySkipIisCustomErrors = true;

            return(PartialView(model));
        }