/// <summary>
        /// Add a new card to the profile. It gets appended to the end of the list of cards.
        /// Make sure your Merchant account can support more cards. The default amount is 1.
        /// You can change this limit in the online Members area for Merchants located at:
        /// https://www.beanstream.com/admin/sDefault.asp
        /// and heading to Configuration -> Payment Profile Configuration
        /// </summary>
        /// <returns>The response</returns>
        /// <param name="profileId">Profile identifier.</param>
        /// <param name="card">Card.</param>
        public ProfileResponse AddCard(string profileId, Card card)
        {
            string url = BeanstreamUrls.CardsUrl
                .Replace ("{v}", String.IsNullOrEmpty (_configuration.Version) ? "v1" : "v" + _configuration.Version)
                .Replace ("{p}", String.IsNullOrEmpty (_configuration.Platform) ? "www" : _configuration.Platform)
                .Replace ("{id}", profileId);

            HttpsWebRequest req = new HttpsWebRequest () {
                MerchantId = _configuration.MerchantId,
                Passcode = _configuration.ProfilesApiPasscode,
                WebCommandExecutor = _webCommandExecuter
            };

            // the json wants to be wrapped in a 'card' group
            var c = new {
                card
            };

            string response = req.ProcessTransaction (HttpMethod.Post, url, c);
            return JsonConvert.DeserializeObject<ProfileResponse>(response);
        }
        private ProfileResponse CreateProfile(Token token, Card card, Address billingAddress, CustomFields customFields, string language, string comment)
        {
            if (token == null && card == null) {
                Gateway.ThrowIfNullArgument (null, "Card and Token both null!");
            }

            if (token == null) {
                Gateway.ThrowIfNullArgument (card, "card");
                Gateway.ThrowIfNullArgument (card.Number, "card.number");
                Gateway.ThrowIfNullArgument (card.Name, "card.name");
                Gateway.ThrowIfNullArgument (card.ExpiryMonth, "card.expiryMonth");
                Gateway.ThrowIfNullArgument (card.ExpiryYear, "card.expiryYear");
            }
            if (card == null) {
                Gateway.ThrowIfNullArgument (token, "token");
                Gateway.ThrowIfNullArgument (token.Name, "token.name");
                Gateway.ThrowIfNullArgument (token.Code, "token.code");
            }

            string url = BeanstreamUrls.BaseProfilesUrl
                .Replace ("{v}", String.IsNullOrEmpty (_configuration.Version) ? "v1" : "v" + _configuration.Version)
                .Replace ("{p}", String.IsNullOrEmpty (_configuration.Platform) ? "www" : _configuration.Platform);

            HttpsWebRequest req = new HttpsWebRequest () {
                MerchantId = _configuration.MerchantId,
                Passcode = _configuration.ProfilesApiPasscode,
                WebCommandExecutor = _webCommandExecuter
            };

            var profile = new {
                card = card,
                token = token,
                billing = billingAddress,
                custom = customFields
            };

            string response = req.ProcessTransaction (HttpMethod.Post, url, profile);

            return JsonConvert.DeserializeObject<ProfileResponse>(response);
        }
        /// <summary>
        /// Updates the card on the profile.
        /// </summary>
        /// <returns>The result of the update</returns>
        /// <param name="profileId">Profile identifier.</param>
        /// <param name="card">Card.</param>
        public ProfileResponse UpdateCard(string profileId, Card card)
        {
            string url = BeanstreamUrls.CardsUrl
                .Replace ("{v}", String.IsNullOrEmpty (_configuration.Version) ? "v1" : "v" + _configuration.Version)
                .Replace ("{p}", String.IsNullOrEmpty (_configuration.Platform) ? "www" : _configuration.Platform)
                .Replace ("{id}", profileId)
                         + "/" + card.Id;

            HttpsWebRequest req = new HttpsWebRequest () {
                MerchantId = _configuration.MerchantId,
                Passcode = _configuration.ProfilesApiPasscode,
                WebCommandExecutor = _webCommandExecuter
            };

            if (card.Number.Contains ("X") )
                card.Number = null; // when a card is returned from the server the number will be masked with X's. We don't want to submit that back.

            // the json wants to be wrapped in a 'card' group
            var c = new {
                card
            };

            string response = req.ProcessTransaction (HttpMethod.Put, url, c);
            return JsonConvert.DeserializeObject<ProfileResponse>(response);
        }
 /// <summary>
 /// Create a Payment Profile with a Credit Card and billing address
 /// </summary>
 /// <returns>The profile response containing the profile ID</returns>
 /// <param name="card">Card.</param>
 /// <param name="billingAddress">Billing address.</param>
 /// <param name="customFields">Custom fields. Optional</param>
 /// <param name="language">Language. Optional</param>
 /// <param name="comment">Comment. Optional</param>
 public ProfileResponse CreateProfile(Card card, Address billingAddress, CustomFields customFields, string language, string comment)
 {
     return CreateProfile (null, card, billingAddress, customFields, language, comment);
 }
 /// <summary>
 /// Create a Payment Profile with a Credit Card and billing address
 /// </summary>
 /// <returns>The profile response containing the profile ID</returns>
 /// <param name="card">Card.</param>
 /// <param name="billingAddress">Billing address.</param>
 public ProfileResponse CreateProfile(Card card, Address billingAddress)
 {
     return CreateProfile (card, billingAddress, null, null, null);
 }
 public ProfileResponse UpdateCard(ProfilesAPI api, Card card)
 {
     return api.UpdateCard (Id, card);
 }
 /// <summary>
 /// Add a card to this payment profile
 /// </summary>
 /// <returns>The card.</returns>
 /// <param name="card">Card.</param>
 /// <param name="gateway">Gateway.</param>
 public ProfileResponse AddCard(ProfilesAPI api, Card card)
 {
     return api.AddCard (Id, card);
 }