Analytics Software Sustaining EngineerAltura Associates, LLC is a professional services firm focused on improving energy, environmental, and financial performance across all levels of an organization. We go beyond traditional consulting, using a people-centric approach designed to make immediate and lasting performance improvements.

Selling on StackHub

Products & Licenses

How to be a Vendor

Organizations may sell products and licences on StackHub. To do so, 3 things are required:

  1. A Product to Sell
  2. A Page to Sell It On
  3. A Stripe Account to Receive Funds
A Product to Sell

Products may be created on the My Products page.

A product can either sell a StackHub package, a bundle of points, or both. Generated license files may then be (optionally) constrained for use by a specific SkyArc license, or a SkyArc orgaanization, and given an expiry date. These details are expressed as properties in the license file.

You may also add custom properties to license files should you wish to encode extra details.

Note that individual licence files may be hand edited by the vendor after a sale.

A Page to Sell It On

Products may only be sold from Product (and Organisation) pages. That is, the links and buttons to buy products are only visible on vendor pages. Therefore to sell a product, you need a vendor page to advertise it on.

Pages may be created on the My Pages page.

If you have multiple vendor pages, you may optionally choose which pages contain links to sell which products.

A Stripe Account to Receive Funds

StackHub uses the Stripe Platform to process all payments. Therefore to receive funds from your sales, you need a Stripe account.

A Stripe account is easy to set up and their intuitive dashboard gives you instant access to payment history and bank account transfers.

License Validation

When a product is sold, StackHub generates a securely signed license file on your behalf. The customer should install the package and license on their system, but it is up to you to check that a valid licence exists for the package.

This necessitates a bit of custom code to perform the following:

  1. Find a license file for your packge
  2. Verify the signature property is valid
  3. Verify the constraint properties are valid
  4. Disable the package (or limit functionality) should the license be invalid

If your product runs on SkyArc (SkySpark, FinStack, etc, ...) then typically you would create a Fantom extension that overrides the onStart() method. There it should then use the StackHubLic class to find a license related to your product and check that it is valid. If it is not, then you should disable your extension.

Note that SkySpark will automatically mark a license as invalid if:

  1. The signature property is invalid
  2. It contains an out of date expires property.
  3. It contains a skyarcLic property that does not match the SkyArc License Number.
  4. It contains a skyarcOrg property that does not match the SkyArc Organization ID (or subOrg ID).

Validation of any other license property requires custom Fantom code.

Note that even though a license is invalid, it is still up to you to disable your extension.

See LicHelper for sample code on how to validate licenses. Contact StackHub should you require help with this process.


The Fantom class can help you find valid StackHub licences for your product on SkyArc systems such as SkySpark and FinStack. Note that the StackHubLic class and extension disabling feature is only available in SkySpark 3.0.13 or later.

Copy and paste the Fantom class from the GitHub Snippet below into your SkyArc project.


Repeated calls to the findXXX() methods whittle down the number of valid licences until one is left. The remaining licence may be retrieved with get().

A LicErr is thrown should no licence match the given criteria. This may be caught to disable the containing SkyArc extension.

Licence validation may be performed during the extension onStart() event. Typical usage would be:

using skyarcd::Ext
using skyarcd::ExtMeta
using haystack::Ref
using stackhub::StackHubLic
@ExtMeta { name = "acmeExt" }
const class AcmeExt : Ext {
    ** Validate the licence file.
    final override Void onStart() {
        try {
            lic := LicHelper(sys)
                .findVendor(Ref("87654321-87654321", "Acme"))
                .findPackage(Depend("acmeExt 1.0"))
            cap := LicHelper.parseCapacity(lic)
            // ... validate licence capacity here ...
  "${lic.product.dis} licensed to ${lic.licensee} --> okay")
        } catch (LicErr err) {
            // if a valid licence can not be found, disable this extension
            StackHubLic.extToFault(this, err.msg)

Note findVendor() should be called with your StackHub Vendor ID available from the My Products page.

findPackage() should probably be called with the details of the current pod:

findPackage(Depend("${} ${typeof.pod.version}"))

Issuing Refunds

When a product is purchased, the flow of funds through Stripe is as follows:

  Customer --> You (the Vendor) --> StackHub (& Stripe)

When a customer buys a product, the full amount is paid to your Stripe account. Stripe then immediately and automatically transfers a percentage fee to StackHub, and takes a small transaction fee for themselves.

Should a customer wish for a refund, they should contact yourselves directly.

The onus is then on you to find the payment in your Stripe account (under Payments) and refund it.