diff --git a/modules/wps/commerce_paypal_wps.info b/modules/wps/commerce_paypal_wps.info
index 42460e5..9533eeb 100644
--- a/modules/wps/commerce_paypal_wps.info
+++ b/modules/wps/commerce_paypal_wps.info
@@ -8,5 +8,8 @@ dependencies[] = commerce_order
 dependencies[] = commerce_paypal
 core = 7.x
 
+; Rules
+files[] = commerce_paypal_wps.rules.inc
+
 ; Simple tests
 ; files[] = tests/commerce_paypal_wps.test
diff --git a/modules/wps/commerce_paypal_wps.module b/modules/wps/commerce_paypal_wps.module
index fc9ef8a..6ac55d2 100644
--- a/modules/wps/commerce_paypal_wps.module
+++ b/modules/wps/commerce_paypal_wps.module
@@ -46,6 +46,13 @@ function commerce_paypal_wps_default_settings() {
     'ipn_logging' => 'notification',
     'show_payment_instructions' => FALSE,
     'ipn_create_billing_profile' => FALSE,
+    'subscription_access' => 0,
+    'subscription' => array(
+      't3' => 'D',    
+      'p3' => '',
+      'src' => FALSE,
+      'sra' => FALSE,
+    ),    
   );
 }
 
@@ -122,6 +129,53 @@ function commerce_paypal_wps_settings_form($settings = array()) {
     '#description' => t('This is most useful for sites that do not collect billing information locally but still want to have customer names on orders.'),
     '#default_value' => $settings['ipn_create_billing_profile'],
   );
+  
+  // Subscriptions
+  $form['subscription_access'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Subscription payment'),
+    '#default_value' => $settings['subscription_access'],
+  );
+  $form['subscription'] = array(
+    '#type' => 'fieldset',
+    '#tree' => TRUE,
+    '#title' => t('Subscription settings'),
+    '#states' => array(
+      'visible' => array(   // action to take.
+        ':input[name="parameter[payment_method][settings][payment_method][settings][subscription_access]"]' => array('checked' => TRUE),
+      ),
+    ),
+  );
+  $form['subscription']['t3'] = array(
+    '#type' => 'select',
+    '#title' => t('Regular subscription units of duration (t3)'),
+    '#options' => array(
+      'D' => 'D – for days; allowable range for p3 is 1 to 90',
+      'W' => 'W – for weeks; allowable range for p3 is 1 to 52',
+      'M' => 'M – for months; allowable range for p3 is 1 to 24',
+      'Y' => 'Y – for years; allowable range for p3 is 1 to 5',
+    ),
+    '#default_value' => $settings['subscription']['t3'],
+  );
+  $form['subscription']['p3'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Subscription duration (p3)'),
+    '#description' => t('Specify an integer value in the allowable range for the units of duration that you specify with t3.'),
+    '#default_value' => $settings['subscription']['p3'],
+    '#element_validate' => array('element_validate_integer')
+  );  
+  $form['subscription']['src'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Infinite recurring payments (src)'),
+    '#description' => t('If set to “1,” the payment will recur unless your customer cancels the subscription before the end of the billing cycle. If omitted, the subscription payment will not recur at the end of the billing cycle.'),
+    '#default_value' => $settings['subscription']['src'],
+  );
+  $form['subscription']['sra'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Reattempt on failure (sra)'),
+    '#description' => t('If set to “1,” and the payment fails, the payment will be reattempted two more times. After the third failure, the subscription will be cancelled. If omitted and the payment fails, payment will not be reattempted and the subscription will be immediately cancelled.'),
+    '#default_value' => $settings['subscription']['sra'],
+  );  
 
   return $form;
 }
@@ -236,6 +290,11 @@ function commerce_paypal_wps_paypal_ipn_validate($order, $payment_method, $ipn)
  * Payment method callback: process an IPN once it's been validated.
  */
 function commerce_paypal_wps_paypal_ipn_process($order, $payment_method, &$ipn) {
+  if (!empty($ipn['txn_type']) && substr($ipn['txn_type'], 0, 6) == 'subscr') {
+    // Invoke a rule event for subscription related IPNs
+    rules_invoke_all('commerce_paypal_wps_subscr_ipn', $order, $ipn['txn_type']);
+  }
+  
   // Do not perform any processing on WPS transactions here that do not have
   // transaction IDs, indicating they are non-payment IPNs such as those used
   // for subscription signup requests.
@@ -380,11 +439,11 @@ function commerce_paypal_wps_order_form($form, &$form_state, $order, $settings)
 
   // Ensure a default value for the payment_method setting.
   $settings += array('payment_method' => '');
-
+  
   // Build the data array that will be translated into hidden form values.
   $data = array(
     // Specify the checkout experience to present to the user.
-    'cmd' => '_cart',
+    'cmd' => !empty($settings['subscription_access']) ? '_xclick-subscriptions' : '_cart',
 
     // Signify we're passing in a shopping cart from our system.
     'upload' => 1,
@@ -423,13 +482,37 @@ function commerce_paypal_wps_order_form($form, &$form_state, $order, $settings)
     // Use the timestamp to generate a unique invoice number
     'invoice' => commerce_paypal_ipn_invoice($order),
 
-    // Define a single item in the cart representing the whole order
-    'amount_1' => commerce_currency_amount_to_decimal(commerce_currency_convert($amount, $order_currency_code, $currency_code), $currency_code),
-    'item_name_1' => t('Order @order_number at @store', array('@order_number' => $order->order_number, '@store' => variable_get('site_name', url('<front>', array('absolute' => TRUE))))),
-    'on0_1' => t('Product count'),
-    'os0_1' => commerce_line_items_quantity($wrapper->commerce_line_items, commerce_product_line_item_types()),
-  );
 
+  );
+  
+  // When required, add subscription specific data to the transaction
+  if (!empty($settings['subscription_access'])) {
+    $data += array(
+      'p3' => $settings['subscription']['p3'],
+      't3' => $settings['subscription']['t3'],
+      'src' => $settings['subscription']['src'],
+      'sra' => $settings['subscription']['sra'],
+    );
+	
+	$item_name_key = 'item_name';
+	$amount_key = 'a3';
+  }
+  else {
+  	$data += array(
+	   // Define a single item in the cart representing the whole order
+	  'on0_1' => t('Product count'),
+	  'os0_1' => commerce_line_items_quantity($wrapper->commerce_line_items, commerce_product_line_item_types()), 	
+	);
+	
+	$item_name_key = 'item_name_1';
+	$amount_key = 'amount_1';
+  }
+  
+  $data += array(
+    $item_name_key => t('Order @order_number at @store', array('@order_number' => $order->order_number, '@store' => variable_get('site_name', url('<front>', array('absolute' => TRUE))))),
+    $amount_key => commerce_currency_amount_to_decimal(commerce_currency_convert($amount, $order_currency_code, $currency_code), $currency_code),
+  );
+  
   // Allow modules to alter parameters of the API request.
   drupal_alter('commerce_paypal_wps_order_form_data', $data, $order);
 
@@ -515,3 +598,10 @@ function commerce_paypal_wps_languages() {
 function commerce_paypal_wps_currencies() {
   return drupal_map_assoc(array('AUD', 'BRL', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD', 'HUF', 'ILS', 'JPY', 'MXN', 'MYR', 'NOK', 'NZD', 'PHP', 'PLN', 'SEK', 'SGD', 'THB', 'TRY', 'TWD', 'USD'));
 }
+
+/**
+ * Returns an array of all possible subscr_* IPN txn_type's.
+ */
+function commerce_paypal_wps_subscr_types() {
+  return drupal_map_assoc(array('subscr_signup', 'subscr_cancel', 'subscr_modify', 'subscr_payment', 'subscr_failed', 'subscr_eot'));
+}
diff --git a/modules/wps/commerce_paypal_wps.rules.inc b/modules/wps/commerce_paypal_wps.rules.inc
new file mode 100644
index 0000000..5d85d68
--- /dev/null
+++ b/modules/wps/commerce_paypal_wps.rules.inc
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Implementation of hook_rules_event_info().
+ * @ingroup rules
+ */
+function commerce_paypal_wps_rules_event_info() {
+  $events = array();
+
+  $events['commerce_paypal_wps_subscr_ipn'] = array(
+    'label' => t('A subscription related IPN is received for an order'),
+    'group' => t('Commerce Paypal WPS'),
+    'variables' => array(
+      'commerce_order' => array(
+        'label' => t('Order', array(), array('context' => 'a drupal commerce order')),
+        'type' => 'commerce_order',
+        'skip save' => TRUE,
+      ),
+      'txn_type' => array(
+        'label' => t('IPN Transaction Type'),
+        'type' => 'text',
+        'options list' => 'commerce_paypal_wps_subscr_types',
+      ),      
+    ),
+    'access callback' => 'commerce_order_rules_access',
+  );
+
+  return $events;
+}
+?>
\ No newline at end of file
