Requirements
Joomla! 4.4 PHP 8.1 PHP 8.2
Joomla! 5.1 Joomla! 5.2 PHP 8.1PHP 8.2 PHP 8.3
- Basic Joomla! knowledge available between the chair and the keyboard :)
Installation is easy!
- Download the package
- in the Back-end go to menu Extensions > Manage
- in the tab [Upload file package] click [browse] and select your downloaded package
- click [Upload & Install], wait for the installation to finish
- go to plugins and activate the ochSubscriptions - System plugin
Component Configuration
- In the back-end go to menu Components > ochSubscriptions.
- In the component click on the [Options] button
>> configure the generic ochSubscriptions options and permissions
>> Add your personal download id in the Advanced Settings - In ochSubscriptions > Countries > click 'Update EU Vat Rates' to import the latest EU Vat Rates
- If States enabled: In ochSubscriptions > States > click 'Import States' to get a current list of States per Country.
- Publish the ochSubscriptions - System plugin
>> This is a required plugin responsible for adding the customer billing information into the Joomla user profile - Install and publish a ochpayment plugin: PayLater plugin is installed as part of the package.
- Configure and setup the ochSubscriptions cronjobs
Activate Joomla! One Click update and change-log integration
When you install the extension, it will automatically integrate with the Joomla Updater for both updates and change-logs.
On first use, the Joomla updater will prompt you with a 'Download Key is missing!' message.
- On this site: Go to [Tools > My Account > My Download Keys], and copy your Download ID#.
- On your site: Go to System > Update Sites, locate the extension, and paste the Download ID into the 'Download Key' field. Click [Save and Close].
Important:
If you're using this Download ID on a new server, you’ll receive an email to approve the device. Click the link in the email to enable downloads from this server.
Without approval, updates won’t be authorized, and the Joomla updater will display a 401 Unauthorized error when trying to fetch updates.
That’s it! You're all set.
ochSubscriptions is build on and 'interfaces' with the Joomla Build in ACL functionality. it is important to understand that not ochSubscription enforces which user can access what content, but Joomla itself does. By utilizing this core Joomla functionality you are guaranteed of the maximum level of security and maintenance.
How Joomla 'decides' which user can access what content
Basic principles:
- All content in Joomla (offered from Joomla itself or via extensions) has a configured 'Access Level'
- All users (registered or visitors) of Joomla have one or more assigned User Groups, a visitor has by default assigned the 'Public' User Group
Authorization process:
- A user (logged in) or visitor visits your website and want so see Content (e.g. a article), it does a request to Joomla to show the Content
- Joomla checks if the assigned User Groups to that requesting User is on the Access Level of the Content item
- Yes: The User Group(s) for this user is on the Access Level of that Content item, the the content is shown
- No: the User Group(s) for this user are not on the Access Level of that Content Item, the user is shown a 40x page stating no access
Joomla comes with a set of build in User Groups and Access Levels that you can assign to resp. Users and Content Items
- You can assign User Groups to users in the back-end > User Manager > Manage > edit user > tab 'Assigned User Groups'
- You can create your own User Groups in the back-end > User Management > Groups (groups can be nested to have a better overview)
- You can create your own (or change existing) Access levels in the back-end > User Manager > Viewing Access Levels. Here you specify the Access level and what User Groups are part of that Access Level
As an example, you have a group of users that you want to give access to a special set of articles. The articles are part of the category 'training' you created for this purpose. By default all Content items are set to a viewing level of 'Public' which means that everybody can see the Content. This is not what you want, so you create a new User Group called 'students'. next you assign that 'students' user Group to the Users that you want to have access to these special article to. Finally you create a new Access Level called 'Students' and set it to contain the User Group 'students'.
Now you need to 'bind' the Content to this new Access level, so you go to the 'training' Category you created (that holds the articles) and set the 'Access' from Public (everybody can access) to your newly created Access Level: 'Students'.
And that is it: when a regular user logs in he/she cannot access the articles because he is not assigned a User Groups that is assigned to the Access Level for this category, but when a 'student' logs in he/she can see the articles.
How ochSubscription interfaces with the Joomla Access Levels / User Groups
Building on the example above: you sell an online training where customers (the student) have access for 3 months to the training material. You have the training setup as Articles in the category 'training'. Only User accounts that are assigned the 'student' User Group have access to this category and its articles.
In ochSubscriptions you created a new Product called 'Online Training'. You have configured the product to both add and remove the User Group 'students' to the customer.
Interface (subscription) process
- A (new) Customer buys your ochSubscription created product 'Online Training'. ochSubscriptions will handle the checkout, payment and create an invoice
- When the payment is okay (money received) ochSubscriptions will create a active subscription for this Product / Customer with a start date of (purchase date) and an end-date of purchase date + 3 months (configured in the product)
- The configured User Group for this product is ADDED to the Customer his/ her User Account that is created during the checkout. The Customer can login with this User Account and has direct access the training material
- After 3 months the subscription expires, ochsubscriptions will the REMOVE the configured User Group for this product from the Customer's User Account. When the Customer tries to access the training material he/she will get a 'not allowed' message
New in version 3.7.0
ochSubscriptions is fully integrated with Joomla Core Privacy Tool Suite.ochSubscriptions is integrating with the Joomla Core Privacy Tool Suite. In order to use it you need to configure the Joomla Privacy Tool Suite for your site: https://docs.joomla.org/J3.x:Privacy
You can enable (enabled by default) and configure ochSubscriptions integration in the Privacy Integration tab of ochSubscriptions options:
- Enable Privacy Integration: Enable Privacy Export / Delete requests in Joomla Core Privacy Tool Suite.
- Automatic Privacy Consent: When enabled the Privacy Consent for the Customer is automatically set on account creation via checkout. When disabled (and the Joomla Core System - Privacy Consent plugin is enabled) the Privacy Consent is required on (first) login by the customer (handled by Joomla Core System - Privacy Consent plugin).
- Export User Data: Enable to Export User / Customer data.
- Export Logging Data: Enable to Export (Download / Update / Validation) logs for User.
- Export Subscriptions: Enable to Export Subscriptions for User.
- Export Transactions: Enable to Export processed Transactions for User.
- Export Temp Transactions: Enable to Export Temp (Abandoned) Transactions for User.
- Export Orders: Enable to Export Orders for User.
Privacy Consents
When 'Automatic Privacy Consent' is enabled, a Privacy Consent record will be automatically created for the user on account creation when doing a checkout.
When 'Automatic Privacy Consent' is disabled and you have enabled the Joomla Core plugin System - Privacy Consent (which is responsible for enforcing Privacy Consents), the user will be redirected to his account edit page after logging in to consent to the Privacy article configured in the System - Privacy Consent plugin. Without consenting the user cannot continue as consenting is required: this is default Joomla behavior!
When upgrading to ochSubscriptions from a version prior to 3.7.0 or when you had 'Automatic Privacy Consent' disabled but enabled it now, you can create the Privacy Consents in bulk for (selected) customers via ochSubscriptions > Customers > toolbar button [Add Privacy Consents]. This will add a Privacy Consent record for users who do not already have a consent record. The consent date will be set to the account creation date (as that is the date they consented in the checkout).
All consents can be viewed / handled in Joomla Core Users > Privacy > Consents view
Export Requests
When a user requests an export, ochSubscriptions will add the configured data exports to the exported XML file.
All export requests can be viewed / handled in Joomla Core Users > Privacy > Requests
Remove Requests
Account 'removal' is fully handled by the Joomla Core Privacy Tool Suite plugin Privacy - User Accounts. Joomla will NOT remove / delete the user account, but it will anonymize the account data (username, email) and block the account.
Important!
ochSubscriptions will NOT remove or change any data for this user account. This needs to be done manually as Customer data registered in ochSubscriptions is subject to (Tax) legislation and data retention can differ per country. You cannot delete a Customer when this customer has an invoice and / or active subscription.Important
Importing data from rd-subscriptions is only possible in ochSubscriptions versions 3.13.3ochSubscriptions has the possibility to import rd-subs version 2.10 (the lastest rd-subs versions). If you are running a lower version, you need to upgrade that first.
In the back-end > component > ochSubscriptions > sidebar menu > Import
Important, wait until you get the message ' Import finished...' in the Import Message Console.
What is imported
- All required tables are imported
- All (downloadable) files are imported
- All (downloadable) invoices are imported
What is not imported
- Tables holding temporary information (like temp_transactions, ordercodes)
- Countries Table
- Customers country field (as that is linked to a non existing country table)
- States Table
- Templates Table
Important: What needs 'attention' after import
- Access to files / categories in RD-Subs was handle via the subscription a customer had. This is now handled Joomla ACL. All files / categories have a default Access Level of Public: everybody is allowed to download! So you need to create User Groups and Access Viewing Levels for your products and assign these to the categories / files.
- All users now have 1 unique Download ID instead of 1 Download ID per subscription. This because in ochSubscriptions the Access level is determined not by the subscription but by the user's membership of User Groups. All your users should replace their RD-Subs download IDs with this new ochSubscription (User) Download ID. The ochSubscriptions system plugin has an option that can help you easy that transition.
- Also note that adding Customers to User groups (and by doing that giving them Access Viewing rights) was not a core feature of RD-Subs. This was done by a RD-Subs system plugin and was optional. in ochSubscriptions this is now required as this is the new way of securing what subscribers can and cannot do on your website!
- Invoices are imported and invoice files are copied to ochSubscriptions. When an invoice is imported you cannot (re)generate it via the back-end. This because Invoicing changed dramatically and the information needed to create an invoice is not available in the imported invoices.
- Imported invoices cannot be refunded. Refunding an imported invoice needs to be done manually.
- URL changes: note that ochSubscriptions implemented a new (front-end) SEF router, this also changes the way URL's are constructed. Remember to update your update server URL's in your Joomla extensions!
- Templates cannot be imported as these have changed a lot, a new set of templates is installed by default, you need to adjust these to your liking.
- DO NOT FORGET to disable the RD-Subs cronjobs and set the new ochSubscription cronjobs!
RD-Subs Joomla One-Click Updater Migration Helper
In order to help you and your users with a smooth transition to the new Updater URL's in your extensions and the new download id's for your users, a helper function has been created. In the ochSubscriptions plugin tab 'Advanced', you can enable the 'Handle RD-Subs requests' setting.
What this will do is redirect all requests to [yourdomain]/index.php?option=com_rdsubs&view=updater to the new ochSubscriptions URL. When a download key is provided in the URL (which is done by the Joomla One Click updater), then that download key will be replaced with the new user's download key (if found and valid). All catched and redirected requests will be logged so you can see who is still using the old RD-Subs methods and inform them / update them.
ochSubscriptions is for it's correct working depended on two cronjobs
Daily Cron (required!)
[yourdomain]/index.php?option=com_ochsubscriptions&task=cron.dailyCron&key=[yourcrontabkey]
This is the main cronjob. As the name suggests, it should only be run ONCE a day. This cronjob is responsible for (configurable in the 'automation' tab in ochSubscription options):
- Disable expired subscriptions: remove the User Groups from the User accounts
- Send expiry reminders to customers
- Check / update EU Vatrates
- Remove disabled coupons
- Remove unfinished orders
- Purge temporary transactions
- Calculate statistics
- Purge order codes
- Purge Cache
- Send queued emails
Regular Cron
[yourdomain]/index.php?option=com_ochsubscriptions&task=cron.runCron&key=[yourcrontabkey]
- Send queued emails
ochSubscriptions is equipped with a simple yet powerful system that enables you to place variables inserted into your templates into text fields. These variables are replaced by values and enable you to customize and personalize messages and text.
A variable consist of to parts: {object:field}
The object is the actual Joomla! / extension object, so all fields in these objects are available.
If an object or field is not available, the variable will not be replaced and displayed as is.
If a field is empty (not filled in by the user), the variable will be replaced with the value of the field (empty).
Templates | |||||||||||||||||||
Object | Field | Variables | Header | Footer | Page-payment-success | Page-payment-failed | Page-payment-paylater | Invoice-template | Invoice-items-template | Invoice-vat-template | Email-account-created | Email-free-product-activation | Email-invoice-send | Email-invoice-refund-send | Email-subscription-state-change | Email-subscription-expired | Email-subscription-expiry-notification | Email-payment-success | Email-payment-paylater |
config | currency | {config:currency} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x |
currency_position | {config:currency_position} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
price_vat | {config:price_vat} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
show_vat_notice | {config:show_vat_notice} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
default_country | {config:default_country} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
company_name | {config:company_name} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
company_address | {config:company_address} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
company_zip_city | {config:company_zip_city} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
Companie-country | {config:Companie-country} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
company_email | {config:company_email} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
company_website | {config:company_website} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
company_chamber | {config:company_chamber} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
company_vatnumber | {config:company_vatnumber} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
comany_accountnumber | {config:comany_accountnumber} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
comany_bicswift | {config:comany_bicswift} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
emails_sent-from_name | {config:emails_sent-from_name} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
emails_sent_from | {config:emails_sent_from} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
emails_reply_to_name | {config:emails_reply_to_name} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
emails_reply_to | {config:emails_reply_to} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
show_1st_addressline | {config:show_1st_addressline} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
show_2nd_addressline | {config:show_2nd_addressline} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
show_zipcode | {config:show_zipcode} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
show_city | {config:show_city} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
show_country | {config:show_country} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
show_state | {config:show_state} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
show_mobile | {config:show_mobile} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
show_business_registration | {config:show_business_registration} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
vat_country | {config:vat_country} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
show_country | {config:show_country} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
customer | id | {customer:id} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | ||
userid | {customer:userid} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |||
firstname | {customer:firstname} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |||
lastname | {customer:lastname} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |||
address1 | {customer:address1} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |||
address2 | {customer:address2} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |||
zipcode | {customer:zipcode} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |||
city | {customer:city} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |||
country | {customer:country} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |||
state | {customer:state} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |||
phone | {customer:phone} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |||
mobile | {customer:mobile} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |||
is_business | {customer:is_business} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |||
companyname | {customer:companyname} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |||
vatnumber | {customer:vatnumber} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |||
ip_address | {customer:ip_address} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |||
watchful_key | {customer:watchful_key} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |||
download_id | {customer:download_id} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |||
global | sitename | {global:sitename} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x |
site_url | {global:site_url} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
checkout_url | {global:checkout_url} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
user | id | {user:id} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x |
name | {user:name} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
username | {user:username} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
{user:email} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | ||
block | {user:block} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
registerDate | {user:registerDate} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
lastvisitDate | {user:lastvisitDate} | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | |
transaction | transaction_id | {transaction:transaction_id} | x | x | x | x | x | x | |||||||||||
ordercode | {transaction:ordercode} | x | x | x | x | x | x | x | |||||||||||
orderlist | {transaction:orderlist} | x | x | x | x | x | x | x | |||||||||||
orderlist_simple | {transaction:orderlist_simple} | x | x | x | x | x | x | x | |||||||||||
gross_price | {transaction:gross_price} | x | x | x | x | x | x | ||||||||||||
disco_price | {transaction:disco_price} | x | x | x | x | x | x | ||||||||||||
net_price | {transaction:net_price} | x | x | x | x | x | 0 | x | |||||||||||
vat_amount | {transaction:vat_amount} | x | x | x | x | ||||||||||||||
vat_percentage | {transaction:vat_percentage} | x | x | x | x | ||||||||||||||
action | {transaction:action} | x | |||||||||||||||||
invoice | id | {invoice:id} | x | x | x | x | x | ||||||||||||
invoice_no | {invoice:invoice_no} | x | x | x | x | x | |||||||||||||
invoice_number | {invoice:invoice_number} | x | x | x | x | x | |||||||||||||
userid | {invoice:userid} | x | x | x | x | x | |||||||||||||
ordercode | {invoice:ordercode} | x | x | x | x | x | |||||||||||||
invoicedate | {invoice:invoicedate} | x | x | x | x | x | |||||||||||||
vat_number | {invoice:vat_number} | x | x | x | x | x | |||||||||||||
paid | {invoice:paid} | x | x | x | x | x | |||||||||||||
provider | {invoice:provider} | x | x | x | x | x | |||||||||||||
transaction_id | {invoice:transaction_id} | x | x | x | x | x | |||||||||||||
invoice_type | {invoice:invoice_type} | x | x | x | x | x | |||||||||||||
refund_invoice | {invoice:refund_invoice} | x | x | x | x | x | |||||||||||||
Refund-reason | {invoice:Refund-reason} | x | x | x | x | x | |||||||||||||
invoice_send | {invoice:invoice_send} | x | x | x | x | x | |||||||||||||
refund_date | {invoice:refund_date} | x | x | x | x | x | |||||||||||||
firstname | {invoice:firstname} | x | x | x | x | x | |||||||||||||
lastname | {invoice:lastname} | x | x | x | x | x | |||||||||||||
address1 | {invoice:address1} | x | x | x | x | x | |||||||||||||
address2 | {invoice:address2} | x | x | x | x | x | |||||||||||||
zipcode | {invoice:zipcode} | x | x | x | x | x | |||||||||||||
city | {invoice:city} | x | x | x | x | x | |||||||||||||
country | {invoice:country} | x | x | x | x | x | |||||||||||||
state | {invoice:state} | x | x | x | x | x | |||||||||||||
phone | {invoice:phone} | x | x | x | x | x | |||||||||||||
mobile | {invoice:mobile} | x | x | x | x | x | |||||||||||||
is_business | {invoice:is_business} | x | x | x | x | x | |||||||||||||
companyname | {invoice:companyname} | x | x | x | x | x | |||||||||||||
vatnumber | {invoice:vatnumber} | x | x | x | x | x | |||||||||||||
vat_validation_result | {invoice:vat_validation_result} | x | x | x | x | x | |||||||||||||
invoice_vat_ic | {invoice:invoice_vat_ic} | x | x | x | x | x | |||||||||||||
vat_validation_date | {invoice:vat_validation_date} | x | x | x | x | x | |||||||||||||
ip_address | {invoice:ip_address} | x | x | x | x | x | |||||||||||||
watchful_key | {invoice:watchful_key} | x | x | x | x | x | |||||||||||||
download_id | {invoice:download_id} | x | x | x | x | x | |||||||||||||
country_3-code | {invoice:country_3-code} | x | x | x | x | x | |||||||||||||
country_2_code | {invoice:country_2_code} | x | x | x | x | x | |||||||||||||
country_2_vatcode | {invoice:country_2_vatcode} | x | x | x | x | x | |||||||||||||
requires_vat | {invoice:requires_vat} | x | x | x | x | x | |||||||||||||
force_vat_payment | {invoice:force_vat_payment} | x | x | x | x | x | |||||||||||||
amount | {invoice:amount} | x | x | x | x | x | |||||||||||||
date | {invoice:date} | x | x | x | x | x | |||||||||||||
type | {invoice:type} | x | x | x | x | x | |||||||||||||
plugin | {invoice:plugin} | x | x | x | x | x | |||||||||||||
{invoice:email} | x | x | x | x | x | ||||||||||||||
gross_price | {invoice:gross_price} | x | x | x | x | x | |||||||||||||
disco_price | {invoice:disco_price} | x | x | x | x | x | |||||||||||||
net_price | {invoice:net_price} | x | x | x | x | x | |||||||||||||
vat_amount | {invoice:vat_amount} | x | x | x | x | x | |||||||||||||
invoice_date | {invoice:invoice_date} | x | x | x | x | x | |||||||||||||
invoice_bruto | {invoice:invoice_bruto} | x | x | x | x | x | |||||||||||||
invoice_net | {invoice:invoice_net} | x | x | x | x | x | |||||||||||||
invoice_net_pre_vat | {invoice:invoice_net_pre_vat} | x | x | x | x | x | |||||||||||||
invoice_total_vat | {invoice:invoice_total_vat} | x | x | x | x | x | |||||||||||||
invoice_discount | {invoice:invoice_discount} | x | x | x | x | x | |||||||||||||
invoice_payment_provider_fee | {invoice:invoice_payment_provider_fee} | x | x | x | x | x | |||||||||||||
invoice_gross | {invoice:invoice_gross} | x | x | x | x | x | |||||||||||||
orderlist | {invoice:orderlist} | x | x | x | x | x | |||||||||||||
orderlist_simple | {invoice:orderlist_simple} | x | x | x | x | x | |||||||||||||
subscription | action | {subscription:action} | x | ||||||||||||||||
product | {subscription:product} | x | x | x | |||||||||||||||
product_alias | {subscription:product_alias} | x | x | x | |||||||||||||||
product_price | {subscription:product_price} | x | |||||||||||||||||
days | {subscription:days} | x | |||||||||||||||||
date | {subscription:date} | x | |||||||||||||||||
coupon | {subscription:coupon} | x | |||||||||||||||||
discount | {subscription:discount} | x |
Conditional Statements
You can use a simple (not nested!) conditional statement in your templates.
The conditional statement can have the following format:
{if({config:company_chamber}!= )}Chamber of Commerce#: {config:company_chamber}{endif}
When the config:company_chamber is not (!=) empty (use a space to depict empty), display the text between the {if...} and {endif}
Or a conditional statement with an {else}
{if({config:company_chamber}!= )}Chamber of Commerce#: {config:company_chamber}{else}No Chamber of Commerce number provided{endif}
When the config:company_chamber is not (!=) empty, display the text between the {if...} and {else} else (so there no value), display the text between {else} and {endif}
Operators
the following operators can be used in the if statement:
- == (equals)
- != (not equal)
- <> (not equal)
- < (less then)
- > (greater then)
- >= (greater then or equal)
- <= (less then or equal)
Number and Date Formatting
Variables that have numbers or dates as value can be formatted by adding a format code to the variable:
- price > {invoice:net_price|price} will format the invoice net_price as a price (as configured in ochSubscriptions configuration)
- date > {invoice:invoice_date|date} will format the invoice invoice date as a date (as configured in ochSubscription configuration)
- shortdate > {invoice:invoice|shortdate} will format the invoice invoice_date with the Joomla Global Language string DATE_FORMAT_LC4)
The ochpayment - PayLater plugin is part of the ochSubscriptions package
This payment plugin can be used to have customers do manual / offline bank transfers for the amount due on the invoice. This requires manual actions from both customer as shop owner.
The plugin has the following configuration settings:
- Plugin Tab:
- Payment Logo: here you can select a different logo to be displayed on the checkout page
- Custom Class: you can set a custom class on the payment button in the checkout page to be used for your own CSS
- Minimum amount: here you can set a minimum amount that needs to be bought before this payment provider is displayed. If you sell products with high values and you want to offer customers this payment provider for these high values, you can set the minimum amount here. NOTE: do not use this option if this is the only Payment provider you have installed!
- Process Order: when set to NO, the order is created in the back-end waiting for you to confirm the payment by the customer and by confirming, processing the order, when set to YES, no order will be created in the back-end and directly processed even when the user has not paid the invoice
- Create Invoice: do you want to create an invoice
- Send Invoice: do you want to send the invoice to the customer directly
- PayLater Description: show a short description of this payment provider below the button in the checkout page
- Payment Fee Type: here you can set a payment fee type for this payment provider. A payment fee is an additional amount on the checkout page / invoice for using this payment provider.
- Amount: When the Payment Fee Type is configure to amount or percentage, this is the amount or percentage on the order that will be charged.
- Advanced Tab:
- Enable Debug Info: when enabled all messages are logged in the log file for the plugin
The ochpayment - Mollie plugin is NOT part of the ochSubscriptions package. You need an additional subscription.
This payment plugin gives your customers the possibility to pay via the Mollie Checkout. Mollie is a dutch payment provider that originally started out as an iDEAL payment gateway but currently has many different payment options you can configure in the Mollie dashboard:
- iDEAL
- Creditcard
- Apple Pay (requires credit card)
- Klarna
- Paypal
- Overboeking
- Sofort
- Cadeau cart
- Bancontact
- EPS
- Giropay
- Przelewy24
- KBC/CBC Payment Button
- Belfius Direct Net
- Voucher
- SEPA-incasso
Getting Started with Mollie
- Mollie website
- Getting Started with Mollie
- Mollie on your website or platform
- Mollie supported ISO4217 Currency Codes
The plugin has the following configuration settings:
- Plugin Tab:
- Payment Logo: here you can select a different logo to be displayed on the checkout page
- Custom Class: you can set a custom class on the payment button in the checkout page to be used for your own CSS
- Order Description: A short 'message' to the customer, the ordercode will always be appended
- Mollie Description: show a short description of this payment provider below the button in the checkout page
- Payment Fee Type: here you can set a payment fee type for this payment provider. A payment fee is an additional amount on the checkout page / invoice for using this payment provider.
- Amount: When the Payment Fee Type is configure to amount or percentage, this is the amount or percentage on the order that will be charged.
- Include or Exclude Countries: Select whether to include or exclude the plugin on selected countries
- Countries: The selected countries to include or exclude the plugin on
- API Options Tab:
- Mollie Mode: Live or Test, set the mode of the plugin, use Live on production sites, test when testing
- Mollie Live API Key: the Mollie Live API key as generated for your Mollie account / site. This key will be used when Mollie Mode = Live
- Mollie Test API Key: the Mollie Test API key as generated for your Mollie account / site. This key will be used when Mollie Mode = Test
- Automatic Refund: when enabled, refunding an invoice in the ochSubscriptions back-end will automatically create a refund transaction for Mollie
- Mollie Fallback Language: Mollie will automatically try to detect the customer his language setting on the Checkout page, when not able to, this language will be used as fallback
- Currency Code: the ISO 4217 Currency Code to be used for the Mollie transactions
- Advanced Tab:
- Download ID: Personal Download ID as found on your Subscriptions page, used for the Joomla! One Click update system.
- Enable Debug Info: when enabled all messages are logged in the log file for the plugin
The ochpayment - PayPal plugin is NOT part of the ochSubscriptions package. You need an additional subscription.
This payment plugin gives your customers the possibility to pay via the PayPal Checkout. PayPal checkout will offer your Customer a dynamic set of payment options depending on variables like Country of origin. The following Payment providers are supported by PayPal
- Creditcard or debit card
- PayPal Credit
- Bancontact
- BLIK
- EPS
- Giropay
- iDEAL
- Mercado Pago
- MyBank
- Przelewy24
- SEPA-lastschrift
- Sofort
- Venmo
You need to create a set of PayPal API credentials: 1 for the production environment and 1 for the sandbox (test) environment: https://developer.paypal.com/docs/platforms/get-started/
The credentails are configured in the plugin configuration.
Getting Started with PayPal
The plugin has the following configuration settings:
- Plugin Tab:
- Payment Logo: here you can select a different logo to be displayed on the checkout page
- Custom Class: you can set a custom class on the payment button in the checkout page to be used for your own CSS
- Order Description: A short 'message' to the customer, the ordercode will always be appended
- PayPal Description: show a short description of this payment provider below the button in the checkout page
- Payment Fee Type: here you can set a payment fee type for this payment provider. A payment fee is an additional amount on the checkout page / invoice for using this payment provider.
- Amount: When the Payment Fee Type is configure to amount or percentage, this is the amount or percentage on the order that will be charged.
- API Options Tab:
- PayPal Mode: Live or Sandbox, set the mode of the plugin, use Live on production sites, sandbox when testing
- PayPal Live Client ID: the PayPal Live Client ID key as generated in your PayPal Developer Dashboard This key will be used when PayPal Mode = Live
- PayPal Live Secret:the PayPal Live Secret key as generated in your PayPal Developer Dashboard This key will be used when PayPal Mode = Live
- PayPal Sandbox Client ID: the PayPal Sandbox Client ID key as generated in your PayPal Developer Dashboard This key will be used when PayPal Mode = Sandbox
- PayPal Sandbox Secret:the PayPal Sandbox Secret key as generated in your PayPal Developer Dashboard This key will be used when PayPal Mode = Sandbox
- Automatic Refund: when enabled, refunding an invoice in the ochSubscriptions back-end will automatically create a refund transaction for PayPal
- Currency Code: the ISO 4217 Currency Code to be used for the PayPal transactions
- Advanced Tab:
- Download ID: Personal Download ID as found on your Subscriptions page, used for the Joomla! One Click update system.
- Enable Debug Info: when enabled all messages are logged in the log file for the plugin
The ochpayment - Stripe plugin is NOT part of the ochSubscriptions package. You need an additional subscription.
This payment plugin gives your customers the possibility to pay via the Stripe Checkout. Stripe checkout will offer your Customer a dynamic set of payment options depending on variables like Country of origin and device. The following Payment providers are supported by Stripe
- Creditcards
- Canadia PADs
- Afterpay / Clearpay
- Alipay
- Bancontact
- Boleto
- EPS
- FPX
- giropay
- GrabPay
- iDEAL
- OXXO
- P24
- SEPA Direct Debit
- Sofrt
- WeChat Pay
You need to create a set of PayPal API credentials: 1 for the production environment and 1 for the sandbox (test) environment: https://developer.paypal.com/docs/platforms/get-started/
The credentails are configured in the plugin configuration.
Getting Started with Stripe
Prerequisites
Before configuring the ochSubscriptions - Stripe plugin on your website you to:
- Create a Customer Account on Stripe
- In the stripe Developers Dashboard you need to copy both the Live Secret key and Test Secret key (note: NOT the publishable keys) > https://dashboard.stripe.com/apikeys
- In the stripe Developers Dashboard you need to create a WebHook endpoint for both the Live Mode as well as the Test Mode > https://dashboard.stripe.com/webhooks
- URL: https://[yourdomain]/index.php?option=com_ochsubscriptions&task=payment.webhook&processor=stripe
- Events to send (4) : payment_intent.succeeded, payment_intent.processing, payment_intent.payment_failed, payment_intent.canceled
- Configure all the Payment Methods that you want to use > https://dashboard.stripe.com/settings/payments
The plugin has the following configuration settings:
- Plugin Tab:
- Payment Logo: here you can select a different logo to be displayed on the checkout page
- Custom Class: you can set a custom class on the payment button in the checkout page to be used for your own CSS
- Order Description: A short 'message' to the customer, the ordercode will always be appended
- Push Email to Stripe: Stripe requires a Customer Email address, you can push this email from the user on your site or have the Stripe checkout page ask for it
- Enable Funding: Select the payment methods that are configured in your Stripe account (and that are working!)
- Stripe Description: show a short description of this payment provider below the button in the checkout page
- Payment Fee Type: here you can set a payment fee type for this payment provider. A payment fee is an additional amount on the checkout page / invoice for using this payment provider.
- Amount: When the Payment Fee Type is configure to amount or percentage, this is the amount or percentage on the order that will be charged.
- Include or Exclude Countries: Select whether to include or exclude the plugin on selected countries
- Countries: The selected countries to include or exclude the plugin on
- API Options Tab:
- Stripe Mode: Live or Test, set the mode of the plugin, use Live on production sites, test when testing
- Stripe Live Secret Key: the Stripe Live Secret key as generated in your Stripe Developer Dashboard. This key will be used when Stripe Mode = Live
- Stripe Test Secret Key: the Stripe Test Secret key as generated in your Stripe Developer Dashboard. This key will be used when Stripe Mode = Test
- Stripe Live WebHook Signing Secret: the Stripe webhook signing key as generated in your Stripe Developer Dashboard. This key will be used when Stripe Mode = Live
- Stripe Test WebHook Signing Secret: the Stripe webhook signing key as generated in your Stripe Developer Dashboard. This key will be used when Stripe Mode = Test
- Automatic Refund: when enabled, refunding an invoice in the ochSubscriptions back-end will automatically create a refund transaction for PayPal
- Currency Code: the ISO 4217 Currency Code to be used for the Stripe transactions, make sure you are using a Stripe supported currency > https://stripe.com/docs/currencies
- Limit WebHook to Stripe IP Addresses: setting to only process webhook request originating from Stripe.
- Advanced Tab:
- Download ID: Personal Download ID as found on your Subscriptions page, used for the Joomla! One Click update system.
- Enable Debug Info: when enabled all messages are logged in the log file for the plugin
Testing Stripe plugin
It is important that you test the configured Stripe plugin and you Stripe configuration.
- Set the plugin in Stripe Mode: Test [save]
- Set the plugin in debug mode (advanced tab)
- Testing Webhooks:
- In the Stripe development Dashboard > switch to Test Mode > Webhooks > select created WebHook endpoint > click [Send test event] and send a test event for all 4 added Events: payment_intent.succeeded, payment_intent.processing, payment_intent.payment_failed, payment_intent.canceled
- The Test Event should succeed, solve any issues that are reported
- On you website add a product to your card, login withyour / a account, select the Stripe payment method and click [Proceed to payment]
- The Stripe Checkout page should be displayed. If not fix errors reported (see: plg_ochpayment_stripe-log.php logfile)
- Test your configured and offered Payment Methods in the Stripe Checkout
If Testing is working, switch your plugin to Stripe Mode: Live.
The ochsubscriptions - AcyMailing Subscriptions plugin is NOT part of the ochSubscriptions package. You need an additional subscription.
Add AcyMailing Newsletter Lists functionality to ochSubscriptions. Both AcyMailing 5 and AcyMailing 7 are supported
When the plugin is configured and enabled, the ochSubscription Product view in the back-end gets an additional tab: 'AcyMailing Lists'
In this tab you can configure the following AcyMailing integration functionality:
- Add to AcyMailing Lists: the customer will be added to the selected AcyMailing list(s) when buying a subscription to this product
- Remove from AcyMailing Lists: the customer will be removed from the selected AcyMailing list(s) when his subscription to this product expires
You can add a customer to a different set of lists then you remove the customer from, giving you e.g. the possibility to mail this customer even when he doesn't have a valid subscription anymore for updates on this product.
The plugin has the following configuration settings:
- Plugin Tab:
- Use for AcyMailing Version: Select the version of AcyMaiing you have installed > 5 or 7 are supported
- Advanced Tab:
- Download ID: Personal Download ID as found on your Subscriptions page, used for the Joomla! One Click update system.
The content - ochSubscriptionsTools plugin is NOT part of the ochSubscriptions package. You need an additional subscription.
The ochSubscriptions Tools content plugin adds the possibility to display your products, files and files in categories automatically in your content by adding a tag in the content.
You can use the following tags:
- {ochsubscriptionstools files="[alias-file1], [alias-file2], ..."}
- {ochsubscriptionstools products="[alias-product1], [alias-product2], ..."}
- {ochsubscriptionstools category="[alias-category]"}
When any of these tags are encountered in your content the plugin will replace it with its respective rendered file, product or category. Rendering is done using the layout files used in ochSubscriptions, so template overrides you created for ochSubscriptions will also reflect on this plugin.
displaying a category will display the file(s) in that category when the current visitor has access rights to download them, if not it will automatically display the product that giver access to the files in this category
Configuration is not applicable: just enable the plugin and you are good to go!
Product example: ochSubscriptions - Tools - 6 months
File example: ochSubscriptionsTools 1.0.0
No files found or files unpublished.
Category example: ochSubscriptions Tools (subscription)
The Module- ochCross-sell is NOT part of the ochSubscriptions package. You need an additional subscription.
The ochSubscriptions Cross-sell module adds the possibility to cross-sell products in the checkout page (dynamically) based on the products that are already in the cart.
It works on any of the three checkout build-in module positions:
- checkout-cart-top
- checkout-cart-bottom
- checkout-payment-bottom
The ochCross-sell module has three types with which you can configure which products should be offered as cross-sell products:
- Related Products: The module will show the configured related products for the product(s) in the cart. The related products are configured in ochSubscriptions > product
- Fixed Products: you can configure one or more products that will be displayed regardless of what product(s) is in the cart
- Mapped Products: Here you can create your own mapping between the product(s) in the cart and what product(s) should then be shown as cross-sell product(s)
The ochCross-sell module is using a tmpl file for displaying the cross-sell products, so you can easily override the looks of the module via a Joomla template override.
Below is an overview of all Events that are triggered by ochSubscriptions. Events enable you to 'hook' into ochSubscriptions processes and add your own functionality.
File | Function | Group | Triggered Event |
administrator/libraries/.../Amount.php | __construct | ochpayment | onProviderFee |
administrator/libraries/.../ContentConstructor.php | render | ochsubscriptions | onRenderOchContentConstructor |
administrator/libraries/.../Coupon.php | getCoupon | ochsubscriptions | onDiscountBeforeApply |
administrator/libraries/.../Discount.php | apply | ochsubscriptions | onDiscountBeforeUpdate |
administrator/libraries/.../Download.php | logging | ochsubscriptions | onDownloadGetExtraData |
administrator/libraries/.../Invoice.php |
createInvoice sendInvoice |
ochsubscriptions | onInvoiceAfterCreate ochsubscriptions | onInvoiceAfterSend |
administrator/libraries/.../Payment.php |
processOrderedItems createInvoice |
ochsubscriptions | onSubscriptionAfterprocessAll ochsubscriptions | onInvoiceAfterProcess |
administrator/libraries/.../PaymentPlugin.php | response | ochsubscriptions | onShowPaymentMessage |
administrator/libraries/.../Registration.php | getUserData | user | onContentPrepareData |
administrator/libraries/.../Transaction.php | save | ochsubscriptions | onTransactionAfterSave |
administrator/models/invoice.php |
creditinvoice creditinvoice |
ochpayment | onRefund ochsubscriptions | onInvoiceBeforeRemove |
administrator/models/product.php |
save save |
ochsubscriptions | onProductBeforeSave ochsubscriptions | onProductAfterSave |
administrator/models/subscription.php |
save onSubscriptionAfterProcess onSubscriptionAfterRemove |
ochsubscriptions | onSubscriptionAfterSave ochsubscriptions | onSubscriptionAfterProcess ochsubscriptions | onSubscriptionAfterRemove |
administrator/views/product/view.html.php | addToolbar | ochsubscriptions | onProductAddToolbar |
administrator/views/product/tmpl/edit.php | ochsubscriptions | onProductShowTab | |
site/controllers/download.php |
file invoice |
ochsubscriptions | onFileBeforeDownload ochsubscriptions | onInvoiceBeforeDownload |
site/controllers/signup.php |
register register register checkout validateUserInput |
ochsubscriptions | onBeforeSaveUserDetails ochsubscriptions | onAfterSaveUserDetails ochsubscriptions | onBeforePaymentRedirect ochsubscriptions | onBeforePaymentRedirect captcha | onCheckAnswer |
site/controllers/updater.php | download | ochsubscriptions | onFileBeforeDownload |
site/models/checkout.php |
getProcessors updateProductQuantityInCart removeProduct |
ochpayment | onDisplay ochsubscriptions | onCheckoutAfterChangeOrder ochsubscriptions | onCheckoutAfterRemoveorder |
site/models/order.php | addProductToOrder | ochsubscriptions | onProductAfterOrder |
site/models/payment.php |
process response webhook |
ochpayment | onProcess ochpayment | onResponse ochpayment | onWebhook |
plugin/system/ochsubscriptions.php | onUserAfterSave | ochsubscriptions | onCustomerAfterSave |
Joomla Extension manifest file (xml)
<changelogurl>[your-domain]/index.php?option=com_ochsubscriptions&view=changelog&format=xml&element=[element-name]</changelogurl>
<updateservers>
<server type="extension" name="[the-name-of-your-extension]">[your-domain]/index.php?option=com_ochsubscriptions&view=updater&format=xml&element=[element-name]</server>
</updateservers>
<dlid prefix="key=" />
Where [element-name] is the name used in the file tab 'Joomla Updater', and [your-domain] is the base URL to your server.
Validating Download ID
With this function you can provide information to your customer regarding the validity of the subscription. In my own extensions / plugins I have set it to warn the customer when the subscription will expire in 30 days, when downloading a new version a warning message will then be generated, or when saving the component / plugin configuration.
(see OchHelper class method validateDownloadId)
[Joomla 3] Adding Download ID to Joomla updater download request
(see OchHelper class method prepareUpdate for components)
(see any of my plugins, method onInstallerBeforePackageDownload)
Build-in Module Positions
For offering you maximum flexibility, the checkout page has three module positions with which it is possible to add your own content to the page:
- checkout-cart-top
- checkout-cart-bottom
- checkout-payment-bottom
JavaScript functions
Adding products to the checkout page without having to reload the checkout page can be done with JavaScript.
e.g. You want to add a button on the checkout page to give the Customer the possibility to add an additional product to the cart.
You can add that button via a Joomla Custom HTML module and place it on any of the three available module positions.
The button / link you want the customer to click to add the product should have the following onClick event:
onclick="OCH.doAddProduct(XYZ, event);
where XYZ is the ID of the product you want to add.
Checkout / Cart indicator
New in Version 3.11.0: option to add an indicator to your checkout menu item.
ochSubscriptions (the system plugin) will add a JS variable to your page source when there is one or more product in the checkout / cart. You need to create a JS script to read that value and set an indicator on the checkout menu item (can be any indicator). Below the script I am using on my own site.
Prerequisites / notes:
- The 'checkout' menu item has a class named 'checkout-counter', with this class I can identify the menu item
- My template is build on Bootstrap 5 so the indicator wil be using Bootstrap 5 build in functionality
Script:
The script will be executed when the page is fully loaded. It will then read the com_ochsubscriptions Joomla JS options set on the page. Next it will check if in the JS options variable a key/value 'checkout_counter' is set: the checkout_counter will hold the number of products in the checkout / cart, or 0 / non-existing when no products in the cart.
When the 'checkout_counter' is not 0, the the script will add a <span> with the (numbered) indicator and the 'not-empty' class to the relevant menu item.
(function (document) {
"use strict";
document.addEventListener("DOMContentLoaded", function () {
const ochSubscriptions =
Joomla.getOptions("com_ochsubscriptions") || [];
if (ochSubscriptions.checkout_counter) {
let checkout_menu = document.querySelectorAll(".checkout-counter");
const spanElement = document.createElement("span");
spanElement.setAttribute(
"class",
"position-absolute translate-middle badge rounded-pill bg-danger"
);
spanElement.innerHTML = ochSubscriptions.checkout_counter;
checkout_menu.forEach((menu) => {
menu.classList.add("not-empty");
menu.appendChild(spanElement);
});
}
});
})(document, Joomla);
Tips & Tricks
- You can automatically add a coupon code to the checkout by adding ?coupon=[couponcode] to the URL. the ochSubscriptions system plugin has a build in 'coupon catcher' and will add the coupon to the session.
Technical support and feature requests via our forum (You need a valid subscription to be able to post)