Retrieve the order

After processing the payment information, some web checkout systems will issue a POST request to the Commerce store to redirect the shopper back to the checkout page to complete the order.

The POST request triggers a PAGE_CHANGED event. Your widget code should subscribe to this topic. For example:

$.Topic(pubsub.topicNames.PAGE_CHANGED).subscribe(
             widget.handlePageChanged.bind(widget));

The widget’s handlePageChanged() function should handle the PAGE_CHANGED event by parsing the parameters in the incoming URL to extract custom properties that identify the order. For example:

widget.handlePageChanged = function(pageData) {

  var widget = this;
  if (pageData.pageId === "checkout") {
    var urlParameters = pageData.parameters;
    if (urlParameters) {

      // extract the URL parameters
      var params = urlParameters.split('&');
      var result = {};
      for (var i = 0; i < params.length; i++) {
        var entries = params[i].split('=');
        result[entries[0]] = entries[1];
      }

      if (widget.order().paymentGateway()) {
        widget.order().paymentGateway().type = '';
      }

   . . .

In addition, the handlePageChanged() function should subscribe to the DEFERRED_CART_LOAD event. When it receives this event, it should determine whether the web checkout succeeded. If so, it should add the custom properties to the payment observables array in the OrderViewModel, and then load the shopping cart using the getOrder() function. If the checkout has failed, it should reload the cart from local storage. For example:

   . . .

      $.Topic(pubsub.topicNames.DEFERRED_CART_LOAD).subscribe(function() {
          if(result.param1 && result.param2) {

          // add the extracted parameters to the payment as custom properties
          var payment = {type: "generic", customProperties: result};
          var payments = [payment];
          widget.order().updatePayments(payments);
          widget.order().getOrder();
          }
          else {
            widget.cart().loadCart();
            }
          storageApi.getInstance().setItem(
                 ccConstants.SKIP_LOADING_LOCAL_CART,false);

          });

    }
  }
};

If the checkout succeeds, the getOrder() function is executed, which invokes the Store API getInitialOrder endpoint to retrieve the incomplete order. When the server receives the request, it invokes the Generic Payment webhook, which sends a retrievetransaction request to the web checkout system. For example:

{
    "transactionType" : "0900",
    "transactionTimestamp" : "2016-06-07T23:31:14+0000",
    "customProperties" : {
      "param1" : "test1",
      "param2" : "test2"
    },
    "gatewaySettings" : [ ],
    "channel" : "storefront"
 }

The webhook response from the web checkout system must include the orderId so Commerce can retrieve the order, and the paymentId to identify the correct payment group. You may want to include these values in the customProperties object of the webhook request to ensure they are available to send in the response.

The response can also include an additionalProperties object, as well as an externalProperties object that specifies a list of the properties in the additionalProperties object that should be returned to the storefront. For example:

{
     "orderId": "o60412",
     "paymentId: "pg60411",
     "siteId": "siteUS",
     "transactionTimestamp": "2016-06-07T23:31:14+0000",
     "hostTimestamp": "2016-06-07T23:31:14+0000",
     "transactionType": "0900",
     "additionalProperties": {
          "RetrieveAddProp2": "RetrieveProp2_value",
          "RetrieveAddProp1": "RetrieveProp1_value"
     },
     "externalProperties": ["RetrieveAddProp2"],
     "response": {
          "success": true,
          "code": "Response Code Value",
          "description": "Response description value",
          "reason": "Response reason value"
     }
}

A successful response triggers an ORDER_RETRIEVED_INITIAL event. Your widget can subscribe to this topic:

$.Topic(pubsub.topicNames.ORDER_RETRIEVED_INITIAL).subscribe(
    widget.handleOrderRetrieved.bind(widget));

The widget’s handleOrderRetrieved() function should handle the ORDER_RETRIEVED_INITIAL event by adding the updated payment information to the OrderViewModel:

widget.handleOrderRetrieved = function(orderEvent) {

    var widget = this;
    widget.order().id(orderEvent.order.id);
    widget.order().isVerified(true);

    var payment = {type: "generic",
    paymentGroupId: orderEvent.order.payments[0].paymentGroupId};
    var payments = [payment];
    widget.order().updatePayments(payments);
};