Salesforce Integration Instructions

This guide is to help you set up the integration between SAP Sales Cloud CPQ and Salesforce.com (SFDCSalesforce.com) so an end-user can create quotes within the Salesforce environment as well as populate the quote back into the Salesforce sales opportunity.

If you haven’t already, you need to create a developers account at Salesforce. Go to the following website and sign up:

https://developer.salesforce.com

You will also need your SAP CPQ tenant info. If you are embarking on this setup, you most likely have a tenant. If not, you should contact your manager to get a tenant.

For successful integration, you should enable cookies in the browser, whether on your computer or the mobile device.

Salesforce Setup

There are 6 essential steps to set up the SAP CPQ - Salesforce integration. Read over the concepts first as they will assist you in the task.

Integration of SAP CPQ and Salesforce is supported by both Quote 1.0 and Quote 2.0.

First, you need to create a custom object in Salesforce for the quote

Prerequisites

  • Log into the Salesforce site.
  • Before you start, know where to enter the setup feature in Salesforce. At any time you can click the Setup button to get back into setup. Setup is found in the upper right-hand side of Salesforce(Figure 1).
  • Follow the directions closely, they will save you valuable time in the long run

Figure 1 - Setup link


  • Most of the parameters are case sensitive.
  • Salesforce uses __c at the end of their objects, this is a double underscore!
  • Salesforce is constantly upgrading their solution, so the below directions can easily be different in the tenant you are logged into, the procedures may be the same, however, but the menus may have changed.
  • There are sometimes a few different ways to get to something you’re working on.
  • Remember to click Save at the end of each task.

Figure 2 - Apps setup

Step 1: Create custom object "Quote"

  • Click on Setup link at the top-right menu
  • Click on Add App button (See figure 3)


Figure 3 - Create an app


Input form (figure 4) is shown. Fill out the input fields with the data below.

  • in App filed type Quote
  • in Label field type Quote
  • in Plural Label field type Quotes

Figure 4 - Fill out object's data


You can access the quote object via menu BuildCreateObjects. (See figure 5)

Figure 5 - Access custom objects via menu


List of custom objects is displayed in a table as depicted on figure 6.

Figure 6 - Custom objects list


Click on Quote link to open Custom Object Details page (Figure 7). This page shows all properties related to your custom object Quote.

Figure 7 - Custom objects list

Step 2: Add Custom Fields to Quote Object

Now that you defined the Quote object you need to define the fields in Salesforce that we will eventually match up to SAP CPQ.

To add custom fields, click on new link under Custom Fields & Relationships submenu from the top menu.(See figure 8).

Figure 8 - Create new custom fields


You will need to create eight fields with the below parameters to the Quote object.

Fields are case-sensitive and remember, the __ before letter “c” (__c) is a double underscore!

Field names and attributes that you must create are:

Field nameData typeLength
Discount PercentPercent Length - 16, Decimal Places – 2
Total List PriceCurrency Length - 16, Decimal Places – 2
OpportunityLookup Relationship Related to Opportunity
Owner IDNumber Length - 18, Decimal Places – 0
PrimaryCheckbox
Quote IDNumber Length - 18, Decimal Places - 0
Total Net Price Currency Length - 16, Decimal Places – 2
Revision Number Text 10


Let’s walk through the first one and then you can do all other fields with the same procedure.

  • Example for field Discount Percent

Select the field type (See figure 9).

Figure 9 - Choose data type


Click Next and fill out the following fields .(See figure 10)

Figure 10 - Field data


Click Next. Custom field-level security options are displayed. On this page, you can define which Profiles will be able to see your field and which not. (See figure 11)

Figure 11 - Custom field visibility permissions


Click Next. On this page, you can define Layout page where your custom field will be displayed. if quote Layout option is not checked, please check it and click Save (See figure 12). You can click Save & New if you are ready to create the next field. Once you have finished creating all eight fields you’re ready for the next step.

Figure 12 - Choose layout page to display custom field


You are done with custom fields definitions. You can find a list of custom fields by going to BuildObjects and clicking on quote label. The list looks like shown in figure 13.

Figure 13 - List of custom fields


Now, under Standard fields section, find quote Name standard field and click on edit next to field name (See figure 14). Rename it from quote Name to Quote Number.

Figure 14 - Rename standard field


Step 3: Create a Visualforce Page

You now need to create a Visualforce (VF) Page. Visualforce is a framework that allows developers to build sophisticated, custom user interfaces that can be hosted natively on the Force.com platform. The Visualforce framework includes a tag-based markup language, similar to HTML, and a set of server-side “standard controllers” that make basic database operations, such as queries and saves, very simple to perform.

Go to SetupBuildDevelopVisualforce Pages (See Figure 15).

Figure 15 - Visualforce pages


First, create new view page by clicking on Create New View link. (See figure 16)

Figure 16 - Create New View


View creation form is displayed. Fill out fields this way:

  • View Name: CPQ Installation

and in Step 4 section check radio button with label Visible to all users (included partner and customer portal users). This will make a view visible to all. (See figure 17)

Figure 17 - Fill out fields on Create New View form


Click Save.

Now you will create two pages - one for creating a new Quote, and another for editing a Quote.

To create a new page, click on New button as shown in figure 18.

Figure 18 - Create New Page



First, create a New quote.

  • Label: CPQQuoteNew
  • Name: CPQQuoteNew

Select the Available for Lightning Experience, Lightning Communities, and the mobile app checkbox. This makes the page available in the lightning design and on mobile devices.


Cut and Paste the apex code provided below in Codebox 1, and paste into the text box under Visualforce Markup tab. You must replace the URL with the URL of the SAP CPQ website you want to connect to, as well as the domain name.

<apex:page standardController="Quote__c" showHeader="true" >
<script type="text/javascript">
    document.onreadystatechange = function () {
        var iframeElm = document.getElementById('iframe1');
        var parentStyle = window.getComputedStyle(iframeElm.offsetParent);
        var parentPaddingTop = parseInt(parentStyle.paddingTop);
        var parentPaddingBottom = parseInt(parentStyle.paddingBottom);
        var iframeBorder = parseInt(window.getComputedStyle(iframeElm).borderWidth) || 2;
        var iframeParentPadding = parentPaddingTop + parentPaddingBottom;
 
        // only do if on mobile 
        if((typeof sforce != 'undefined') && sforce && (!!sforce.one)){
            // when document is ready set height, width and style
            setHeight(iframeElm, iframeParentPadding, iframeBorder);
            setWidth(iframeElm, iframeBorder);
            setStyle(iframeElm); 
 
            // if window is resized adjust width again to be responsive
            window.addEventListener("resize", function () {
                setHeight(iframeElm, iframeParentPadding, iframeBorder);
                setWidth(iframeElm, iframeBorder);
            }, true);
        } else {
            setClasicHeight(iframeParentPadding, iframeBorder);
            window.addEventListener("resize", function () {
                setClasicHeight(iframeParentPadding, iframeBorder);
            }, true);
        }
    }
 
    function setClasicHeight(iframeParentPadding , iframeBorder) {
        var iframeEl = document.getElementById('iframe1');
        var headerEl = document.getElementById('AppBodyHeader');
        var footerEl = document.getElementsByClassName('bPageFooter')[0];
        var tableEl = document.getElementsByClassName('bodyDiv')[0];
 
        // Get height values for all Salesforce elements (header, footer and container padding)
        var sfElementsHeight = parseInt(headerEl.offsetHeight) + parseInt(footerEl.offsetHeight) + parseInt(window.getComputedStyle(tableEl).borderTopWidth);
 
        // Set minimum iframe height
        iframeEl.style.minHeight = '600px';
        iframeEl.style.height = window.getWindowHeight() - sfElementsHeight - iframeParentPadding - (2 * iframeBorder)  + "px";
    }
 
    function setHeight(iframeElm, iframeParentPadding, iframeBorder) {
        // height is set to full window
        var newHeight = window.innerHeight - iframeParentPadding - (2 * iframeBorder) + "px";
        iframeElm.style.height = newHeight;
        // if not already set set maxHeight to iframe url so that SAP CPQ sets correct size
        if (iframeElm.src.indexOf("maxHeight") === -1) {
            iframeElm.src = iframeElm.src + "&maxHeight=" + newHeight;
        }
    }
 
    function setWidth(iframeElm, iframeBorder) {         
        // Set width to parent width - 2 * border size to avoid horizontal scroll
        var widthValue = document.body.clientWidth - (2 * iframeBorder) + "px";
        iframeElm.style.width = widthValue;
    }
 
    function setStyle(iframeElm){        
        //Get style of parent element
        var parentStyle = window.getComputedStyle(iframeElm.offsetParent);
        var parentLeft = parentStyle.paddingLeft;
        var parentRight = parentStyle.paddingRight;
 
        // setting margin and overflow
        iframeElm.style.marginLeft = '-' + parentLeft;
        iframeElm.style.marginRight = '-' + parentRight;
        iframeElm.style.overflow = "hidden";
    }
</script>
<iframe id="iframe1" width="100%" scrolling="true" src="https://sandbox.webcomcpq.com/salesforce/SfLogin.aspx?sfauthUserID={!$User.Username}&apiPartnerURL={!$Api.Partner_Server_URL_290}&apiSessionID={!$Api.Session_ID}&domain_name=TestDomain&apiPass=Password&action=New&sfqpOpportunityID={!Quote__c.Opportunity__c}" />
</apex:page>
Codebox 1 - apex code for page Create New Quote


Now create the Edit quote.

  • Label: CPQQuoteEdit
  • Name: CPQQuoteEdit

Select the Available for Lightning Experience, Lightning Communities, and the mobile app checkbox. This makes the page available in the lightning design and on mobile devices.

In the Visualforce Markup tab, add the text from the below Codebox 2. Again, replace the URL and the domain name.

   <apex:page standardController="Quote__c" showHeader="true" >
<script type="text/javascript">
    document.onreadystatechange = function () {
        var iframeElm = document.getElementById('iframe1');
        var parentStyle = window.getComputedStyle(iframeElm.offsetParent);
        var parentPaddingTop = parseInt(parentStyle.paddingTop);
        var parentPaddingBottom = parseInt(parentStyle.paddingBottom);
        var iframeBorder = parseInt(window.getComputedStyle(iframeElm).borderWidth) || 2;
        var iframeParentPadding = parentPaddingTop + parentPaddingBottom;
 
        // only do if on mobile 
        if((typeof sforce != 'undefined') && sforce && (!!sforce.one)){
            // when document is ready set height, width and style
            setHeight(iframeElm, iframeParentPadding, iframeBorder);
            setWidth(iframeElm, iframeBorder);
            setStyle(iframeElm); 
 
            // if window is resized adjust width again to be responsive
            window.addEventListener("resize", function () {
                setHeight(iframeElm, iframeParentPadding, iframeBorder);
                setWidth(iframeElm, iframeBorder);
            }, true);
        } else {
            setClasicHeight(iframeParentPadding, iframeBorder);
            window.addEventListener("resize", function () {
                setClasicHeight(iframeParentPadding, iframeBorder);
            }, true);
        }
    }
 
    function setClasicHeight(iframeParentPadding , iframeBorder) {
        var iframeEl = document.getElementById('iframe1');
        var headerEl = document.getElementById('AppBodyHeader');
        var footerEl = document.getElementsByClassName('bPageFooter')[0];
        var tableEl = document.getElementsByClassName('bodyDiv')[0];
 
        // Get height values for all Salesforce elements (header, footer and container padding)
        var sfElementsHeight = parseInt(headerEl.offsetHeight) + parseInt(footerEl.offsetHeight) + parseInt(window.getComputedStyle(tableEl).borderTopWidth);
 
        // Set minimum iframe height
        iframeEl.style.minHeight = '600px';
        iframeEl.style.height = window.getWindowHeight() - sfElementsHeight - iframeParentPadding - (2 * iframeBorder)  + "px";
    }
 
    function setHeight(iframeElm, iframeParentPadding, iframeBorder) {
        // height is set to full window
        var newHeight = window.innerHeight - iframeParentPadding - (2 * iframeBorder) + "px";
        iframeElm.style.height = newHeight;
        // if not already set set maxHeight to iframe url so that SAP CPQ sets correct size
        if (iframeElm.src.indexOf("maxHeight") === -1) {
            iframeElm.src = iframeElm.src + "&maxHeight=" + newHeight;
        }
    }
 
    function setWidth(iframeElm, iframeBorder) {         
        // Set width to parent width - 2 * border size to avoid horizontal scroll
        var widthValue = document.body.clientWidth - (2 * iframeBorder) + "px";
        iframeElm.style.width = widthValue;
    }
 
    function setStyle(iframeElm){        
        //Get style of parent element
        var parentStyle = window.getComputedStyle(iframeElm.offsetParent);
        var parentLeft = parentStyle.paddingLeft;
        var parentRight = parentStyle.paddingRight;
 
        // setting margin and overflow
        iframeElm.style.marginLeft = '-' + parentLeft;
        iframeElm.style.marginRight = '-' + parentRight;
        iframeElm.style.overflow = "hidden";
    }
</script>
<iframe id="iframe1" width="100%" scrolling="true" src="https://sandbox.webcomcpq.com/salesforce/SfLogin.aspx?sfauthUserID={!$User.Username}&apiPartnerURL={!$Api.Partner_Server_URL_290}&apiSessionID={!$Api.Session_ID}&domain_name=TestDomain&apiPass=Password&action=Edit&sfqpOpportunityID={!Quote__c.Opportunity__c}&OwnerId={!CEILING(Quote__c.Owner_Id__c)}&QuoteId={!CEILING(Quote__c.Quote_Id__c)}"/>
 
</apex:page>
Codebox 2 - apex code for page Edit Quote


Quote Cloning is not required for setting up the initial integration with Salesforce.

To carry out Quote Cloning: Create S-Control (due to the error that exists in Salesforce Visual Force page functionality, we are not able to provide instructions how to set up this feature by using the VF page. As soon as the error is resolved in Salesforce, we will post instructions here).

Label: Quote - Clone Primary.

S-Control Name: Quote_Clone_Primary

Type : HTML

Content :

<script>var me = window.name;
        if (me){
	       var iframes = parent.document.getElementsByName(me); 
	       if (iframes && iframes.length == 1) {
		    iframes[0].style.height = 1000 + "px"; 
		} 
         } 
         window.location="https://CPQApplicationName/salesforce/SfLogin.aspx?sfauthUserID={!User.Username}&apiPartnerURL={!$Api.Partner_Server_URL_290}&apiSessionID={!API.Session_ID}&domain_name=TenantName&apiPass=Password&action=ClonePrimary&sfqpOpportunityID={!Opportunity.Id}"
</script>

Figure 19

In the Custom Buttons and Links section of the new custom object, you should add a new button:

  • Label: Clone From Primary
  • Name: Clone From Primary
  • Display Type: List Button
  • Behavior: Display in the existing window with the sidebar
  • Content Source: S-Control
  • Content: Quote - Clone_Primary

You can also use apiPass to enhance security. In CRM Integration Setup → General, there is an entry Security password for verifying entrance to CPQ through the Salesforce backdoor. Use the word “password” as your password (Figure 20).

If this entry is left blank, apiPass from the Visual Force page URL will not be verified upon entrance through the backdoor. However, if this entry is not empty the value written in the Visual Force page URL will be matched with the value written in this entry in SAP CPQ administration upon entering SAP CPQ through SF backdoor. If they don't match, the user will not be able to enter SAP CPQ. If Security password for verifying entrance to SAP CPQ through the Salesforce backdoor is not empty, replace Password in the Visual Force page with the entry from SAP CPQ.

Step 4: Override Quote’s Standard Buttons and Links

Now that we created VF pages, we want to use them right? So we need to replace the standard pages for new, edit and view with the pages we just created.
Go to SetupBuildCreateObjects (See Figures 21 and 22).


Figure 21 and Figure 22


Scroll down to the Buttons, Links and Actions section (See figure 23).

Figure 23 - Buttons, Links and Actions section


Here you can select the particular VisualForce (VF) page from the dropdown, which will be assigned to the desired button. To do this, click Edit button of the particular action. That leads you to the Override Properties section (see Figure 24).

Figure 24 - Override properties for actions


  • Override View: Choose Visual Force page CPQQuoteEdit (Note: View uses the Edit page).
  • Override Edit: Choose Visual Force page CPQQuoteEdit.
  • Override New: Choose Visual Force page CPQQuoteNew.

Step 5: Change Opportunity Page Layout

Now that we have setup the Quote page, including its attributes, we need to add it to the Opportunity Page Layout.
Go to SetupCustomizeOpportunitiesPage Layouts (See Figure 25).


Figure 25 - Opportunity customizations page


You can edit all the pages for opportunity per business function. For now, click Edit for Opportunity (Sales) Layout. (See Figure 26).

Figure 26 - Edit Opportunity Sales layout


When you click Edit on the appropriate page layout, you will find a Quotes Section at the bottom of the screen (See Figure 27).

You can drag the quote section to the top so that it will display at the top of the opportunity page.

Figure 27 - Quotes related list


On Quotes area, click the “wrench” to enter properties. On this page, select columns listed below and move them from Available Fields list to the Selected FIelds list. Click Ok.(see Figure 28).

Figure 28 - Select fields


Step 6: Open the existing SAP CPQ quote page within Salesforce tab

To have the SAP Sales Cloud CPQ quote page appear within Salesforce and have one, seamless interface, you must configure the following:

Go to SetupBuildCreateTabs and create a New Tab by clicking the New button under the Custom Object Tabs section. (See Figure 29).

Figure 29 - Create new tab


You should be able to see the Quote object you created in the drop-down menu (See Figure 30).


Figure 30 - Choose “quote” from the drop down


Click on next twice (you do not need to change any default settings on the next two screens). When the button “Save” shows up, click on it to save your settings.
You should now be able to see the SAP CPQ Quotes tab in the menu bar at the top of the page (See Figure 31).

Figure 31 - Quote tab in the top menu


You have now completed the SAP CPQ setup in Salesforce. Now you must set up SAP CPQ to sync with the new Salesforce object you have just created.

SAP CPQ side Setup

Log into your SAP CPQ domain and go to the Setup section (See Figure 32).

Figure 32 - SAP CPQ setup


Frist of, you must enable Salesforce integration in SAP CPQ setup, in order to get the additional menu options under CRM Integration submenu. To do so, go to SetupCRM IntegrationGeneral (See Figures 33 and 34).

Figure 33 - SAP CPQ setup (General)


Figure 34 - SAP CPQ setup (Choose Salesforce as integration CRM)


Now, go to SetupCRM Integration SetupCRM Quote (See Figure 35)

Figure 35 - CRM Quote


Fields are case-sensitive and remember, the __ before letter “c” (__c) is a double underscore!


In the first section (Basic mappings - See Figure 36), populate fields with the following values:

  • CRM Quote Object Name: Quote__c
  • CRM Field For Persisting Quote Id: Quote_Id__c
  • CRM Field For Persisting Quote Owner Id: Owner_Id__c
  • CRM Field For Persisting About Primary Quote: Primary__c


Figure 36 - Basic CRM mappings

Click on “Save” before proceeding to additional mappings.

Alternatively, you can click CRM Lookup on the right-hand side, and select the field. If you are within the same web browser session, this should be available. Don't forget to click Save before proceeding to additional mappings.

In the second section (additional mappings), click Add Mappings (See Figures 37).

Figure 37 - Adding additional mapping


You will need to create five mappings. Take a look at Figure 38 for an example of the first one. Here is the list of all mappings:

  • Discount_Percent__c:<*CTX(Quote.Total.AverageProductDiscountPercent.DefaultDecimal)*>
  • Total_List_Price__c:<*CTX(Quote.Total.TotalListPrice.MarketDecimal)*>
  • Name: <*CTX(Quote.CartCompositeNumber)*>
  • Total_Net_Price__c:<*CTX(Quote.Total.TotalNetPrice.MarketDecimal)*>
  • Revision_Number__c:<*CTX(Quote.Revision.RevisionNumber)*>


Figure 38 - All additional mappings


You have now completed the Setup. Go back to Salesforce to test it out. To do so, click Opportunities in your Salesforce account, create new Opportunity, or open the existing one.
Scroll down to the Quotes section and click New Quote (See Figure 39).

New quote creation


Your quote page should open directly into Salesforce. If this doesn’t occur, go back and check your steps. Mistakes are common on Visualforce pages, especially with the URL and the domain.

Notes

  • When test-building a quote, and watching it appear in Salesforce, the quote will appear in the Notes and Attachments section. Or, if configured properly, it will appear in the Quotes section. The products in the quote will be added to the Products Tab.
  • If your products don’t have a part number, they may not transfer properly. In this case, go to Product Setup and add a product code/number to the product’s existing attributes.
  • Sometimes the account and contacts in Salesforce don’t have all the proper information, so you may need to ensure your contacts have all the proper fields set up correctly (e.g. country and zip code). Also, make sure you have a functioning address.

Miscellaneous - Support for Salesforce Lightning design

This feature is available only in Responsive Design


Salesforce announced their Lightning design recently, so SAP CPQ started to support it. Administrators can turn a „Lightning“ design on by setting the system parameter “Enable Lightning UI” to true. This parameter can be found under SetupGeneralApplication Parameters.
Depending on this parameter and if you have turned on Lightning UI in your Salesforce environment, then upon landing into SAP CPQ from Salesforce, SAP CPQ look and feel will adjust to the Salesforce Lightning look and feel.
If you want your design to be in accordance with the Salesforce Lightning UI then you can select two different action icons for the Lightning and standard SAP CPQ look and feel. (See Figure A)

Figure A – Setting different action icon for Lightning Salesforce UI

Troubleshooting

  • If you are not able to connect to SAP CPQ and it advises you to contact SAP CPQ administrator, check the VisualForce Page and ensure everything is correct, especially the domain name.
  • Also check the Quote identifiers (e.g. Quote_ID__c). Make sure they match exactly, remember they are case sensitive and it is a double underscore, __c.
  • If it connects to SAP CPQ but doesn’t log you in, check the user mapping and the password in CRM integration > General. Try removing the password and/or entering it.

More Information

You are here: SAP Sales Cloud CPQ Online HelpAdmin Page HelpIntegrationsSalesforce Integration Instructions