Blog

RSS
Payment Director - Conditional payment methods- Friday, January 4, 2013

Payment Director allows a store owner to conditionally determine which payment methods to show the customer and to calculate additional payment fees.  Let’s start with the basics…

By default, all Payment Methods that are marked Active in admin > Configuration > Payment Methods are available to your customers.   Then, you set up Payment Director Option records as needed to hide options and calculate fees.   Each option’s Expression field is evaluated, and if ‘true’ (or ‘Show’) then the option will be presented to the customer.  If ‘false’ (or ‘Hide’), then the payment option is removed.  You can include an Option record for all your active payment methods, but if only some are conditional, then it’s easiest to just have Option records for those;  if an active payment method is not included in payment director, then it will automatically be shown to the customer.

Here are some example scenarios for offering payment methods, and their Option records/expressions:

Offer 'payment in store' method only when "In-Store Pickup" shipping method selected:

  Option  Payments.PayInStore         ShippingOptionName = "In-Store Pickup"

Local Deliveries can include CashOnDelivery:

  Option  Payments.CashOnDelivery Customer.ShippingAddress.ZipPostalCode.StartsWith("100")

Customers in role "Members" can include PurchaseOrder  (use the role's System Name):

  Option  Payments.PurchaseOrder      Customer.IsInCustomerRole("Members")

If an admin is impersonating a Customer, then use Manual Credit Card, otherwise the customer enters a credit card that Authorize.Net will process:

  Option  Payments.Manual             OriginalCustomerIfImpersonated != null

  Option  Payments.AuthorizeNet       OriginalCustomerIfImpersonated = null

Only offer Paypal if a FedEx shipping method was selected (a method that has tracking :)

  Option  Payments.PayPalStandard     ShippingOptionName.StartsWith("FedEx")

Only offer credit card if there are  no Gift Cards in the cart

  Option  Payments.Manual           NOT Items.Any(Product.IsGiftCard)

When entering records in the Add new 'Payment Director' record dialog, select Option in the Type  field drop down, and then the Payment Name field will present a drop down with only active payment methods.    


Then, enter an expression that evaluates to a Boolean (true or false) using one or more or more of the following operands:

  • Customer  (also has function IsInRole("systemname") )
  • ShippingAddress
  • ShippingOption  (.ShippingRateComputationMethodSystemName, .Rate, .Name, .Description)
  • ShippingOptionName
  • Items  (shopping cart items collection)
  • OriginalCustomerIfImpersonated (if != null then you are impersonating)
  • WorkingLanguage  (.Name, and .LanguageCulture)
  • WorkingCurrency (.Name, .CurrencyCode, .Rate, and .DisplayLocale)
  • TaxDisplayType  (IncludingTax = 0, ExcludingTax = 10)
  • CreditCardType  (e.g. for Authorize.NET :  "Visa", "MasterCard", "Discover", "Amex")
  • PurchaseOrderNumber
  • OrderTotalWithoutPaymentFee
  • FriendlyName

   (UPDATE: Here are more operands added added from 3.60 and on)

  • CurrentStoreId
  • CurrentStoreName
  • IsImpersonating (Boolean)
  • CustomValues  
    • (The nopC PaymentInfoCustomValues is a Dictionary of Key/Values set by other payment plugins.  This variable converts that dictionary to a string of "key:value|key:value|...".  You can use CustomValues.StringBetween("key:","|") to get a value.

Here are some examples:

WorkingLanguage.Name = "English"

WorkingLanguage.LanguageCulture = "en-US"

We'll introduce more features in the next blog :)


Comments (4)
Simple Free Shipping based on Role- Tuesday, December 18, 2012

Here's a very simple free shipping scenario with fixed rates.  Customers in the "Free Shipping" role get an option for free shipping ($0).  If not in that role, they see regular shipping.  (The leading "!" is the NOT operator.)   Everybody sees an option for "Fast Shipping".  

(Update: 12/20/2021 - Customer.CustomerRoles won't work in 4.x and above.   Use Customer.GetCustomerRoles() to get the full collection, or to check a specific role, use helper property  Customer.IsInRole("role system name").  The below has been modified to use Customer.IsInRole() )

Order

Type

Name

Expression

Rate Expression

10

Option

Free Shipping

Customer.IsInRole("Free Shipping")

0

20

Option

Regular Shipping

!Customer.IsInRole("Free Shipping")

5

30

Option

Fast Shipping

true

10

 

So, if the customer is in the Free Shipping role, then she sees

Select shipping method
 Free Shipping ($0.00)
 Fast Shipping ($10.00)

And if she's not in that role she sees

Select shipping method
 Regular Shipping ($5.00)
 Fast Shipping ($10.00)

 

You can always add additional criteria.   If there are a lot of criteria, then create a variable to make it easier to read and maintain.  For example, let's also have additional criteria that the cart subtotal must be greater than $250

Order

Type

Name

Expression

Rate Expression

5

Boolean

HasFreeShipping

Customer.IsInRole("Free Shipping") and [$SubTotalWithDiscounts] > 250

 

10

Option

Free Shipping

[HasFreeShipping]

0

20

Option

Regular Shipping

![HasFreeShipping]

5

30

Option

Fast Shipping

true

10

 


Tags :  FreeShipping
Comments (2)
Shipping Discount - use a negative surcharge- Friday, December 14, 2012

Similar to adding an insurance surchargeto the shipping rate, one can provide a discount just by making the surcharge a negative amount.

In this example, we’ll use the “Shipping by weight” calculator for shipping, and set a discount of $2.99 if the cart’s total is $20 or more.

Order

Type

Name

Expression

Rate Expression

Surcharge Expression

10

Option

Shipping

true

Shipping.ByWeight

([$SubTotalWithDiscounts] > 20) ? -2.99 : 0

As mentioned in prior blogs, the " ? : " is the ternary if-then-else operator.  These can be chained together if needed - for example to have discounts based on amount like this:

Subtotal greater than

Discount

100

7.99

50

5.99

20

2.99


Then the expression would look like

  ([$SubTotalWithDiscounts] > 100) ? -7.99 :  ([$SubTotalWithDiscounts] > 50) ? -5.99 :  ([$SubTotalWithDiscounts] > 20) ? -2.99 : 0

Tags :  Discount
Comments (1)
$5 Ground for orders over $50 except Alaska & Hawaii- Sunday, December 9, 2012

Another simple example of having a reduced Ground shipping rate

Basically, you use the Surcharge to negate the Ground Rate and then add $5.   In this example, we do it for USPS.  (Read more about using Surcharge to adjust the rate here)

Order

Type

Name

Expression

Rate Expression

Surcharge Expression

100

Packing

Pack

true

Packing.FirstFitSingleBox

 

110

Option

USPS

true

Shipping.USPS

([$SubTotalWithDiscounts] > 50) AND !("AK,HI".Contains([State]) AND [$Name].Contains("Ground")) ? -[$Rate] + 5 : 0

For the most accurate carrier rates, set your package size - see this blog about packing 

Tags :  FreeShipping
Comments (0)
Free Shipping over ‘X’ but still charge “Additional Shipping Charges”- Friday, December 7, 2012

If you want to use Free Shipping over ‘X’ but still charge “Additional Shipping Charges”, you can't use nopC’s built-in Admin > Configuration > Settings > Shipping >> "Free Shipping over 'X'" because it will ignore Additional Shipping Charges set on product variants.  The built-in Free Shipping over ‘X’ is always calculated last after shipping plugins return their options.   You can make this work with Shipping Director.  First, be sure to turn off "Free Shipping over 'X' " in admin.  (And as always when using SD, be sure that SD is the only Active rate calc method.)

This is really easy to do in SD – just calculate a 0 rate when the subtotal is over X!  Then, NopC will always add the additional shipping charges.  For example, here’s free shipping ($0) if the subtotal is more than $50:

Order

Type

Name

Expression

Rate Expression

10

OptionExit

Shipping

[$SubTotalWithDiscounts] >= 50

0

 

Of course, to make this complete, we'll add the second Option record to provide the rate if the cart does not meet the minimum amount.  And, to get a little fancy, we’ll use the Name Expression to show the customer “Free Shipping” if none of the items have any additional shipping charges, otherwise show “Shipping”:

Order

Type

Name

Expression

Rate Expression

Name Expression

10

OptionExit

Shipping

[$SubTotalWithDiscounts] >= 50

0

Items.Any(Product.AdditionalShippingCharge > 0) ? "Shipping" : "Free Shipping"

20

Option

Shipping

true

5

 

The second record above is a flat $5 rate, but you can of course use any type and number of additional methods/rates instead.

(P.S.  updated on July 2014 - ProductVariant -> Product)

Tags :  FreeShipping
Comments (0)
Shipping Director 1.07 available for NopCommerce 2.70 and 2.65- Wednesday, December 5, 2012
Here are the new features (I'll blog about them in more detail soon :)

SortExpression setting
  An optional sort of the options after all records have been processed.
  You can sort the options by any expression involving the shipping option fields: Rate, Name, Description

Query Expression support for First(), FirstOrDefault() and Select()
  e.g. Instead of saying Items.Where(...).First(), you can just say Items.First(...)

More Extension functions:
  String
    Split(separator)
    IsNumeric()
    IsInteger()
  ShoppingCartItem
    GetAttributeValues(attributeName, valueSeparator)
    GetAttributeValues(attributeName)
    HasAttributeValue(attributeName, valueName)
    HasAttributeValue(attributeName)
    HasAttributeValue(valueId)
  Product
    HasCategory(categoryName) 
    HasCategory(categoryId) 
    HasCategoryMatch(categoryNameRegex)
  
Test
  A store owner or developer can test their shipping calculations in the configuration page.  Testing here is not limited to the 5 transaction limit in trial/evaluation mode.
  You can select a customer to use test cart/address. (You must take that test customer through checkout process to the point of shipping address selection for that address to be stored with customer.)

Export tab delimited
Import tab delimited 
  Export/Import is not only great for backup and migrations, but also allows store owner to use different shipping scenarios with ease.
  Additionally, you can work in Excel where data entry can be easier for advanced users - just save as "Text (tab delimited)".

Tags :  1.07
Comments (1)
More about Packing- Friday, October 12, 2012

As per the blog that discusses Shipping Director built-in variables:

Rate Request Type - When Packaging, can be set by user to indicate the way that rate requests are made to other rate calculation methods when Packaging

Note that the Rate Request Types pertain when rate requests are made to other rate calculation methods (i.e. external methods like FedEx, UPS, etc.)

An external method like FedEx does its own "packing" - it will take the items in the cart, and "approximate" the number of packages based on dimensions/weight.   I've posted nopCommerce forum topics about how poor the algorithm is, and that's why I provide here at nopTools.com a modified version of the FedEx plugin(which was adopted by nopCommerce in version 2.50), and also created SD’s First Fit Single Box packing.

“OneRequestForAllPackages” is the default setting - it calls the external shipping plugin just once, and that plugin will do its own approximation of the number of packages.  That's when it's useful to use the new FedEx plugin which supports "PackByOneItemPerPackage" - then, the packing done by SD is respected by the FedEx plugin (no additional "approximate packing" is done).

With “OneRequestPerPackage”, SD will make multiple requests (one per package) to the external plugin, and aggregate the like named carrier options.   Liked named aggregation means that when FedEx returns a "Ground" rate for each separate request, they are added together, and the customer sees a single "Ground" option/rate.

“OneRequestPerSender” is used when using the Packing record type’s Sender Expression.  Here too, SD will make multiple requests (one per sender) to the external plugin, and again does liked named aggregation.  This blog about Packing by Warehouseprovides a good explanation.

Tags :  Packing
Comments (1)
Flat Rate Shipping with Multiple Options- Sunday, October 7, 2012

Here a basic example of how to set up various shipping rate options.  When you have certain conditions that depend on Country where you only want to offer a single option, then use OptionExit so that no other options are evaluated.  When you want to offer multiple options, then use Option - each condition expression is evaluated, and if true, then the option is presented to the customer.  A typical example would be when you want to offer Ground, Next day, etc.

Example requirements:

  • International $100
  • Canada $55
  • Hawaii & Alaska $55
  • Free ground shipping orders over $100, except HI and AK.
  • Ground $15 for all orders under $100
  • Next Day Air $95
  • 2 Day Air $85
  • 3 Day Air $75

Order

Type

Name

Expression

Rate Expression

100

String

Country

ShippingAddress.Country.TwoLetterIsoCode

 

110

String

State

ShippingAddress.StateProvince.Abbreviation

 

200

OptionExit

International

!("US,CA".Contains([Country]))

100

210

OptionExit

Canada

[Country] = "CA"

55

220

OptionExit

Hawaii & Alaska

"AK,HI".Contains([State])

55

300

Option

Free Ground Shipping

[$SubTotalWithDiscounts] > 100

0

310

Option

Ground

[$SubTotalWithDiscounts] <= 100

15

320

Option

Next Day Air

true

95

330

Option

2 Day Air

true

85

340

Option

3 Day Air

true

75

 

Also, check out the first part of this blog   I.e. you need to use ErrorExit to check for country/state as the initial record, because if in Estimate Shipping the customer does not choose a Country or State it will cause an error in the above references.

You can leave out the zip code check based on above conditions:

ShippingAddress.Country = null  or ("US,CA".Contains(ShippingAddress.Country.TwoLetterIsoCode) and ShippingAddress.StateProvince = null)


Tags :  FlatRateGettingStarted
Comments (2)
Exclude Shipping Methods by Product (Variant) Attribute- Saturday, September 29, 2012

Previously in this blog Exclude Shipping Methods by Specification Attribute we discussed checking a Product Specification Attribute.  The scenario was that if a product required assembly, that it could not be picked up in the store.

In this blog, we'll look at how to examine a Product Attribute.  (Product Attributes are actually Product Variant Attributes).    For example, let's say our "Assembled" attribute is something the customer chooses at the time of adding an item to a cart; they can choose a value of "Yes", or "No".   NopCommerce stores customer attribute choices in the shopping cart item's AttributeXml field.  However, we don't have to parse the XML - this field is a string, and we can just look for the correct <Value> tag in the string using the Contains() function.  Here's what a typical AttributeXml looks like for a product variant having only a single attribute  (I've added spacing and linefeeds for readability):

<Attributes>
     <ProductVariantAttribute ID="1">
         <ProductVariantAttributeValue><Value>1</Value></ProductVariantAttributeValue>
     </ProductVariantAttribute>
</Attributes>

It's that <ProductVariantAttributeValue><Value>1</Value> we are looking for - that number "1" in the value tag is the unique Id of the attribute value in the database table (just <Value>1</Value> would be enough, but I'll also include the parent tag to make it clear)

We'll use the same scenatio we did last time - Always offer Fedex, and only offer In-Store pickup if item does NOT require assembly (the leading "!" is the NOT operator).  Here we go...

Order

Type

Name

Expression

Rate Expression

100

String

Assembled Yes Tag

"<ProductVariantAttributeValue><Value>1</Value>"

 

200

Option

In-Store Pickup

!Items.Any(

AttributesXml.Contains([Assembled Yes Tag]))

0

300

Option

FedEx

true

Shipping.Fedex

Yep, that's it!  You will, however, have to find the correct Value Id.  To do that, either check in the database - e.g:

-- Products (Variants) and their Attribute/Values
SELECT p.Name as ProductName, pv.Name as VariantName, 
       pa.Id as AttributeId, pa.Name as AttributeName,
       pvav.Id as ValueId, pvav.Name as ValueName
  FROM Product p
  join ProductVariant pv
    on pv.ProductId = p.Id
  join ProductVariant_ProductAttribute_Mapping m
    on m.ProductVariantId = pv.Id
  join ProductAttribute pa
    on pa.Id = m.ProductAttributeId
  join ProductVariantAttributeValue pvav
    on pvav.ProductVariantAttributeId = m.Id  
where pvav.Name = 'Small'    
order by p.Name, pv.Name, pa.Name, pvav.name

or, you can use Shipping Director to just dump out the AttributeXml to examine.  Set up this record:

Add new 'Shipping Director' record

Order

0

Active

checked

Type

ErrorExit

Name

AttributesXml

Expression

true

Description Expression

Items.First().AttributesXml

Then, put an item with desired selection in the cart and Estimate Shipping.

Tags :  AttributesExcludeOption
Comments (1)
Exclude Shipping Methods by Specification Attribute- Thursday, September 27, 2012

[Update 9/2014  - note that as of nopCommerce 3.0, there is no longer a ProductVariant, so just delete "ProductVariant." from any expression below]

You can have shipping calculations based on the product specification attributes of items in the cart.
As an example, let's exclude a shipping method if the "Assembled" specification attribute option is applied to any item in the cart:
We have configured a Specification Attribute "Assembly" having only a single option "Assembled", and we want to hide shipping option "In-Store Pickup" if any items in the cart have the "Assembled" specification attribute option.

Here how it looks if you're using an carrier rate calculation method like Fedex.  The first Option record is an "In-Store Pickup" defined in SD and will appear with $0 only if no products in the cart have "Assembled" attribute.
(We'll use a Reference as a shortcut to get the specification attributes to make it more readable):

Order

Type

Name

Expression

Rate Expression

100

Reference

Attributes

ProductVariant.Product.ProductSpecificationAttributes

 

200

Option

In-Store Pickup

!Items.Any([@Attributes].Any( SpecificationAttributeOption.Name = "Assembled"))

0

300

Option

FedEx

true

Shipping.Fedex


Here how it looks if you're using an internal rate calculation method like ByWeight, and defined a Shipping Method "In-Store Pickup" in Admin > Configuration > Shipping > Shipping Methods:

Order

Type

Name

Expression

Rate Expression

Name Expression

100

Reference

Attributes

ProductVariant.Product.ProductSpecificationAttributes

 

 

200

Option

Shipping By Weight

true

Shipping.ByWeight

[$Name] = "In-Store Pickup" and Items.Any([@Attributes].Any( SpecificationAttributeOption.Name = "Assembled")) ? "" : [$Name]

When Shipping Director processes the Option record, the Name Expression is computed for each shipping method option returned by the Shipping.Weight plugin (e.g. "In-Store Pickup", "Ground", "Air", etc.).

When a plugin returns multiple shipping options, calculating a specific Name Expression to blank will suppress that option. (the ternary opertator " ? : " acts like an if-then-else)

For the SpecificationAttributeOption in the above example, if you want to use the Id rather than the Name (e.g. your Name is localized, or it it might be changing in future), then be sure to check the SQL database table [SpecificationAttributeOption] to get the correct Id:
   ... .Any(SpecificationAttributeOption.Id = 1) ...

If you've localized your shipping methods names (i.e. created a language resource with Resource Name = "In-Store Pickup"), then be sure to use SD's GetLocaleString() function (must be assigned to a string variable) to get the localized name for use in the expression above:

Order

Type

Name

Expression

10

String

In-Store Pickup Text

GetLocaleString("In-Store Pickup")

Then in the Option record, reference the variable : ... $Name = [In-Store Pickup Text] and Items.Any(...



(P.S.  If you ever need to check the Attribute rather than an AttributeOption, then use SpecificationAttributeOption.SpecificationAttribute.Name .  For example, above we said we have a Specification Attribute "Assembly" having only a single option "Assembled".  But it could also have had two options: "Assembled" and "Not Assembled".  If we didn't care which option, but just that it had the "Assembly" Attribute, then we'd use SpecificationAttributeOption.SpecificationAttribute.Name = "Assembly".)

Tags :  AttributesExcludeOption
Comments (3)
 First ... Previous 3 4 5 6 7 Next ... Last