How to Sell Access Keys

By default, Kadence Cloud has a built-in simple system to allow you to generate access keys. You can use them for yourself, and/or share them. However, if you want to sell access keys we recommend using a more robust access key generation tool. One that integrates with WooCommerce, syncs with a product, and generally provides more control.

Our favorite solution is WooCommerce Software License. It works really well with subscriptions and allows the user to generate keys for themselves. It however is not free.

Another great option that is free is License Manager for WooCommerce. In this tutorial we will cover the basics for both.

We have covered the entire setup in a video which goes over the enitre setup process.

Step 1. Create your Cloud Access Product

In this tutorial, we won’t cover using WooCommerce Subscriptions but the process is similar. Create a new product, set it as virtual, and depending on which plugin you are using set up the license configuration.

WooCommerce Software License

License Manager for WooCommerce

Step 2. Connect Kadence Cloud to License Check

For this step, you need to add a custom PHP filter depending on which license manager plugin you are using. For that, I suggest using a code snippet plugin to add the PHP filter.

WooCommerce Software License Filter Setup

The PHP filter below will check if the license is valid and if it’s activated for the domain of the request site. If it’s activated then it will return true and if it’s not yet been activated for the domain it will try to activate. If the key is not valid or is already used on the max number of sites it will prevent access.

*NOTE: Be sure to change out PRODUCT_UNIQUE_ID with the Unique ID you set when creating your product in the license configuration (line 22).

/**
 * Validates license with WooCommerce Software License.
 *
 * @param Boolean         $access true or false based on access.
 * @param String          $key the access key.
 * @param WP_REST_Request $request full details about the request.
 * @return Boolean based on if access should be granted.
 */
function custom_check_cloud_access( $access, $key, $request ) {
	// If true the key matches with settings in Kadence Cloud. Let that pass for testing purposes.
	if ( $access ) {
		return $access;
	}
	// Make sure WooCommerce Software License exists.
	global $WOO_SL_API;
	if ( $WOO_SL_API ) {
		$site = preg_replace('(^https?://)', '', $request->get_param( 'site' ) );
		$args =   array(
			'licence_key'       => $key,
			'domain'            => $site,
			'woo_sl_action'     => 'status-check',
			'product_unique_id' => 'PRODUCT_UNIQUE_ID',
		);
		$response = $WOO_SL_API->API_call( $args );
		$response = json_decode( $response );
		end( $response );
		$response_data = current( $response );
		if ( is_object( $response_data ) && 'success' === $response_data->status ) {
			// Lets activate it for this domain if it's not.
			if ( $response_data->status_code && 's203' === $response_data->status_code ) {
				$args['woo_sl_action'] = 'activate';
				$response = $WOO_SL_API->API_call( $args );
			}
			return true;
		} else if ( is_object( $response_data ) && 'error' === $response_data->status ) {
			// Lets activate it for this domain if possible.
			if ( $response_data->status_code && 'e204' === $response_data->status_code ) {
				$args['woo_sl_action'] = 'activate';
				$response = $WOO_SL_API->API_call( $args );
				$response = json_decode( $response );
				end( $response );
				$response_data = current( $response );
				if ( is_object( $response_data ) && 'success' === $response_data->status ) {
					return true;
				} else {
					return false;
				}
			} else {
				return false;
			}
		} else {
			return false;
		}
	}
	return $access;
}
add_filter( 'kadence_cloud_rest_request_access', 'custom_check_cloud_access', 10, 3 );

If you want to limit your WooCommerce Software License access keys to a specific collection in your cloud you can do that using the following filter. You will just need to replace the “COLLECTION_SLUG” on line 4 with the slug you want to send.

/**
 * Set access to a specific cloud library collection.
 *
 * @param array  $args the query args for retrieving items.
 * @param string $key the access key.
 * @param array  $request_extras the extra args for the request.
 * @return array with updated query args.
 */
function custom_kadence_cloud_query_args( $args, $key, $request_extras ) {
	if ( ! isset( $args['tax_query'] ) ) {
		$args['tax_query'] = array(
			array(
				'taxonomy' => 'kadence-cloud-collections',
				'field' => 'slug',
				'terms' => array( 'COLLECTION_SLUG' ),
			),
		);
	}
	return $args;
}
add_filter( 'kadence_cloud_template_query_args', 'custom_kadence_cloud_query_args', 10, 3 );

Selling Multiple Collections with WooCommerce Software License

Let’s say you have more than one collection that you want to sell on your site. An easy way to accomplish this is by defining custom prefixes per product license generation.

Now we will change out the two functions above to match up our license keys with the correct collection. For this example, the first collection is going to have a slug of COLLECTION_ONE and the second collection is going to have a slug of COLLECTION_TWO. The license generator for collection one is going to have a prefix of col_one and the license generator for collection two is going to have a prefix of col_two. Finally, the Unique product IDs also have to be connected so for collection one in this example the product id is PRODUCT_UNIQUE_ID and for collection two it’s PRODUCT_UNIQUE_ID_TWO.

/**
 * Validates license with WooCommerce Software License.
 *
 * @param Boolean         $access true or false based on access.
 * @param String          $key the access key.
 * @param WP_REST_Request $request full details about the request.
 * @return Boolean based on if access should be granted.
 */
function custom_check_cloud_access( $access, $key, $request ) {
	// If true the key matches with settings in Kadence Cloud. Let that pass for testing purposes.
	if ( $access ) {
		return $access;
	}
	// Make sure WooCommerce Software License exists.
	global $WOO_SL_API;
	if ( $WOO_SL_API ) {
		if ( substr( $key, 0, strlen( 'col_one' ) ) === 'col_one' ) {
			$product_id = 'PRODUCT_UNIQUE_ID';
		} else {
			$product_id = 'PRODUCT_UNIQUE_ID_TWO';
		}
		$site = preg_replace('(^https?://)', '', $request->get_param( 'site' ) );
		$args =   array(
			'licence_key'       => $key,
			'domain'            => $site,
			'woo_sl_action'     => 'status-check',
			'product_unique_id' => $product_id,
		);
		$response = $WOO_SL_API->API_call( $args );
		$response = json_decode( $response );
		end( $response );
		$response_data = current( $response );
		if ( is_object( $response_data ) && 'success' === $response_data->status ) {
			// Lets activate it for this domain if it's not.
			if ( $response_data->status_code && 's203' === $response_data->status_code ) {
				$args['woo_sl_action'] = 'activate';
				$response = $WOO_SL_API->API_call( $args );
			}
			return true;
		} else if ( is_object( $response_data ) && 'error' === $response_data->status ) {
			// Lets activate it for this domain if possible.
			if ( $response_data->status_code && 'e204' === $response_data->status_code ) {
				$args['woo_sl_action'] = 'activate';
				$response = $WOO_SL_API->API_call( $args );
				$response = json_decode( $response );
				end( $response );
				$response_data = current( $response );
				if ( is_object( $response_data ) && 'success' === $response_data->status ) {
					return true;
				} else {
					return false;
				}
			} else {
				return false;
			}
		} else {
			return false;
		}
	}
	return $access;
}
add_filter( 'kadence_cloud_rest_request_access', 'custom_check_cloud_access', 10, 3 );

Next we want to limit access to the correct collection based on the license key. We can do that with the following function.

/**
 * Set access to a specific cloud library collection.
 *
 * @param array  $args the query args for retrieving items.
 * @param string $key the access key.
 * @param array  $request_extras the extra args for the request.
 * @return array with updated query args.
 */
function custom_kadence_cloud_query_args( $args, $key, $request_extras ) {
	if ( substr( $key, 0, strlen( 'col_one' ) ) === 'col_one' ) {
		$args['tax_query'] = array(
			array(
				'taxonomy' => 'kadence-cloud-collections',
				'field' => 'slug',
				'terms' => array( 'COLLECTION_ONE' ),
			),
		);
	} else {
		$args['tax_query'] = array(
			array(
				'taxonomy' => 'kadence-cloud-collections',
				'field' => 'slug',
				'terms' => array( 'COLLECTION_TWO' ),
			),
		);
	}
	return $args;
}
add_filter( 'kadence_cloud_template_query_args', 'custom_kadence_cloud_query_args', 10, 3 );

License Manager for WooCommerce filter setup

The PHP filter below will check if the license is valid. It won’t be able to check based on a max number of sites but more simply to see if the license is valid or not.

/**
 * Validates license with license manager for woocommerce.
 *
 * @param Boolean         $access true or false based on access.
 * @param String          $key the access key.
 * @param WP_REST_Request $request full details about the request.
 * @return Boolean based on if access should be granted.
 */
function custom_check_cloud_access( $access, $key, $request ) {
	// If true the key matches with settings in Kadence Cloud.
	if ( $access ) {
		return $access;
	}
	// Make sure license manager for woocommerce exists.
	if ( class_exists( 'LicenseManagerForWooCommerce\Repositories\Resources\License' ) ) {
		$license = \LicenseManagerForWooCommerce\Repositories\Resources\License::instance()->findBy(
			array( 'hash' => apply_filters( 'lmfwc_hash', $key ) )
		);
		if ( ! $license ) {
			// No license was found.
			return false;
		} else {
			// Check if expired.
			$expiresAt = $license->getExpiresAt();
			$dateExpiresAt = new DateTime($expiresAt);
			$dateNow = new DateTime('now', new DateTimeZone('UTC'));
			if ( $dateNow < $dateExpiresAt ) {
				return false;
			}
			// Make sure it shows "activated".
			if ( intval( $license->getTimesActivated() ) < 1 ) {
				$timesActivatedNew = 1;
				$updatedLicense = \LicenseManagerForWooCommerce\Repositories\Resources\License::instance()->update(
					$license->getId(),
					array(
						'times_activated' => $timesActivatedNew
					)
				);
			}
			// We have success lets return true.
			return true;
		}
	}
	return $access;
}
add_filter( 'kadence_cloud_rest_request_access', 'custom_check_cloud_access', 10, 3 );