Stripe Account ============== +---------------+----------------------------------------------------------------------+ | Metric | Target | +===============+======================================================================+ | RPO | n/a (no backups possible) | +---------------+----------------------------------------------------------------------+ | RTO | 8 hours | +---------------+----------------------------------------------------------------------+ Losing access to Stripe does not directly impact business continuity, however it prevents us from billing customers (who are billed via Stripe) and prevents new signups (via Stripe). Cancelled Subscriptions ----------------------- Subscriptions cannot be deleted in Stripe, even if an account has been deleted. But they can be cancelled, which is irreversible and prevents us from billing that customer via this subscription. If a Subscription is cancelled, a new one will need to be created. The old subscription information would need to be manually copied over (i.e. associated product / price). The new Subscription would need to be manually inserted into ``brain``, and the cluster "moved" to it accordingly. This will require: 1. Inserting it into the ``core.subscriptions`` table 2. Setting ``core.clusters.subscription_id`` to the new one Deleted Accounts (Customers) ---------------------------- A deleted Stripe customer is a big problem, as we immediately lose the payment method (CC) associated with this customer - the only way to restore that is to ask the customer to re-add it. Nonetheless, re-creating a Customer would involve the following steps: 1. Re-creating the customer in Stripe 2. Updating ``core.stripe_customers.id`` for the organization 3. Re-creating any cancelled Subscriptions (same as above) 4. Informing the customer and asking for them to re-add their CC. Deleted Products & Prices ------------------------- This is tedious but possible. Part 1: Restore products and prices ################################### .. code-block:: console $ crash -U dev --hosts https://braindev.aks1.westeurope.azure.cratedb.net:4200 Password: CONNECT OK cr> SELECT * FROM core.product_pricing where offer = 'stripe'; +---------+--------+---------+--------+---------------------+-------------------+--------------------------------+----------------------+---------------------------+ | kind | name | tier | offer | plan | region | billing_dimension | price_per_dtu_minute | min_per_billing_dimension | +---------+--------+---------+--------+---------------------+-------------------+--------------------------------+----------------------+---------------------------+ | cluster | edge | basic | stripe | prod_JbO1EkQATqlHdZ | _default_ | price_1IyBFPJOpFszwfhBmXCp0aF8 | 0 | 1 | | cluster | gp_v2 | premium | stripe | prod_IT3F155QzMr8dU | _default_ | price_1J8hqlJOpFszwfhBzxMupULv | 711187 | 1 | | cluster | gp_v2 | basic | stripe | prod_IT3F155QzMr8dU | _default_ | price_1J7z9vJOpFszwfhBUoRaigg2 | 184932 | 1 | | cluster | so_v2 | basic | stripe | prod_IT3p4dt6YIGsDO | _default_ | price_1J7zCVJOpFszwfhBNAQ3ldnr | 262557 | 1 | | cluster | io_v2 | basic | stripe | prod_IT3r9dDRWciKHU | _default_ | price_1J7zBqJOpFszwfhBsmEjPLYF | 145890 | 1 | | cluster | mso | pro | stripe | prod_JlWVOLivXO4szi | _default_ | price_1J8hesJOpFszwfhBipLBX9KO | 794064 | 1 | | cluster | mso | basic | stripe | prod_JlWVOLivXO4szi | _default_ | price_1J7zSAJOpFszwfhBeADTCiYU | 411187 | 1 | | cluster | gp_v2 | pro | stripe | prod_IT3F155QzMr8dU | _default_ | price_1J8hcbJOpFszwfhB2ED9mUHu | 362557 | 1 | | cluster | io_v2 | pro | stripe | prod_IT3r9dDRWciKHU | _default_ | price_1J8hdYJOpFszwfhBqekdJTLU | 284932 | 1 | | cluster | so_v2 | pro | stripe | prod_IT3p4dt6YIGsDO | _default_ | price_1J8heIJOpFszwfhBq0Hh6Nux | 511187 | 1 | | cluster | io_v2 | premium | stripe | prod_IT3r9dDRWciKHU | _default_ | price_1J8hrPJOpFszwfhBKPQOQZVd | 562557 | 1 | | cluster | so_v2 | premium | stripe | prod_IT3p4dt6YIGsDO | _default_ | price_1J8hryJOpFszwfhBr2zh0Qvr | 994064 | 1 | | cluster | mso | premium | stripe | prod_JlWVOLivXO4szi | _default_ | price_1J8hsRJOpFszwfhBnMqs7dQS | 1531279 | 1 | | cluster | dev_v2 | basic | stripe | prod_IVct7VwgPA9X75 | _default_ | price_1Idt3RJOpFszwfhBD2q0buaR | 15982 | 1 | | cluster | dev_v3 | basic | stripe | prod_IVct7VwgPA9X75 | _default_ | price_1JNZkwJOpFszwfhBLNkf0d2I | 81050 | 1 | | cluster | dev_v3 | basic | stripe | prod_IVct7VwgPA9X75 | aks1.eastus.azure | price_1JahtRJOpFszwfhBBtcmoz6V | 10000 | 1 | | cluster | io_v2 | basic | stripe | prod_IT3r9dDRWciKHU | test.aws | price_1JfPp9JOpFszwfhBpKudg9zC | 165890 | 1 | | cluster | io_v2 | basic | stripe | prod_IT3r9dDRWciKHU | aks1.eastus.azure | price_1JfPp9JOpFszwfhBpKudg9zC | 185890 | 1 | +---------+--------+---------+--------+---------------------+-------------------+--------------------------------+----------------------+---------------------------+ .. note:: The example is for dev brain, but the prod brain is analogous. The ``plan`` corresponds to a ``Product`` in Stripe, and the ``billing_dimension`` is the price within the ``Product``. Most likely you will need to create new products / prices, and update the IDs in this table accordingly. Good luck :( The ``price_per_dtu_minute`` to Stripe price calculation is in the `CrateDB Cloud Pricing document`_ in Sharepoint. Part 2: Update ``core.cluster_billing_info`` ############################################ The ``core.cluster_billing_info`` table for running clusters will have old information about the plans and prices, and needs to be updated. .. code-block:: console cr> SELECT b.* FROM core.clusters c, core.cluster_billing_info b where c.is_deleted = false and c.id = b.cluster_id and b.offer = 'stripe' and b.name != 'edge'; +--------------------------------------+---------+--------+-------+--------+---------------------+-------------------+--------------------------------+----------------------+---------------------------+ | cluster_id | kind | name | tier | offer | plan | region | billing_dimension | price_per_dtu_minute | min_per_billing_dimension | +--------------------------------------+---------+--------+-------+--------+---------------------+-------------------+--------------------------------+----------------------+---------------------------+ | 242deafc-24e2-4875-9f70-c56a6d07f885 | cluster | dev_v3 | basic | stripe | prod_IVct7VwgPA9X75 | aks1.eastus.azure | price_1JahtRJOpFszwfhBBtcmoz6V | 10000 | 1 | | af9aa487-cf03-416d-9759-3f43eb34e968 | cluster | dev_v3 | basic | stripe | prod_IVct7VwgPA9X75 | aks1.eastus.azure | price_1JahtRJOpFszwfhBBtcmoz6V | 10000 | 1 | +--------------------------------------+---------+--------+-------+--------+---------------------+-------------------+--------------------------------+----------------------+---------------------------+ You get the picture: the plan and billing dimension have to be updated to match what's in Stripe now. Part 3: Add new prices to the subscriptions in Stripe ##################################################### Now that the billing info table is updated, the consumption reporting will happen against the new prices. However, these prices also need to be added to the customer's Stripe subscription for billing to work properly. First, get a list of affected subscriptions: .. code-block:: console cr> SELECT s.id, s.reference, b.billing_dimension FROM core.clusters c, core.cluster_billing_info b, core.subscriptions s where c.is_deleted = false and c.id = b.cluster_id and c.subscription_id = s.id and b.offer = 'stripe' and b.name ! = 'edge'; +--------------------------------------+--------------------+--------------------------------+ | id | reference | billing_dimension | +--------------------------------------+--------------------+--------------------------------+ | e4721073-1080-47eb-99d5-9bd8d7d06995 | sub_JqU3tdWhMHMRFe | price_1JahtRJOpFszwfhBBtcmoz6V | | 43a63c87-cd02-4173-91ad-1a1a2dd76612 | sub_JAS5dc2n5AJuxx | price_1JahtRJOpFszwfhBBtcmoz6V | +--------------------------------------+--------------------+--------------------------------+ The ``reference`` is the Stripe subscription id. You can enter that into the Stripe dashboard's Search field to go to the right subscription. Now go to ``Actions`` -> ``Update subscription`` and click on ``Add Product``. Now add the relevant price (``billing_dimension``) to the subscription: .. image:: images/edit_subscription.png :width: 100% After this, billing should work. Double check the ``core.consumption_report`` table for the given subscription: .. code-block:: console cr> SELECT * FROM core.consumption_report where subscription_id = 'sub_JqU3tdWhMHMRFe' order by from_ts desc limit 5; +---------------+---------------+--------------------------------------+--------------------+-------------------+-------------------------------+ | from_ts | to_ts | cluster_id | subscription_id | consumption_total | reporting_id | +---------------+---------------+--------------------------------------+--------------------+-------------------+-------------------------------+ | 1641463745114 | 1641466802169 | 242deafc-24e2-4875-9f70-c56a6d07f885 | sub_JqU3tdWhMHMRFe | 51.0 | mbur_1KEtnAJOpFszwfhBrkLgR9ug | | 1641304802448 | 1641307169735 | 8d71bd37-4b70-4bee-8592-a1069bac9ad4 | sub_JqU3tdWhMHMRFe | 39.0 | mbur_1KEEaMJOpFszwfhBrbP9ES0G | | 1641301202205 | 1641304802448 | 8d71bd37-4b70-4bee-8592-a1069bac9ad4 | sub_JqU3tdWhMHMRFe | 60.0 | mbur_1KEDeaJOpFszwfhB6gu7r7xF | | 1641297601637 | 1641301202205 | 8d71bd37-4b70-4bee-8592-a1069bac9ad4 | sub_JqU3tdWhMHMRFe | 60.0 | mbur_1KECiCJOpFszwfhBrHe66kyj | | 1641294339920 | 1641297601637 | 8d71bd37-4b70-4bee-8592-a1069bac9ad4 | sub_JqU3tdWhMHMRFe | 54.0 | mbur_1KEBmFJOpFszwfhBKFNFjivH | +---------------+---------------+--------------------------------------+--------------------+-------------------+-------------------------------+ There should be no entries with a ``NULL`` reporting_id after a consumption reporting job has run (they run every hour). .. _CrateDB Cloud Pricing document: https://craty.sharepoint.com/:x:/s/cratedb-cloud/EW2fy0ouTn9HryM0n_469f0Bc3nvhuQRaW4FD3nXxN9Y-A?e=AcOh1u