init (JS API v2)
Version 2 API only.
init
Method Signature | void init(merchantConfig); |
Description | Initializes the shopping cart. This is the very first method that must be called when using the ultraCart module. |
Parameters | merchantConfig – see the table below for configuration options |
Result | void |
Configuration Options
The configuration options passed to init is a hash. The hash is complex, but it is also powerful and concise.
We show you below an example, which demonstrates the hierarchy, and then explain each section.
Merchant Level Properties
Property | Required | Default | Explanation | Examples |
merchantId | YES | – | Your merchant ID | "DEMO" |
screenBrandingThemeCode | NO | 'DFLT' | Your screen branding code, if you use one. The JS API doesn't use the screen branding code, but if you provide one, it will attach it to the cart object. This will determine how receipt and upsell pages appear downstream. | 'DFLT','WHATEVER','MY2NDTHEME' |
isCheckoutPage | NO | false | You'll almost always want this to be true. It's provided in the event you wish to use the JS API to make item queries. When doing that, it's faster to avoid initializing the cart. If true, additional code is run during init() to populate shipping methods and such. This must be true if you are collecting address information, displaying shipping, or finalizing an order. | true or false |
checkoutSite | NO | 'secure.ultracart.com' | this server name is only used during checkout after you submit your cart. It is the url that will host your receipt and upsell after pages. You may omit this, and checkout will proceed to secure.ultracart.com. If you provide a value, it must be an SSL alias that points to secure.ultracart.com (Custom SSL Certificate). | 'www.mystore.com' |
remoteApiUrl | NO | secure.ultracart.com/cgi-bin/UCCheckoutAPIJSON | This is a critical setting. See XHR Issues and the Relay Script | location.protocol + "//" + location.hostname + "/cgi-bin/UCCheckoutAPIJSON", |
debugMode | NO | false | set to true to see debugging out in the browser console | true,false |
verboseAjax | NO | false | set to true to see A LOT of debugging output | true,false |
addressPriority | NO | 'shipping' | Many web sites only wish to collect shipping or billing, but not both. Some sites also wish to show one address and hide the other unless the customer selects a check box. When the | 'shipping','billing' |
updateShippingOnAddressChange | NO | false | if this is true, shippingFields must be mapped below or no events will fire. if shipping fields are mapped (see mappings below), then when any of the required html fields change, and if there is enough information present, then the script will refresh the shipping methods. Setting this to true will allow your checkout to constantly update shipping estimates as address information is provided. | true,false |
shippingCountries | NO | null | This property expects an array of strings which are countries. By default, when the cart initializes, it makes a call to getAllowedCountries to populate the country dropdowns with allowed countries. This is dynamic and easy to use, but requires an additional ajax call. If speed is a concern, or you ship to one or two countries, you may provide them here and eliminate the extra round trip during the init phase | ['United States','Canada'] |
billingCountries | NO | null | same as shippingCountries above, but for billing | ['United States','Canada'] |
unifiedAffiliateTracking | NO | false | set this to true if you're using a custom ssl certificate (NOT secure.ultracart.com) and you have affiliates When true, a script is dynamically inserted into the head element. It in turn makes a call to the checkout site which does some cookie magic to unify affiliates. It seems like a lot of work, but tracking affiliates is a complex business. | |
doNotTestRemoteConnection | NO | false | When the page initializes, a test call is made to the remote server. This helps identify relay problems and prints out very clear debugging information. Once your web site is complete, and you're certain there are no connectivity issues, you may set this to true to eliminate a single round trip. |
Events
The ultraCart object will fire events during the shopping experience. These events allow your checkout page to update asynchronously. You register functions as listeners during the init call by passing them in as part of the configuration. See the above example for the syntax.
Below, the term 'renderer' is used frequently. A renderer is nothing more than a javascript function that takes zero parameters and updates the web page in some fashion. Here's an example of a renderer that updates the coupon section of a page.
/** * renders the coupons that are applied to the current transaction */ function renderCoupons(){ var coupons = ultraCart.getCart().coupons; var html = ''; if(coupons.length > 0){ html += "<div class='couponHeader'>Applied Coupons:</div>"; for(var i = 0; i < coupons.length; i++){ var coupon = coupons[i]; html += "<div><span style='float:left;vertical-align:middle'>" + coupon.couponCode + "</span><span class='coupon_link' onclick='removeCoupon(\"" + coupon.couponCode + "\")'><img src='images/delete_coupon.png' alt='remove coupon' style='float:left;vertical-align:middle' /><\/span><\/div>"; } } var couponsApplied = jQuery('#couponsApplied'); couponsApplied.html(html); }
The online demo has numerous renderXXX methods. Review the cart_X.X.js script. (At the time of this writing, the version was cart_1.0.js).
The ultraCart object has the following events defined:
var EVENT_CART_CHANGE = 'cartchange'; var EVENT_CART_READY = 'cartready'; var EVENT_SHIPPING_CHANGE = 'shippingchange'; var EVENT_ADDRESS_CHANGE = 'addresschange'; var EVENT_SHIPPING_METHODS_CHANGE = 'shippingmethodschange'; var EVENT_PROFILE_CHANGE = 'profilechange'; var events = { EVENT_CART_CHANGE:EVENT_CART_CHANGE, EVENT_CART_READY:EVENT_CART_READY, EVENT_SHIPPING_CHANGE:EVENT_SHIPPING_CHANGE, EVENT_ADDRESS_CHANGE:EVENT_ADDRESS_CHANGE, EVENT_SHIPPING_METHODS_CHANGE:EVENT_SHIPPING_METHODS_CHANGE, EVENT_PROFILE_CHANGE:EVENT_PROFILE_CHANGE };
Event | Constant | When is it fired | What typically is updated |
cartchange | ultraCart.events.EVENT_CART_CHANGE | whenever a remote method call returns an updated cart. for example, after addItem() or updateItem() | usually most renderers (functions acting as listeners) will be assigned to this event, since it's impossible to tell what might have changed during the round trip to the server. |
cartready | ultraCart.eventss.EVENT_CART_READY | this is fired once during the initialization. most renderers will listen to this, and this is also a good place to assign one-time functions that need a cart object to run. | |
shippingchange | ultraCart.events.EVENT_SHIPPING_CHANGE | this event fires when a customer selects a shipping method. | A shipping method change will usually update the shipping section, and the summary section |
addresschange | ultraCart.events.EVENT_SHIPPING_CHANGE | this event fires when a customer changes their address information. Internally, the ultraCart script will listen to this event to determine if the shipping estimates need updating. | In our experience, this event usually doesn't have listeners. There not much visually that needs doing when the address changes. |
shippingmethodschange | ultraCart.events.EVENT_SHIPPING_METHODS_CHANGE | fires when estimateShipping() returns | Whenever this fires, the dropdown box of available shipping methods will need to update. Also, if a selected shipping method is now unavailable, a message may need displaying. |
profilechange | ultraCart.events.EVENT_PROFILE_CHANGE | This is fired if loginCustomerProfile() returns successfully. | If the customer logs in using a customer profile, many of the prices will change, so cart items will need refreshing, as well as shipping prices. |
Field Mapping
Any fields mapping in the field mapping section will be automatically managed by the ultraCart object. During the init
phase, any mapped html elements will have a blur
method attached to them that, when fired, will save the field value to the cart object (type ultraCart.getCart()
in your browser console. Then, as long as your finalize method contains a call to saveFieldElements()
, all information will be saved to the cart. The field mappings are also required to fire EVENT_ADDRESS_CHANGE events and automatically update shipping.
The field mappings work really well. The only problem reported with them is when developers accidentally stomp on the blur method. The ultraCart script will attach the blur events using jQuery namespaced events. A code snippet is show below. Any events created by the ultraCart script will use the .ultraCart
namespace. Please use namespaces, and avoid overwriting or un-binding any events in the .ultraCart
namespace.
jQuery(element).bind('blur.ultraCart', ucMakeBindShippingField(field, element));
The syntax for mapping html elements to cart is cartField→htmlElementId (see the example above).
The follow cart fields may be tied to html elements:
- shipToAddress1
- shipToAddress2
- shipToCity
- shipToCompany
- shipToCountry
- shipToEveningPhone
- shipToFirstName
- shipToLastName
- shipToPhone
- shipToPostalCode
- shipToResidential
- shipToState
- shipToTitle
- billToAddress1
- billToAddress2
- billToCity
- billToCompany
- billToCountry
- billToDayPhone
- billToEveningPhone
- billToFirstName
- billToLastName
- billToPostalCode
- billToState
- billToTitle
- creditCardExpirationMonth
- creditCardExpirationYear
- creditCardNumber
- creditCardType
- creditCardVerificationNumber
- purchaseOrderNumber
- mailingListOptIn
- customField1
- customField2
- customField3
- customField4
- customField5
- customField6
- customField7
Also, if provided, these fields are used to update shipping. The country, state, and zip fields are required to trigger an estimated shipping update, and the address1 and address2 fields just zero in the shipping costs further.
- shipToAddress1
- shipToAddress2
- shipToCity
- shipToState
- shipToZip
- shipToCountry
the shipToCountry is required to calculate taxes. If you only ship to the United States, and therefore do not have a country html field, make sure you set the cart.shipToCountry somewhere in your code. Failing to do that will prevent taxes from calculating. Since the cart must be fully initialized before you set the country, a great way to do this is to create a javascript function and add it as a listener to the cartready event.
function stuffToDoWhenCartIsReady(){ ultraCart.getCart().shipToCountry = 'United States'; } // and then, within your merchant config, add the method as a listener... var merchantCartConfig = { /* LOTS OF OTHER CONFIGURATION OPTIONS HERE (NOT SHOWN) */ listeners:{ "cartready":[stuffToDoWhenCartIsReady, renderCartVisibility, renderCartItems, renderSubtotal, renderCoupons, renderSummary, renderShipping, renderGoogleCheckout, renderPayPalCheckout], "cartchange":[renderCartVisibility, renderCartItems, renderSubtotal, renderCoupons, renderSummary, renderGoogleCheckout, renderPayPalCheckout], "shippingchange":[renderSummary], "addresschange":[], "shippingmethodschange":[renderShipping] } } ultraCart.init(merchantCartConfig);
Formatting
The merchant configuration contains a section for number formatting:
numberFormatConfig:{ hasCurrency:true, currentPosition:ultraCart.numberFormat.LEFT_INSIDE, currencySymbol:'$', negativeFormat:ultraCart.numberFormat.LEFT_DASH, roundToPlaces:2, places:2, truncate:false, hasSeparators:true, separatorValue:ultraCart.numberFormat.COMMA, decimalValue:ultraCart.numberFormat.PERIOD },
Constants available for the numberFormatConfig
- COMMA = ','
- PERIOD = '.'
- DASH = '-'
- LEFT_PAREN = '('
- RIGHT_PAREN = ')'
- LEFT_OUTSIDE - currency position will be to the left of the number and outside any parens (if parenthesis are configured to show), example: $(453.23)
- LEFT_INSIDE - currency position will be to the left of the number and inside any parens (if parenthesis are configured to show), example: ($453.23)
- RIGHT_INSIDE - currency position will be to the right of the number and outside any parens (if parenthesis are configured to show), example: (453.23) EUR
- RIGHT_OUTSIDE - currency position will be to the right of the number and inside any parens (if parenthesis are configured to show), example: (453.23 EUR)
- LEFT_DASH - for negative values, puts the dash sign before the value
- RIGHT_DASH - for negative values, puts the dash sign after the value
- PARENTHESIS - for negative values, surrounds the values with parenthesis
The entire numberFormatConfig is optional, as is any configuration directive within it. If you omit the numberFormatConfig key from your configuration, it will not be available at all. However, if you supply an empty numberFormatConfig, it will be initialized using all defaults.
Configuration | Default | What does the UltraCart demo use? | Explanation |
hasCurrency | false | true | if true, the currency symbol is printed when |
currentPosition | LEFT_OUTSIDE | LEFT_INSIDE | where to put the currency symbol |
currencySymbol | '$' | '$' | |
negativeFormat | LEFT_DASH | LEFT_DASH | how to display negative numbers. Choices are LEFT_DASH, RIGHT_DASH, and PARENTHESIS |
roundToPlaces | 2 | 2 | when |
places | 2 | 2 | places is used by truncate to determine where to cut things off |
truncate | false | false | Don't set this to true. Ever. Don't truncate things. The |
hasSeparators | true | false | If true, the separatorValue is added to formatted values. It's a matter of preference, and only really comes into play if your checkout page deals with large values. The demo has this set to false, but it should probably be true. Wouldn't hurt. |
separatorValue | COMMA | COMMA | The value used to denote thousands. For United States, the comma is used. For European states, the period is used. |
decimalValue | PERIOD | PERIOD |
By setting this configuration, developers gain access to utility methods for display currencies on their web page:
ultraCart.numberFormat.toCurrency(val)
ultraCart.numberFormat.toPercentage(val)
Here is an example renderer that makes heavy use of the numberFormat.
function renderSummary() { var nf = ultarCart.numberFormat; var c = ultraCart.getCart(); if (c.items.length == 0) { jQuery('#summaryContainer').hide(); return; } else { jQuery('#summaryContainer').show(); } // shipping must be dealt with specially. to prevent customers from gaming the system, there are several instances // where the price of shipping is reset. So, when rendering, always lookup the shipping method and calculate the cost // from that rather than using the cart.shippingHandlingWithDiscount, although the latter would be simpler var totalTax = c.tax; var shippingTotal = ' '; // don't display anything if there's no choice var total = c.subtotalWithDiscount + c.tax; var shippingChoice = ultraCart.getShippingChoice(); if (shippingChoice) { totalTax += shippingChoice.tax; if (shippingChoice.cost == 0) { shippingTotal = '<strong>FREE Shipping!</strong>'; } else { shippingTotal = nf.toCurrency(shippingChoice.cost); } total += shippingChoice.cost; total += shippingChoice.tax; } jQuery('#summarySubtotal').html("<div class='summaryLabel'>Subtotal:<\/div><div class='summaryField'>" + nf.toCurrency(c.subtotalWithDiscount) + "<\/div>"); jQuery('#summaryTax').html("<div class='summaryLabel'>Tax:<\/div><div class='summaryField'>" + (totalTax == 0 ? "<span class='tax'>No Sales Tax!</span>" : nf.toCurrency(totalTax)) + "<\/div>"); jQuery('#summaryShipping').html("<div class='summaryLabel'>Shipping:<\/div><div class='summaryField'>" + shippingTotal + "<\/div>"); jQuery('#summaryTotal').html("<div class='summaryLabel'>Total:<\/div><div class='summaryField'>" + nf.toCurrency(total) + "<\/div>"); }