public ActionResult PDTHandler(FormCollection form) { string tx = _webHelper.QueryString <string>("tx"); Dictionary <string, string> values; string response; var processor = _paymentService.LoadPaymentMethodBySystemName("Payments.PayPalStandard") as PayPalStandardPaymentProcessor; if (processor == null || !processor.IsPaymentMethodActive(_paymentSettings) || !processor.PluginDescriptor.Installed) { throw new SmartException(_helper.Resource("NoModuleLoading")); // codehint: sm-edit } if (processor.GetPDTDetails(tx, out values, out response)) { string orderNumber = string.Empty; values.TryGetValue("custom", out orderNumber); Guid orderNumberGuid = Guid.Empty; try { orderNumberGuid = new Guid(orderNumber); } catch { } Order order = _orderService.GetOrderByGuid(orderNumberGuid); if (order != null) { decimal total = decimal.Zero; try { total = decimal.Parse(values["mc_gross"], new CultureInfo("en-US")); } catch (Exception exc) { Logger.Error(_helper.Resource("FailedGetGross"), exc); } string payer_status = string.Empty; values.TryGetValue("payer_status", out payer_status); string payment_status = string.Empty; values.TryGetValue("payment_status", out payment_status); string pending_reason = string.Empty; values.TryGetValue("pending_reason", out pending_reason); string mc_currency = string.Empty; values.TryGetValue("mc_currency", out mc_currency); string txn_id = string.Empty; values.TryGetValue("txn_id", out txn_id); string payment_type = string.Empty; values.TryGetValue("payment_type", out payment_type); string payer_id = string.Empty; values.TryGetValue("payer_id", out payer_id); string receiver_id = string.Empty; values.TryGetValue("receiver_id", out receiver_id); string invoice = string.Empty; values.TryGetValue("invoice", out invoice); string payment_fee = string.Empty; values.TryGetValue("payment_fee", out payment_fee); string paymentNote = _helper.Resource("PaymentNote").FormatWith(total, mc_currency, payer_status, payment_status, pending_reason, txn_id, payment_type, payer_id, receiver_id, invoice, payment_fee); //order note order.OrderNotes.Add(new OrderNote() { Note = paymentNote, DisplayToCustomer = false, CreatedOnUtc = DateTime.UtcNow }); _orderService.UpdateOrder(order); //validate order total if (_paypalStandardPaymentSettings.PdtValidateOrderTotal && !Math.Round(total, 2).Equals(Math.Round(order.OrderTotal, 2))) { Logger.Error(_helper.Resource("UnequalTotalOrder").FormatWith(total, order.OrderTotal)); return(RedirectToAction("Index", "Home", new { area = "" })); } //mark order as paid if (_orderProcessingService.CanMarkOrderAsPaid(order)) { order.AuthorizationTransactionId = txn_id; _orderService.UpdateOrder(order); _orderProcessingService.MarkOrderAsPaid(order); } } return(RedirectToRoute("CheckoutCompleted")); } else { string orderNumber = string.Empty; values.TryGetValue("custom", out orderNumber); Guid orderNumberGuid = Guid.Empty; try { orderNumberGuid = new Guid(orderNumber); } catch { } Order order = _orderService.GetOrderByGuid(orderNumberGuid); if (order != null) { //order note order.OrderNotes.Add(new OrderNote() { Note = "{0} {1}".FormatWith(_helper.Resource("PdtFailed"), response), DisplayToCustomer = false, CreatedOnUtc = DateTime.UtcNow }); _orderService.UpdateOrder(order); } return(RedirectToAction("Index", "Home", new { area = "" })); } }
/// <summary> /// Post process payment (used by payment gateways that require redirecting to a third-party URL) /// </summary> /// <param name="postProcessPaymentRequest">Payment info required for an order processing</param> public override void PostProcessPayment(PostProcessPaymentRequest postProcessPaymentRequest) { var builder = new StringBuilder(); builder.Append(GetPaypalUrl()); string cmd = string.Empty; if (_paypalStandardPaymentSettings.PassProductNamesAndTotals) { cmd = "_cart"; } else { cmd = "_xclick"; } builder.AppendFormat("?cmd={0}&business={1}", cmd, HttpUtility.UrlEncode(_paypalStandardPaymentSettings.BusinessEmail)); if (_paypalStandardPaymentSettings.PassProductNamesAndTotals) { builder.AppendFormat("&upload=1"); //get the items in the cart decimal cartTotal = decimal.Zero; var cartItems = postProcessPaymentRequest.Order.OrderItems; int x = 1; foreach (var item in cartItems) { var unitPriceExclTax = item.UnitPriceExclTax; var priceExclTax = item.PriceExclTax; //round var unitPriceExclTaxRounded = Math.Round(unitPriceExclTax, 2); builder.AppendFormat("&item_name_" + x + "={0}", HttpUtility.UrlEncode(item.Product.Name)); builder.AppendFormat("&amount_" + x + "={0}", unitPriceExclTaxRounded.ToString("0.00", CultureInfo.InvariantCulture)); builder.AppendFormat("&quantity_" + x + "={0}", item.Quantity); x++; cartTotal += priceExclTax; } //the checkout attributes that have a dollar value and send them to Paypal as items to be paid for var caValues = _checkoutAttributeParser.ParseCheckoutAttributeValues(postProcessPaymentRequest.Order.CheckoutAttributesXml); foreach (var val in caValues) { var attPrice = _taxService.GetCheckoutAttributePrice(val, false, postProcessPaymentRequest.Order.Customer); //round var attPriceRounded = Math.Round(attPrice, 2); if (attPrice > decimal.Zero) //if it has a price { var ca = val.CheckoutAttribute; if (ca != null) { var attName = ca.Name; //set the name builder.AppendFormat("&item_name_" + x + "={0}", HttpUtility.UrlEncode(attName)); //name builder.AppendFormat("&amount_" + x + "={0}", attPriceRounded.ToString("0.00", CultureInfo.InvariantCulture)); //amount builder.AppendFormat("&quantity_" + x + "={0}", 1); //quantity x++; cartTotal += attPrice; } } } //order totals //shipping var orderShippingExclTax = postProcessPaymentRequest.Order.OrderShippingExclTax; var orderShippingExclTaxRounded = Math.Round(orderShippingExclTax, 2); if (orderShippingExclTax > decimal.Zero) { builder.AppendFormat("&item_name_" + x + "={0}", HttpUtility.UrlEncode(_helper.Resource("ShippingFee"))); builder.AppendFormat("&amount_" + x + "={0}", orderShippingExclTaxRounded.ToString("0.00", CultureInfo.InvariantCulture)); builder.AppendFormat("&quantity_" + x + "={0}", 1); x++; cartTotal += orderShippingExclTax; } //payment method additional fee var paymentMethodAdditionalFeeExclTax = postProcessPaymentRequest.Order.PaymentMethodAdditionalFeeExclTax; var paymentMethodAdditionalFeeExclTaxRounded = Math.Round(paymentMethodAdditionalFeeExclTax, 2); if (paymentMethodAdditionalFeeExclTax > decimal.Zero) { builder.AppendFormat("&item_name_" + x + "={0}", HttpUtility.UrlEncode(_helper.Resource("PaymentMethodFee"))); builder.AppendFormat("&amount_" + x + "={0}", paymentMethodAdditionalFeeExclTaxRounded.ToString("0.00", CultureInfo.InvariantCulture)); builder.AppendFormat("&quantity_" + x + "={0}", 1); x++; cartTotal += paymentMethodAdditionalFeeExclTax; } //tax var orderTax = postProcessPaymentRequest.Order.OrderTax; var orderTaxRounded = Math.Round(orderTax, 2); if (orderTax > decimal.Zero) { //builder.AppendFormat("&tax_1={0}", orderTax.ToString("0.00", CultureInfo.InvariantCulture)); //add tax as item builder.AppendFormat("&item_name_" + x + "={0}", HttpUtility.UrlEncode(_helper.Resource("SalesTax"))); builder.AppendFormat("&amount_" + x + "={0}", orderTaxRounded.ToString("0.00", CultureInfo.InvariantCulture)); //amount builder.AppendFormat("&quantity_" + x + "={0}", 1); //quantity cartTotal += orderTax; x++; } if (cartTotal > postProcessPaymentRequest.Order.OrderTotal) { /* Take the difference between what the order total is and what it should be and use that as the "discount". * The difference equals the amount of the gift card and/or reward points used. */ decimal discountTotal = cartTotal - postProcessPaymentRequest.Order.OrderTotal; discountTotal = Math.Round(discountTotal, 2); //gift card or rewared point amount applied to cart in SmartStore.NET - shows in Paypal as "discount" builder.AppendFormat("&discount_amount_cart={0}", discountTotal.ToString("0.00", CultureInfo.InvariantCulture)); } } else { //pass order total builder.AppendFormat("&item_name=Order Number {0}", postProcessPaymentRequest.Order.GetOrderNumber()); var orderTotal = Math.Round(postProcessPaymentRequest.Order.OrderTotal, 2); builder.AppendFormat("&amount={0}", orderTotal.ToString("0.00", CultureInfo.InvariantCulture)); } builder.AppendFormat("&custom={0}", postProcessPaymentRequest.Order.OrderGuid); builder.AppendFormat("&charset={0}", "utf-8"); builder.Append(string.Format("&no_note=1¤cy_code={0}", HttpUtility.UrlEncode(_currencyService.GetCurrencyById(_currencySettings.PrimaryStoreCurrencyId).CurrencyCode))); builder.AppendFormat("&invoice={0}", postProcessPaymentRequest.Order.GetOrderNumber()); builder.AppendFormat("&rm=2", new object[0]); if (postProcessPaymentRequest.Order.ShippingStatus != ShippingStatus.ShippingNotRequired) { builder.AppendFormat("&no_shipping=2", new object[0]); } else { builder.AppendFormat("&no_shipping=1", new object[0]); } string returnUrl = _webHelper.GetStoreLocation(false) + "Plugins/PaymentPayPalStandard/PDTHandler"; string cancelReturnUrl = _webHelper.GetStoreLocation(false) + "Plugins/PaymentPayPalStandard/CancelOrder"; builder.AppendFormat("&return={0}&cancel_return={1}", HttpUtility.UrlEncode(returnUrl), HttpUtility.UrlEncode(cancelReturnUrl)); //Instant Payment Notification (server to server message) if (_paypalStandardPaymentSettings.EnableIpn) { string ipnUrl; if (String.IsNullOrWhiteSpace(_paypalStandardPaymentSettings.IpnUrl)) { ipnUrl = _webHelper.GetStoreLocation(false) + "Plugins/PaymentPayPalStandard/IPNHandler"; } else { ipnUrl = _paypalStandardPaymentSettings.IpnUrl; } builder.AppendFormat("¬ify_url={0}", ipnUrl); } //address builder.AppendFormat("&address_override=1"); builder.AppendFormat("&first_name={0}", HttpUtility.UrlEncode(postProcessPaymentRequest.Order.BillingAddress.FirstName)); builder.AppendFormat("&last_name={0}", HttpUtility.UrlEncode(postProcessPaymentRequest.Order.BillingAddress.LastName)); builder.AppendFormat("&address1={0}", HttpUtility.UrlEncode(postProcessPaymentRequest.Order.BillingAddress.Address1)); builder.AppendFormat("&address2={0}", HttpUtility.UrlEncode(postProcessPaymentRequest.Order.BillingAddress.Address2)); builder.AppendFormat("&city={0}", HttpUtility.UrlEncode(postProcessPaymentRequest.Order.BillingAddress.City)); //if (!String.IsNullOrEmpty(postProcessPaymentRequest.Order.BillingAddress.PhoneNumber)) //{ // //strip out all non-digit characters from phone number; // string billingPhoneNumber = System.Text.RegularExpressions.Regex.Replace(postProcessPaymentRequest.Order.BillingAddress.PhoneNumber, @"\D", string.Empty); // if (billingPhoneNumber.Length >= 10) // { // builder.AppendFormat("&night_phone_a={0}", HttpUtility.UrlEncode(billingPhoneNumber.Substring(0, 3))); // builder.AppendFormat("&night_phone_b={0}", HttpUtility.UrlEncode(billingPhoneNumber.Substring(3, 3))); // builder.AppendFormat("&night_phone_c={0}", HttpUtility.UrlEncode(billingPhoneNumber.Substring(6, 4))); // } //} if (postProcessPaymentRequest.Order.BillingAddress.StateProvince != null) { builder.AppendFormat("&state={0}", HttpUtility.UrlEncode(postProcessPaymentRequest.Order.BillingAddress.StateProvince.Abbreviation)); } else { builder.AppendFormat("&state={0}", ""); } if (postProcessPaymentRequest.Order.BillingAddress.Country != null) { builder.AppendFormat("&country={0}", HttpUtility.UrlEncode(postProcessPaymentRequest.Order.BillingAddress.Country.TwoLetterIsoCode)); } else { builder.AppendFormat("&country={0}", ""); } builder.AppendFormat("&zip={0}", HttpUtility.UrlEncode(postProcessPaymentRequest.Order.BillingAddress.ZipPostalCode)); builder.AppendFormat("&email={0}", HttpUtility.UrlEncode(postProcessPaymentRequest.Order.BillingAddress.Email)); _httpContext.Response.Redirect(builder.ToString()); }