Your SlideShare is downloading. ×
Under the Hood of a Salesforce.com Business Application
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Under the Hood of a Salesforce.com Business Application

5,792
views

Published on

Salesforce.com uses the Force.com cloud platform to develop internal applications as well as customer-facing applications. In this session, we'll take a close look at how salesforce.com built its App …

Salesforce.com uses the Force.com cloud platform to develop internal applications as well as customer-facing applications. In this session, we'll take a close look at how salesforce.com built its App Store application. Learn how to build complex, mission-critical applications that can scale, integrate with other systems, and provide the best user experience possible using Force.com pages (Visualforce), Force.com code (Apex), and the full platform stack.

Published in: Business, Technology

0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
5,792
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
217
Comments
0
Likes
3
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide
  • Use of basic oob features of platform
  • Highlight integrations to AppExchange applications like DocuSign, CyberSourceHighlight approval using metadata.Mix process scheduling
  • Highlight how VF component is referenced in the pageHighlight use of Omiture integration as part of each page view tracking
  • Transcript

    • 1. Under the Hood of a Salesforce.com Business Application
      Developers
      Emin Gerba: Salesforce.com
      Samarpan Jain: Salesforce.com
    • 2. Safe Harbor
      Safe harbor statement under the Private Securities Litigation Reform Act of 1995: This presentation may contain forward-looking statements that involve risks, uncertainties, and assumptions. If any such uncertainties materialize or if any of the assumptions proves incorrect, the results of salesforce.com, inc. could differ materially from the results expressed or implied by the forward-looking statements we make. All statements other than statements of historical fact could be deemed forward-looking, including any projections of subscriber growth, earnings, revenues, or other financial items and any statements regarding strategies or plans of management for future operations, statements of belief, any statements concerning new, planned, or upgraded services or technology developments and customer contracts or use of our services.
      The risks and uncertainties referred to above include – but are not limited to – risks associated with developing and delivering new functionality for our service, our new business model, our past operating losses, possible fluctuations in our operating results and rate of growth, interruptions or delays in our Web hosting, breach of our security measures, the outcome of intellectual property and other litigation, risks associated with possible mergers and acquisitions, the immature market in which we operate, our relatively limited operating history, our ability to expand, retain, and motivate our employees and manage our growth, new releases of our service and successful customer deployment, our limited history reselling non-salesforce.com products, and utilization and selling to larger enterprise customers. Further information on potential factors that could affect the financial results of salesforce.com, inc. is included in our annual report on Form 10-K for the most recent fiscal year ended January 31, 2010. This documents and others are available on the SEC Filings section of the Investor Information section of our Web site.
      Any unreleased services or features referenced in this or other press releases or public statements are not currently available and may not be delivered on time or at all. Customers who purchase our services should make the purchase decisions based upon features that are currently available. Salesforce.com, inc. assumes no obligation and does not intend to update these forward-looking statements.
    • 3. Agenda
      • Salesforce.com application landscape – a quick overview
      • 4. Major functional areas running on Force.com
      • 5. Deep-dive on Checkout & Quote-to-Cash
      • 6. Q&A
    • Salesforce.com application landscape
    • 7. Customer Service
      Sales & Marketing
      Enterprise
      Infrastructure
      Compliance and Risk
      Human Capital Management
      Development
      Finance
      • Performance Management
      • 8. Time-off Manager
      • 9. Volunteer Tracking
      • 10. Recruiting Management
      • 11. Callidus Comp Plan Communicator
      • 12. Kelly Contingent Worker Outsourcing
      • 13. Workday HCM
      • 14. ADP payroll
      • 15. Coupa Procure to Pay
      • 16. Concur T&E Manager
      • 17. Manhattan Space & Lease Management
      • 18. Ruesch Payment Services
      • 19. Oracle eBusiness Suite Financials
      • 20. Sabrix for Tax
      • 21. Hyperion Financial Management and Planning
      • 22. Salesforce Customer Service & Support Portal
      • 23. Salesforce Knowledge Base
      • 24. Salesforce Ideas
      • 25. Appirio Services Management
      • 26. Plateau Learning Management
      • 27. IT Help Desk
      • 28. Asset Management Object
      • 29. iLinc Web Meetings
      • 30. Live Ops Global Contact Center Infrastructure
      • 31. Google Docs
      • 32. Omniture Web Analytics
      • 33. Business Objects/SPSS BI
      • 34. OpenCms Web CMS
      • 35. Ping Identity Management
      • 36. Microsoft Exchange
      • 37. Perforce Software Config Mgmt
      • 38. Oracle BPEL Process Manager
      • 39. Cisco Call Manager
      • 40. Agile Scrum and Bug Management
      • 41. Program and Resource Management
      • 42. Test Repository
      • 43. Audit Controls Management
      • 44. Business Impact Analysis
      • 45. Change Management
      • 46. Salesforce Automation (“Org 62”)
      • 47. Opportunity to Quote
      • 48. Quote to Cash
      • 49. Checkout (e-commerce & account management)
      • 50. Event Management
      • 51. Access Hoovers
      • 52. Clicktools Survey Tool
      • 53. Conga Mail Merge
      • 54. D&B
      • 55. Sales Genius
      • 56. Mindjet Org Charting
      • 57. Ribbit Voice to Text
      • 58. Inside View Account News
      • 59. Click to Dial (CTI Integrations)
      • 60. Instant Service Live Chat
      • 61. Xactly Sales Compensation
      • 62. Comergent Configurator
      • 63. CyberSource payment gateway
      • 64. DocuSign e-signature portal
      • 65. Aptus agreements management
      Legend
      • Salesforce.com products
      • 66. Built on force.com
      • 67. SAAS/PAAS Products
      • 68. On Premise Applications
    • A View from the salesforce.com IT Cloud
      Major Business Applications on Force.com
      • Sales force Automation (campaign, lead, opportunity management)
      • 69. Checkout (eCommerce & account management)
      • 70. Quote to Cash
      • 71. Customer Service & Support Portal
      • 72. Event Management
      • 73. Agile Scrum & Bug Management
      • 74. Program & Resource Management
      • 75. Performance Management
      • 76. Time-off Manager
      • 77. Volunteer Tracking
      • 78. Recruiting Management
      • 79. IT Help Desk
      • 80. Change Management
    • Checkout & Quote-to-Cash
    • 81.
      • It covers a lot of ground
      Xactly
      Incent
      sales commissions
      configurator
      service
      renewal forecasting
      opportunity management
      customer notifications
      service renewal & suspension
      quoting & approvals
      e-commerce portal
      contract & order
      management
      billing & credit memo
      engine
      financials
      payment
      management
      CyberSource
      payment processor
      DocuSign
      e-signature portal
      CyberSource
      payment processor
      usage entitlements & tracking
      cloud
      on-premise
      force.com
    • 82.
      • Customer self-service account management and purchase of SFDC and partner services & products.
      • 83. Streamlined electronic interaction between customers and sales: publish quotes, e-signature, place orders, etc.
      • 84. Advanced quoting & approval flows for sales; craft custom deals, including custom pricing, product terms, contract terms, etc.
      • 85. Sophisticated approval flows defined by sales ops, finance, and legal, with rule based and human approvals.
      • 86. Renewals forecasting layer that tracks current vs. projected service levels across our customer base by product category.
      • Order management application that enforces data integrity, stamps data required by finance for revenue recognition and even stages data for sales commission payouts.
      • 87. Service enablement & suspension based on activated orders, received payments, etc.
      • 88. Billing & credit memo engine that creates invoices and credit memos based on orders
      • 89. Usage entitlement creation based on orders, actual usage tracking.
      • 90. Back-end integrations that pushes invoices & credit memos from Salesforce to Oracle Financials for creation of accounting entries, brings back tax calc
    • Technologies
      • Customer Portal for e-commerce, utilizing High Volume portal user
      • 91. Apex triggers, classes, and web services to implement core business logic
      • 92. Batch Apex to implement bulk functionality. Employs software development best practices, like object orientation, design patterns, etc.
      • 93. Visualforce to implement streamlined, scalable, tailored look & feel.
      • 94. Salesforce.com sharing (private), user profiles to enforce granular data access security.
      • 95. 3rd party configurator engine and Force.com to provide comprehensive quoting capabilities. Bi-directional communication between Salesforce.com and configurator implemented using Apex call-outs and Apex web services.
    • Technologies
      • Integration to CyberSource payment gateway, using hosted CC/DD page using silent https post.
      • 96. Multiple approval flows leveraging standard Salesforce.com approvals engine, additional custom control logic in Apex driven by metadata
      • 97. Approval requests, including quote details and cumulative approval comments, sent out via email. Executives able to approve quotes via email on their mobile devices. Utilizes Apex, Visualforce e-mail templates.
      • 98. Integrates to DocuSign platform for electronic signature, using AppExchange package, Wsdl2Apex functionality, Apex.
      • 99. A caching layer in Apex that caches information across request event handlers – e.g. before insert to after insert; allows for significantly more data to be processed with flat memory consumption
    • The back-end
      Xactly
      Incent
      sales commissions
      configurator
      service
      renewal forecasting
      opportunity management
      customer notifications
      service renewal & suspension
      quoting
      e-commerce portal
      contract & order
      management
      billing & credit memo
      engine
      financials
      payment
      management
      CyberSource
      payment processor
      DocuSign
      e-signature portal
      CyberSource
      payment processor
      usage entitlements & tracking
      cloud
      on-premise
      focus
      force.com
    • 100. You will see examples of:
      • How we used Design Patterns to implement a scalable, flexible billing engine
      • 101. Use of SOQL to implement complex filtering criteria
    • Flyweight Pattern
      • Your design requires a whole lot of objects that would be too expensive to create separately.
      • 102. The objects can be made shareable; they can be designed so they do not contain contextual state. Perfect for stateless business logic!
      • 103. Sharing objects would significantly decrease the number of needed objects and memory requirements.
      Factory Pattern
      • You wish to make your client independent of the actual subclasses of the product.
      • 104. You wish to centralize the creation logic in one place.
    • Using Design Patterns in Apex - Flyweight
      public class GroupAlgorithmimplements BaseBill.TrxAlg{
      public boolean Execute(List<BaseBill.TransactionClass> trx_list){
      ...
      BObj.OrderClass lhOrder = (BObj.OrderClass)trx_list[0];
      BObj.OrderClass rhOrder = (BObj.OrderClass)trx_list[1];
      /* 1. Forced separation flag */
      if(lhOrder.GetSObject().BillSep__c || rhOrder.GetSObject().BillSep__c){
      return false;
      }
      /* 2. Contract */
      if(lhOrder.GetSObject().Ctr!=rhOrder.GetSObject().Ctr){
      return false;
      }
      ....
      /* 4. Shipping Address */
      String lhCountry, lhState, lhCity, lhZIP, rhCountry, rhState, rhCity, rhZIP;
      lhCountry=lhOrder.GetSObject().ShippingCountry!=null?
      lhOrder.GetSObject().ShippingCountry : lhOrder.GetSObject().Contract.ShippingCountry;
      ....
      if(lhCity.equalsIgnoreCase(rhCity) && lhState.equalsIgnoreCase(rhState) && lhZIP.equalsIgnoreCase(rhZIP)){
      ….
      }else{
      if(lhCity.equalsIgnoreCase(rhCity)) return true;
      }
      return false;
      }
      }
    • 105. Using Design Patterns in Apex – Flyweight
      public class …{
      /* Provide functionality for the object to compare itself to the supplied object using the provided TrxAlgorithm */
      public boolean DoCompare(TrxAlgFactory trxAlgFact, TrxClass trx){
      List<TrxClass > trxList = new TrxClass []{this, trx};
      TrxAlg trxAlg = trxAlgFact.getAlgorithm(trxList);
      return trxAlg.Execute(trxList);
      }
      /* Invokes the Execute method on the provided algorithm object and passes itself to it.
      It also must invoke the same method on all its children */
      public virtual void DoCreate(TrxAlgFactory trxAlgFact){
      List<TrxClass > trx = new TrxClass []{this};
      TrxAlg trxAlg = trxAlgFact.getAlgorithm(trx);
      trxAlg.Execute(trx);
      if(this.children!=null){
      for(TrxClass child:this.children){
      child.DoCreate(trxAlgFact);
      }
      }
      }
      }
    • 106. Using Design Patterns in Apex - Factory
      // This method decides the algorithm to be returned based on the nature of the object
      public ...TrxAlg getAlgorithm(List<...TrxClass> trxList){
      ...
      if(containsHdr(trxList)){
      return new InvoiceHeaderCreationAlgorithm();
      }else if(containOdr(trxList)){
      return new GroupAlgorithm();
      }else if(containsItemBFZero(trxList)){
      return new BFZeroAlgorithm();
      }else if(containsItemBFNotZero(trxList)){
      ....
      }else{
      throw new ...InvalidDataException(...);
      }
      return null;
      }
      }
    • 107. Making SOQL do complex filtering
      private OrdItem[] getBilOrds(String revOwn, Integer maxRows , String ctr, ...){
      OrdItem[] billRows;
      String baseQuery = 'SELECT Id, ListPrice, …’ + 'FROM OrdItem '+
      'WHERE Ord.ActDate!=null AND Ord.Status != 'Canceled' AND '+
      '(Ord.Cont.EndDate > '+String.valueOf(System.Today())+' OR (PE.BillFreq=0 AND ’+
      ‘Ord.Cont.EndDate = '+String.valueOf(System.Today())+')) AND '+
      ‘(OriItemId!=null OR (BillThrDate__c = null AND '+
      ‘(OIEffectiveDate__c - Ord.Cont.OrdPrebillDays <= '+String.valueOf(System.Today())+')) OR '+
      '(BillThrDate__c != null AND (OIEndDate__c - BillTrhDate__c > 0) AND '+
      'PE.BillFreq !=0 AND (BillThrDate__c - Ord.Cont.OrdPrebillDays < ‘+String.valueOf(System.Today())+'))) AND
      Ord.Cont.Id=''+ctr+''';
    • 108. Order Management
      Xactly
      Incent
      Xactly
      Incent
      sales commissions
      configurator
      service
      renewal forecasting
      opportunity management
      customer notifications
      service renewal & suspension
      quoting & approvals
      e-commerce portal
      contract & order
      management
      billing & credit memo
      engine
      financials
      payment
      management
      CyberSource
      payment processor
      DocuSign
      e-signature portal
      CyberSource
      payment processor
      usage entitlements & tracking
      cloud
      on-premise
      focus
      force.com
    • 109. You will see examples of:
      • How we cache data in Apex to reduce resource usage
    • Transactional caching in Apex
    • 110. Cache implementation
      public class OrderCache extends BaseCache
      public override Map<Id, SObject> getCache(Set<Id> sObjectIdList, String soqlQuery, boolean reQuery, boolean lockRecords) {
      //If the records need to be locked,we add to the list if(lockRecords) { lockedIds.addAll(sObjectIdList); }//Doing the search first because if the map already contains the required orders, then we do not do any soql and work with the existing map Map<Id, Order> selectedOrders = searchCache(sObjectIdList); if(reQuery || selectedOrders == null) { //If we are requerying either due to forced requery or the selected ids are not there in the cache, see if the cache size is beyond threshold ….
      selectedOrders = getOrderInfo(sObjectIdList, soqlQuery); orderMap.putAll(selectedOrders); } return selectedOrders;}
      public override Map<Id, SObject> addToCache(List<SObject> sObjectList) {
      if(orderMap == null) {
      orderMap = new Map<Id, Order>();
      }
      for(sObject glSObject : sObjectList) {
      if(glSObject instanceOf Order) {
      Order order = (Order) glSObject;
      orderMap.put(order.Id, order);
      }
      }
      return orderMap;
      }
      public override void persist() {
      if(orderMap != null && orderMap.size() > 0) {
      update orderMap.values(); …
    • 111. Using the cache
      public class OrderInfo {
      //Caching all of the order/order item related info
      public static EntityCache orderCache = new OrderCache();
      ….
      public static Map<Id, List<OrderItem>> getOrdersWithOrderItems(List<Order> orders, Boolean lockRecords) {
      Set<Id> orderIds = new Set<Id>();
      orderIds.addAll(eimUtils.getIds(orders));
      Map<Id,Order> orderMap = (Map<Id, Order>)orderCache.getCache(orderIds, '', false, lockRecords);
      Map<Id, List<OrderItem>> orderToOrderItemsMap = new Map<Id, List<OrderItem>>();
      for(Order sOrder:orderMap.values()) {
      if(sOrder.OrderItems != null) orderToOrderItemsMap.put(sOrder.Id, sOrder.OrderItems);
      }
      return orderToOrderItemsMap;
      }
      //Adds any order/order item to the cache. If the object already exists, the new object will replace it.
      public static void addToOrderCache(Order sOrder) {
      orderCache.addToCache(sOrder);
      }
      }
    • 112. You will see examples of:
      • Use of language override and transactional data to set locale without relying on the browser locale
    • 113.
    • 114. Using language override
      <apex:page controller="InvoiceController" title="Salesforce" language="{!language}" showHeader="false">
      <div id="sfdcheader">
      <table cellspacing="0" cellpadding="0" width="100%" border="0">
      <tbody>
      <tr>
      <td valign="top" align="left">{!FromName}<br/>
      <apex:outputtext escape="false" value="{!FORMAT_ADDRESS(divInfo.oldFromStreet1,
      divInfo.oldFromStreet2__c, divInfo.oldFromCity,
      divInfo.oldFromState__c, divInfo.oldFromZip,
      divInfo.FromCountry, '<br/>')}"/></td>
      </apex:outputText>

      <tbody>
      <tr>
      <th width="160" align="left">{!$Label.tableService}</th> …
      <th width="93" class=“num">{!$Label.tableQty} …
      <th width="90" class="currency">{!$Label.tableTotal}</th>
      </tr>
      <apex:repeat value="{!orderData.lineWrappers}" var="tranLine">
      <tr>
      <td>{!tranLine.lineNo}</td>
      <td class="num">{!FORMAT(tranLine.line.Quantity)}</td>
      <td class="currency">{!tranLine.formatTotalPrice}</td>
      </tr>
      </apex:repeat>
      </apex:page>
    • 115. Using transactional data to determine locale
      public with sharing class InvoiceController extends TransactionController {
      ….
      public String getCoverSheetName() {
      String firstName = getname(getContract().MailingFirstName__c);
      String lastName = getName(getContract().MailingLastName__c);
      String salutation = getname(getContract().MailingSalutation__c);
      String result = '';
      ….
      if ('ja' == getContract().BillingLanguage || 'ko' == getContract().BillingLanguage || getContract().BillingLanguage.contains('zh')) {
      return result + lastName + ' ' + firstName + ' '+salutation;
      } else {
      return result + salutation +' '+ firstName + ' ' + lastName;
      }
      return result;
      }
      public String getLanguage() {
      Contract c = getContract();
      if (c == null) return 'en_US';
      if (getContract().BillingLanguage == 'en_US') {
      if (c.RevenueOwner__c == 'ROWH' || c.RevenueOwner__c == 'US') {
      return 'en_US';
      } else if(c.RevenueOwner__c == 'EU' || c.RevenueOwner__c == 'ASIA PAC') {
      return 'en_GB';
      }
      }
      return c.BillingLanguage;
      }
      }
    • 116. Checkout
      Xactly
      Incent
      sales commissions
      configurator
      service
      renewal forecasting
      opportunity management
      customer notifications
      service renewal & suspension
      quoting & approvals
      e-commerce portal
      contract & order
      management
      billing & credit memo
      engine
      financials
      payment
      management
      CyberSource
      payment processor
      DocuSign
      e-signature portal
      CyberSource
      payment processor
      usage entitlements & tracking
      cloud
      on-premise
      focus
      force.com
    • 117. You will see examples of:
      • Use of Visualforce components to achieve flexible look & feel
      • 118. Use of metadata to control display of content blocks
      • 119. Use of iFrames in Visualforce to display external content and integrate with an e-signature portal
      • 120. Use of Visualforce to perform silent post and integrate with a payment processing gateway
    • 121. Building a header component
      <apex:component controller="StoreNavBarController" >
      <apex:stylesheet value="{!URLFOR($Resource.styleszip, '/common/css/styles.css')}"/>
      <apex:includeScript value="{!URLFOR($Resource.styleszip, '/common/js/sf.js')}"/>
      <apex:attribute ... />
      <div id="pagewrap" style="width:980px;text-align:left;overflow: visible;">
      <div class="sfLogo">
      <apex:image styleClass="logo" ...sf_logo_onblue.png')}" width="159" height="124" ... />
      </div>
      <div id="header">
      <div class="links">
      <span class="welcome"> {!$Label.store_welcome},&nbsp; <em>{!userName}</em> ...
      </div><!-- .links -->
      <span class='endofcontainer'><!-- .endofcontainer --></span>
      </div><!-- header --> ...
      <div id="bodycontent">
      <apex:outputText rendered="{!FromPage != '062'}">
      <apex:form >
      <ul id="nav" style="padding-left:0px"> ...
      <!-- trial org -->
      <apex:outputText rendered="{!stat}"> ...
      <apex:outputText rendered="{!FromPage == 'quoteDoor'}">
      <li...>{!$Label.store_editions}</li>
      </apex:outputText> ...
      </apex:outputText>
      </ul>
      </apex:form>
      </apex:outputText>
      </apex:component>
    • 122. Components in action
      <apex:page id="thePage" showHeader="false" standardStylesheets="false" controller="FastBuyPageController">
      <c:storeOmniture pgName="Fast Buy Quote Edit Form"/>
      <c:storeMenu FromPage="fastbuyedit"/>
      <apex:outputPanel id="mainpage" rendered="{!!showErr}">
      <div id='bodycontent'>
      <apex:form id="editForm"> <!-- form -->
      <div id="subscriptionSection">
      <apex:outputPanel rendered="{!showErrorBubble}">
      <div id="licenseSelection">
      <div id="totalPrice">
      <b>{!$Label.store_total}:&nbsp;&nbsp;
      <apex:outputText value="{!format_currency(quote.CurrIsoCode,licPrd.Total_Price__c)}"/></b>
      </div> ….
      <apex:inputText value="{!ordQty}" id="licText" rendered="{!!isLmtSeats}" />
      <apex:commandLink action="{!save}">{!$Label.store_update}</apex:commandLink>
      </div>
      <p class="ccMessage">* {!$Label.store_creditcardcharged}</p>
      </div> <!-- licenseSelection -->
      ………
      </apex:form> <!-- form -->
      </div><!-- #bodycontent -->
      </apex:outputPanel>
      <c:storefooter />
      </apex:page>
    • 123. The brains of the page controller
      public class StoreNavBarController{
      private List<StoreConfig__c> storeConfigs;
      public StoreNavBarController(){
      getAccountExecInfo();
      // get all store config objects for this edition
      storeConfigs = StoreUtil.getStoreConfigs();
      }
      public boolean getStat(){
      return StoreUtil.getStat();
      }
      public String getUserName(){
      return UserInfo.getName();
      }
      private void getAccountExecInfo() {
      Exception err = null;
      try {
      StoreUtil.AccountExecInfo aeInfo = StoreUtil.getAccountExec(UserInfo.getUserId());
      aeName = aeInfo.name;

      return;
      } catch(Exception e) {
      err = e;

      }
      // return defaults if cannot get real AE info
      aeName = Label.store_ae_name_default;
      aePhone = Label.store_ae_phone_default;
      }
    • 124. Metadata Configuration
      public static List<StoreConfig__c> getStoreConfigs() {
      try {
      String orgEdition = StoreControllerUtil.getOrgEdition();
      return [select Id, HideRequestSalesAssistance__c, MaximumSeats__c, ….. HideAccountContact__c, HideAdditionalProduct__c,
      HideLowerEditions__c, EditionName__c
      from StoreConfig__c where EditionName__c =: orgEdition];
      } catch (Exception e) {
      return null;
      }
      }
      }
    • 125. E-signature Portal Integration
    • 126.
    • 127. Staging a document for e-signature
      public void docusignSetup() {

      // launch docusign with new envelope
      // 1. Create document
      PageReference page = new PageReference(…);
      Blob myblob = page.getContentAsPDF();
      SFDCToDocusignAPI.DocuSignDocument mydoc = new SFDCToDocusignAPI.DocuSignDocument('Quote Legal View','pdf',myblob);
      // 2. Create recipient
      SFDCToDocusignAPI.DocusignRecipient toReceip =
      new SFDCToDocusignAPI.DocusignRecipient(this.portalUserInfo.Contact.Email,…);
      // 3. Create connection (contains envelope)
      SFDCToDocusignAPI env = new SFDCToDocusignAPI('Embedded Signing',‘Store Flow',…);
      // 4. Add document to envelope
      envelope.addDocuments(mydoc);
      // 5. Add recipient to envelope
      envelope.addRecipients(toReceip);
      // 6. Create the Portal configuration (Request the token)
      // change the URL based on whether this is inline or
      SFDCToDocusignAPI.DocusignPortalInfo portInfo = new SFDCToDocusignAPI.DocusignPortalInfo(email,
      'https://...salesforce.com/apex/storeorderlanding?il=...);
      String retUrl = env.RequestDSToken(portInfo);
      this.docusignPage = new PageReference(retUrl);
      this.docusignPage.setRedirect(true);
      ...
    • 128. Using iFrame to serve external content
      <apex:page title="Docusign Entry" controller="DocusignInitController" action="{!docusignSetup}" showHeader="false" standardStylesheets="true">
      <c:storeOmniture pgName="Docusign Initialization"/>
      <c:storeMenu FromPage="docusign" rendered="{!!isCancel}"/>
      <apex:iframe src="{!docusignUrl}" rendered="{!!isCancel && !hasError}"/>
      <apex:outputText rendered="{!hasError}" value="This quote is already processed"/>
      <apex:outputText rendered="{!isCancel}">
      <script type="text/javascript">
      parent.goBackToQuote();
      </script>
      </apex:outputText>
      <c:storefooter rendered="{!!isCancel}"/>
      </apex:page>
    • 129. Payment Processing Gateway Integration
    • 130.
    • 131. Credit Card processing using silent post in Visualforce
      <apex:page id="superRoot" controller="StoreCreditCardController" title="{!$Label.store_enterCCDetails}" showHeader="false" standardStylesheets="true">
      <apex:includeScript value="{!$Resource.cardvalidation}"/>

      <apex:form action=“{!CreditCardSystemUrl}">

      <input type="text" name="lastName">
      <select name="card_cardType" id="ccTypes"><br />
      <option value="">{!$Label.store_select}</option>
      <option value="001">Visa</option> …
      </select>
      <input type="text" name="cardNumber"/>
      <select name="card_expirationMonth" id="cardExpMnth">
      <option value="01">01</option> ...
      </select>
      <select name="card_expirationYear" id="cardExpYr">
      <option value="2010">2010</option> …
      </select>
      <input type="hidden" name="orderPage_receiptResponseURL" value="https://.../apex/ReceiptPage" />
      <input type="hidden" name="orderPage_signaturePublic" value="{!InsertSignature}"/>
      <input type="hidden" name="merchantID" value=…/> …
      </apex:form>
      </apex:page>
    • 132. The controller behind silent post
      public class StoreCreditCardController {

      // This method gathers the data and calls a Crypto class method to generate signature
      public String InsertSignature(String amt, …){
      String data = getMerchantID() + amt + …;
      return EncodingUtil.base64Encode(Crypto.generateMac('HmacSHA1',Blob.valueOf(data),
      Blob.valueOf(getPublicKey())));
      }
       
      public boolean VerifySignature(String data){
      return (tranField == EncodingUtil.base64Encode(Crypto.generateMac('HmacSHA1',Blob.valueOf(data),
      Blob.valueOf(getPublicKey()))));
      }

    • 133. Landing for silent post
      <apex:form >
      <apex:actionFunction name="callReceipt" action="{!initi}" /> …
      <div id="waitingBlock" >
      </apex:outputText>
      <div id="imgBlock" style="padding-left:100px">
      <img src="{!URLFOR($Resource.styleszip,'/images/waiting_spin.gif')}"></img></div>
      </div> <!-- waitingBlock -->
      </apex:form>
      … and the controller
      public class StoreReceiptController{
      public PageReference initPage(){
      reason = ApexPages.currentPage().getParameters().get('reason');
        if(VerifySignature()){
      if(reason == '100'){
      receiptFwd = new PageReference('/‘…&reason='+status );
      }else{
      //Read the reason code and redirect the user to credit card page
      receiptFwd = new PageReference('/apex/creditcardform?...&reason='+status );
      }

    • 134. Key Take Aways
      • You can run a very complex, mission-critical application on Force.com.
      • 135. Taking advantage of force.com features can help you achieve your goals.
      • 136. Use AppExchange applications, SAAS solutions to extend you business functionality.
      • 137. Use Apex and Visualforce to extend stock Salesforce.com functionality
      and tailor user experience.
    • 138. Question & Answer
      Emin Gerba
      Salesforce.com
      Director, Software Engineering
      Samarpan Jain
      Salesforce.com
      Principal Architect
    • 139. Under the Hood of a Salesforce.com Business Application
    • 140. Visit the Developer Training and Support Booth in Force.com Zone
      D I S C O V E R
      Developer training, certification and support resources
      that help you achieve
      S U C C E S S
      Find us in the Partner Demo Area of
      Force.com Zone 2nd Floor Moscone West
      Learn about Developer Certifications
      Discover Developer Learning Paths
    • 141. Remember. . .
      • Check Chatter for additional session information
      • 142. Get your developer Workbooks and Cheat Sheets in the Force.com Zone
      • 143. Visit for more information related to this topic
      Don’t forget the survey!
    • 144. How Could Dreamforce Be Better? Tell Us!
      Log in to the Dreamforce app to submit
      surveys for the sessions you attended
      Use the Dreamforce Mobile app to submit surveys
      OR
      Every session survey you submit is a chance to win an iPod nano!