Thanks for posting here :) Before we get to the code a little background.
When uCommerce was first released the prevalent way of creating sites in Umbraco was using XSLT as you probably know. So we spent time on create an easy to use set of XSLT extensions, which means that less knowledge about how to string the various uCommerce object together was required.
With the rise of Razor we're going to redo the API specifically for Razor to make the simple scenarios like the ones below much easier to deal with. In the meantime though here's the nitty gritty. Hope you find it useful.
Add to basket
// First load the current catalog (URLs will contain this information)
int catalogId = 0;
string catalogName = "";
ProductCatalog catalog;
if (int.TryParse(SiteContext.Current.CatalogContext.GetCurrentCatalogName, out catalogId)
{
catalog = ProductCatalog.Get(catalogId);
}
else
{
catalog = ProductCatalog.SingleOrDefault(x => x.Name == catalogName);
}
// Then load the product to add
Product product = Product.All().Single(x => x.Sku == "mySku" && x.VariantSku == "myVariantSku");
PurchaseOrder order = SiteContext.Current.OrderContext.GetBasket();
order.AddProduct(catalog, product);
// Exec basket pipeline to update totals
Library.ExecuteBasketPipeline();
Update address info
/* BILLING */
var billingAddress = order.BillingAddress ?? new OrderAddress();
address.AddressName = "Billing";
address.FirstName = "firstName";
address.LastName = "lastName";
address.EmailAddress = "emailAddress";
address.PhoneNumber = "phoneNumber";
address.MobilePhoneNumber = "mobilePhoneNumber";
address.CompanyName = "company";
address.Line1 = "line1";
address.Line2 = "line2";
address.PostalCode = "postCode";
address.City = "city";
address.State = "state";
address.Attention = "attention";
address.Country = Country.Get(countryId);
address.PurchaseOrder = order;
order.BillingAddress = billingAddress;
order.Save(); // Saves cascade to children, so the address is saved as well
Create shipment
/* SHIPPING */
// First we'll need a shipping method using the name as defined in the backend, e.g. Ground or Air
var shippingMethod = ShippingMethod.SingleOrDefault(x => x.Name = "Ground");
var shipment = order.CreateShipment(shippingMethod, billingAddress);
// Add all order lines to shipment using a handy extension mehod in UCommerce.Extensions called ForEach
order.OrderLines.ForEach(x => shipment.AddOrderLine(x));
// Execute basket pipeline to make sure totals are up to date
// Also save order and new shipment
PipelineFactory.Create<PurhcaseOrder>("basket").Execute(order);
Payment
/* PAYMENT */
// As with shipping grab the payment method to use by name as defined in the backend
var paymentMethod = PaymentMethod.SingleOrDefault(x => x.Name == "Account");
// Use the library to create the payment and request it from the gateway
Library.CreatePayment(paymentMethod.Id);
// Alternatively you can use to defer the request if you
// need to display an confirm page before handing it over
// to the gateway. The false value indicates that the request // should be deferred. // You can then use Library.RequestPayments() // to trigger the gateway
Library.CreatePayment(paymentMethod.Id, -1, false, true);
I have a question about implementing the Add to Basket functionality you have posted in this thread. Whereabouts would this code sit? I have a page called ProductDetails.cshtml which displays the details of the product along with an Add To Basket button, upon clicking this button, what should I do, redirect to another page, or just capture the postback within the ProductDetails.cshtml file, do the functionality specified in the Add To Basket area of the thread above, and then redirect to the basket/cart page?
I have tried adding the code to the page, but it complains on various points such as the line "
PurchaseOrder order =SiteContext.Current.OrderContext.GetBasket();
gives an error message about casting not being possible,
Any help on this would be appreciated as I am keen to get the Add To Basket functionality working within my site ASAP.
@Mr A: No, but I've rewritten different ways of integrating products into a normal website (not shop per se), as well as a few steps in the checkout-flow to simplify things a bit for a specific project. I'll be happy to share.
@Thomas , I got everything working , but i cant still figure out the emails issue, as I want to send emails to the customer when the item is shipped , currently when the client buy any stuff from my website, he gets an email for order confirmation, and when i change the status of the order to shipped from backend , he doesnt gets and email for shipment , i also set shippedEmail settingsa in the pipeline. Also the order confirmation email is just sent to the buyer not the seller(me). Any ideas how you have done settings for emails , any assistance will be highly appreciated .
You can trigger e-amil in the order processing interface by adding the SendEmail task to the ToCompleted pipeline. Part of the config for the pipeline task itself is the name of the e-mail to send.
Create a new e-mail type valled "OrderConfirmation" in the backend and be sure to use that same name in the pipeline config.
I also implemented the above mentioned solution, by Søren Spelling Lund and it worked great. Many thanks for that, it explained many concepts too.
At the end of the code after CreatePayment() call, I added Library.RequestPayment() to redirect to PayPal sandbox. It also worked fine and the payment process through PayPal sandbox was completed successfully.
Now I want to get this order, listed in the New Orders List in the uCommerce section. I guess this would require additional coding but since i am new to uCommerce I don't know its api libraries much. I tried to execute "checkout" pipeline at the end of the code but it threw some security exception that the payment is not sufficient for the order guid..... I also tried to execute "saveorder" pipeline in the end but it had no effect.
I have added the code below just in case:
protected void btnBuyProdNow_Click(object sender, EventArgs e) { // First load the current catalog (URLs will contain this information) int catalogId = 0; string catalogName = "uCommerce"; ProductCatalog catalog; SiteContext.Current.OrderContext.NewBasket(Currency.SingleOrDefault(x => x.ExchangeRate == 100)); if (int.TryParse(SiteContext.Current.CatalogContext.CurrentCatalogName, out catalogId)) catalog = ProductCatalog.Get(catalogId); else catalog = ProductCatalog.SingleOrDefault(x => x.Name == catalogName); // Then load the product to add Product product = Product.All().Single(x => x.Sku == "MyProd-01"); PurchaseOrder order = SiteContext.Current.OrderContext.GetBasket().PurchaseOrder; order.AddProduct(catalog, product, 1); // Exec basket pipeline to update totals Library.ExecuteBasketPipeline(); /* BILLING */ var address = order.BillingAddress ?? new OrderAddress(); address.AddressName = "Billing"; address.FirstName = "firstName"; address.LastName = "lastName"; address.EmailAddress = "emailAddress"; address.PhoneNumber = "phoneNumber"; address.MobilePhoneNumber = "mobilePhoneNumber"; address.CompanyName = "company"; address.Line1 = "line1"; address.Line2 = "line2"; address.PostalCode = "postCode"; address.City = "city"; address.State = "state"; address.Attention = "attention"; address.Country = Country.FirstOrDefault(x => x.Name == "Great Britain"); address.PurchaseOrder = order; order.BillingAddress = address; order.Save(); // Saves cascade to children, so the address is saved as well /* SHIPPING */ // First we'll need a shipping method using the name as defined in the backend, e.g. Ground or Air var shippingMethod = ShippingMethod.SingleOrDefault(x => x.Name == "Download"); var shipment = order.CreateShipment(shippingMethod, address); // Add all order lines to shipment using a handy extension mehod in UCommerce.Extensions called ForEach order.OrderLines.ForEach(x => shipment.AddOrderLine(x)); // Execute basket pipeline to make sure totals are up to date // Also save order and new shipment PipelineFactory.Create("basket").Execute(order); /* PAYMENT */ // As with shipping grab the payment method to use by name as defined in the backend var paymentMethod = PaymentMethod.SingleOrDefault(x => x.Name == "PayPal"); // Use the library to create the payment and request it from the gateway Library.CreatePayment(paymentMethod.Id); // Alternatively you can use to defer the request if you // need to display an confirm page before handing it over // to the gateway. The false value indicates that the request // should be deferred. // You can then use Library.RequestPayments() // to trigger the gateway Library.CreatePayment(paymentMethod.Id, -1, false, true); Library.RequestPayments(); }
Kindly help me in this issue. Many thanks.
PS: Just in case if this is related, I want to integrate the above code in umbraco contour, either in a workflow or as a new FieldType to be added in the last contour step. The purpose is ... the user would complete all the form steps and in the end, either a BuyProd button will complete the actual transaction and return to the last step again. Or ... the actual submit button of contour will execute a custom workflow that would contain the above mentioned code.
Sorry if I miss miss out some posts if some of them where missed out some time before, but I run into a problem just can't seem to fix it.
I am trying to work with totally custom solution here...
My goal is to use plain Razor and I am working with uCommerce installation without any uCommerce Razor store installed.
I eddited UrlRewriting.config so it fits my shop setup.
Basically I need to add a product to cart on button click...
Same thing Søren showed in his example on "Add to basket" but I need that code to be executed only on product add to cart button click.
As there is no Razor button onClick event most likely? I tryed to use Form from uCommerce demo shop:
<form method="post">
<div class="span12 well">
<aside class="span5" itemprop="offers" itemscope itemtype="http://schema.org/Offer">
<p class="item-price" itemprop="price">@price.YourPrice.Amount</p>
</aside>
<input name="product-sku" id="product-sku" type="hidden" value="@product.Sku" />
<input name="quantity-to-add" id="quantity-to-add" type="hidden" value="1" />
<input name="catalog-id" id="catalog-id" type="hidden" value="@SiteContext.Current.CatalogContext.CurrentCatalog.ProductCatalogId" />
<!-- We have to default the button to "success" for those customers who don't have JavaScript enabled -in which case it will still be a clear call to action -->
<input name="add-to-basket" id="add-to-basket" class="btn btn-block btn-success" type="submit" value="Add to basket" />
</div>
</form>
But it does not seem to work - it just posts the form and nothing happens...
What am I missing?
Any suggestions or thoughts are more than welcome! :-)
I have implementated a ShippingMethodService I name UpsShippingMethodService. It appears from the above discussion that I need to access the method as follows;
var shippingMethod = ShippingMethod.SingleOrDefault(x => x.Name == "UPS Ground);
Do I need to create a method for each Ups shipping type, call the service to load it, then call the above method to get the price?
You have to iterate over the shipping methods provided by TransactionLibrary.GetShippingMethods() and call GetShippingMethodService().CalculateShippingPrice(shipment) on each shipment on your order.
Hi. I think this is crucually important that we add an answer to my following question to this thread:
In case I am working with uCommerce via API calls, and at my Delivery information page POST processing code I need to initiate a payment redirect to a selected payment gateway, what do I return in MVC action?
I know I need to call
Library.CreatePayment(paymentMethod.Id);
but that wouldn't return an ActionResult. Which action result is assumed to be used whenever one needs to initite a Payment dance from controller code?
step by step Process on Ordering
Hi. can you list step by step the process on what fuctions I should call to create order, checkout, and update info, then post. in razor.. thanks
Hi Ramon,
Thanks for posting here :) Before we get to the code a little background.
When uCommerce was first released the prevalent way of creating sites in Umbraco was using XSLT as you probably know. So we spent time on create an easy to use set of XSLT extensions, which means that less knowledge about how to string the various uCommerce object together was required.
With the rise of Razor we're going to redo the API specifically for Razor to make the simple scenarios like the ones below much easier to deal with. In the meantime though here's the nitty gritty. Hope you find it useful.
Add to basket
Update address info
Create shipment
Payment
Hi Soren,
I have a question about implementing the Add to Basket functionality you have posted in this thread. Whereabouts would this code sit? I have a page called ProductDetails.cshtml which displays the details of the product along with an Add To Basket button, upon clicking this button, what should I do, redirect to another page, or just capture the postback within the ProductDetails.cshtml file, do the functionality specified in the Add To Basket area of the thread above, and then redirect to the basket/cart page?
I have tried adding the code to the page, but it complains on various points such as the line "
gives an error message about casting not being possible,
Any help on this would be appreciated as I am keen to get the Add To Basket functionality working within my site ASAP.
Cheers,
Graham
The object returned from GetBasket is actually of type "Basket", which is a wrapper for PurchaseOrder.
The line needs to read
Didn't work untill I changed Library to TransactionLibrary in:
Thomas have you written all pages in Razor for ucommerce
@Mr A: No, but I've rewritten different ways of integrating products into a normal website (not shop per se), as well as a few steps in the checkout-flow to simplify things a bit for a specific project. I'll be happy to share.
@Thomas , I got everything working , but i cant still figure out the emails issue, as I want to send emails to the customer when the item is shipped , currently when the client buy any stuff from my website, he gets an email for order confirmation, and when i change the status of the order to shipped from backend , he doesnt gets and email for shipment , i also set shippedEmail settingsa in the pipeline. Also the order confirmation email is just sent to the buyer not the seller(me). Any ideas how you have done settings for emails , any assistance will be highly appreciated .
You can trigger e-amil in the order processing interface by adding the SendEmail task to the ToCompleted pipeline. Part of the config for the pipeline task itself is the name of the e-mail to send.
Create a new e-mail type valled "OrderConfirmation" in the backend and be sure to use that same name in the pipeline config.
(Sorry, it occured to me later that I should have started a new topic for this post instead. Therefore, I have created a new topic for this same, at: http://our.umbraco.org/projects/website-utilities/ucommerce/ucommerce-support/33365-Adding-the-completed-order-to-New-Orders-list-programatically)
Hi,
I also implemented the above mentioned solution, by Søren Spelling Lund and it worked great. Many thanks for that, it explained many concepts too.
At the end of the code after CreatePayment() call, I added Library.RequestPayment() to redirect to PayPal sandbox. It also worked fine and the payment process through PayPal sandbox was completed successfully.
Now I want to get this order, listed in the New Orders List in the uCommerce section. I guess this would require additional coding but since i am new to uCommerce I don't know its api libraries much. I tried to execute "checkout" pipeline at the end of the code but it threw some security exception that the payment is not sufficient for the order guid..... I also tried to execute "saveorder" pipeline in the end but it had no effect.
I have added the code below just in case:
protected void btnBuyProdNow_Click(object sender, EventArgs e)
{
// First load the current catalog (URLs will contain this information)
int catalogId = 0;
string catalogName = "uCommerce";
ProductCatalog catalog;
SiteContext.Current.OrderContext.NewBasket(Currency.SingleOrDefault(x => x.ExchangeRate == 100));
if (int.TryParse(SiteContext.Current.CatalogContext.CurrentCatalogName, out catalogId))
catalog = ProductCatalog.Get(catalogId);
else
catalog = ProductCatalog.SingleOrDefault(x => x.Name == catalogName);
// Then load the product to add
Product product = Product.All().Single(x => x.Sku == "MyProd-01");
PurchaseOrder order = SiteContext.Current.OrderContext.GetBasket().PurchaseOrder;
order.AddProduct(catalog, product, 1);
// Exec basket pipeline to update totals
Library.ExecuteBasketPipeline();
/* BILLING */
var address = order.BillingAddress ?? new OrderAddress();
address.AddressName = "Billing";
address.FirstName = "firstName";
address.LastName = "lastName";
address.EmailAddress = "emailAddress";
address.PhoneNumber = "phoneNumber";
address.MobilePhoneNumber = "mobilePhoneNumber";
address.CompanyName = "company";
address.Line1 = "line1";
address.Line2 = "line2";
address.PostalCode = "postCode";
address.City = "city";
address.State = "state";
address.Attention = "attention";
address.Country = Country.FirstOrDefault(x => x.Name == "Great Britain");
address.PurchaseOrder = order;
order.BillingAddress = address;
order.Save(); // Saves cascade to children, so the address is saved as well
/* SHIPPING */
// First we'll need a shipping method using the name as defined in the backend, e.g. Ground or Air
var shippingMethod = ShippingMethod.SingleOrDefault(x => x.Name == "Download");
var shipment = order.CreateShipment(shippingMethod, address);
// Add all order lines to shipment using a handy extension mehod in UCommerce.Extensions called ForEach
order.OrderLines.ForEach(x => shipment.AddOrderLine(x));
// Execute basket pipeline to make sure totals are up to date
// Also save order and new shipment
PipelineFactory.Create("basket").Execute(order);
/* PAYMENT */
// As with shipping grab the payment method to use by name as defined in the backend
var paymentMethod = PaymentMethod.SingleOrDefault(x => x.Name == "PayPal");
// Use the library to create the payment and request it from the gateway
Library.CreatePayment(paymentMethod.Id);
// Alternatively you can use to defer the request if you
// need to display an confirm page before handing it over
// to the gateway. The false value indicates that the request
// should be deferred.
// You can then use Library.RequestPayments()
// to trigger the gateway
Library.CreatePayment(paymentMethod.Id, -1, false, true);
Library.RequestPayments();
}
Kindly help me in this issue. Many thanks.
PS: Just in case if this is related, I want to integrate the above code in umbraco contour, either in a workflow or as a new FieldType to be added in the last contour step. The purpose is ... the user would complete all the form steps and in the end, either a BuyProd button will complete the actual transaction and return to the last step again. Or ... the actual submit button of contour will execute a custom workflow that would contain the above mentioned code.
Hi Guys,
Sorry if I miss miss out some posts if some of them where missed out some time before, but I run into a problem just can't seem to fix it.
I am trying to work with totally custom solution here...
My goal is to use plain Razor and I am working with uCommerce installation without any uCommerce Razor store installed.
I eddited UrlRewriting.config so it fits my shop setup.
Basically I need to add a product to cart on button click...
Same thing Søren showed in his example on "Add to basket" but I need that code to be executed only on product add to cart button click.
As there is no Razor button onClick event most likely? I tryed to use Form from uCommerce demo shop:
But it does not seem to work - it just posts the form and nothing happens...
What am I missing?
Any suggestions or thoughts are more than welcome! :-)
Dmitrij
Hi Dmitrij,
If you want to handle the post server-side you can add code to the top of the page you're posting to (in this case it would be the same page) like:
Hej Soren,
That is exactly what I neede :) Short and precise ;)))
I have implementated a ShippingMethodService I name UpsShippingMethodService. It appears from the above discussion that I need to access the method as follows;
var shippingMethod = ShippingMethod.SingleOrDefault(x => x.Name == "UPS Ground);
Do I need to create a method for each Ups shipping type, call the service to load it, then call the above method to get the price?
Gary Prothero, [email protected]
ProWorks Corporation
Enter Your Shipping Preference
You have to iterate over the shipping methods provided by TransactionLibrary.GetShippingMethods() and call GetShippingMethodService().CalculateShippingPrice(shipment) on each shipment on your order.
Hope this helps.
Hi. I think this is crucually important that we add an answer to my following question to this thread:
In case I am working with uCommerce via API calls, and at my Delivery information page POST processing code I need to initiate a payment redirect to a selected payment gateway, what do I return in MVC action?
I know I need to call
Library.CreatePayment(paymentMethod.Id);
but that wouldn't return an ActionResult. Which action result is assumed to be used whenever one needs to initite a Payment dance from controller code?
Thanks.
Ok, got an answer to my own question - all I need to perform a redirect from MVC is to place, for example, the following in my razor view:
is working on a reply...