diff --git a/master/bt5/slapos_subscription_request/TestTemplateItem/portal_components/test.erp5.testSlapOSSubscriptionCancellationScenario.py b/master/bt5/slapos_subscription_request/TestTemplateItem/portal_components/test.erp5.testSlapOSSubscriptionCancellationScenario.py
new file mode 100644
index 0000000000000000000000000000000000000000..81952f136c699577ee7df505c9d4d99a8c45639f
--- /dev/null
+++ b/master/bt5/slapos_subscription_request/TestTemplateItem/portal_components/test.erp5.testSlapOSSubscriptionCancellationScenario.py
@@ -0,0 +1,200 @@
+# -*- coding:utf-8 -*-
+##############################################################################
+#
+# Copyright (c) 2019 Nexedi SA and Contributors. All Rights Reserved.
+#
+# This program is Free Software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+##############################################################################
+
+from erp5.component.test.testSlapOSSubscriptionScenario import TestSlapOSSubscriptionScenarioMixin
+#from erp5.component.test.SlapOSTestCaseMixin import changeSkin
+
+
+class TestSlapOSSubscriptionCancellationScenario(TestSlapOSSubscriptionScenarioMixin):
+
+  def invokeBasicSimulationAlarmList(self):
+    # stabilise aggregated invoices and expand them
+    self.stepCallSlaposManageBuildingCalculatingDeliveryAlarm()
+    self.tic()
+
+    # update invoices with their tax & discount
+    self.stepCallSlaposTriggerBuildAlarm()
+    self.tic()
+    self.stepCallSlaposManageBuildingCalculatingDeliveryAlarm()
+    self.tic()
+
+    # update invoices with their tax & discount transaction lines
+    self.stepCallSlaposTriggerBuildAlarm()
+    self.tic()
+    self.stepCallSlaposManageBuildingCalculatingDeliveryAlarm()
+    self.tic()
+
+    # stop the invoices and solve them again
+    self.stepCallSlaposStopConfirmedAggregatedSaleInvoiceTransactionAlarm()
+    self.tic()
+    self.stepCallSlaposManageBuildingCalculatingDeliveryAlarm()
+    self.tic()
+
+  def test_subscription_scenario_reservation_cancellation_scenario(self):
+
+    self.subscription_server = self.createPublicServerForAdminUser()
+
+    # Call as anonymous... check response?
+    default_email_text = "abc%s@nexedi.com" % self.new_id
+    name="ABC %s" % self.new_id
+    amount = 1
+
+    self.logout()
+    self._requestSubscription(
+      subscription_reference=self.subscription_condition.getReference(),
+      amount=amount,
+      name=name,
+      default_email_text=default_email_text,
+      confirmation_required=False,
+      REQUEST=self.portal.REQUEST)
+
+    self.login()
+    # I'm not sure if this is realistic
+    self.tic()
+
+    subscription_request = self.getSubscriptionRequest(
+      default_email_text, self.subscription_condition)
+
+    self.checkDraftSubscriptionRequest(subscription_request,
+                      default_email_text, self.subscription_condition, amount=amount)
+
+    ### Here all fine, Now let's consider the user never payed. 
+    invoice = subscription_request.getCausalityValue(
+      portal_type="Sale Invoice Transaction")
+    self.assertEqual(invoice.getSimulationState(), "confirmed")
+    self.assertEqual(invoice.getCausalityState(), "building")
+    # Invoices are not payed!
+    payment_list = invoice.getCausalityRelatedValueList(portal_type="Payment Transaction")
+    self.assertEqual(len(payment_list), 1)
+    payment = payment_list[0]
+
+    self.assertEqual(payment.getSimulationState(), "started")
+    self.assertEqual(subscription_request.getSimulationState(), "draft")
+
+    self.invokeBasicSimulationAlarmList()
+
+    payment.cancel()
+    self.invokeBasicSimulationAlarmList()
+
+    # Call alarm to check payment and invoice and move foward to planned.
+    self.stepCallSlaposSubscriptionRequestProcessDraftAlarm()
+    self.tic()
+
+    payment_list = invoice.getCausalityRelatedValueList(portal_type="Payment Transaction")
+    self.assertEqual(len(payment_list), 1)
+    payment = payment_list[0]
+    self.assertEqual(payment.getSimulationState(), "cancelled")
+
+    # Alarm is conflicting
+    self.assertEqual(subscription_request.getSimulationState(), "cancelled")
+
+  def test_subscription_scenario_reservation_cancellation_late_alarm_scenario(self):
+
+    self.subscription_server = self.createPublicServerForAdminUser()
+
+    # Call as anonymous... check response?
+    default_email_text = "abc%s@nexedi.com" % self.new_id
+    name="ABC %s" % self.new_id
+    amount = 1
+
+    self.logout()
+    self._requestSubscription(
+      subscription_reference=self.subscription_condition.getReference(),
+      amount=amount,
+      name=name,
+      default_email_text=default_email_text,
+      confirmation_required=False,
+      REQUEST=self.portal.REQUEST)
+
+    self.login()
+    # I'm not sure if this is realistic
+    self.tic()
+
+    subscription_request = self.getSubscriptionRequest(
+      default_email_text, self.subscription_condition)
+
+    self.checkDraftSubscriptionRequest(subscription_request,
+                      default_email_text, self.subscription_condition, amount=amount)
+
+    ### Here all fine, Now let's consider the user never payed. 
+    invoice = subscription_request.getCausalityValue(
+      portal_type="Sale Invoice Transaction")
+    self.assertEqual(invoice.getSimulationState(), "confirmed")
+    self.assertEqual(invoice.getCausalityState(), "building")
+    # Invoices are not payed!
+    payment_list = invoice.getCausalityRelatedValueList(portal_type="Payment Transaction")
+    self.assertEqual(len(payment_list), 1)
+    payment = payment_list[0]
+
+    self.assertEqual(payment.getSimulationState(), "started")
+    self.assertEqual(subscription_request.getSimulationState(), "draft")
+
+    self.invokeBasicSimulationAlarmList()
+
+    # stop the invoices and solve them again
+    self.stepCallSlaposStopConfirmedAggregatedSaleInvoiceTransactionAlarm()
+    self.tic()
+    self.stepCallSlaposManageBuildingCalculatingDeliveryAlarm()
+    self.tic()
+    self.invokeBasicSimulationAlarmList()
+    self.assertEqual(invoice.getSimulationState(), "stopped")
+    self.assertEqual(invoice.getCausalityState(), "solved")
+
+    self.assertEqual(payment.getSimulationState(), "started")
+
+    # Cancel Payment and ensure all is cancelled along
+    payment.cancel()
+    self.assertEqual(payment.getSimulationState(), "cancelled")
+
+    self.tic()
+    self.assertEqual(invoice.getSimulationState(), "stopped")
+    self.assertEqual(invoice.getCausalityState(), "solved")
+
+    builder = self.portal.portal_orders.slapos_payment_transaction_builder
+    for _ in range(500):
+      # build the aggregated payment
+      self.stepCallSlaposTriggerPaymentTransactionOrderBuilderAlarm()
+      self.tic()
+      # If there is something unbuild recall alarm, this is mostly for 
+      # live tests with date on the development sites.
+      if not len(builder.OrderBuilder_generateUnrelatedInvoiceList()):
+        break
+
+    # start the payzen payment
+    self.stepCallSlaposPayzenUpdateConfirmedPaymentAlarm()
+    self.tic()
+
+    self.invokeBasicSimulationAlarmList()
+
+    # Call alarm to check payment and invoice and move foward to planned.
+    self.stepCallSlaposSubscriptionRequestProcessDraftAlarm()
+    self.tic()
+
+    payment_list = invoice.getCausalityRelatedValueList(portal_type="Payment Transaction")
+    self.assertEqual(len(payment_list), 1)
+    payment = payment_list[0]
+    self.assertEqual(payment.getSimulationState(), "cancelled")
+    self.assertEqual(invoice.getSimulationState(), "cancelled")
+
+    # Alarm is conflicting
+    self.assertEqual(subscription_request.getSimulationState(), "cancelled")
+
+
diff --git a/master/bt5/slapos_subscription_request/TestTemplateItem/portal_components/test.erp5.testSlapOSSubscriptionCancellationScenario.xml b/master/bt5/slapos_subscription_request/TestTemplateItem/portal_components/test.erp5.testSlapOSSubscriptionCancellationScenario.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ca2dc01198f42d774f5fcb90157b185183b1cd2b
--- /dev/null
+++ b/master/bt5/slapos_subscription_request/TestTemplateItem/portal_components/test.erp5.testSlapOSSubscriptionCancellationScenario.xml
@@ -0,0 +1,133 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Test Component" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_recorded_property_dict</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
+            </value>
+        </item>
+        <item>
+            <key> <string>default_reference</string> </key>
+            <value> <string>testSlapOSSubscriptionCancellationScenario</string> </value>
+        </item>
+        <item>
+            <key> <string>default_source_reference</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>test.erp5.testSlapOSSubscriptionCancellationScenario</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Test Component</string> </value>
+        </item>
+        <item>
+            <key> <string>sid</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>text_content_error_message</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>text_content_warning_message</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>version</string> </key>
+            <value> <string>erp5</string> </value>
+        </item>
+        <item>
+            <key> <string>workflow_history</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="2" aka="AAAAAAAAAAI=">
+    <pickle>
+      <global name="PersistentMapping" module="Persistence.mapping"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>data</string> </key>
+            <value>
+              <dictionary/>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="3" aka="AAAAAAAAAAM=">
+    <pickle>
+      <global name="PersistentMapping" module="Persistence.mapping"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>data</string> </key>
+            <value>
+              <dictionary>
+                <item>
+                    <key> <string>component_validation_workflow</string> </key>
+                    <value>
+                      <persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
+                    </value>
+                </item>
+              </dictionary>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="4" aka="AAAAAAAAAAQ=">
+    <pickle>
+      <global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_log</string> </key>
+            <value>
+              <list>
+                <dictionary>
+                  <item>
+                      <key> <string>action</string> </key>
+                      <value> <string>validate</string> </value>
+                  </item>
+                  <item>
+                      <key> <string>validation_state</string> </key>
+                      <value> <string>validated</string> </value>
+                  </item>
+                </dictionary>
+              </list>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_subscription_request/bt/template_test_id_list b/master/bt5/slapos_subscription_request/bt/template_test_id_list
index b856a63803f855ab5f64f2fad6609f6d77ad3d87..639036a38de1f6a12a3055b4ab62b1a066020f4e 100644
--- a/master/bt5/slapos_subscription_request/bt/template_test_id_list
+++ b/master/bt5/slapos_subscription_request/bt/template_test_id_list
@@ -12,4 +12,5 @@ test.erp5.testSlapOSSubscriptionInvitationTokenChineseScenario
 test.erp5.testSlapOSSubscriptionSecondMonthPaymentScenario
 test.erp5.testSlapOSSubscriptionSecondMonthPaymentChineseScenario
 test.erp5.testSlapOSSubscriptionDualOrganisationScenario
-test.erp5.testSlapOSSubscriptionDualOrganisationChineseScenario
\ No newline at end of file
+test.erp5.testSlapOSSubscriptionDualOrganisationChineseScenario
+test.erp5.testSlapOSSubscriptionCancellationScenario
\ No newline at end of file