Andrei,
Here is the final code... supports gift cards, reward points and checkout attributes!
public string PostProcessPayment(Order order)
{
StringBuilder builder = new StringBuilder();
string returnURL = CommonHelper.GetStoreLocation(false) + "PaypalPDTHandler.aspx";
string cancel_returnURL = CommonHelper.GetStoreLocation(false) + "PaypalCancel.aspx";
builder.Append(GetPaypalUrl());
builder.AppendFormat("?cmd=_cart&business={0}", HttpUtility.UrlEncode(businessEmail));
builder.AppendFormat("&upload=1");
//get the items in the cart
var cartItems = order.NpOrderProductVariants;
int x = 1; //items must start at 1
decimal cartTotal = decimal.Zero;
foreach (var item in cartItems) //loop through the cart items
{
//get the productvariant so we can get the name
var pName = ProductManager.GetProductVariantById(item.ProductVariantId);
string vName = pName.FullProductName; //set the name
builder.AppendFormat("&item_name_" + x + "={0}", HttpUtility.UrlEncode(vName)); //name
builder.AppendFormat("&amount_" + x + "={0}", item.UnitPriceExclTax); //amount
builder.AppendFormat("&quantity_" + x + "={0}", item.Quantity); //quantity
x++; //increment item number
cartTotal = cartTotal + item.PriceExclTax; //keep a running cart total
}
//the checkout attributes that have a dollar value and send them to Paypal as items to be paid for
var caValues = CheckoutAttributeHelper.ParseCheckoutAttributeValues(order.CheckoutAttributesXml);
foreach (var val in caValues)
{
var attPrice = TaxManager.GetCheckoutAttributePrice(val, false, NopContext.Current.User);
if (attPrice > 0) //if it has a price
{
var caName = CheckoutAttributeManager.GetCheckoutAttributeById(val.CheckoutAttributeId);
var attName = caName.LocalizedName; //set the name
builder.AppendFormat("&item_name_" + x + "={0}", attName); //name
builder.AppendFormat("&amount_" + x + "={0}", attPrice); //amount
builder.AppendForma&quantity_" + x + "={0}", 1); //quantity
x++;
}
}
//add tax as an item - if tax not configured in Paypal
//builder.AppendFormat("&item_name_" + x + "={0}", "Sales Tax");
//builder.AppendFormat("&amount_" + x + "={0}", order.OrderTax);
cartTotal = cartTotal + order.OrderShippingExclTax + order.OrderTax;
decimal discountTotal = decimal.Zero;
if (cartTotal > order.OrderTotal) //else we're not even going to Paypal :)
{
/*/ 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. /*/
discountTotal = cartTotal - order.OrderTotal;
}
//gift card or rewared point amount applied to cart in nopCommerce - shows in Paypal as "discount"
builder.AppendFormat("&discount_amount_cart={0}", discountTotal);
builder.AppendFormat("&custom={0}", order.OrderGuid);
builder.Append(string.Format("&no_note=1¤cy_code={0}", HttpUtility.UrlEncode(CurrencyManager.PrimaryStoreCurrency.CurrencyCode)));
builder.AppendFormat("&invoice={0}", order.OrderId);
builder.AppendFormat("&rm=2", new object[0]);
if (order.ShippingStatus != ShippingStatusEnum.ShippingNotRequired)
builder.AppendFormat("&no_shipping=2", new object[0]);
else
builder.AppendFormat("&no_shipping=1", new object[0]);
builder.AppendFormat("&shipping_1={0}", order.OrderShippingExclTax);
//can use "handling" for extra charges - will be added to "shipping & handling"
builder.AppendFormat("&handling_1={0}", GetAdditionalHandlingFee());
builder.AppendFormat("&return={0}&cancel_return={1}", HttpUtility.UrlEncode(returnURL), HttpUtility.UrlEncode(cancel_returnURL));
builder.AppendFormat("&first_name={0}", HttpUtility.UrlEncode(order.BillingFirstName));
builder.AppendFormat("&last_name={0}", HttpUtility.UrlEncode(order.BillingLastName));
builder.AppendFormat("&address1={0}", HttpUtility.UrlEncode(order.BillingAddress1));
builder.AppendFormat("&address2={0}", HttpUtility.UrlEncode(order.BillingAddress2));
builder.AppendFormat("&city={0}", HttpUtility.UrlEncode(order.BillingCity));
StateProvince billingStateProvince = StateProvinceManager.GetStateProvinceById(order.BillingStateProvinceId);
if (billingStateProvince != null)
builder.AppendFormat("&state={0}", HttpUtility.UrlEncode(billingStateProvince.Abbreviation));
else
builder.AppendFormat("&state={0}", HttpUtility.UrlEncode(order.BillingStateProvince));
Country billingCountry = CountryManager.GetCountryById(order.BillingCountryId);
if (billingCountry != null)
builder.AppendFormat("&country={0}", HttpUtility.UrlEncode(billingCountry.TwoLetterIsoCode));
else
builder.AppendFormat("&country={0}", HttpUtility.UrlEncode(order.BillingCountry));
builder.AppendFormat("&zip={0}", HttpUtility.UrlEncode(order.BillingZipPostalCode));
//To send phone number - work on this later - not required to pass.
//Paypal requires email addressess and phone numbers from ALL customers, so it would be good to pre-fill them -
//would be an issue with countries other than US.
//var phoneN = order.BillingPhoneNumber; //parse?
//doesn't look like phone number is formatted in any particular way in nopCommerce... hard to parse
//builder.AppendFormat("&night_phone_a={0}", "123"); //area code
//builder.AppendFormat("&night_phone_b={0}", "555"); //prefix
//builder.AppendFormat("&night_phone_c={0}", "1111"); //last four
builder.AppendFormat("&email={0}", HttpUtility.UrlEncode(order.BillingEmail));
HttpContext.Current.Response.Redirect(builder.ToString());
return string.Empty;
}
Perhaps you can slip this into the 1.80 beta so people can test it? :)