The basics of a Store are the ingredients for this "Simple Store" module. Create a store in a couple of minutes without spending a lot of money due the overhead of features you are never using!
Simple Store support the following features
Make sure your system meets the minimum requirements:
For every paid addon you need to validate your license in order to activate the module.
On a local environment, like *.dev
*.local
*.localhost
*.test
the license is valid for testing and building a new or existing sites.
For every other domain, you need to have a valid license.
Once installed, you will asked to enter your license key. When you entered a valid license you can hit the "Save license" button. This will start validating your license and will redirect you to addons.reinos.nl to login into your account. You can also register a new account in this process.
Once logged in, you are asked to use your current account or to login with another one.
Using the current logged in account, the server will check all info related to your license and once valid, it will redirect you back to your site where you see either a success message or an error message.
This module is using a license field to check if the license for the module is valid or not. On addons.reinos.nl you can check your license and add your valid domains.
In the Module CP you can enter then your license
When you enter a wrong license, the module will not work and it shows you an warning
Sometimes it happens that the license system says you have an invalid license. When this happens, make sure you have entered your domain url in your account, next to your license on addons.reinos.nl.
If this will not fix your license problem, please contact us on https://addons.reinos.nl/support
On the CP page you can modify a couple of things.
Set this to the url where your order is shown on the frontend.
By setting this url, you are able to view the order in the admin panel just the way the user its seeing the order.
(By default we always show the native Order view)
Set the price for shipping
Set the first (high) tax rate
The second (low) tax rate
Set the default rate
The TAX rate for the shipping
Is the price of a product incl TAX or excl TAX or none?
Set the default currency
Set the decimal point value to format the price
Set the thousand separator
The From address
The from name
Send the mail also to notification one or more addresses.
Send it as text or HTML
Set a default country
Select the countries that are allowed for the shop
This is the field where you can put your store info (can be HTML for formatting the data). This data will be printed in your invoices (top right)
Make a sum of all discount of just the first.
If not enabled, it will pick the highest value.
What should we log?
The module comes with some default predefined templates that can be used for your shop. On this page you can install them.
Create a discount coupon or add a discount per member ID with a fixed amount or order percentage.
(Note: discount code can only be used one time)
This is where you can track all error logs
The order overview page. For the detail page we connect the url of your frontend to the order. If you did not set an order template (we suggest you do), it will show the details in a simple page.
Enter your license key to activate your module
By using this Gateway you can order any product without doing a real payment. Mostly this is used to send the customer a custom invoice. But it can also be used when developing your site where you cannot use the real provider.
This is a Dutch payment provider that support a large amount of payment methods.
Go to your dashboard --> Developers --> API Keys. There you see an API key for either testing or for production. Both API keys are needed, so you can copy both.
This is another Dutch payment provider that support a large amount of payment methods.
Go to your dashboard --> Settings --> Website --> API Keys. By default you have a production account, but you can also create a developer account via https://testmerchant.multisafepay.com to obtain a test API key
For Paypal we use the REST client to give the best Paypal experience.
Client ID
and the Secret
to the Simple Store Paypal fields.We support Stripe checkout. See the official documentation https://stripe.com/docs/payments/checkout
If you'd like to use a different Gateway, please let me know, so I can add this for you (not free).
In order to setup the store you have to follow the following steps.
Create a channel (e.g. called Products) with at least the following fields
product_price
and assign the fieldtype Simple Store
to it.product_sale_price
and assign the fieldtype Simple Store
to it. *product_disable_shipping
and assign the fieldtype toggle
to it. ** Not required, but the template expect this field. However, you can omit this field in your own template
The tag for adding items to the cart
{exp:reinos_simple_store:add_to_cart}
Below are the Tag Parameters. Those parameters can be used in the tag described above
The return url, default to the current url
return_url=""
The SKU for a product. I omitted, it allows you to add a single product multiple lines to your cart.
sky=""
Set the entry_id of your product. This way we can collect the ids for later and easy use in the cart
entry_id=""
Set the name of the product
product_name=""
Set the price of the product.
product_price="0.00"
Set the sale price of the product.
product_sale_price="0.00"
Set the tax.
This can either low
or high
so it will fetch the rate set in the settings, or a custom numeric value.
If omit the param, it will fallback on the default tax rate set in the settings.
tax="low"
tax="22"
When adding a product, your can clear the cart to have a cart with always one product.
clear_cart="no"
If you have no shipping cost, you can disable it for a product
disable_shipping="no"
Set the form class
form_class=""
Set the form id
form_id=""
Set custom fields
custom_fields:test="value"
custom_fields:or_an_other_value="value"
Set nice labels for your custom fields.
This also works for input elements.
custom_fields_label:test="Your nice label for field TEST"
group items in your cart together if more then one.
Sometimes you want to put a product with the same SKU but with different custom fields as seperated items in your cart. By disabling the grouped option, you can achieve this because by default you will end up with one item in the cart but with a qty of 2 or more.
grouped="yes"
<input name="qty" value="1"/><br>
<input name="custom_fields[yet_another]" value="custom value"/><br>
<input name="custom_fields[and_another]" value="other custom value"/><br>
{if error:invalid_price}
<p style="color:red;">You have entered an invalid price</p>
{/if}
{if error:invalid_sale_price}
<p style="color:red;">You have entered an invalid sale price</p>
{/if}
Loop over the cart variables and items
{exp:reinos_simple_store:cart}
Below are the Tag Parameters. Those parameters can be used in the tag described above
The return url, default to the current url
return_url=""
Set the form class
form_class=""
Set the form id
form_id=""
Set a prefix
prefix="cart:"
Set the cart as updated, so it can update the qty
can_update="yes"
Below are the Tag Variables. Those Variables can be used in the tag described above
Check if there are no_items
{if cart:no_items}...{/if}
Loop over the items in the cart
{cart:items}
{cart:name}
{cart:price}
{cart:price:formatted}
{cart:old_price} // when dealing with a sale price, this is the original_price
{cart:old_price:formatted} // when dealing with a sale price, this is the original_price
{cart:price_plus_tax}
{cart:price_plus_tax:formatted}
{cart:old_price_plus_tax} // when dealing with a sale price, this is the original_price
{cart:old_price_plus_tax:formatted} // when dealing with a sale price, this is the original_price
{cart:qty}
{cart:sku}
{cart:entry_id}
{cart:disable_shipping}
{cart:price_total}
{cart:price_total:formatted}
{cart:old_price_total} // when dealing with a sale price, this is the original_price
{cart:old_price_total:formatted} // when dealing with a sale price, this is the original_price
{cart:price_total_plus_tax}
{cart:price_total_plus_tax:formatted}
{cart:old_price_total_plus_tax} // when dealing with a sale price, this is the original_price
{cart:old_price_total_plus_tax:formatted} // when dealing with a sale price, this is the original_price
{cart:custom_fields}<strong>{custom_fields:label}:</strong> {custom_fields:value}{/cart:custom_fields}
{cart:on_sale} // bool if the product is on sale
{/cart:items}
The total number of different products in the cart
{cart:total_items}
The total qty of all items in the cart
{cart:total_items_qty}
{cart:subtotal}
{cart:subtotal:formatted}
{cart:subtotal_plus_tax}
{cart:subtotal_plus_tax:formatted}
To use the coupon code, simply add the field <input type="text" name="coupon_code" value="{cart:coupon_code}"/>
. (see the examples for details)
{cart:discount}
{cart:discount:formatted}
{cart:total}
{cart:total:formatted}
{cart:total_plus_tax}
{cart:total_plus_tax:formatted}
{cart:tax}
{cart:tax:formatted}
{cart:shipping}
{cart:shipping:formatted}
{cart:shipping_plus_tax}
{cart:shipping_plus_tax:formatted}
Hold all entry_ids as a pipeline delimited string
{cart:entry_ids}
With the remove Cart Item Tag your are able to remove a single item from the cart
{exp:reinos_simple_store:delete_cart_item}
Below are the Tag Parameters. Those parameters can be used in the tag described above
The unique cart item ID
cart_item_id=""
Below are the Tag Variables. Those Variables can be used in the tag described above
The actual url that can be used to delete the cart item
{exp:reinos_simple_store:cart prefix="cart:" can_update="yes"}
{cart:items}
{exp:reinos_simple_store:delete_cart_item cart_item_id="{cart:id}"}
<a href="{remove_cart_item_url}">Remove</a>
{/exp:reinos_simple_store:delete_cart_item}
{/cart:items}
{/exp:reinos_simple_store:cart}
The Checkout tag
{exp:reinos_simple_store:checkout}
Below are the Tag Parameters. Those parameters can be used in the tag described above
Set the customer phone as required.
customer_phone_required="false"
Set the customer company name as required.
customer_company_required="false"
The return url, default to the current url
return_url=""
Set the form class
form_class=""
Set the form id
form_id=""
Control wether the billing address fields are required or not.
enable_billing_address="yes" (default)
Control wether the shipping address fields are required or not.
enable_shipping_address="yes" (default)
Below are the Tag Variables. Those Variables can be used in the tag described above
Global errors
{global_error}
Check for global errors
{if has_global_errors}
{global_error}
{/if}
Check for field errors
{if has_field_errors}
...
{/if}
Error, if there is one, per field
{customer_first_name:error}
{customer_last_name:error}
{customer_email:error}
{customer_phone:error}
{customer_company:error}
{billing_address:error}
{billing_address2:error}
{billing_zip:error}
{billing_city:error}
{billing_country:error}
{shipping_address:error}
{shipping_address2:error}
{shipping_zip:error}
{shipping_city:error}
{shipping_country:error}
{!-- for example --}
{if customer_company:error != ''}<span class="text-red">{customer_company:error}</span>{/if}
Values, if there is something, per field
{customer_first_name:value}
{customer_last_name:value}
{customer_email:value}
{customer_phone:value}
{customer_company:value}
{billing_address:value}
{billing_address2:value}
{billing_zip:value}
{billing_city:value}
{billing_country:value}
{shipping_address:value}
{shipping_address2:value}
{shipping_zip:value}
{shipping_city:value}
{shipping_country:value}
Add extra fields to your checkout process.
You need to define the field names in extra_fields
and in the body of {exp:reinos_simple_store:checkout} you can add the actual HTML
{exp:reinos_simple_store:checkout
extra_fields="agree_with_terms|name|email"
}
<input name="name" placeholder="extra[name]" />
<input name="email" type="extra[email]" placeholder="email" />
<input type="checkbox" name="extra[agree_with_terms]" value="yes"/> Agree with the terms
{/exp:reinos_simple_store:checkout}
This tag will convert your ISO-2 lang code to a readable one.
{exp:reinos_simple_store:country}DE{/exp:reinos_simple_store:country}
Get a select HTML list of all your countries, and also checking the settings for default and allowed countries
{exp:reinos_simple_store:country_list type="billing" class="form-control" value=""}
Below are the Tag Parameters. Those parameters can be used in the tag described above
Set the CLASS for the select
class=""
Set the ID for the select
id=""
Set to billing
or shipping
type="billing"
set the default value
value=""
Format the price to the correct decimals and currency symbol
{exp:reinos_simple_store:format}9.95{/exp:reinos_simple_store:format}
Below the global variables that can be used anywhere.
{reinos_simple_store_total_in_cart}
The order tag. It comes in 2 flavours, one for getting a single order {exp:reinos_simple_store:order}
and one for getting a list of orders {exp:reinos_simple_store:orders}
.
Both tags have the same parameters and variables.
{exp:reinos_simple_store:order}
{exp:reinos_simple_store:orders}
Below are the Tag Parameters. Those parameters can be used in the tag described above
Prefix the variables
prefix="order:"
Set a order_id for the order you want to fetch
order_id=""
Set a hash for the order you want to fetch
hash=""
Select all orders for the given member_id
member_id=""
Filter based on the status.
Possible options: open
paid
pending
failed
expired
cancelled
refunded
paid_chargeback
status="open"
Below are the Tag Variables. Those Variables can be used in the tag described above
Check if there is any result
{if no_results}...{/if}
Check if we still cancan pay the order.
Some providers support to pay after the order has been created but somehow is now paid and still open
{if order:can_complete }
Your order is not yet payed, finish your order by clicking <a href="{order:payment_url}">here</a>.
{/if}
The payment url, used when the order is open and should be paid
{if order:can_complete }
Your order is not yet payed, finish your order by clicking <a href="{order:payment_url}">here</a>.
{/if}
{order:order_id}
{order:time format="%d %M %Y"}
{order:transaction_id}
{order:status}
{order:customer_company}
{order:status}
{order:customer_last_name}
{order:customer_email}
{order:customer_phone}
{order:billing_address}
{order:billing_address2}
{order:billing_zip}
{order:billing_city}
The ISO-2 lang code. Convert it with {exp:reinos_simple_store:country}
to get a readable name
{exp:reinos_mollie:country}{order:billing_country}{/exp:reinos_mollie:country}
{order:shipping_address}
{order:shipping_address2}
{order:shipping_zip}
{order:shipping_city}
The ISO-2 lang code. Convert it with {exp:reinos_simple_store:country}
to get a readable name
{exp:reinos_mollie:country}{order:shipping_country}{/exp:reinos_mollie:country}
Loop over the items in the order
{order:items}
{order:name}
{order:price}
{order:price:formatted}
{order:old_price} // when dealing with a sale price, this is the original_price
{order:old_price:formatted} // when dealing with a sale price, this is the original_price
{order:price_plus_tax}
{order:price_plus_tax:formatted}
{order:old_price_plus_tax} // when dealing with a sale price, this is the original_price
{order:old_price_plus_tax:formatted} // when dealing with a sale price, this is the original_price
{order:qty}
{order:sku}
{order:entry_id}
{order:disable_shipping}
{order:price_total}
{order:price_total:formatted}
{order:old_price_total} // when dealing with a sale price, this is the original_price
{order:old_price_total:formatted} // when dealing with a sale price, this is the original_price
{order:price_total_plus_tax}
{order:price_total_plus_tax:formatted}
{order:old_price_total_plus_tax} // when dealing with a sale price, this is the original_price
{order:old_price_total_plus_tax:formatted} // when dealing with a sale price, this is the original_price
{order:items:custom_fields}<strong>{custom_fields:label}:</strong> {custom_fields:value}{/order:items:custom_fields}
{order:items:on_sale} // bool if the product is on sale
{/order:items}
{order:subtotal}
{order:subtotal:formatted}
{order:subtotal_plus_tax}
{order:subtotal_plus_tax:formatted}
{order:discount}
{order:discount:formatted}
{order:total}
{order:total:formatted}
{order:total_plus_tax}
{order:total_plus_tax:formatted}
{order:tax}
{order:tax:formatted}
{order:shipping}
{order:shipping:formatted}
{order:shipping_plus_tax}
{order:shipping_plus_tax:formatted}
Hold all entry_ids as a pipeline delimited string
{order:entry_ids}
Get the extra fields that are used in the checkout tag
{order:extra_fields}
{extra_field:name}: {extra_field:value}
{/order:extra_fields}
The price fieldtype is a special fieldtype that can hold currency values.
By default the fieldtype field output a numeric value that can be used for the {exp:reinos_mollie:add_to_cart product_price=""}
parameter.
Below are the Fieldtype Modifiers. Those Variables can be used in the tag described above
Output the price without TAX and formatted
{your-field-name:no_tax}
Output the price with TAX and formatted
{your-field-name:plus_tax} //fall back on the default tax value
{your-field-name:plus_tax tax="low"}
{your-field-name:plus_tax tax="high"}
{your-field-name:plus_tax tax="22"} //custom numeric value
Output the price with TAX as a numeric value
{your-field-name:plus_tax_numeric} //fall back on the default tax value
{your-field-name:plus_tax_numeric tax="low"}
{your-field-name:plus_tax_numeric tax="high"}
{your-field-name:plus_tax_numeric tax="22"} //custom numeric value
Output the price without TAX as a numeric value
{your-field-name:no_tax_numeric}
Output the price, as given as a numeric value
{your-field-name:numeric} //fall back on the default tax value
{your-field-name:numeric tax="low"}
{your-field-name:numeric tax="high"}
{your-field-name:numeric tax="22"} //custom numeric value
Output the price, as given formatted
{your-field-name:formatted} //fall back on the default tax value
{your-field-name:formatted tax="low"}
{your-field-name:formatted tax="high"}
{your-field-name:formatted tax="22"} //custom numeric value
As of version 2.x.x it is possible to sync your Order and Order Items to your regular Entry Channels. By doing so, you have the freedom at your proposal via regular Entry tags. But also you can add extra fields if you'd like.
After you configure the settings, syncing is done in the background. Orders will be synced to the Entries and if you changed an order that sits in an entry, it will also be synced back to the module so the module and the entries are in sync.
Note: If you upgraded from an older version before 2.x.x. You have to manually sync the entries. Please go to you Order overview and click "Sync Order Status". On this page you can sync your entries.
Remember, syncing a lot of order can take a while.
First you need to create your channels and your fields. For the Order Channel you can sync the following fields:
The following fields should be created for an Order Channel
text input
text input
text input
text input
text input
text input
text input
text input
text input
text input
text input
text input
text input
text input
text input
simple store - price
simple store - price
simple store - price
simple store - price
simple store - price
simple store - price
simple store - price
simple store - price
text input
text input
text input
simple store - custom fields
- render the custom fieldssimple store - order fields
- render the Items of an OrderThe following fields should be created for the Order Items Channel
text input
text input
text input
text input
simple store - price
simple store - price
simple store - price
simple store - price
simple store - price
simple store - price
simple store - price
simple store - price
simple store - custom fields
- render the custom fieldsThe following fields needs to configured in order to sync your Orders to Entries.
Field | Description |
---|---|
Channel | Choose the channel where we should save the Order to. |
Order Title Prefix | Set a prefix for the title. By default we will use #order-{orderId} |
URL Title Prefix | Set prefix for your URL Title |
Order Status | Select the Status from your Channel that we should map |
Order Fields | Select a Field from your Channel that we should map |
Just like the orders, Order Items needs to be configured in the same way as Orders.
Field | Description |
---|---|
Channel | Choose the channel where we should save the Order Item to. |
Order Title Prefix | Set a prefix for the title |
Order Status | Select the Status from your Channel that we should map |
Order Fields | Select a Field from your Channel that we should map |
The custom_field fieldtype is a special fieldtype that can read out the custom fields of a synced item. It will render a table in the Channel Entry view and has a tagpair to render the custom_fields in your HTML.
You should use
{order_custom_fields}
{custom_fields:label}
{custom_fields:value}
{/order_custom_fields}
The order_items fieldtype is a special fieldtype that can read out the Order Items of a synced item. It will render a table in the Channel Entry view and has a tagpair to render the order_items in your HTML.
You should use
{order_items_field}
{order_item:entry_id}
{/order_items_field}
{exp:reinos_simple_store:orders member_id='1'}
to list orders for a specific user{exp:reinos_simple_store:delete_cart_item cart_item_id=""}
to remove a single product from the cartstatus="open"
param to the {exp:reinos_simple_store:order}
tagsale_price
custom_fields:test="test value"
) can be set via custom_fields_label:test="Testing"
. Input fields are supported as welltotal_items_qty
--> return the total qty of all items in the cart{exp:reinos_simple_store:store_address}
to print the global store address fieldcustomer_phone_required
customer_company_required
to mark the Phone and Company name as required if needed{billing_country_full_name}
and {billing_country_full_name}
to output the full name for the country{cart:total_items}
variable:formatted
price values