How to sell keys from one site for libraries hosted on another.

If you are interested in selling cloud library access you may perhaps want to have Woocommerce and your shop on a different WordPress install then the location of your cloud library. For example the shop where you sell your library might be on the domain buycloudlibrary.com and the actual cloud library could be on a sub domain like modern.buycloudlibrary.com

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

Step 1. Create your Cloud Access Product (WooCommerce Site)

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.

Let’s assume 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.

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.

It’s important to note the customer will need to know the url of your cloud site in our example that is a subdomain. It’s important that you put that in the product description or in the product order information so the customer knows what url to add to Kadence Cloud when making the connection.

Step 2. Connect Kadence Cloud to License Check (Cloud Site)

For this step, you need to add a custom PHP filter. For that, I suggest using a code snippet plugin to add the PHP filter. You will be adding this snippet to the site where you have your Kadence Cloud and not the site where WooCommerce is installed.

The following snippet will get the key used for access and remote query the site where you have WooCommerce and WooCommerce Software License running to verify its validity. It’s important that you change out “https://buycloudlibrary.com” with the URL for where you have woocommerce running.

/**
 * 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;
	}
	// Define woocommerce site.
	$api_url = 'https://buycloudlibrary.com';
	// Determine product ID based on key.
	if ( substr( $key, 0, strlen( 'col_one' ) ) === 'col_one' ) {
		$product_id = 'PRODUCT_UNIQUE_ID';
	} else {
		$product_id = 'PRODUCT_UNIQUE_ID_TWO';
	}
	// Get the requester site.
	$site = preg_replace('(^https?://)', '', $request->get_param( 'site' ) );
	$args = array(
		'woo_sl_action'      => 'status-check',
		'licence_key'        => $key,
		'product_unique_id'  => $product_id,
		'domain'             => $site,
	);
	$request_uri = $api_url . '?' . http_build_query( $args );
	$data = wp_safe_remote_get( $request_uri );
	// Couldn't Access the api site.
	if ( is_wp_error( $data ) || $data['response']['code'] != 200 ) {
		return $access;
	}

	$data_body = json_decode( $data['body'] );
	if ( ! is_object( $data_body ) && isset( $data_body[0] ) && is_object( $data_body[0] ) ) {
		$data_body = $data_body[0];
	}
	if ( isset( $data_body->status) ) {
		if ( $data_body->status == 'success' ) {
			// Lets activate it for this domain if it's not.
			if ( $data_body->status_code && 's203' === $data_body->status_code ) {
				$args['woo_sl_action'] = 'activate';
				$request_uri = $api_url . '?' . http_build_query( $args );
				$second_data = wp_safe_remote_get( $request_uri );
			}
			//the license is active and the software is active
			return true;
		} elseif ( $data_body->status == 'error' ) {
			// Lets activate it for this domain if possible.
			if ( $data_body->status_code && 'e204' === $data_body->status_code ) {
				$args['woo_sl_action'] = 'activate';
				$request_uri = $api_url . '?' . http_build_query( $args );
				$second_data = wp_safe_remote_get( $request_uri );
				// Couldn't Access the api site.
				if ( is_wp_error( $second_data ) || $second_data['response']['code'] != 200 ) {
					return $access;
				}
				$response = json_decode( $second_data );
				end( $response );
				$response_data = current( $response );
				if ( is_object( $response_data ) && 'success' === $response_data->status ) {
					return true;
				} else {
					return $access;
				}
			}
			return $access;
		}
	}
	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 );