HomeDocumentationDelivery Options

Delivery Options

myparcelnl/delivery-options issues on GitHub
myparcelnl/delivery-options pull requets on GitHub

This is the MyParcel delivery options module for use in any e-commerce platform's checkout, by platform 1 (MyParcel) , platform 2 (SendMyParcel) and platform 3 (Flespakket) customers. It's used to show your customers the possible delivery and/or pickup options for their location, based on your settings. It only has the bare minimum css styling, so it should integrate with the design of your webshop easily.

Browser support

This app runs on Vue.js 2.6.14, it supports IE9 and up.

Sandbox

An example of the delivery options functionality can be found in our sandbox. Here you can try out every combination of settings and copy the code for use in your project.

Installation

Dependencies

Install @myparcel/delivery-options with your package manager:

yarn add @myparcel/delivery-options
pnpm add @myparcel/delivery-options
npm install @myparcel/delivery-options

Usage

  1. Is Vue.js ^2.6.0 present on the page you want to use the Delivery Options on?
    • Yes: Include dist/myparcel.lib.js.
    • No: Include dist/myparcel.js.
  2. Place <div id="myparcel-delivery-options"></div> in your HTML.
  3. Trigger the following event:
    document.dispatchEvent(new Event('myparcel_update_delivery_options'));
    
  4. The delivery options will be rendered inside the div you created before.

Check out the available options and usage examples for further configuration.

Available options

window.MyParcelConfig = {
  config: {
    platform: 'belgie',

    // Use this object to enable carriers and override settings per carrier.
    carrierSettings: {
      bpost: {
        deliveryDaysWindow: 7,
        allowDeliveryOptions: true,
        allowPickupLocations: true,
      },
      dpd: {
        allowDeliveryOptions: true,
        allowPickupLocations: true,
      },
    },

    // All settings below can be overridden per carrier via the carrierSettings object

    // The price for each option
    priceMorningDelivery: 7.95,
    priceStandardDelivery: 5.85,
    priceSameDayDelivery: 7.65,
    priceEveningDelivery: 6.25,
    priceSignature: 0.35,
    priceOnlyRecipient: 0.30,
    pricePickup: 5.85,

    // Shipment options
    allowSaturdayDelivery: true,
    allowPickupLocations: true,
    allowSignature: true,

    // Other settings
    dropOffDays: '1;2;3;4;5;6',
    cutoffTime: '15:00',
    deliveryDaysWindow: 4,
    dropOffDelay: 1,
  },
  strings: {
    saturdayDeliveryTitle: 'Zaterdaglevering',
    wrongPostalCodeCity: 'Combinatie postcode/plaats onbekend',

    // Address strings
    city: 'Plaats',
    postcode: 'Postcode',
    houseNumber: 'Huisnummer',
    addressNotFound: 'Adresgegevens niet ingevuld',

    // Delivery moment titles.
    // If any of these is not set, the delivery time will be visible instead.
    deliveryEveningTitle: 'Avondlevering',
    deliveryMorningTitle: 'Ochtendlevering',
    deliveryStandardTitle: 'Standaardlevering',

    deliveryTitle: 'Bezorgen op',
    pickupTitle: 'Afhalen op locatie',

    // Shipment options
    onlyRecipientTitle: 'Home address only',
    signatureTitle: 'Handtekening',

    pickUpFrom: 'Afhalen vanaf',
    openingHours: 'Openingstijden',

    // Other strings
    closed: 'Gesloten',
    from: 'Vanaf',
    loadMore: 'Laad meer',
    retry: 'Opnieuw',
  },
  address: {
    cc: 'BE',
    city: 'Antwerpen',
    postalCode: '2000',
  }
};

When there is no title set for deliveryMorningTitle, deliveryStandardTitle or deliveryEveningTitle , the delivery time will automatically be visible. For more in-depth explanation of each config item and string and an interactive demo please see our sandbox

To get the object with the selected options from the delivery options do the following:

const data = document.querySelector('#mypa-input').value;
const obj = JSON.parse(data);

// `obj` will be something like this:
// {
//   "delivery": "deliver",
//   "deliveryDate": "8-8-2019",
//   "deliveryMoment": "standard",
//   "shipmentOptions": {signature: true, only_recipient: false}
// }

Usage Examples

These examples assume you've already loaded the delivery options in your page. See [Installation] if you haven't. You have to provide a configuration file in the following format as window.MyParcelConfig and initialize the delivery options with an event.

Setting up the configuration

This is an example.

window.MyParcelConfig = {
  config: {
    platform: 'belgie', // REQUIRED!
    carrierSettings: {
      bpost: {
        allowDeliveryOptions: true,
        allowPickupLocations: true,
      },
      dpd: {
        allowDeliveryOptions: true,
        allowPickupLocations: true,
      },
    },
  },
  address: {
    cc: 'BE',
    city: 'Antwerpen',
    postalCode: '2000',
  },
};

// Trigger this event on the document to tell the delivery options to update.
// Usually only needed on initializing and when the address changes.
document.dispatchEvent(new Event('myparcel_update_delivery_options'));

Getting the address from your environment

  1. Set up the link between the address fields and the delivery options:
    /**
     * Get data from form fields and put it in the global MyParcelConfig.
     */
    function updateAddress() {
      window.MyParcelConfig.address = {
        cc: document.querySelector('#country').value,
        postalCode: document.querySelector('#house_number').value,
        number: document.querySelector('#postcode').value,
        city: document.querySelector('#address_1').value,
      };
    
      /*
       * Send the event that tells the delivery options module to reload data.
       */
      document.dispatchEvent(new Event('myparcel_update_delivery_options'));
    
      // IE9–11 compatible example
      var event = document.createEvent('HTMLEvents');
      event.initEvent('myparcel_update_delivery_options', true, false);
      document.querySelector('body').dispatchEvent(event);
    }
    
  2. Add event listeners to each address field to execute this function:
    // ES6 example, use var for older environments.
    const addressFields = [
      '<Country field selector>',
      '<Postal code field selector>',
      '<Address line 1 field selector>',
    ];
    
    addressFields.forEach((field) => {
      document.querySelector(field).addEventListener('change', updateAddress);
    });
    
  3. Now, when a user changes the value in any of the fields set in addressFields the window.MyParcelConfig will be updated and the delivery options module will receive the event that tells it to update. The delivery options will reload and fetch the available options for the new address.

Usage in forms

You'll often want to use the delivery options module in a checkout form in your webshop software. Below are some things to keep in mind, but if you're interested in doing this you should check out our Magento2 and WooCommerce plugins locally and read through these implementations. You can find the best files to get started with in [Integration examples]. We also recommend you join our [Slack] support channel to get (fast!) answers to any questions you might have.

  1. Follow the steps in [Installation] and copy myparcel.js (Vue included) or myparcel.lib.js (Vue not included) from node_modules/@myparcel/delivery-options/dist to your js folder.
  2. The things you'll need to do :
  • Have either a window.MyParcelConfig or dispatch a CustomEvent with the settings you want in the page where you're loading the delivery options.
  • Send events to the delivery options telling it when to update or rerender.
  • Listen to the delivery options' events to update your application according to the changes.
  • Attach the output data to the order that is being created.

Allowing or disallowing settings for specific countries

Let's say you want to disallow delivery to the Netherlands, only allow pickup in Belgium, for bpost. For DPD you want pickup only, wherever it's possible.

The configuration would look like this:

window.MyParcelConfig = {
  config: {
    platform: 'belgie',
    carrierSettings: {
      bpost: {
        // Allow delivery options in all countries it's possible in except the Netherlands.
        allowDeliveryOptions: { allow: false, items: ['NL'] },
        // Only allow pickup locations in Belgium.
        allowPickupLocations: { allow: true, items: ['BE'] },
      },
      dpd: {
        allowDeliveryOptions: false,
        allowPickupLocations: true,
      }
    }
  }
};

This is currently only possible for allowDeliveryOptions and allowPickupLocations. If you want this feature to be available for more settings, please create a feature request. Or, if you want to do it yourself you can send us a pull request!

Using Instabox for same day delivery only

Use case: You always want to use PostNL for regular shipments, but if a same day delivery is possible, you want to allow your customer to choose Instabox.

Example configuration:

window.MyParcelConfig = {
  config: {
    platform: 'myparcel',
    allowSameDayDelivery: true,
    cutoffTimeSameDay: '8:30',
    deliveryDaysWindow: 7,
    dropOffDelay: 1,
    priceSameDayDelivery: 6.65,
    priceStandardDelivery: 4.95,
    carrierSettings: {
      // Carriers are shown in order of the carrierSettings object, so RJP will be above PostNL.
      instabox: {
        allowDeliveryOptions: true,
        deliveryDaysWindow: 1,
        dropOffDelay: 0,
      },
      postnl: {
        allowDeliveryOptions: true,
      }
    }
  }
};

The fields deliveryDaysWindow and dropOffDelay inside carrierSettings.instabox are very important here. This setup would give you the following logic:

Current day and time: Tuesday, 6:45
Current day and time: Tuesday, 14:30

Integration examples

Here are some existing implementations that can help you get started:

It's more complex in Magento 2 because of the way its shipping methods work.

Attach data to an order using a hidden input

In WooCommerce and Magento 2 we injected a hidden text input inside the checkout <form> elements to hold this data and automatically pass it to the $_POST variable.

// Listen to the CustomEvent the delivery option sends back out once its data has been updated
document.addEventListener('myparcel_updated_delivery_options', (event) => {
  myHiddenInput.value = JSON.stringify(event.detail);

  // And now trigger updating the checkout of whatever platform you're using.
  // WooCommerce example:
  document.dispatchEvent(new Event('update_checkout'));

  // In Magento 2 we would update quote.shippingMethod here to trigger the changes.
});

Deselect options

You might want to integrate the delivery options into a list of existing shipping methods, like we've done in Magento 2 . So when the user selects a different shipping method you'll want the delivery options to appear unselected.

Deselect 1

Note: If you only have one option, so either "delivery" or "pickup", the option will appear disabled. Until there's a built in solution, there's the following workaround.

If you only use delivery:

document.getElementById('myparcel-delivery-options__delivery--deliver').disabled =
  false;

If you only use pickup:

document.getElementById('myparcel-delivery-options__delivery--pickup').disabled =
  false;
Deselect 2

To deselect all options, dispatch the myparcel_disable_delivery_options event. You could do this as when your users select a different shipping method, for example.

document.dispatchEvent(new Event('myparcel_disable_delivery_options'));

The delivery options will look like this:

Deselect 3

Contributing

  1. Fork this repository and clone it to your machine
  2. Run npm install
  3. Run npm run serve to start the app
  4. Make your changes conforming to our code style
    • We recommend enabling ESLint in your editor to make this easier.
    • Add/update unit tests if necessary.
  5. Commit, keeping the following rules in mind:
  6. Create a pull request
    • Keep your pull requests focused on single subjects.
    • Please explain what you changed and why.
    • We will check your code and thoroughly test it before merging.
Edit this page
Last updated: 
Contributors Richard Perdaan