UBERCART PRODUCT KEYS This is a quick intro to the uc_product_keys module. TERMINOLOGY ----------- Product key - A string of text used to unlock or activate a software product. Product key sequence - A collection of product keys, any of which can be used to unlock or activate a specific software product. Dynamic sequences - A product key sequence where all keys are generated dynamically by some external code. Activation - The process by which the sofware becomes operational. It usually involves having the software communicate with an activation server. Revokation - If a license is revoked, any attempt to activate it the software will be denied. This may not shut down any activated programs, but will prevent the product key from being used to activate any more products. CONCEPTUAL MODEL ---------------- 1. Create a software product. 2. Create a mechanism for generating product keys. 3. Place code in the software which prevents the software from working without a valid product key. 4. Create a product sequence for the product. 5. Create the Ubercart product that sells the product key. 6. Tell the product to use the sequence you created. 7. If product keys are generated off-line, generate a batch of keys, encrypt them if necessary and import them into the database. 8. User downloads software. 9. User purchases product key. If product keys are dynamically generated, uc_product_keys will ask your code to generate the keys and will send them to the customer. A non-dynamic key is taken from the database. If uc_stock is used, the stock count will be decremented. 10. User enters product key into the software and software becomes operational. Alternatively, 10. User enters product key and software communicates with the Web site (using code you create). The software sends an installation ID and the server returns an activation ID. This makes the program operational. 11. The code can increment the activation count in the database. It can also check for the revokation flag and avoid sending the activatioon code. PLEASE NOTE! ------------ If an administrator creates an order and the product is associated with a product key sequence, a product key is not generated unless the order is enters the 'payment_received' or 'completed' states. Once an order is completed, you should not add or remove products associated with product keys to the order. Create a new order if you want to issue a new product key to a customer. If you add products to a completed order, no product keys will be generated. If you remove products from an order, the product keys are not deleted. ------------ USER INTERFACE -------------- Permissions: administer product keys view everyone's product keys Everyone can always view the product keys they have purchased. Where to find things: Home » Administer » Store administration » Products » Product keys Administer product keys Home » <Product> » Edit (fieldset "Product key") Associate a product with a product key sequence Home » <Product> » Edit » Product keys Lists all product keys associated with this product Home » My account » Product keys Lets users view their product keys Product key sequence features: You can create, rename, edit and delete product sequences. If you delete a sequence, any assigned product keys stay in the database. Unassigned keys are deleted. Product key features: You can import product keys using one of two formats: 1. sequence name<tab>key<eol> 2. sequence name<eol> key<eol> more of same key<eol> .<eol> The first format has one key per line. You create this in a spreadsheet and output it as a tab-separated-values file. The second format allows for multi-line keys. The key ends when the software finds a line containing only a specific string ("." by default). Once imported, you can view all keys, delete unassigned keys and revoke (or unrevoke) assigned keys. Table variations Tables are used to display sequences and keys. If you have admin access, the tables will display all fields and some fields may be editable. If you have "view everyone's keys" access, you can view all fields, but none will be editable. If you have neither, you can obly view keys you have purchased and you get to see only a few fields. To view all product keys, go to Home » Administer » Store administration » Products » Product keys To view all product keys associated with one product, go to Home » <Product> » Edit » Product keys To view all product keys associated with one customer, go to <User's account page> » Product keys EXTENDING THE MODULE -------------------- Sample module There is a sample extension module in the uc_product_keys_sample sub-directory that demonstrates how to extend uc_product_keys. You can also use this module as a starting point for your own extensions. If you don't plan to use uc_product_keys_sample, delete it, zip it or move it out of the Drupal tree. Unfortunately, Drupal.org does not allow me to check in the file in ZIP or GZ format. To view the module in action, enable it on the Module page. Extending the database You will often want to add your own data fields to the product keys and product key sequences. To do so, create your own module. In the module.install file, in hook_install(), use db_add_field() to add your own fields to uc_product_keys and uc_product_key_sequences (you may want to namespace the field names to avoid collisions with future enhancements I make to the tables). Your fields will be automatically loaded and saved along with the standard fields. You will also benefit from the cache. Hooks hook_uc_product_keys_sequence_api() This hook allows you to extend product key sequences. $arg1 - If $op is 'load_multiple', then $arg1 is an array of product key sequence objects. Otherwise, it is a single product key sequence object. $op - The operation being performed. Possible values: load - A product key sequence has been loaded. You may add extra data to the sequence. load_all - All product key sequences have been loaded. You may add extra data to the sequences. insert - A product key sequence has been inserted into the database. update - An existing product key sequence has been updated. delete - An existing product key sequence has been deleted. </ul> Returns true if the operation succeeded; false otherwise. ********** hook_uc_product_keys_api() This hook allows you to extend product keys. $arg1 - If $op is 'create_multiple' or 'load_multiple', then $arg1 is an array of product key objects. Otherwise, it is a single product key object. $op - The operation being performed. Possible values: create_multiple - For dynamically created keys, you will need to at least fill in the product_key field. You may also add extra data to the keys. The $other parameter is an associative array containing references to: product - The product node associated with this key. user - The user who is purchasing the key. order - The order associated with this key. order_product - The specific line item on the order associated with this key. load - A product key has been loaded. You may add extra data to the key. load_multiple - A set of product keys have been loaded. You may add extra data to the keys. The $sequence parameter will be null and the keys may belong to different sequences. insert - A product key has been inserted into the database. update - An existing product key has been updated. delete - An existing product key has been deleted. $sequence - The sequence object associated with the key. In some cases, this may be null. $other - An array containing additional information. See $op. Returns true if the operation succeeded; false otherwise. ********** hook_uc_product_keys_theme_list_api() This hook makes it easier to theme new values added to the sequence or product key list displays. $op - The operation being performed. Possible values are: sequence_header - Supply a array of header names for any new items added to the sequence listing. sequence_row - Supply the matching row values for the new items added to the sequence listing. key_header - Supply a array of header names for any new items added to the key listing. key_row - Supply the matching row values for the new items added to the key listing. key_long_header - Supply a array of header names for any new items added to the key listing whose values may be very long. key_long_row - Supply the matching row values for the new long items added to the key listing. $a1 - The header or row array in which to place names or values. $form - The form (only present for rows; otherwise, an empty array is passed). $obj - The sequence or key associated with a particular row (only present for rows; otherwise, null is passed). ********** hook_uc_product_keys_decrypt($product_key) If you want to encrypt the product keys in the database, you will need to implement this hook in order to decrypt the keys. The keys will always be displayed in their decrypted form. $product_key - An encrypted product key Returns the decrypted product key There needs to be a hook for reading extra fields when importing keys. This is on my TO-DO list and I'm not sure how best to implement it. ********** hook_uc_product_keys_order_ready($order, $status) This hook allows you to specify the whether an order is ready to have the product keys delivered to the customer. It is only called when the order is being updated. You will need to decide if the order is ready to have product keys issued to the customer (return TRUE) or is not ready (return FALSE) or you don't know (return NULL). If any module returns FALSE, the keys are not issued. If one or more modules return TRUE (and none return FALSE), the keys are issued. If all modules return NULL or if there are no hook methods implemented, a default test is used: the order has transitioned to the payment_received or completed states. You will need this hook in case you are using a payment module where you don't want the keys issued on one or the other or both states. Typically, you will check the payment type. If it is one you want to control, you will return TRUE or FALSE. Otherwise, you will return NULL. Even if all hooks report that the order is ready, keys are never issued for any order that already has keys. (We perform the hook check first to avoid the database access needed for the second check). $order - The order (with the old order status). $status - The new order status (note: *not* the order state). Returns TRUE if the product keys should be assigned; FALSE if it should not be assigned and NULL if the hook method doesn't know the right answer. Utility Functions These functions allow you to hook your activation and revokation code to the database. Get a product key from the database by name. uc_product_keys_get_key($product_key) $product_key - The (encrypted) product key string to use to find a product key in the database. Returns - The product key object. Increment the number of activations of a product_key. uc_product_keys_increment_activation($product_key) $product_key - The (encrypted) product key string to use to find a product key in the database. Sets the revoke flag for this key. You will need to check the flag in your product activation code in order to make this be meaningful. uc_product_keys_revoke_key($product_key) $product_key - The (encrypted) product key string to use to find a product key in the database.