Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Michelle Topp 33 posts 143 karma points
    Sep 23, 2016 @ 09:28
    Michelle Topp
    0

    Manually fullfiling an order in code.

    Hi,

    How would one go about manually fulfilling orders?

    I thought we had it all set out correctly, but it's not processing the payment and moving the order the paid category in the back end. As well as not clearing the basket.

    We're using the worldpay payment gateway, and we've now got that working for recurring and normal payments.

    We are using the CheckoutManager(), is this correct? Before we redirect to Worldpay we start the invoice on the BazaarCheckoutConfirmController so we can retrieve it when we come back :

    var checkoutManager = Basket.GetCheckoutManager();

            var shipmentRateQuotes = Enumerable.Empty<IShipmentRateQuote>().ToArray();
    
            // The default basket packaging strategy only creates a single shipment
            var shipment = Basket.PackageBasket(checkoutManager.Customer.GetShipToAddress()).FirstOrDefault();
    

    var invoice = checkoutManager.Payment.PrepareInvoice();

    // Quote the shipment
    shipmentRateQuotes = shipment.ShipmentRateQuotes().ToArray();
    if (shipmentRateQuotes.Any() && !invoice.ShippingLineItems().Any())
    {
        //// Assume the first selection.  Customer will be able to update this later
            //// but this allows for a taxation calculation as well in the event shipping charges
            //// are taxable.
            checkoutManager.Shipping.SaveShipmentRateQuote(shipmentRateQuotes.First());
    }
    

    Also bear in mind that non of the items are shippable as they are online items.

    When a payment is done Worldpay forwards the site to a "notification" page which checks if it's successful or not and then redirects the customer to a success or failed page.

    On this notification controller we're processing all the information,

         var invoiceService = _merchellocontext.Services.InvoiceService;
    
         var invoice = invoiceService.GetByKey(invoiceKey);
    
          invoice.InvoiceStatus = invoiceService.GetInvoiceStatusByKey(Core.Constants.DefaultKeys.InvoiceStatus.Paid);               
    
         // invoice must be saved before applying a payment albeit typically the provider checks this and should do it for you. 
                            invoiceService.Save(invoice);
                            var paymentMethods = GatewayContext.Payment.GetPaymentGatewayMethods().ToArray();
    
        var checkoutManager = Basket.GetCheckoutManager();
    
                            checkoutManager.Payment.SavePaymentMethod(paymentMethods.First().PaymentMethod);
    
        var attempt = checkoutManager.Payment.AuthorizeCapturePayment(paymentMethods.First().PaymentMethod.ProviderKey);
    
        var approved = attempt.ApproveOrderCreation;
    
        if (approved)
        {
            var order = invoice.PrepareOrder();
            MerchelloContext.Current.Services.OrderService.Save(order);
        }
     Basket.Empty();
    

    I've probably not got this right whatsoever, I've tried loads of things to get it to do it to no avail.

    I also want to set the item to fulfilled at the end of this as it's not shippable.

    Any help would be muchly appreciated

  • Rusty Swayne 1655 posts 4993 karma points c-trib
    Sep 23, 2016 @ 15:41
    Rusty Swayne
    101

    Hey Michelle,

    Using the CheckoutManager is correct and it sounds like your close - but I think your missing a step since the payment should be captured by the payment provider and you should not need to "manually" set the invoice to paid as you are in the notification.

    That being said, IMO, the redirecting providers are a bit trickier than the ones that do straight API calls so you may have wound up having to work around some stuff - I've never worked with WorldPay myself.

    In general the workflow should be something like (using PayPal as the example):

    Tip: It's useful for tracking down issues to save the results from each back and forth in a record and stash them into the payment extended data collection (thats what line 89 is doing).

    Merchello handles this event here: https://github.com/rustyswayne/Merchello/blob/mdev-230/src/Merchello.Web.Store/UmbracoApplicationEvents.cs#L40

    If you would not mind sending me your code for the WorldPay provider I'd love to see it =)

Please Sign in or register to post replies

Write your reply to:

Draft