Shipping Fee Calculator

Using the Shipping Fee Calculator, you can configure your Store to collect estimated shipping charges from your customers who purchase physical products. There are two ways you can configure the Shipping Fee Calculator:

  • FastSpring can charge a simple flat rate for any order containing physical products (regardless of the number of items in the order or quantities).
  • Alternatively, you can provide FastSpring with a JavaScript snippet to calculate the estimated shipping charges based on the contents of the order (including the customer’s country and postal code).

Shipping Fee Conditions

FastSpring only collects estimated shipping charges when an order includes products or bundles with a product format of Digital Product and Shipment or Physical Shipment. For orders containing only products whose format is Digital Product or Software as a Service, or containing only subscription products, shipping charges are not collected.

On the detail page for each product or bundle, the product format appears in the Fulfillment section. You change it by clicking Change Product Format.

Web Storefront Customer Experience

Here is an illustration of how the estimated shipping charges can appear in your Web Storefront:


Note The optional icon for Shipping Charges pictured above is for illustrative purposes only. No icon is provided by default, but you can optionally upload one when enabling shipping fee charges (see below).

Enabling Shipping Fee Charges

Shipping fee charges are enabled at the Store level. When you enable the Shipping Fee Calculator, all Storefronts in the Store begin collecting estimated shipping charges for physical products.

To enable the Shipping Fee Calculator

  1. From the FastSpring App, select the Developer Tools menu. The Extensionstab is selected by default.
  1. Click the Shipping Fee Calculator card. A description of the extension appears.
  2. Click Setup. The configuration fields appear.
    • Title – Enter the name of the line item for estimated shipping charges that will appear to customers on the Web Storefront when a product or a bundle with a physical format is in the cart. For example, you might enter “Shipping Charges.” You can optionally click the drop-down selector and enter the Title in each desired language.
    • Short Description – Optionally, enter a brief description of the estimated shipping charges to appear on the Web Storefront. This field accepts markdown for rich text support. You can optionally click the drop-down selector and enter the Short Description in each desired language.
    • Long Description – Optionally, enter a longer explanation of the estimated shipping charges. Customers who click the title text for the estimated shipping charge will see a popup window with the contents of this field. This field accepts markdown for rich text support. You can optionally click the drop-down selector and enter the Long Description in each desired language.
    • Icon – Optionally, click Choose File and browse to and select an image file to appear next to the estimated shipping charge Title on a Web Storefront.
    • Shipping Fee Calculation Method – Click the drop-down and select Flat Rate Fee or Shipping Fee Script.  Note Due to server caching, it may take several minutes before you will be able to see the effects of changes to the shipping fee calculator. If you test and find that your changes do not seem to have taken effect, please allow up to ten minutes for the cache to update.
    • If you want to simply charge a single flat rate for all orders that include at least one physical product or bundle, select Flat Rate Fee. You can enter the amount of the estimated shipping charges in each currency supported by your Store. You must enter the amount in at least the Store’s base currency (usually USD).
    • If you want to supply a shipping fee calculation script to parse the JSON order object data in real-time during order processing and return the estimated shipping charge amount to be added to the order, select Shipping Fee Script. You can then enter or paste in the script, as shown in the example below. Be sure to check out the Coding Guidelines for the Calculation Script and our available Example Shipping Fee Calculation Scripts.
  1. Click Enable.

Coding Guidelines for the Calculation Script

Here are some essential guidelines for use when creating your shipping fee calculation script.

  • The shipping script does not support ECMAScript 6 language features.
  • You can define functions within the script and use them as you would within other scripts.
  • Due to server caching, it may take several minutes before you will be able to see the effects of changes to the script. If you test and find that your changes do not seem to have taken effect, please allow up to ten minutes for the cache to update.
  • The shipping script does not support external libraries or frameworks like jQuery.
  • Your script should return “false” in cases where you do not want to add shipping charges to the order at all.
  • Your script should return either a number or an object with three-letter currency codes as properties, and numbers as values, as in the following example: Example of valid return values for your script return 5.50; // OR… // currency codes are not case sensitive return { “USD”: 14, “eur”: 20 };

Examples and Resources

Here are some resources that may help you in developing your own customized script. These include an example of the order object, two examples of a useful function for getting the product quantity from the order object, and three example scripts.

The following JSON string is an example of the order object that is passed to the shipping script. Your script can use the data in this object to calculate the amount of estimated shipping charges to be collected for the order. Order object example

{
  "order": {
    "currency": "USD",
    "country": "US",
    "taxExemptionAllowed": false,
    "total": "$0.00",
    "totalValue": 0.0,
    "tax": "$0.00",
    "taxValue": 0.0,
    "totalWithTax": "$0.00",
    "totalWithTaxValue": 0.0,
    "discountTotal": "$0.00",
    "discountTotalValue": 0.0,
    "discountTotalPercentValue": 0.0,
    "taxPriceType": "none",
    "taxType": "US",
    "groups": [
      {
        "items": [
          {
            "selected": false,
            "path": "physical",
            "pid": "physical",
            "quantity": 1,
            "price": "$2.00",
            "priceValue": 2.0,
            "priceTotal": "$2.00",
            "priceTotalValue": 2.0,
            "unitPrice": "$2.00",
            "unitPriceValue": 2.0,
            "unitDiscountValue": 0.0,
            "discountPercentValue": 0.0,
            "discountTotal": "$0.00",
            "discountTotalValue": 0.0,
            "total": "$2.00",
            "totalValue": 2.0,
            "quantityEditable": true,
            "removable": true,
            "image": "https://localhost:8443/icon.png",
            "display": "Physical 1",
            "description": {},
            "pricing": {
              "quantity": "allow"
            },
            "groups": [],
            "productFormat": "physical",
            "product": "physical",
            "variation": "physical"
          },
          {
            "selected": false,
            "path": "test3",
            "pid": "test3",
            "quantity": 1,
            "price": "$5.00",
            "priceValue": 5.0,
            "priceTotal": "$5.00",
            "priceTotalValue": 5.0,
            "unitPrice": "$5.00",
            "unitPriceValue": 5.0,
            "unitDiscountValue": 0.0,
            "discountPercentValue": 0.0,
            "discountTotal": "$0.00",
            "discountTotalValue": 0.0,
            "total": "$5.00",
            "totalValue": 5.0,
            "quantityEditable": true,
            "removable": true,
            "image": "https://localhost:8443/icon.png",
            "display": "Physical 2",
            "description": {},
            "pricing": {
              "quantity": "allow"
            },
            "groups": [],
            "productFormat": "physical",
            "product": "test3",
            "variation": "test3"
          }
        ],
        "driver": "demo",
        "required": false,
        "type": "add",
        "selections": false
      },
      {
        "items": [
          {
            "selected": false,
            "path": "test1",
            "pid": "test1",
            "quantity": 1,
            "price": "$4.59",
            "priceValue": 4.59,
            "priceTotal": "$4.59",
            "priceTotalValue": 4.59,
            "unitPrice": "$4.59",
            "unitPriceValue": 4.59,
            "unitDiscountValue": 0.0,
            "discountPercentValue": 0.0,
            "discountTotal": "$0.00",
            "discountTotalValue": 0.0,
            "total": "$4.59",
            "totalValue": 4.59,
            "quantityEditable": false,
            "removable": true,
            "image": "https://localhost:8443/icon.png",
            "display": "Digital 1",
            "description": {
              "summary": "Test",
              "full": "Test"
            },
            "pricing": {
              "quantity": "lock"
            },
            "groups": [],
            "productFormat": "digital",
            "product": "test1",
            "variation": "test1"
          },
          {
            "selected": false,
            "path": "test2",
            "pid": "test2",
            "quantity": 1,
            "price": "$16.99",
            "priceValue": 16.99,
            "priceTotal": "$16.99",
            "priceTotalValue": 16.99,
            "unitPrice": "$16.99",
            "unitPriceValue": 16.99,
            "unitDiscountValue": 0.0,
            "discountPercentValue": 0.0,
            "discountTotal": "$0.00",
            "discountTotalValue": 0.0,
            "total": "$16.99",
            "totalValue": 16.99,
            "quantityEditable": true,
            "removable": true,
            "image": "https://localhost:8443/icon.png",
            "display": "Digital 2",
            "description": {
              "summary": "Test",
              "full": "Test"
            },
            "pricing": {
              "quantity": "allow"
            },
            "groups": [],
            "productFormat": "digital",
            "product": "test2",
            "variation": "test2"
          },
          {
            "selected": false,
            "path": "physical-bundle",
            "pid": "physical-bundle",
            "quantity": 1,
            "price": "$6.00",
            "priceValue": 6.0,
            "priceTotal": "$6.00",
            "priceTotalValue": 6.0,
            "unitPrice": "$6.00",
            "unitPriceValue": 6.0,
            "unitDiscountValue": 0.0,
            "discountPercentValue": 0.0,
            "discountTotal": "$0.00",
            "discountTotalValue": 0.0,
            "total": "$6.00",
            "totalValue": 6.0,
            "quantityEditable": true,
            "removable": true,
            "bundle": true,
            "display": "Physical Bundle",
            "description": {},
            "pricing": {
              "quantity": "allow"
            },
            "groups": [
              {
                "display": "Physical Bundle",
                "items": [
                  {
                    "selected": false,
                    "path": "physical",
                    "pid": "physical",
                    "quantity": 1,
                    "price": "$0.00",
                    "priceValue": 0.0,
                    "priceTotal": "$0.00",
                    "priceTotalValue": 0.0,
                    "unitPrice": "$0.00",
                    "unitPriceValue": 0.0,
                    "unitDiscountValue": 0.0,
                    "discountPercentValue": 0.0,
                    "discountTotal": "$0.00",
                    "discountTotalValue": 0.0,
                    "total": "$0.00",
                    "totalValue": 0.0,
                    "quantityEditable": true,
                    "removable": true,
                    "image": "https://localhost:8443/icon.png",
                    "display": "Physical 1",
                    "description": {},
                    "pricing": {
                      "quantity": "allow"
                    },
                    "groups": [],
                    "productFormat": "physical",
                    "product": "physical",
                    "variation": "physical"
                  },
                  {
                    "selected": false,
                    "path": "test3",
                    "pid": "test3",
                    "quantity": 1,
                    "price": "$0.00",
                    "priceValue": 0.0,
                    "priceTotal": "$0.00",
                    "priceTotalValue": 0.0,
                    "unitPrice": "$0.00",
                    "unitPriceValue": 0.0,
                    "unitDiscountValue": 0.0,
                    "discountPercentValue": 0.0,
                    "discountTotal": "$0.00",
                    "discountTotalValue": 0.0,
                    "total": "$0.00",
                    "totalValue": 0.0,
                    "quantityEditable": true,
                    "removable": true,
                    "image": "https://localhost:8443/icon.png",
                    "display": "Physical 2",
                    "description": {},
                    "pricing": {
                      "quantity": "allow"
                    },
                    "groups": [],
                    "productFormat": "physical",
                    "product": "test3",
                    "variation": "test3"
                  }
                ],
                "driver": "physical-bundle",
                "required": false,
                "type": "bundle",
                "selections": false
              }
            ],
            "productFormat": "digital",
            "product": "physical-bundle",
            "variation": "physical-bundle"
          }
        ],
        "driver": "demo",
        "required": false,
        "type": "add",
        "selections": false
      }
    ],
    "coupons": [],
    "payments": [],
    "selections": false,
    "creationTime": 0
  },
  "messages": [],
  "phrases": {
    "MakeDefault": "Make Default",
    "Store": "Store",
    "Edit": "Edit",
    "SubscriptionAddonTerms.Single": "Renews along with subscription",
    "ChangePlanAndQuantity": "Change Plan & Quantity",
    "ViewDetails": "View Details",
    "Month": "month",
    "NoActiveSubscriptions": "No active subscriptions",
    "AutorenewOffWarning": "If automatic renew is turned off you will be required to enter payment details every time this subscription renews. Turn off automatic renew?",
    "Unexpected": "An unexpected error occurred.  Please try again, or refresh the page in your browser.",
    "BankPaymentWireInstructionTitle": "Bank Transfer Instructions",
    "PaymentVariant.jcb": "JCB",
    "BankPaymentWireInstructionAccountHolder": "Beneficiary/Account Holder",
    "TryAgain": "Try Again",
    "PaymentVariant.visa": "Visa",
    "Weeks": "weeks",
    "ErrorServer": "An unexpected error occurred. Please try again later.",
    "CancelSubscription": "Cancel Subscription",
    "CardDeclined": "Your credit card was declined. Please try another card, or choose a different form of payment.",
    "EnterTaxInformationJp": "Enter National Tax ID",
    "TaxInformationEU": "Includes VAT",
    "CardSecurityCodeHintAmex": "The CID is a 4 digit number printed on the front of your card.",
    "EnterZipToCalculate": "Enter ZIP",
    "FieldErrors": "Please correct the highlighted fields.",
    "DownloadNow": "Download Now",
    "Refunds": "Refunds",
    "Starting": "starting",
    "Close": "Close",
    "Week": "week",
    "Orders": "Orders",
    "PaymentType.ideal": "iDEAL",
    "BillingHistory": "Billing History",
    "ShippingTitle": "Shipping Address",
    "ConfirmCancelSubscription": "Are you sure you want to cancel the subscription?",
    "YouSaved": "You saved",
    "EUVatExemptInvalid": "Your company's VAT identification number could not be validated.",
    "JpConsumptionTaxExemptApplied": "Your company's National Tax ID has been applied, and the Consumption Tax charges have been removed.",
    "CardExpireYearPlaceholder": "YY",
    "Days": "days",
    "TermsOfSale": "Terms of Sale",
    "ShippingCity": "City",
    "WaitRedirectTitle": "Please wait...",
    "PaymentType.card": "Credit / Debit Card",
    "PaymentOption.wire": "Wire Transfer",
    "GetInvoice": "Get Invoice",
    "SavePaymentDetails": "Save Payment Details",
    "FirstName": "First Name",
    "TaxValue": "Tax:",
    "LightBox.UpgradeAvailable": "Upgrade available",
    "BankPaymentWireInstructionIban": "IBAN",
    "WaitRedirectAbout": "We are redirecting your browser, please wait.",
    "BankPaymentWireInstructionDialogTitle": "Bank Transfer Instructions",
    "CouponCode": "Coupon Code",
    "ForFree": "for free",
    "CardInfoBRL": "This purchase is subject to applicable Brazilian laws and rules of an international transaction",
    "Year": "year",
    "BankPaymentWireInstructionBankAddress": "Address",
    "EUVatExemptInfo": "If you are placing an order on behalf of a company in the EU, enter the company's VAT identification number and the VAT charges will be removed.",
    "Footer.ThisPurchase": "This purchase and product fulfillment are through ",
    "YourProfile": "Your Profile",
    "BillDescriptor": "Charges will appear on your bill as",
    "Add": "Add",
    "PaymentOption.sofort": "Sofort",
    "Email": "Email",
    "DeleteItem": "Remove",
    "Pay": "Pay",
    "JpConsumptionTaxAbout": "Prices and order total includes Consumption Tax.",
    "RegionAF": "Africa",
    "VolumeDiscountsAvailable": "Volume Discounts Available",
    "InactiveSubscriptions": "Inactive Subscriptions",
    "ConfirmUpdatePaymentMethod": "Are you sure you want to change your default payment method?",
    "Test": "Test",
    "CardExpired": "Your credit card has expired. Please try another card, or choose a different form of payment.",
    "EUVatExemptApplied": "Your company's VAT identification number has been applied, and VAT charges have been removed.",
    "SavingsTitle": "You Save",
    "Years": "years",
    "Failed": "Failed",
    "CardSecurityCodePlaceholder": "CVC",
    "EnterPaymentDetails": "Enter Payment Details",
    "For": "for",
    "Shipment": "Shipment",
    "Free": "Free",
    "ShippingStreet": "Address",
    "CardExpireMonth": "Card Expire Month",
    "FirstCharge": "First charge:",
    "PlaceYourOrder": "Place Your Order",
    "PaymentDetails": "Payment Details",
    "SubmitLocale": "Submit",
    "LastName": "Last Name",
    "Ending": "Ends on",
    "UnsupportedInTestMode": "Not supported while in testing mode.",
    "UseThis": "Use This",
    "Subscriptions": "Subscriptions",
    "Addons": "Addons",
    "Forbidden": "Could not validate provided information",
    "OrderEmpty": "Your Order Is Empty",
    "Continue": "Continue",
    "CardNumberPlaceholder": "Card Number",
    "BankPaymentWireInstructionDescription": "When paying by bank transfer, your product cannot be delivered until payment is received in full. After we receive payment, please allow 3 business days for processing.",
    "EUVatDialogTitle": "VAT Information",
    "ManageAccount": "Account Management",
    "SubscriptionManagement": "Full Terms and Subscription Management",
    "Abandonment.PurchaseWithDiscount": "Purchase With Discount",
    "Abandonment.CompleteYourOrder": "Complete Your Order",
    "NextCharge": "Next charge:",
    "CardCvvInvalid": "Your credit card security code (CVC) is invalid.",
    "PaymentType.wire": "Wire Transfer",
    "AccountManagement": "Account Management",
    "Coupon": "Coupon Code",
    "CouponCall": "Enter Promotional Code",
    "TaxInformationJp": "Includes Consumption Tax",
    "OrderOn": "Order on",
    "Cancelled": "Cancelled",
    "PaymentPending": "Payment Pending",
    "RegionAS": "Asia",
    "RegionAM": "Americas",
    "Every": "Every",
    "JpNationalTaxId": "National Tax ID",
    "PaymentType.free": "FREE",
    "Address": "Address",
    "ChooseCountry": "Choose Country",
    "AccountDetailsPaymentMethods": "Account Details and Payment Methods",
    "PostOrderExpectationDescription": "We are sending a copy of all important order information to your email address.",
    "Remove": "Remove",
    "OrderSubtotal": "Subtotal",
    "PaymentMethods": "Payment Methods",
    "BankPaymentWireInstructionViewNowButton": "View Instructions Now",
    "ConfirmOk": "Yes",
    "PaymentType.sepa": "Direct Debit",
    "CancelledAtBank": "Payment cancelled.",
    "AutoRenewCollectedInfomarion": "You payment information was securely stored for automatic renewals",
    "Debit": "Debit",
    "OrderSectionTitle": "Your Order",
    "PaymentOption.sepa": "Direct Debit",
    "EditProfile": "Edit Profile",
    "BankTransferNote": "When paying by bank transfer, your product cannot be delivered until payment is received in full. After we receive payment, please allow 3 business days for processing. Payment Instructions",
    "ConfirmCancel": "Cancel",
    "Card": "Card",
    "Calculating": "Calculating",
    "FreeTrialUntil": "Free trial until",
    "ShippingRegion": "State",
    "BankPaymentWireInstructionAccountNo": "Account No",
    "EUVatID": "VAT ID",
    "Next": "Next",
    "ShippingPostalCode": "Postal Code",
    "PaymentInformation": "Payment Information",
    "Country": "Country",
    "PayNow": "Pay Now",
    "Current": "Current",
    "JpConsumptionTaxDialogTitle": "Consumption Tax Information",
    "ActiveSubscriptions": "Active Subscriptions",
    "Complete": "Complete",
    "PaymentOption.giropay": "GiroPay",
    "PaymentType.amazon": "Pay with Amazon",
    "BankPaymentWireInstructionBank": "Bank",
    "JpConsumptionTaxtExemptInvalid": "Your company's National Tax ID could not be validated.",
    "PaymentType.paypal": "PayPal Checkout",
    "RenewsAutomatically": "Renews automatically by the seller",
    "BankPaymentWireInstructionDialogIntroduction": "Initiate a Bank Transfer via your own bank to:",
    "NoInactiveSubscriptions": "No inactive subscriptions",
    "PaymentOption.paypal": "PayPal Account",
    "ConfirmUpdateSubscriptionPaymentMethod": "Are you sure you want to change the default subscription payment method?",
    "EnterEmail": "Please enter your email address to continue",
    "RegionOC": "Oceania",
    "Footer.TrustedReseller": ", a trusted reseller for this store.",
    "PaymentSectionTitle": "Your Payment",
    "HideSubscriptionTerms": "Hide subscription terms",
    "Ended": "Ended",
    "PostOrderExpectationTitle": "Thank you for your order!",
    "YourOrderIs": "Your order is",
    "Manage": "Manage",
    "BankPaymentWireInstructionSwiftCode": "Swift-Code",
    "Default": "Default",
    "PaymentVariant.discover": "Discover",
    "PaymentOption.amazon": "Amazon",
    "LastCharge": "Last charge",
    "ShowHistory": "Show billing history",
    "Day": "day",
    "FailurePayPalCountryUpdate": "Your PayPal account's country was different.  We've updated your order using the country on your PayPal account.  Please review the total and try again.",
    "CardNumber": "Card Number",
    "SubscriptionTerms": "Subscription terms",
    "EnterTaxInformationEU": "Enter VAT ID",
    "PaymentOption.alipay": "Alipay",
    "PaymentVariant.amex": "American Express",
    "ApplyCoupon": "Apply",
    "Tax": "Tax",
    "ErrorChoosePaymentMethod": "Please choose a payment method.",
    "EndingWith": "Ending with",
    "ChooseLanguage": "Choose Language",
    "EmailFormInstructions": "Please enter the email address associated with this account",
    "PaymentType.giropay": "GiroPay",
    "ChooseLocale": "Choose Country / Language...",
    "TaxNotApplicable": "Not Applicable",
    "PaymentType.alipay": "Alipay",
    "BillingPostalCode": "Billing Postal Code",
    "CardSecurityCodeHint": "The CVC Number is a 3 digit number on the back of your card.",
    "PaymentType.sofort": "Sofort",
    "JpConsumptionTaxExemptInfo": "If you are placing an order on behalf of a company in Japan, enter the company's National Tax ID and the Consumption Tax charges will be removed.",
    "MailingListSubscribe": "Get free updates about our products and offerings",
    "RenewEvery": "renew every",
    "Refunded": "Refunded",
    "ShippingPhoneNumber": "Phone Number",
    "AndEndingOn": "and ending on",
    "TaxUS": "Tax",
    "Months": "months",
    "Footer.WeUse": "We use industry-standard encryption to protect the confidentiality of your personal information.",
    "RenewsEvery": "Renews every",
    "City": "City",
    "EUVatAbout": "Prices and order total includes VAT.",
    "CardSecurityCode": "Card Security Code",
    "OrderInvoice": "Order Invoice",
    "ConfirmTitle": "Confirm",
    "Price": "Price",
    "AddPaymentMethod": "Add Payment Method",
    "Save": "Save",
    "FailureRisk": "We regret that your order could not be accepted. We value your business and would like to help you complete this order. Please contact us for assistance.",
    "LightBox.InYourCart": "In your cart",
    "CouponInvalid": "The promotional code you entered does not exist.",
    "OrderContainsAdhoc": "Payment details will be kept for future orders.",
    "CardsAccepted": "We accept",
    "PaymentInformationTitle": "Payment Information",
    "PaymentOption.ideal": "iDEAL",
    "Updating": "Updating",
    "ManageYourOrders": "Manage Your Orders",
    "PaymentOption.card": "Credit / Debit Card",
    "UpdatePaymentMethod": "Update payment method",
    "Credit": "Credit",
    "BankPaymentWireInstructionPaymentReference": "Payment Reference",
    "OrderReference": "Order Reference",
    "Inactive": "Inactive",
    "UpgradeAndContinue": "Upgrade and continue!",
    "TaxInformationUS": "+Tax",
    "on": "on",
    "PaymentVariant.mastercard": "Mastercard",
    "Bundle": "Bundle",
    "PrivacyPolicy": "Privacy Policy",
    "JpNationalTaxIdSubmit": "Submit",
    "Quantity": "Quantity",
    "RegionEUR": "Europe",
    "YourOrders": "Your Orders",
    "DownloadAction": "Download Now",
    "InvoiceLinkText": "View Invoice",
    "Today": "today",
    "CardExpireMonthPlaceholder": "MM",
    "ConfirmRemovePaymentMethod": "Are you sure you want to remove the payment method?",
    "ShippingAddress": "Shipping Address",
    "Total": "Total",
    "FailureGeneric": "An unexpected error occurred, and we are not currently able to accept payment.",
    "EUVatIDSubmit": "Submit",
    "OrderTotal": "Total",
    "On": "on"
  },
  "locks": [],
  "paymentOptions": [],
  "promotionOptions": [],
  "session": {
    "location": "https://localhost:8443/bm-store/demo*/session/demo",
    "sandbox": "https://localhost:8443/bm-store/demo**sandbox",
    "token": "new/1pCZzub0Ti0bVyHM3l337w",
    "primary": "demo",
    "id": "demo",
    "live": false
  },
  "variables": {
    "integrationBehaviourGA": "default",
    "collectingEmailCheckbox": "true",
    "cartCrossSellsPositionProduct": "belowdriver",
    "purchaseBtn": "addToCart",
    "confirmCancelBtnFontSize": "14px",
    "showCouponField": "true",
    "productImageSize": "large",
    "crossSellsPositionProduct": "belowdriver",
    "nortonDisplay": "large",
    "upSellsDisplay": "page",
    "popupHeadingAlign": "left",
    "showCompanyField": "disable",
    "offerTitleSize": "16px",
    "showVatLink": "true",
    "topbarFreezing": "false",
    "listUpSellsDisplay": "page",
    "upSellsPosition": "below",
    "cartUpSellsDisplay": "page",
    "panelHeaderTextColor": "#333",
    "countrySelector": "visible",
    "offerImageSizeInsideCart": "medium",
    "listUpSellsPosition": "below",
    "popupOnWindowClose": "false",
    "integrationBehaviourGTM": "default",
    "productTitle": "showDescription",
    "licenses": "true",
    "cartUpSellsPosition": "below",
    "requireEmail": "false",
    "panelHeaderColorNew": "#f5f5f5",
    "font": "Helvetica-Neue",
    "offerImageSizeOutsideCart": "large",
    "listCrossSellsPositionProduct": "belowdriver",
    "logo": "https://localhost:8443/icon.png"",
    "subscriptionUsePaymentMethodBtnFontSize": "14px",
    "popupTimeout": "10",
    "priceSize": "large",
    "showListCheckbox": "false",
    "textAlign": "left",
    "productTitleSize": "18px",
    "managePaymentMethodBtnFontSize": "14px",
    "popupTextAlign": "left",
    "forcePhoneNumberCollection": "false",
    "couponFieldExpanded": "true",
    "shortCheckout": "true",
    "savePaymentDetailsBtnFontSize": "14px",
    "footer": "© 1999-2020 Acme, Inc.. All rights reserved.",
    "popupOnTimeout": "false",
    "title": "Acme Store",
    "addPaymentMethodBtnFontSize": "12px",
    "forcePhysicalAddressCollection": "false",
    "popupButtonAlign": "left",
    "confirmOkBtnFontSize": "14px",
    "addToCartBtnFontSize": "14px",
    "crossSellsPositionStorefront": "below",
    "showEmailOnCartPage": "both",
    "manageSubscriptionBtnFontSize": "14px"
  },
  "country": "US",
  "countryDisplay": "United States",
  "countryRequiresPostalCode": true,
  "countryRequiresRegion": true,
  "language": "en",
  "languageDisplay": "English",
  "defaultLanguage": true,
  "live": false,
  "hasAccount": false
}

Example functions

The following are two variations of a function that calculates the total number of physically shippable items in an order. You can add these functions to any script.Total quantity of physical items in the order including individual products within any bundle

function getTotalQuantity() {
  // This function gets the total quantity of physical items in the
  // order and it counts the number of products in a bundle.
  var count = 0;
  var groups = order.groups;
  for (var i = 0; i < groups.length; i++) {
    var items = groups[i].items;
    for (var j = 0; j < items.length; j++) {
      if (items[j].selected) {
        if (items[j].bundle) {
          var bundleItems = items[j].groups[0].items;
          for (var k = 0; k < bundleItems.length; k++) {
            if (bundleItems[k].productFormat === 'physical' || bundleItems[k].productFormat === 'digital-and-physical') {
              count += bundleItems[k].quantity;
            }
          }
        } else {
          if (items[j].productFormat === 'physical' || items[j].productFormat === 'digital-and-physical') {
            count += items[j].quantity;
          }
        }
      }
    }
  }
  return count;
}

Total quantity of physical items in the order, with bundles treated as a single product

function getTotalQuantity() {
  // This function gets the total quantity of physical items in the
  // order but it only treats bundles as one product.
  var count = 0;
  var groups = order.groups;
  for (var i = 0; i < groups.length; i++) {
    var items = groups[i].items;
    for (var j = 0; j < items.length; j++) {
      if (items[j].selected) {
        if (items[j].bundle) {
          var hasPhysicalProducts = false;
          var bundleItems = items[j].groups[0].items;
          for (var k = 0; k < bundleItems.length; k++) {
            if (bundleItems[k].productFormat === 'physical' || bundleItems[k].productFormat === 'digital-and-physical') {
              hasPhysicalProducts = true;
              break;
            }
          }
          if (hasPhysicalProducts) {
            count += items[j].quantity;
          }
        } else {
          if (items[j].productFormat === 'physical' || items[j].productFormat === 'digital-and-physical') {
            count += items[j].quantity;
          }
        }
      }
    }
  }
  return count;
}

Advanced Example:  Suppose your script calculates the quantity of shippable items in the order, but you need to exclude certain specific physical items from being counted. To do this, you can specify a product attribute and then check for that attribute in your shipping fee calculator script. For example, if you include the cost of shipping in the price of a “CD backup” product–and you do not want to charge shipping for it separately–you might add an attribute with a key such as “cdbackup.” The following example function would exclude products with the attribute “cdbackup” from the quantity calculation.

 Note The product attribute key can be any string you like; “cdbackup” is just an example. As another example, you could set a product attribute with a key of “noshipping” and a value of “true.” You would just need to adjust the following example script accordingly. Example of excluding a physical product from the quantity calculation based on a product attribute

function getTotalQuantity() {
    // This function gets the total quantity of physical items in the
    // order but it only treats bundles as one product.
    var count = 0;
    var groups = order.groups;
    for (var i = 0; i < groups.length; i++) {
        var items = groups[i].items;
        for (var j = 0; j < items.length; j++) {
            if (items[j].selected) {
                if (items[j].bundle) {
                    var hasPhysicalProducts = false;
                    var bundleItems = items[j].groups[0].items;
                    for (var k = 0; k < bundleItems.length; k++) {
                        if (bundleItems[k].productFormat === 'physical' || bundleItems[k].productFormat === 'digital-and-physical') {
                            hasPhysicalProducts = true;
                            break;
                        }
                    }
                    if (hasPhysicalProducts) {
                        count += items[j].quantity;
                    }
                } else {
                    if ((items[j].productFormat === 'physical' || items[j].productFormat === 'digital-and-physical') && ((items[j].attributes && !items[j].attributes.cdbackup ) || !items[j].attributes)) {
                        count += items[j].quantity;
                    }
                }
            }
        }
    }
    return count;
}


var totalQuantity = getTotalQuantity();
if(totalQuantity == 0) {
    return false;
} else {
    return totalQuantity;
}

Example scripts

The following are examples of complete shipping fee calculation scripts.Example Script #1

// Uses a getTotalQuantity function as provided in the examples above.
 
var thisCountry = (typeof order.country === 'undefined') ? 'US' : order.country;
var shippingPrice = {};
if (thisCountry === 'US') {
  shippingPrice.usd = 12;
  shippingPrice.eur = 15;
} else if (thisCountry === 'CA') {
  shippingPrice.usd = 27.99;
  shippingPrice.eur = 29;
} else {
  shippingPrice.usd = 47.99;
  shippingPrice.eur = 49;
}
 
// Add $3 for each addtional unit after the first
var additionalUnitPrice = (3 * (getTotalQuantity() - 1));
shippingPrice.usd += additionalUnitPrice;
shippingPrice.eur += additionalUnitPrice;
 
return shippingPrice;

Example Script #2

// Uses a getTotalQuantity function as provided in the examples above.

var totalQuantity = getTotalQuantity();
if (totalQuantity <= 3) {
  // Charge $10 USD for quantities up to 3
  return 10;
} else if (totalQuantity <= 6) {
  // Charge $15 USD and 20 EUR for quantities 4-6
  return {
    "USD": 15,
    "EUR": 20
  };
} else {
  // Charge $20 USD and 20 EUR for quantities 7 or more
  return {
    "USD": 20,
    "EUR": 20
  };
}

Example Script #3

// Shipping will cost $0 USD when the order is greater than $100 and $7 otherwise
if (order.totalValue > 100) {
  return 0;
} else {
  return 7;
}

Advanced Example: Suppose you want to allow customers to select custom shipping methods, and you need your script to return estimated shipping costs accordingly. If you use Store Builder Library functions to create the shopping cart interface and pre-populate custom order tags (e.g., using fastspring.builder.tag(key,value)), your script can calculate a total estimated shipping cost for all products based on the selected shipping method. The following example would work if you passed a custom order tag with a key of “shipping” and a value of either “UPS,” “FedEx,” or “USPS” – for example, fastspring.builder.tag(“shipping”, “USPS”);Example Script #4

if(order.tags.shipping === 'UPS') {
  return 10;
} else if(order.tags.shipping === 'FedEx') {
  return 12;
} else if(order.tags.shipping === 'USPS') {
  return 7;
} else {
  return 5;
}

Shipping Charges with Popup Storefronts and the Store Builder Library

For Stores that have shipping charges enabled and a script with shipping amounts, adding a physical product to the cart via a Popup Storefront causes the shipping charges to be included in the order total automatically.

If you have enabled the optional Popup Storefront cart, the estimated shipping fee charges appear as a separate line item in the cart.

If you opt to create a shopping cart page using the Store Builder Library, you can access and display the shipping charges using the product path SystemExtension.shippingcalculation.

 Tip When designing a custom shopping cart, bear in mind that the shipping fee charges line item is treated the same as any other product. By default, it would be included in any loop you design to cycle through the order items. If you do not want the shipping charges to be displayed together with each of the order products, you may want to exclude the SystemExtension.shippingcalcultion from your loop explicitly. To create a separate line with the shipping charge amount (e.g., below a subtotal), you can optionally include a separate loop outside the main cart contents area that explicitly excludes*everything else* except the shipping charges. Then, render only the charge amount (i.e., not the product’s display name or a remove control). For an example of how you could code this, please inspect the SBL cart example found at https://fastspringexamples.com/product-type/physical-product/.