Beispiel #1
0
        /// <summary>
        /// Операция для получения токена
        /// </summary>
        /// <param name="amount">Стоимость</param>
        /// <param name="currencyCode">Валюта</param>
        /// <param name="action">Действие на сайте PayPal, которое пользователь должен будет сделать</param>
        /// <param name="cancelUrl">URL, куда перенаправят пользователя в случае ошибки или отказа от проведения платежа</param>
        /// <param name="returnUrl">URL, куда перенаправят пользователя в случае успешного выполнения платежа</param>
        /// <returns>Все параметры, которые пришли от PayPal</returns>
        public Dictionary<string, string> GetToken(Currency currencyCode, PayAction action,  string cancelUrl, string returnUrl)
        {
            var errList = Validate();
            if (errList.Count != 0)
            { throw new Exception("Can`t get PayPal token because an error has occurred: " + string.Join(",", errList.ToArray())); }

            if (string.IsNullOrWhiteSpace(cancelUrl))
            { throw new Exception("Cancel url is not defined"); }

            if (string.IsNullOrWhiteSpace(returnUrl))
            { throw new Exception("Successfull url is not defined"); }

            var retDict = new Dictionary<string, string>();

            /* --- Получаем сумму для оплаты --- */
            decimal amount = basket.Sum(t => Convert.ToDecimal(t.Amount));

            /* --- !Получаем сумму для оплаты --- */

            var client = new WebClient();
            var requestStr = new StringBuilder();
            requestStr.Append(string.Format("{0}/?USER={1}&PWD={2}&SIGNATURE={3}&METHOD=SetExpressCheckout&VERSION={4}&PAYMENTREQUEST_0_AMT={5}&PAYMENTREQUEST_0_CURRENCYCODE={6}&PAYMENTREQUEST_0_PAYMENTACTION={7}&cancelUrl={8}&returnUrl={9}",
                                            PayPalURL, User, Password, Signature, Version, amount.ToString("F").Replace(',','.'), currencyCode.ToString("F"), action.ToString("F"), cancelUrl, returnUrl));

            requestStr.Append(currencyCode == Currency.RUB ? "&LOCALECODE=RU" : "&LOCALECODE=US");

            for (int i = 0; i < basket.Count; i++)
            {
                requestStr.Append(string.Format("&L_PAYMENTREQUEST_0_NAME{0}={1}&L_PAYMENTREQUEST_0_DESC{0}={2}&L_PAYMENTREQUEST_0_AMT{0}={3}&L_PAYMENTREQUEST_0_QTY{0}={4}",
                                                i, basket[i].Name, basket[i].Description, basket[i].Amount.Replace(',', '.'), basket[i].Quantity));
            }

            var sr = new StreamReader(client.OpenRead(requestStr.ToString()));

            string newLine;
            while ((newLine = sr.ReadLine()) != null)
            {
                foreach (var curPair in newLine.Split('&'))
                {
                    var pairKeyVal = curPair.Split('=');
                    retDict.Add(pairKeyVal[0], pairKeyVal[1]);
                }
            }

            TokenResponse = retDict;
            return retDict;
        }
Beispiel #2
0
        /// <summary>
        /// Получаем детали о покупке
        /// </summary>
        /// <param name="token">Токен, пришедший через GET от PayPal</param>
        /// <returns>Детали покупки</returns>
        public Dictionary<string, string> GetCheckoutDetails(string token)
        {
            var errList = Validate();
            if (errList.Count != 0)
            { throw new Exception("Can`t get PayPal token because an error has occurred: " + string.Join(",", errList.ToArray())); }

            if (string.IsNullOrWhiteSpace(token))
            { throw new Exception("Token can`t be empty"); }

            var retDict = new Dictionary<string, string>();

            var client = new WebClient();
            var requestStr = string.Format("{0}/?USER={1}&PWD={2}&SIGNATURE={3}&METHOD=GetExpressCheckoutDetails&VERSION={4}&token={5}",
                                            PayPalURL, User, Password, Signature, Version, token);

            var sr = new StreamReader(client.OpenRead(requestStr));

            string newLine;
            while ((newLine = sr.ReadLine()) != null)
            {
                foreach (var curPair in newLine.Split('&'))
                {
                    var pairKeyVal = curPair.Split('=');
                    retDict.Add(pairKeyVal[0], pairKeyVal[1]);
                }
            }

            TokenResponse = retDict;
            return retDict;
        }
Beispiel #3
0
        /// <summary>
        /// Когда через IPN от сервера PayPal пришло сообщение, мы должны проверить его валидность этим методом
        /// </summary>
        /// <param name="postData">Словарь всех параметров, что пришли в посте через IPN</param>
        /// <param name="isTest">Режим работы PayPal</param>
        public static bool ValidateIPN(Dictionary<string, string> postData, bool isTest)
        {
            var postStr = new StringBuilder();
            foreach(var entry in postData)
            {
                postStr.Append(string.Format("&{0}={1}", entry.Key, entry.Value));
            }

            var client = new WebClient();
            var requestStr = string.Format("{0}/?cmd=_notify-validate{1}",
                isTest?HARDCODED_SandboxPaymentURL : HARDCODED_PaymentURL, postStr);

            var sr = new StreamReader(client.OpenRead(requestStr));

            var newLine = sr.ReadLine();

            /*/* --- Debug --- #1#
            SiteUtils.SendMail(null,
                                null,
                                "*****@*****.**",
                                "Антон Старостин",
                                "Валидация запроса от PayPal",
                                string.Format("<p>Request str: {0}</p><p>Response from PayPal: {1}</p>", requestStr, newLine),
                                true);
            /* --- Debug --- #1#*/

            return !string.IsNullOrWhiteSpace(newLine) && newLine == "VERIFIED"; // В случае подлинного сообщения, вернется VERIFIED, в ином случае - INVALID
        }
Beispiel #4
0
        /// <summary>
        /// Завершает платеж и производит транзакцию
        /// </summary>
        /// <param name="token">Токен, выданный PayPal для операции. После операции перевода он должен прийти в GET параметре</param>
        /// <param name="payerId">Идентификатор плательщика, выданный PayPal после операции. Он должен прийти в GET параметре</param>
        /// <param name="amount">Стоимость. Должна совпадать с той стоимостью, что указана в токене</param>
        /// <returns></returns>
        public Dictionary<string, string> ConfirmPayment(string token, string payerId, decimal amount, Currency curr)
        {
            var errList = Validate();
            if (errList.Count != 0)
            { throw new Exception("Can`t get PayPal token because an error has occurred: " + string.Join(",", errList.ToArray())); }

            if (string.IsNullOrWhiteSpace(payerId))
            { throw new Exception("Payer ID can`t be empty"); }

            if (string.IsNullOrWhiteSpace(token))
            { throw new Exception("Token can`t be empty"); }

            var retDict = new Dictionary<string, string>();

            var client = new WebClient();
            var requestStr = string.Format("{0}/?USER={1}&PWD={2}&SIGNATURE={3}&METHOD=DoExpressCheckoutPayment&VERSION={4}&token={5}&PAYERID={6}&PAYMENTREQUEST_0_AMT={7}&PAYMENTREQUEST_0_CURRENCYCODE={8}",
                                            PayPalURL, User, Password, Signature, Version, token, payerId, amount.ToString("F").Replace(',','.'), curr);

            if (!string.IsNullOrWhiteSpace(NotifyURL))
            {
                requestStr += string.Format("&PAYMENTREQUEST_0_NOTIFYURL={0}", NotifyURL);
            }

            var sr = new StreamReader(client.OpenRead(requestStr));

            string newLine;
            while ((newLine = sr.ReadLine()) != null)
            {
                foreach (var curPair in newLine.Split('&'))
                {
                    var pairKeyVal = curPair.Split('=');
                    retDict.Add(pairKeyVal[0], pairKeyVal[1]);
                }
            }

            TokenResponse = retDict;
            return retDict;
        }
        /// <summary>
        /// Used to render the search result listing (virtual node)
        /// </summary>
        /// <param name="model"></param>
        /// <param name="term">
        /// The search term
        /// </param>
        /// <param name="provider">
        /// The search provider name (optional)
        /// </param>
        /// <param name="p"></param>
        /// <returns></returns>
        public ActionResult Search(RenderModel model, string term, string provider = null, int? p = null)
        {
            var tagPage = model.Content as ArticulateVirtualPage;
            if (tagPage == null)
            {
                throw new InvalidOperationException("The RenderModel.Content instance must be of type " + typeof(ArticulateVirtualPage));
            }

            //create a blog model of the main page
            var rootPageModel = new ListModel(model.Content.Parent);

            if (term == null)
            {
                //nothing to search, just render the view
                var emptyList = new ListModel(tagPage, Enumerable.Empty<IPublishedContent>(), new PagerModel(rootPageModel.PageSize, 0, 0));
                return View(PathHelper.GetThemeViewPath(emptyList, "List"), emptyList);
            }

            if (p != null && p.Value == 1)
            {
                return new RedirectToUmbracoPageResult(model.Content, UmbracoContext);
            }

            if (p == null || p.Value <= 0)
            {
                p = 1;
            }

            var splitSearch = term.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            //The fields to search on and their 'weight' (importance)
            var fields = new Dictionary<string, int>
            {
                {"markdown", 2},
                {"richText", 2},
                {"nodeName", 3},
                {"tags", 1},
                {"categories", 1},
                {"umbracoUrlName", 3}
            };

            //The multipliers for match types
            const int exactMatch = 5;
            const int termMatch = 2;

            var fieldQuery = new StringBuilder();
            //build field query
            foreach (var field in fields)
            {
                //full exact match (which has a higher boost)
                fieldQuery.Append(string.Format("{0}:{1}^{2}", field.Key, "\"" + term + "\"", field.Value * exactMatch));
                fieldQuery.Append(" ");
                //NOTE: Phrase match wildcard isn't really supported unless you use the Lucene
                // API like ComplexPhraseWildcardSomethingOrOther...
                //split match
                foreach (var s in splitSearch)
                {
                    //match on each term, no wildcard, higher boost
                    fieldQuery.Append(string.Format("{0}:{1}^{2}", field.Key, s, field.Value * termMatch));
                    fieldQuery.Append(" ");

                    //match on each term, with wildcard
                    fieldQuery.Append(string.Format("{0}:{1}*", field.Key, s));
                    fieldQuery.Append(" ");
                }
            }

            var criteria = provider == null
                ? ExamineManager.Instance.CreateSearchCriteria()
                : ExamineManager.Instance.SearchProviderCollection[provider].CreateSearchCriteria();

            criteria.RawQuery(string.Format("+parentID:{0} +({1})", rootPageModel.BlogArchiveNode.Id, fieldQuery));

            var searchProvider = provider == null
                ? ExamineManager.Instance.DefaultSearchProvider
                : ExamineManager.Instance.SearchProviderCollection[provider];

            var searchResult = Umbraco.TypedSearch(criteria, searchProvider).ToArray();

            //TODO: I wonder about the performance of this - when we end up with thousands of blog posts,
            // this will probably not be so efficient. I wonder if using an XPath lookup for batches of children
            // would work? The children count could be cached. I'd rather not put blog posts under 'month' nodes
            // just for the sake of performance. Hrm.... Examine possibly too.

            var totalPosts = searchResult.Count();
            var pageSize = rootPageModel.PageSize;

            var totalPages = totalPosts == 0 ? 1 : Convert.ToInt32(Math.Ceiling((double)totalPosts / pageSize));

            //Invalid page, redirect without pages
            if (totalPages < p)
            {
                return new RedirectToUmbracoPageResult(model.Content.Parent, UmbracoContext);
            }

            var pager = new PagerModel(
                pageSize,
                p.Value - 1,
                totalPages,
                totalPages > p ? model.Content.Url.EnsureEndsWith('?') + "term=" + term + "&p=" + (p + 1) : null,
                p > 2 ? model.Content.Url.EnsureEndsWith('?') + "term=" + term + "&p=" + (p - 1) : p > 1 ? model.Content.Url.EnsureEndsWith('?') + "term=" + term : null);

            var listModel = new ListModel(tagPage, searchResult, pager);

            return View(PathHelper.GetThemeViewPath(listModel, "List"), listModel);
        }