Configure consent requests

You must determine which types of data processing activities need consent, how to get permissions, and how to add details to your site’s terms and conditions.

You must also define the GDPR-based shopper profile properties and to determine the next steps in the shopper’s experience when consent is given or revoked. Oracle Commerce does provide a set of tools that you can use and customize to assist with compliance of some of the GDPR requirements.

You can ask consent for various data processing types at different points in a shopper’s visit. Examples of data processing types include, but are not limited to, processing orders, sending marketing material, enabling third-party data sharing, creating cookies, or personalizing the shopper’s experience. You can capture consent when a shopper logs in, during the order checkout process, or when you work within the shopper’s profile. Additionally, the Receive Email Updates checkbox that is displayed on these pages allows you to request email consent.

When a shopper creates an order, your policy may be to consider that the shopper is inherently giving permission to use their personal data for the purpose of processing the order. It is up to you to provide any necessary disclaimer text or to customize order consent requests. To do this, you can customize widgets and profile properties.

If you prefer to request separate consent to capture data for order processing, and the shopper does not give consent, you must determine what actions occur. For example, you might prevent profile registration or guest checkout. Once you have determined the workflow, you should create the necessary customization.

Understand consent properties and cookies

The following table describes properties and cookies provided by Commerce for managing various types of consent:

Consent For Property/Cookie Description
Personalization requireGDPRP13nConsent

This site-level property indicates if the shopper must provide consent when they register on your site. When consenting, the shopper is allowing you the right to perform personalization.

For additional information, refer to the Manage personalization consent section.

Personalization GDPRP13nConsentGranted

This profile property tracks a shopper’s consent status.

For additional information, refer to the Manage personalization consent section.

Personalization GDPRP13ConsentDate

This profile property tracks the date that the shopper provided consent.

For additional information, refer to the Manage personalization consent section.

Personalization and Site GDPRCookieP13nConsentNotRequired

This cookie is placed on a shopper’s browser if your site does not require consent, or if the shopper’s locale is identified as a non-GDPR country.

For additional information, refer to the Manage cookie-based consent section.

Personalization and Site GDPRCookieP13nConsentGranted

This cookie is placed on a shopper’s browser if the shopper has given their consent.

For additional information, refer to the Manage cookie-based consent section.

Site requireGDPRCookieConsent

This site-level property identifies if the shopper is required to accept the cookies used on your site.

For additional information, refer to the Manage cookie-based consent section.

The following sections describe how to use these properties and cookies. Note that this documentation is not intended as legal advice for the GDPR. Please refer to your legal counsel for guidance.

Manage personalization consent

You may want to obtain a shopper’s consent to perform profile-based personalization. For example, if you use audiences, or the product recommendations widget, you may need to collect the personal data stored in a shopper’s profile.

You can collect profile data consent at shopper registration or order checkout by using the GDPR-based profile properties to indicate the need to display consent checkboxes. Configure personalization consent using the following widgets and elements:

  • The customerProfile widget
  • The shopperDetail widget
  • The checkoutRegistration widget
  • The login-registration element
  • The contact-login-for-managed-contacts element

Note that these widgets will contain the necessary consent fields by default when you set your environment to require the GDPR consent.

To indicate that your site needs consent to use the shopper’s personal data, use the Oracle Commerce Admin API updateSite endpoint to set requireGDPRP13nConsent to true. By default, this field is set to false. For example:

PUT /ccadmin/v1/sites/siteUS  HTTP/1.1

{
  "properties":
  {
    "requireGDPRCookieConsent":  true,
    "requireGDPRP13nConsent":  true
  }
}

Then, when a shopper accesses your site, they are presented with a checkbox asking if they would like to see relevant, or personalized, data. Additionally, they will be presented with the Receive Email Updates checkbox.

A shopper’s consent status is stored in the GDPRP13nConsentGranted property of their profile. The date that the shopper provided consent is stored in the GDPRP13nConsentDate property.

You should work with your legal team to determine the actions required for various configurations. For example, if your site uses audiences and you have set the requireGDPRP13NConsent flag to true, shoppers must provide consent. If a shopper does not provide consent, the non-consenting shopper cannot be a member of any of your audiences that use shopper profile data. You may want to indicate to the shopper that this will occur if they do not consent.

Once a shopper has provided initial consent, you can determine what, if any, situations require the shopper to provide new or additional consent. By default, shoppers who have given consent will not be presented with additional consent requests unless you configure your storefront as such.

The following example shows how you could modify the Shopper Details and Customer Profile widget templates to require GDPR personalization consent:

<div class="row col-md-12" data-bind="visible:$parent.site().
    requireGDPRP13nConsent">
  <div class="form group">
    <div class="checkbox" id="CC-customerProfile-edit-personalizationConsent-
            checkbox">
        <label for="CC-customerProfile-edit-personalizationConsent">
          <input type="checkbox" name="personalization-Consent"
                data-bind="checked: GDPRProfileP13nConsentGranted"
                id="CC-customerProfile-edit-personalizationConsent">
          <span data-bind="widgetLocaleText: 'personalizationConsentText'"
                id="CC-customerProfile-edit-personalizationConsent-text"></span>
        </label>
    </div>
  </div>
</div>

Note that you can add text that is appropriate for your environment by editing the widget’s resource file.

For information on audiences, refer to Define Audiences. For information on customizing the product recommendations widget, refer to the Product Recommendations.

Manage cookie-based consent

Cookie-based consent requests are made when you want to obtain consent from shoppers to use cookies that contain personal data during their site visits. Additionally, you can use cookie-based consent requests while creating personalization consent. For example, by setting the requireGDPRCookieConsent site property you can set the consent for receiving cookies. By setting the requireGDPRP13nConsent property, you can set personalization consent.. The need to request consent is based upon the locale of the shopper, and whether the cookie consent property is set to true.

Use the Oracle Commerce Admin API updateSite to set requireGDPRCookieConsent to true. By default, this field is set to false. For example:

PUT /ccadmin/v1/sites/siteUS  HTTP/1.1
{
  "properties":
  {
    "requireGDPRCookieConsent":  true,
    "requireGDPRP13nConsent":  true,
   }
}

The following table displays the possibilities when you set the requireGDPRCookieConsent property to true. When you set the property to true, your consent dialog is displayed to the shopper when they visit the site:

Shopper Response Effect
Gives consent If the shopper gives consent, the GDPRCookieP13nConsentGranted cookie is placed on their browser. No cookies are deleted from the shopper’s browser.
Does not give consent If the shopper does not give consent, Oracle Commerce cookies that contain personal data will be deleted from the shopper’s browser, with the exception of cookies that are identified within the necessaryCookies property list in the widget JSON. No further cookies are added to the browser.
GDPR not applicable If the GDPR is not required, a GDPRCookieP13nConsentNotRequired cookie is placed on the shopper’s browser.

Note: It is important to be aware of the cookies that your site uses, and, in particular, which cookies are deployed by third-party software. For a list of Oracle Commerce cookies, refer to Cookies used in Oracle Commerce.

If you have customized any of the following widgets, you may want to update to the latest default widget to get the new fields, or update your customized widgets to include the GDPR consent and profile personalization consent code elements. For information on upgrading customized widgets, refer to the Upgrade deployed widgets section in Design Your Store Layout :

  • customerProfile widget
  • shopperDetail widget
  • checkoutRegistration widget

You can configure your personalization services, such as the audience feature, to look for the presence of the GDPRProfileP13nConsentGranted cookie on the shopper’s browser and then perform the actions required for your site configuration. Refer to the Manage personalization consent section for information.

Cookie customization example

Oracle Commerce provides access to the file CivicUKCookieControl_sample.zip that contains sample code you can use to model the configuration of your site to comply with certain GDPR regulations. You can obtain this file from the Oracle Commerce Developer Community blog posts at:

https://community.oracle.com/groups/oracle-commerce-cloud-group/blog/2017/09/21/how-to-ensure-cookie-compliance-in-commerce-cloud-with-a-custom-widget

This code asks for consent based on the shopper’s profile settings and the setting of the requireGDPRCookieConsent property. The example uses the Civic UK Cookie Control widget to see if requireGDPRCookieConsent is set to true.

https://www.civicuk.com/cookie-control/v8/documentation

The Civic UK Cookie Control widget is only an example of one way that you could customize your storefront. Oracle Commerce cannot provide or recommend the types of consent that you need to capture, or the mechanisms that you use to capture them. Work with your legal team to determine your requirements.

Note that you can use any cookie consent application, but when you create cookies, they must use the names specified by Oracle Commerce, the GDPRCookieP13nConsentNotRequired and the GDPRCookieP13nConsentRequired cookies. The following example makes use of the application Cookie Control. For information, refer to:

The following example provides a customized configuration for the widget JSON:

{
  "name": "Cookie Control (Civic UK)",
  "javascript": "cukCookieControl",
  "i18nresources":"cukCookieControl",
  "availableToAllPages": true,
  "global": true,
  "globalEnabled": true,
  "config": {
    "apiKey":"94b985b32474b87b3fc2533a19aadeb8c455d5",
    "product":"free",
    "position":"left",
    "theme":"light",
    "initialState":"open",
    "necessaryCookies":["JSESSIONID", "atgRecVisitorId",
        "oauth_token_secret-storefrontUI", "xdVisitorID"]
  }
}

In the above example, the following configurations are set:

  • apiKey – A Cookie Control API key from the Civic UK Cookie Control API for a particular domain. This is a required property.
  • product – The type of the Cookie Control license that is set from the widget. The value can be multisite, custom, or the default, free. This is a required property that corresponds to the API key.
  • position – The position of the consent dialog. For button style widgets, the values can be left or right.
  • initialState – Identifies that the dialog has to be open when the widget starts.
  • necessaryCookies – Indicates the list of cookies that need to be protected from the deletion process.

The following is an example of a customized cukCookieControl.js file:

define(

  //-------------------------------------------------------------------
  // DEPENDENCIES
  //-------------------------------------------------------------------
  ['knockout', 'pubsub', 'CCi18n', 'ccConstants',
     'https://cc.cdn.civiccomputing.com/8.0/cookieControl-8.0.min.js',
     'storageApi'],

  //-------------------------------------------------------------------
  // MODULE DEFINITION
  //-------------------------------------------------------------------
  function(ko, pubsub, CCi18n, CCConstants, CC, storageApi) {
    "use strict";

    return {
        widgetInitialised: ko.observable(false),
      onLoad: function(widget) {
        if(widget.apiKey() !== null ) {
          var cukConfig = {};
          cukConfig.apiKey = widget.apiKey();
          switch (widget.product()) {
            case 'free':
              cukConfig.product = "COMMUNITY";
              break;
            case 'multisite':
              cukConfig.product = "PRO_MULTISITE";
              break;
            case 'pro':
              cukConfig.product = "PRO";
              break;
            default:
              cukConfig.product = "COMMUNITY";
          }

          switch (widget.position()) {
            case 'left':
              cukConfig.position = "LEFT";
              break;
            case 'right':
              cukConfig.position = "RIGHT";
              break;
            default:
              cukConfig.position = "LEFT";
          }

          if(widget.position() !== 'left' && widget.position() !== 'right') {
              cukConfig.position = "LEFT";
            }

          if(widget.theme() === 'light'){
            cukConfig.theme = "LIGHT";
          } else {
            cukConfig.theme = "DARK";
          }

          if(widget.initialState() === 'open'){
            cukConfig.startOpen = "OPEN";
          } else {
            cukConfig.startOpen = "CLOSED";
          }

          cukConfig.optionalCookies = [
                                        {
                                            name : 'analytics',
                                            label : 'Analytical cookies',
                                            description : 'Analytical cookies help
                                               us to improve our website by
                                               collecting and reporting
                                               information on its usage.',
                                            onAccept : this.onConsentAccept,
                                            onRevoke : this.onConsentRevoke
                                        }
                                     ];
          cukConfig.necessaryCookies = widget.necessaryCookies();
          cukConfig.text = {};
          cukConfig.text.title = '<p>' + CCi18n.t('ns.cukCookieControl
             :resources.cccTitle') + '</p>';
          cukConfig.text.intro = '<p>' + CCi18n.t('ns.cukCookieControl
             :resources.cccIntro') + '</p>';

// Main call to invoke Cookie Control, passing the configuration object we have
// set up. cookieControl object is established by the cookieControl-6.2.min.js
// file loaded in dependencies. Also subscribe to PAGE_CHANGED so we can manage
// the use of cookies if user has disallowed their use.
          if(widget.site().requireGDPRCookieConsent){
            if(CookieControl) {
              CookieControl.load( cukConfig );
               $.Topic(pubsub.topicNames.PAGE_CHANGED).subscribe
                   (this.pageChanged.bind(this));
                        this.widgetInitialised(tre);
            }
          }else{
            storageApi.getInstance().saveToCookies
                ("GDPRCookieP13nConsentNotRequired",true,365);
            if(storageApi.getInstance().readFromCookies
                ("GDPRCookieP13nConsentGranted")!==null){
              storageApi.getInstance().removeItem("GDPRCookieP13nConsentGranted");
            }
          }
        }
      },

      pageChanged: function(page){
        if(this.widgetInitialised() && storageApi.getInstance().readFromCookies
             ("GDPRCookieP13nConsentGranted")===null){
            CookieControl.deleteAll();
        }
      },
       onConsentAccept: function() {
        storageApi.getInstance().saveToCookies("GDPRCookieP13nConsentGranted"
            ,true,365);
      },

      onConsentRevoke: function() {
        CookieControl.deleteAll();
      }
    };
  }
);

This JavaScript makes a call to Civic UK CDN with the required parameters in the cukConfig object. In this example, only one category of optionalCookies is created with the name of Analytical Cookies. The onAccept function for this category sets the GDPRCookieP13nConsentGranted cookie and deletes all other cookies except those listed in the necessaryCookies list in the widget.json file. If more categories are required, you can write separate onAccept and onRevoke functions for each category.

When a widget loads, if the requireGDPRCookieConsent property for cookies is set to false, a GDPRCookieP13nConsentNotRequired cookie is created.

The ns.cukCookieControl.json file contains example text that you could use for the messages presented to the shopper:

{
  "resources": {
    "cccTitle" : "This site uses cookies to store information on your computer.",
    "cccIntro" : "Some of these cookies are essential to make our site work and
        others help us to improve by giving us some insight into how the site is
        being used.",
    "cccFull" : "Click for full Privacy Policy..."
  }
}

You can add configurations to the cukConfig object. For more configuration information, refer to the Civic UK documentation.

Cookies used in Oracle Commerce

This section describes the cookies that are issued with Oracle Commerce. This list provides information that may assist you when you are configuring your cookie control for shopper consent. It also indicates cookies that should be protected from deletion by adding them to the necessaryCookies list, as described in the Cookie customization example.

FILE_OAUTH_TOKEN cookie

The FILE_OAUTH_TOKEN cookie, which has a life of 24 hours, stores a token that is needed to access files using the /files servlet on the administration server. Note that this cookie is for the administration interface only and does not contain any personal data. This cookie can be deleted on the client-side, if necessary. It does not need to be included in the necessaryCookies list.

JSESSIONID cookie

The JSESSIONID cookie, which has a life that lasts only until the user’s browsing session ends, helps the server to manage user sessions. It is a standard Java servlet container cookie. While not accessible to scripts, this cookie can be deleted from the client-side. However, the cookie will be re-sent during the next request from the user.

This cookie tracks each request from the same browser, ensuring that the same session data is available on the server side. It does not contain any personal data. You must include this cookie in the necessaryCookies list, or else WebLogic will create new sessions for every request that comes in.

atgRecVisitorId cookie

This cookie does not collect personal data. It has a life expiration of 20 years. It is accessible to scripts, and can be deleted from the client-side. You must add this cookie to the necessaryCookies list.

oauth_token_secret-storefrontUI cookie

The oauth_token_secret-storefrontUI cookie is necessary for storefront user interface operations, as it is used to store the OAuth token of the user that is logged in and keeps the shopper’s login token active during page reloads and multiple tab access. This cookie does collect personal data in the form of the profileId. While the cookie is accessible from scripts, it cannot be deleted from the client-side. If you delete this cookie, shoppers may have to log in again after opening new tabs or refreshing pages. Deleting this cookie would also cause some checkout payment flows to fail when a shopper gets redirected to an external payment site like PayPal. When the browser gets returned to the storefront, the shopper’s authentication state is lost and the checkout process cannot proceed. You should add this cookie to the necessaryCookies list.

EETrViID cookie

The EETrViID cookie is an Oracle WebLogic cookie that stores the Visitor ID. It does not contain any personal data. This cookie cannot be deleted, and therefore cannot be modified by JavaScript in the browser. This cookie does not need to be added to the necessaryCookies list.

BIGIP cookie

The BIGIP cookie is an HTTP Only cookie that maintains a connection to a single application instance. This cookie is not accessible from scripts and contains no personal data. This cookie expires at the end of the session.

xd[tenantID]_[siteID] cookie

These cookies are generated by Visitor ID services and track the visits, which are site-specific. This cookie should be added to the protected list as it does not collect personal data. Note that the _[siteID] is only added to the cookie name if your environment supports multiple sites. You should know your own tenant ID and site ID.

For example: xdtp6a0c0_siteUS, where xdtp6a0c0 is the tenant ID and _siteUS is the site ID.

xs[tenantID]_[cartSharingGroupId] cookie

These cookies are used to find the current incomplete order for an anonymous shopper when the current site is in a cart sharing group. They do not collect personal data.

Soft Login cookie

The Soft Login cookie, which has a life of 13 months, contains a cryptographically secure version of the expiration timestamp and the user’s profile ID. If the shopper does not provide consent, the soft login cookie is not added to their browser, and soft login will not occur. This cookie does collect personal data, and therefore should not be included in the necessaryCookies list. If you delete this cookie, the soft login capability will not function. For information on soft login, refer to Configure the logged-in shopper session. For information on disabling the soft login feature, see Disable soft login.

Configure consent for account-based commerce

If your environment is configured with business accounts, as described in the Configure Business Accounts, you may want to configure profile properties that enable consent requests for account-based contacts. It is up to you to determine what types of consent to gather. For example, you may want to allow some accounts to grant consent on behalf of their contacts.

For example, you could configure your site to recognize when an account-based contact logs in for the first time and present them with various consent requests. Once you have consent, contacts who have visited before are not presented with additional consent checkboxes unless you configure it otherwise.

By default, when an account-based contact logs in, the Contact Login element of the Header widget checks to see if this is the contact’s first login. If it is, the contact is presented with a checkbox for consent to receive marketing emails, and a checkbox for personalization consent if the site has been configured to require consent.

Note that should it be necessary, you can provide agents and delegated administrators with the ability to use the getMember and updateMember endpoints in the Admin REST API to update a shopper’s consent properties. Administrators may also use the updateProfile endpoint to update an account-based shopper’s consent properties. For information on configuring custom properties, see Manage Shopper Profiles.