/// <summary>
 /// Update the payment method with the provided payload attributes
 /// </summary>
 /// <remarks>
 /// This method will set the attributes of this payment method.
 /// It will also persist the new changes to the server.
 /// </remarks>
 public void UpdateAttributes(PaymentMethodPayload payload)
 {
     SetAttributes(payload);
     Update();
 }
 /// <summary>
 /// Update the payment method with the provided payload attributes
 /// </summary>
 /// <remarks>
 /// This method will set the attributes of this payment method. It does not
 /// persist those changes to the server.
 /// </remarks>
 public void SetAttributes(PaymentMethodPayload payload)
 {
     FirstName = payload.FirstName;
     LastName = payload.LastName;
     Address1 = payload.Address1;
     Address2 = payload.Address2;
     City = payload.City;
     State = payload.State;
     Zip = payload.Zip;
     CardNumber = payload.CardNumber;
     Cvv = payload.Cvv;
     ExpiryMonth = payload.ExpiryMonth;
     ExpiryYear = payload.ExpiryYear;
     Custom = payload.Custom;
     Sandbox = payload.Sandbox;
 }
        /// <summary>
        /// Creates a brand new payment method with given parameters.
        /// </summary>
        /// <param name="payload">Payment Method payload, containing parameters for the new PM</param>
        /// <returns>a brand new payment method.</returns>
        public static PaymentMethod Create(PaymentMethodPayload payload)
        {
            // create a payment method
            string pmToken = TokenizePaymentMethod(payload);

            // fetch it ny its token
            PaymentMethod pm = PaymentMethod.Find(pmToken);

            return pm;
        }
        /// <summary>
        /// Creates a brand new payment method with given parameters and returns its token.
        /// </summary>
        /// <param name="payload">Payment Method payload, containing parameters for the new PM</param>
        /// <returns>token of a brand new payment method.</returns>
        public static string TokenizePaymentMethod(PaymentMethodPayload payload)
        {
            // client for creating
            var client = new RestClient();
            client.BaseUrl = Samurai.Site;
            client.UserAgent = "FeeFighters Samurai .NET Client v"+Samurai.Version;

            // create post-request
            var request = new RestRequest(Method.POST);
            request.Timeout = int.MaxValue;
            request.Resource = "payment_methods/tokenize";
            request.AddParameter("Accept", "application/json", ParameterType.HttpHeader);

            request.AddParameter("redirect_url", "http://127.0.0.1:80");
            request.AddParameter("merchant_key", Samurai.MerchantKey);

            request.AddParameter("credit_card[first_name]", payload.FirstName);
            request.AddParameter("credit_card[last_name]", payload.LastName);
            request.AddParameter("credit_card[address_1]", payload.Address1);
            request.AddParameter("credit_card[address_2]", payload.Address2);
            request.AddParameter("credit_card[city]", payload.City);
            request.AddParameter("credit_card[state]", payload.State);
            request.AddParameter("credit_card[zip]", payload.Zip);
            request.AddParameter("credit_card[card_number]", payload.CardNumber);
            request.AddParameter("credit_card[cvv]", payload.Cvv);
            request.AddParameter("credit_card[expiry_month]", payload.ExpiryMonth);
            request.AddParameter("credit_card[expiry_year]", payload.ExpiryYear);
            request.AddParameter("custom", payload.Custom);
            request.AddParameter("sandbox", payload.Sandbox);

            // get response
            if (Samurai.Debug) {
                Console.WriteLine(request.Resource.ToString());
                request.Parameters.ForEach(delegate(RestSharp.Parameter p) {
                    Console.WriteLine(p.ToString());
                });
            }
            var response = client.Execute(request);
            if (Samurai.Debug) {
                Console.WriteLine(response.StatusCode.ToString() + " - " + response.StatusDescription.ToString());
                Console.WriteLine(response.Content.ToString());
            }

            // get token from url
            var match = Regex.Match(response.Content, "\"payment_method_token\":\\s*\"(\\w+)\"", RegexOptions.IgnoreCase);
            return match.Groups[1].ToString();
        }
        public PaymentMethodPayload Merge(PaymentMethodPayload payload)
        {
            if (payload == null) return this;

            if (payload.FirstName != null)  { FirstName = payload.FirstName; }
            if (payload.LastName != null)   { LastName = payload.LastName; }
            if (payload.Address1 != null)   { Address1 = payload.Address1; }
            if (payload.Address2 != null)   { Address2 = payload.Address2; }
            if (payload.City != null)       { City = payload.City; }
            if (payload.State != null)      { State = payload.State; }
            if (payload.Zip != null)        { Zip = payload.Zip; }
            if (payload.CardNumber != null) { CardNumber = payload.CardNumber; }
            if (payload.Cvv != null)        { Cvv = payload.Cvv; }
            ExpiryMonth = payload.ExpiryMonth==0 ? ExpiryMonth : payload.ExpiryMonth;
            ExpiryYear = payload.ExpiryYear==0 ? ExpiryYear : payload.ExpiryYear;
            if (payload.Custom != null)     { Custom = payload.Custom; }
            Sandbox = Sandbox || payload.Sandbox;
            return this;
        }