Giter Site home page Giter Site logo

Comments (14)

perrytew avatar perrytew commented on September 22, 2024

Hey.

Are you calling setFinalizeAfter() on the last checkout page before entering your upsell gauntlet?

http://docs.ultracart.com/display/ucdoc/UltraCart+REST+Checkout+API#UltraCartRESTCheckoutAPI-/rest/cart/setFinalizeAfter

That will ensure the order is captured even if the browser is closed during the upsell.

from responsive_checkout.

plmwebdev avatar plmwebdev commented on September 22, 2024

Thank you for your instantaneous response!

Yes I am calling it ...Here's what I am doing


  if (checkoutResult && checkoutResult.redirectToUrl) {
        jQuery.cookie('UltraCartShoppingCartID', checkoutResult.cart.cartId, { expires: 7, path: '/' });
        localStorage['redirectToUrl'] = checkoutResult.redirectToUrl;
        finalizeAfter();
        window.location.href = after_checkout_page;

##########################


function finalizeAfter() {
  var finalizeCart = null;
  var restUrl = i_am_using_a_proxy ? pathToProxy + '?_url=/rest/cart' : '/rest/cart';
  if (!finalizeCart) {
    jQuery.ajax({
      url: restUrl,
      headers: {'X-UC-Merchant-Id': merchantId,
        "cache-control": "no-cache"},
      dataType: 'json',
      async: true
    }).done(function (cart) {
        finalizeCart = cart;
    });
  }
  var restUrl = i_am_using_a_proxy ? pathToProxy + '?_url=/rest/cart/setFinalizeAfter' :'/rest/cart/setFinalizeAfter';
  jQuery.ajax({
    url: restUrl+"?minutes=20",
    type: 'POST', // Notice
    headers: { 'X-UC-Merchant-Id': merchantId, "cache-control": "no-cache" },
    contentType: 'application/json; charset=UTF-8',
    data: JSON.stringify(finalizeCart),
    dataType: 'json'
  }).done(function (data, textStatus, jqXHR) {
        var txt = jqXHR.status == 204
            ? "Server returned 204 'No Content', so the setFinalizeAfter was successful"
            : "Error. setFinalizeAfter failed with this: " + textStatus;
        var pre = jQuery('<pre>');
        pre.text(txt);
        jQuery('#finalizeResults').html('').append(pre);

  });
}

I see that the var finalizeCart = null; which is wrong I guess and how can I set the cart into that method? Please do let me know!

from responsive_checkout.

perrytew avatar perrytew commented on September 22, 2024

Hey. The big change you need is to nest the second rest call inside the first since they're both async. The second is probably firing before the first returns, so the finalizeCart is null. I've done away with finalizeCart entirely. It's not needed. Here's the untested code I've written:

function finalizeAfter() {
  var restUrl = i_am_using_a_proxy ? pathToProxy + '?_url=/rest/cart' : '/rest/cart';
  jQuery.ajax({
    url: restUrl,
    headers: {'X-UC-Merchant-Id': merchantId,
      "cache-control": "no-cache"},
    dataType: 'json',
    async: true
  }).done(function (cart) {

            // beware the need for ?minutes or &minutes depending on proxy usage.
            var finalizeUrl = i_am_using_a_proxy ? pathToProxy + '?_url=/rest/cart/setFinalizeAfter&minutes=20' : '/rest/cart/setFinalizeAfter?minutes=20'

            jQuery.ajax({
              url: finalizeUrl,
              type: 'POST', // Notice
              headers: { 'X-UC-Merchant-Id': merchantId, "cache-control": "no-cache" },
              contentType: 'application/json; charset=UTF-8',
              data: JSON.stringify(cart),
              dataType: 'json'
            }).done(function (data, textStatus, jqXHR) {
                      var txt = jqXHR.status == 204
                              ? "Server returned 204 'No Content', so the setFinalizeAfter was successful"
                              : "Error. setFinalizeAfter failed with this: " + textStatus;
                      var pre = jQuery('<pre>');
                      pre.text(txt);
                      jQuery('#finalizeResults').html('').append(pre);

                    });

          });
}

from responsive_checkout.

plmwebdev avatar plmwebdev commented on September 22, 2024

Perry,

Thank you for your response. It doesn't even enter into the first done call i..e here

 }).done(function (cart) {
// NOT AT ALL ENTERING HERE
//Tried with console.log("test");
            // beware the need for ?minutes or &minutes depending on proxy usage.
            var finalizeUrl = i_am_using_a_proxy ? pathToProxy + '?_url=/rest/cart/setFinalizeAfter&minutes=20' : '/rest/cart/setFinalizeAfter?minutes=20'

Please do let me know. Once again, thank you very much for your time!

from responsive_checkout.

perrytew avatar perrytew commented on September 22, 2024

where's this page at? I'll need to see it and play with it to advise further.

from responsive_checkout.

plmwebdev avatar plmwebdev commented on September 22, 2024

Here's the page:

http://personallifemedia.com/uc1_test/test.html

from responsive_checkout.

plmwebdev avatar plmwebdev commented on September 22, 2024

@perrytew Did you get a chance to play around? :)

Please do help me!

from responsive_checkout.

perrytew avatar perrytew commented on September 22, 2024

Not yet. Between Black Friday and Christmas, the schedule can be somewhat
demanding.

I’ll have a look now.

from responsive_checkout.

plmwebdev avatar plmwebdev commented on September 22, 2024

Thanks a LOT! :)

from responsive_checkout.

perrytew avatar perrytew commented on September 22, 2024

Well, you've got the old code in there. I'll tell you again, your finalizeAfter has a race condition in it. You cannot call "get cart" and then "finalize after" right afterwards. Your finalizeCart is null. I saw this in the firebug network panel.

Look at my example above and try to implement it. You mention that it didn't work. Still, try to implement it, and then let's look at what the issue is there. If you're struggling with that, set the async: true => async: false in your first call within finalizeAfter (line 133). That's not best practice, but it should make the procedure work until you can get your feet.

Also, you might wish to call validate before you do finalizeAfter just to make sure everything is kosher before heading to the upsell. If you're not calling checkout, call validate, else a simple "missing field" is going to make everything fail silently behind the scenes.

http://docs.ultracart.com/display/ucdoc/UltraCart+REST+Checkout+API#UltraCartRESTCheckoutAPI-/rest/cart/validate

Thanks,
Perry

from responsive_checkout.

plmwebdev avatar plmwebdev commented on September 22, 2024

Thank you very much for time, Perry!

Yup, after making async: false it entered into the first call and now its not getting into the second call

          }).done(function (data, textStatus, jqXHR) {
                    console.log("status2");
                      var txt = jqXHR.status == 204
                              ? "Server returned 204 'No Content', so the setFinalizeAfter was successful"
                              : "Error. setFinalizeAfter failed with this: " + textStatus;
                      var pre = jQuery('<pre>');
                      pre.text(txt);
                      console.log(txt);
                      jQuery('#finalizeResults').html('').append(pre);

from responsive_checkout.

plmwebdev avatar plmwebdev commented on September 22, 2024

@perrytew When you get a could you please look into it? Also when a "upsell" has been configured inside "ultracart" and we add a "product" via responsive checkout ....does it break the in-built upsell funnel? Please do let me know. Once again, thank you very much for your time!

from responsive_checkout.

perrytew avatar perrytew commented on September 22, 2024

Strange. I updated this issue Friday night. Oh well. Here's the code again. I rewrote your order js file to make use of callbacks to avoid the race conditions. If you look at your code, you're calling finalizeOrder right before you set location.href. That finalize call will never complete before the page changes to the next page.

I haven't tested the code myself, so you'll want to examine it thoroughly. But the concepts are there, and I have a good editor. :)

var $j = jQuery.noConflict();

var merchantId = 'CPTX';
var i_am_using_a_proxy = true;
var pathToProxy = '/uc1_test/rest_proxy.php';  // relative or absolute.  it doesn't matter.



// function createCart() {
//   jQuery.ajax({
//     url: '/rest_proxy.php?_url=/rest/cart',
//     headers: {'X-UC-Merchant-Id': 'CPTX',
//       "cache-control": "no-cache"},
//     dataType: 'json'
//   }).done(function (cart) {
//         jQuery('#createCartResults').html('<pre>' + JSON.stringify(cart, null, '  ') + '</pre>');
//       });
// }


//  function addItems(product_code, upsell) {

//   var items = [];
//   items.push({'itemId': product_code, 'quantity': 1});


//   var cart = {
//     'merchantId': 'CPTX',
//     'cartId': '', // will be populated by call
//     'items': items,
//     'upsell': upsell
//   };

//   jQuery.ajax({
//     url: '/rest_proxy.php?_url=/rest/cart',
//     type: 'PUT', // Notice
//     headers: { "cache-control": "no-cache" },
//     contentType: 'application/json; charset=UTF-8',
//     data: JSON.stringify(cart),
//     dataType: 'json'
//   }).done(function (updatedCart) {

//         // delete the last item and update the cart before displaying the results.
//         //updatedCart.items.pop();

//         jQuery.ajax({
//           url: '/rest_proxy.php?_url=/rest/cart',
//           type: 'PUT', // Notice, PUT == update
//           headers: { "cache-control": "no-cache" },
//           contentType: 'application/json; charset=UTF-8',
//           data: JSON.stringify(updatedCart),
//           dataType: 'json'
//         }).done(function (cartWithTwoItems) {

//               // can't use the following line because the cart (with items) will contain javascript strings the jQuery().html() will try to interpret.
//               //jQuery('#addItemsResults').html('<pre>' + JSON.stringify(updatedCart, null, '  ') + '</pre>');
//               var txt = JSON.stringify(cartWithTwoItems, null, '  ');
//               var pre = jQuery('<pre>');
//               pre.text(txt);
//               jQuery('#addItemsResults').html('').append(pre);

//             });
//       });
// }



function checkout(product_code) {
  var cart = {
    'merchantId': merchantId,
    'cartId': '',
    "billToFirstName": $j("#shippingfirstname").val(),
    "billToLastName": $j("#shippinglastname").val(),
    "billToAddress1": $j("#shippingaddress1").val(),
    "billToAddress2": "",
    "billToCity": $j("#shippingcity").val(),
    "billToState": $j("#shippingstate").val(),
    "billToPostalCode": $j("#shippingzip").val(),
    "billToCountry": $j("#shippingcountry").val(),
    "email": $j("#email").val(),
    "emailConfirm": $j("#email").val(),
    "paymentMethod": $j("input[name='paymentMethod']:checked").val(),
    "creditCardType": $j("#creditcardtype").val(),
    "creditCardNumber": $j("#CC_num").val(),
    "creditCardExpirationMonth": $j("#creditcardexpmonth").val(),
    "creditCardExpirationYear": $j("#creditcardexpyear").val(),
    "creditCardVerificationNumber": $j("#CC_cvv").val(),
    'items': [
      {'itemId': product_code, 'quantity': 1}
    ]

    // if this is not a digital product, you're going to need shipping fields too...

  };


  // validate doesn't return back the cart, which we'll need to pass to finalize.  So do a quick update here first
  // to get a cart variable and a cart id assigned by the server.
  updateCart(cart, function(cart){
    validate(cart, finalizeAfter);
  });
}



// a global variable will make this much easier...
var nextPage = 'upsell-page1.html';


function updateCart(cart, callback){
  jQuery.ajax({
    url: i_am_using_a_proxy ? pathToProxy + '?_url=/rest/cart' : '/rest/cart',
    type: 'POST', // Notice
    headers: { "cache-control": "no-cache" },
    contentType: 'application/json; charset=UTF-8',
    data: JSON.stringify(cart),
    dataType: 'json'
  }).done(function (cart) {
            callback(cart);
  });

}

function validate(cart, callback){
  jQuery.ajax({
    url: i_am_using_a_proxy ? pathToProxy + '?_url=/rest/cart/validate' : '/rest/cart/validate',
    type: 'POST', // Notice
    headers: { "cache-control": "no-cache" },
    contentType: 'application/json; charset=UTF-8',
    data: JSON.stringify(cart),
    dataType: 'json'
  }).done(function (errors) {
            if(errors){
              display_cart_errors(errors);
            } else {
              callback(cart);
            }
  });
}


function finalizeAfter(cart){

  jQuery.ajax({
    url: i_am_using_a_proxy ? pathToProxy + '?_url=/rest/cart/setFinalizeAfter&minutes=20' :'/rest/cart/setFinalizeAfter?minutes=20',
    type: 'POST', // Notice
    headers: { 'X-UC-Merchant-Id': merchantId, "cache-control": "no-cache" },
    contentType: 'application/json; charset=UTF-8',
    data: JSON.stringify(finalizeCart),
    dataType: 'json'
  }).done(function (data, textStatus, jqXHR) {
            if(jqXHR.status == 204){
              location.href = nextPage;
            }
  });
}



function displayCart(cart) {
    if (cart) {
      var html = 'Cart: (' + cart.items.length + ') items, Total: $' + cart.total;
      jQuery('#cart-summary').html(html);
    }
  }


function addToCart(itemId, next_page) {
  var restUrl = i_am_using_a_proxy ? pathToProxy + '?_url=/rest/cart' :'/rest/cart';
  // var restUrl = '/rest_proxy.php?_url=/rest/cart';  // you shouldn't change this.
  if (itemId) {
    if (!myCart) {
      // this shouldn't happen, since loadCart should return back a valid cart.  this code is here just in case.
      myCart = {'merchantId': "CPTX", 'cartId': null}; // passing null will create a new cart for us.
    }
    if (!myCart.items) {
      myCart['items'] = [];
    }
    myCart.items.push({itemId: itemId, quantity: 1});
    jQuery.ajax({
      url: restUrl,
      type: 'POST', // Notice
      headers: { "cache-control": "no-cache" },
      contentType: 'application/json; charset=UTF-8',
      data: JSON.stringify(myCart),
      dataType: 'json'
    }).done(function (cart) {
          if(next_page != "")
          window.location.href = next_page;
          //displayCart(cart)
        });
  }
}


  function loadCart() {
    var restUrl = i_am_using_a_proxy ? pathToProxy + '?_url=/rest/cart' : '/rest/cart';
    jQuery.ajax({
      url: restUrl,
      type: 'GET', // Notice
      headers: { "cache-control": "no-cache", "X-UC-Merchant-Id": merchantId },
      dataType: 'json'
    }).done(function (cart) {
          if (cart && cart.cartId) {
            window.myCart = cart;
            jQuery.cookie('UltraCartShoppingCartID', cart.cartId, { expires: 7, path: '/' });
            displayCart(cart);
          }
        });
   }

  function display_cart_errors(errors)
  {
      error_list_html = '';
      if (errors.length != 0) {
      for(var i = 0; i < errors.length; i ++)
      {
        error_list_html += '<li>' + errors[i] + '</li>';
      }
      $j('.errors ol').html(error_list_html);
      $j('.errors').show(250);
      window.setTimeout(scroll_to_errors, 500);
    }else{
      $j('.errors').hide();
    }
  }


function scroll_to_errors()
  {
    $j('html,body').animate({scrollTop: $j('.errors h4').offset().top -20}, 1500);
  }

from responsive_checkout.

plmwebdev avatar plmwebdev commented on September 22, 2024

Thanks Perry for your time and this can be closed! Once again thanks a lot!

from responsive_checkout.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.