stripe: Redirect to /plans if plans downgraded on /billing page visit.

When a customer with plan's status 'DOWNGRADE_AT_END_OF_FREE_TRIAL'
visits /billing page on the free-trial end date before the invoice
cron runs, the 'make_end_of_cycle_updates_if_needed' downgrades the
plan.

Earlier, when such a customer visited /billing page in this time window
it resulted in an assertion error.

This commit fixes the incorrect behaviour by redirecting to '/plans'
page in such cases.
This commit is contained in:
Prakhar Pratyush
2024-03-19 18:03:13 +05:30
committed by Tim Abbott
parent 3418ec8055
commit c9d25b2a95
45 changed files with 2682 additions and 1 deletions

View File

@@ -2351,7 +2351,8 @@ class BillingSession(ABC):
assert plan is not None
new_plan, last_ledger_entry = self.make_end_of_cycle_updates_if_needed(plan, now)
assert last_ledger_entry is not None
if last_ledger_entry is None:
return {"current_plan_downgraded": True}
plan = new_plan if new_plan is not None else plan
context = self.get_billing_context_from_plan(customer, plan, last_ledger_entry, now)

View File

@@ -0,0 +1,33 @@
{
"address": null,
"balance": 0,
"created": 1010000001,
"currency": null,
"default_currency": null,
"default_source": null,
"delinquent": false,
"description": "zulip (Zulip Dev)",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_NORMALIZED0001",
"invoice_prefix": "NORMA01",
"invoice_settings": {
"custom_fields": null,
"default_payment_method": null,
"footer": null,
"rendering_options": null
},
"livemode": false,
"metadata": {
"realm_id": "1",
"realm_str": "zulip"
},
"name": null,
"next_invoice_sequence": 1,
"object": "customer",
"phone": null,
"preferred_locales": [],
"shipping": null,
"tax_exempt": "none",
"test_clock": null
}

View File

@@ -0,0 +1,33 @@
{
"address": null,
"balance": 0,
"created": 1010000001,
"currency": null,
"default_currency": null,
"default_source": null,
"delinquent": false,
"description": "zulip (Zulip Dev)",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_NORMALIZED0001",
"invoice_prefix": "NORMA01",
"invoice_settings": {
"custom_fields": null,
"default_payment_method": "pm_1Ow3qBDEQaroqDjsLa7hmrS7",
"footer": null,
"rendering_options": null
},
"livemode": false,
"metadata": {
"realm_id": "1",
"realm_str": "zulip"
},
"name": null,
"next_invoice_sequence": 1,
"object": "customer",
"phone": null,
"preferred_locales": [],
"shipping": null,
"tax_exempt": "none",
"test_clock": null
}

View File

@@ -0,0 +1,80 @@
{
"address": null,
"balance": 0,
"created": 1010000001,
"currency": null,
"default_currency": null,
"default_source": null,
"delinquent": false,
"description": "zulip (Zulip Dev)",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_NORMALIZED0001",
"invoice_prefix": "NORMA01",
"invoice_settings": {
"custom_fields": null,
"default_payment_method": {
"billing_details": {
"address": {
"city": null,
"country": null,
"line1": null,
"line2": null,
"postal_code": null,
"state": null
},
"email": null,
"name": null,
"phone": null
},
"card": {
"brand": "visa",
"checks": {
"address_line1_check": null,
"address_postal_code_check": null,
"cvc_check": "pass"
},
"country": "US",
"display_brand": "visa",
"exp_month": 3,
"exp_year": 2025,
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"generated_from": null,
"last4": "4242",
"networks": {
"available": [
"visa"
],
"preferred": null
},
"three_d_secure_usage": {
"supported": true
},
"wallet": null
},
"created": 1010000002,
"customer": "cus_NORMALIZED0001",
"id": "pm_1Ow3qBDEQaroqDjsLa7hmrS7",
"livemode": false,
"metadata": {},
"object": "payment_method",
"type": "card"
},
"footer": null,
"rendering_options": null
},
"livemode": false,
"metadata": {
"realm_id": "1",
"realm_str": "zulip"
},
"name": null,
"next_invoice_sequence": 1,
"object": "customer",
"phone": null,
"preferred_locales": [],
"shipping": null,
"tax_exempt": "none",
"test_clock": null
}

View File

@@ -0,0 +1,80 @@
{
"address": null,
"balance": 0,
"created": 1010000001,
"currency": null,
"default_currency": null,
"default_source": null,
"delinquent": false,
"description": "zulip (Zulip Dev)",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_NORMALIZED0001",
"invoice_prefix": "NORMA01",
"invoice_settings": {
"custom_fields": null,
"default_payment_method": {
"billing_details": {
"address": {
"city": null,
"country": null,
"line1": null,
"line2": null,
"postal_code": null,
"state": null
},
"email": null,
"name": null,
"phone": null
},
"card": {
"brand": "visa",
"checks": {
"address_line1_check": null,
"address_postal_code_check": null,
"cvc_check": "pass"
},
"country": "US",
"display_brand": "visa",
"exp_month": 3,
"exp_year": 2025,
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"generated_from": null,
"last4": "4242",
"networks": {
"available": [
"visa"
],
"preferred": null
},
"three_d_secure_usage": {
"supported": true
},
"wallet": null
},
"created": 1010000002,
"customer": "cus_NORMALIZED0001",
"id": "pm_1Ow3qBDEQaroqDjsLa7hmrS7",
"livemode": false,
"metadata": {},
"object": "payment_method",
"type": "card"
},
"footer": null,
"rendering_options": null
},
"livemode": false,
"metadata": {
"realm_id": "1",
"realm_str": "zulip"
},
"name": null,
"next_invoice_sequence": 1,
"object": "customer",
"phone": null,
"preferred_locales": [],
"shipping": null,
"tax_exempt": "none",
"test_clock": null
}

View File

@@ -0,0 +1,80 @@
{
"address": null,
"balance": 0,
"created": 1010000001,
"currency": null,
"default_currency": null,
"default_source": null,
"delinquent": false,
"description": "zulip (Zulip Dev)",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_NORMALIZED0001",
"invoice_prefix": "NORMA01",
"invoice_settings": {
"custom_fields": null,
"default_payment_method": {
"billing_details": {
"address": {
"city": null,
"country": null,
"line1": null,
"line2": null,
"postal_code": null,
"state": null
},
"email": null,
"name": null,
"phone": null
},
"card": {
"brand": "visa",
"checks": {
"address_line1_check": null,
"address_postal_code_check": null,
"cvc_check": "pass"
},
"country": "US",
"display_brand": "visa",
"exp_month": 3,
"exp_year": 2025,
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"generated_from": null,
"last4": "4242",
"networks": {
"available": [
"visa"
],
"preferred": null
},
"three_d_secure_usage": {
"supported": true
},
"wallet": null
},
"created": 1010000002,
"customer": "cus_NORMALIZED0001",
"id": "pm_1Ow3qBDEQaroqDjsLa7hmrS7",
"livemode": false,
"metadata": {},
"object": "payment_method",
"type": "card"
},
"footer": null,
"rendering_options": null
},
"livemode": false,
"metadata": {
"realm_id": "1",
"realm_str": "zulip"
},
"name": null,
"next_invoice_sequence": 1,
"object": "customer",
"phone": null,
"preferred_locales": [],
"shipping": null,
"tax_exempt": "none",
"test_clock": null
}

View File

@@ -0,0 +1,80 @@
{
"address": null,
"balance": 0,
"created": 1010000001,
"currency": null,
"default_currency": null,
"default_source": null,
"delinquent": false,
"description": "zulip (Zulip Dev)",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_NORMALIZED0001",
"invoice_prefix": "NORMA01",
"invoice_settings": {
"custom_fields": null,
"default_payment_method": {
"billing_details": {
"address": {
"city": null,
"country": null,
"line1": null,
"line2": null,
"postal_code": null,
"state": null
},
"email": null,
"name": null,
"phone": null
},
"card": {
"brand": "visa",
"checks": {
"address_line1_check": null,
"address_postal_code_check": null,
"cvc_check": "pass"
},
"country": "US",
"display_brand": "visa",
"exp_month": 3,
"exp_year": 2025,
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"generated_from": null,
"last4": "4242",
"networks": {
"available": [
"visa"
],
"preferred": null
},
"three_d_secure_usage": {
"supported": true
},
"wallet": null
},
"created": 1010000002,
"customer": "cus_NORMALIZED0001",
"id": "pm_1Ow3qBDEQaroqDjsLa7hmrS7",
"livemode": false,
"metadata": {},
"object": "payment_method",
"type": "card"
},
"footer": null,
"rendering_options": null
},
"livemode": false,
"metadata": {
"realm_id": "1",
"realm_str": "zulip"
},
"name": null,
"next_invoice_sequence": 1,
"object": "customer",
"phone": null,
"preferred_locales": [],
"shipping": null,
"tax_exempt": "none",
"test_clock": null
}

View File

@@ -0,0 +1,80 @@
{
"address": null,
"balance": 0,
"created": 1010000001,
"currency": null,
"default_currency": null,
"default_source": null,
"delinquent": false,
"description": "zulip (Zulip Dev)",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_NORMALIZED0001",
"invoice_prefix": "NORMA01",
"invoice_settings": {
"custom_fields": null,
"default_payment_method": {
"billing_details": {
"address": {
"city": null,
"country": null,
"line1": null,
"line2": null,
"postal_code": null,
"state": null
},
"email": null,
"name": null,
"phone": null
},
"card": {
"brand": "visa",
"checks": {
"address_line1_check": null,
"address_postal_code_check": null,
"cvc_check": "pass"
},
"country": "US",
"display_brand": "visa",
"exp_month": 3,
"exp_year": 2025,
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"generated_from": null,
"last4": "4242",
"networks": {
"available": [
"visa"
],
"preferred": null
},
"three_d_secure_usage": {
"supported": true
},
"wallet": null
},
"created": 1010000002,
"customer": "cus_NORMALIZED0001",
"id": "pm_1Ow3qBDEQaroqDjsLa7hmrS7",
"livemode": false,
"metadata": {},
"object": "payment_method",
"type": "card"
},
"footer": null,
"rendering_options": null
},
"livemode": false,
"metadata": {
"realm_id": "1",
"realm_str": "zulip"
},
"name": null,
"next_invoice_sequence": 1,
"object": "customer",
"phone": null,
"preferred_locales": [],
"shipping": null,
"tax_exempt": "none",
"test_clock": null
}

View File

@@ -0,0 +1,60 @@
{
"data": [
{
"api_version": "2020-08-27",
"created": 1010000003,
"data": {
"object": {
"address": null,
"balance": 0,
"created": 1010000001,
"currency": null,
"default_currency": null,
"default_source": null,
"delinquent": false,
"description": "zulip (Zulip Dev)",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_NORMALIZED0001",
"invoice_prefix": "NORMA01",
"invoice_settings": {
"custom_fields": null,
"default_payment_method": "pm_1Ow3qBDEQaroqDjsLa7hmrS7",
"footer": null,
"rendering_options": null
},
"livemode": false,
"metadata": {
"realm_id": "1",
"realm_str": "zulip"
},
"name": null,
"next_invoice_sequence": 1,
"object": "customer",
"phone": null,
"preferred_locales": [],
"shipping": null,
"tax_exempt": "none",
"test_clock": null
},
"previous_attributes": {
"invoice_settings": {
"default_payment_method": null
}
}
},
"id": "evt_1Ow3qDDEQaroqDjs3UP99nfA",
"livemode": false,
"object": "event",
"pending_webhooks": 0,
"request": {
"id": "req_NORMALIZED0001",
"idempotency_key": "4dd2502c-3c01-431d-9c95-586c91e9df1f"
},
"type": "customer.updated"
}
],
"has_more": true,
"object": "list",
"url": "/v1/events"
}

View File

@@ -0,0 +1,6 @@
{
"data": [],
"has_more": false,
"object": "list",
"url": "/v1/invoices"
}

View File

@@ -0,0 +1,34 @@
{
"application": null,
"automatic_payment_methods": null,
"cancellation_reason": null,
"client_secret": "seti_1Ow3qBDEQaroqDjsnrKJpAIX_secret_Plb2syKLtLii6A4iI8h1UjKoD77C3h2",
"created": 1010000002,
"customer": "cus_NORMALIZED0001",
"description": null,
"flow_directions": null,
"id": "seti_1Ow3qBDEQaroqDjsnrKJpAIX",
"last_setup_error": null,
"latest_attempt": "setatt_1Ow3qBDEQaroqDjsKEDti6XU",
"livemode": false,
"mandate": null,
"metadata": {},
"next_action": null,
"object": "setup_intent",
"on_behalf_of": null,
"payment_method": "pm_1Ow3qBDEQaroqDjsLa7hmrS7",
"payment_method_configuration_details": null,
"payment_method_options": {
"card": {
"mandate_options": null,
"network": null,
"request_three_d_secure": "automatic"
}
},
"payment_method_types": [
"card"
],
"single_use_mandate": null,
"status": "succeeded",
"usage": "off_session"
}

View File

@@ -0,0 +1,41 @@
{
"data": [
{
"application": null,
"automatic_payment_methods": null,
"cancellation_reason": null,
"client_secret": "seti_1Ow3q9DEQaroqDjsI0TDS8mb_secret_Plb2QCZPhYGW8kwKo73cM6CMxnDWPkx",
"created": 1010000004,
"customer": "cus_NORMALIZED0001",
"description": null,
"flow_directions": null,
"id": "seti_1Ow3q9DEQaroqDjsI0TDS8mb",
"last_setup_error": null,
"latest_attempt": null,
"livemode": false,
"mandate": null,
"metadata": {},
"next_action": null,
"object": "setup_intent",
"on_behalf_of": null,
"payment_method": null,
"payment_method_configuration_details": null,
"payment_method_options": {
"card": {
"mandate_options": null,
"network": null,
"request_three_d_secure": "automatic"
}
},
"payment_method_types": [
"card"
],
"single_use_mandate": null,
"status": "requires_payment_method",
"usage": "off_session"
}
],
"has_more": true,
"object": "list",
"url": "/v1/setup_intents"
}

View File

@@ -0,0 +1,34 @@
{
"application": null,
"automatic_payment_methods": null,
"cancellation_reason": null,
"client_secret": "seti_1Ow3qBDEQaroqDjsnrKJpAIX_secret_Plb2syKLtLii6A4iI8h1UjKoD77C3h2",
"created": 1010000002,
"customer": "cus_NORMALIZED0001",
"description": null,
"flow_directions": null,
"id": "seti_1Ow3qBDEQaroqDjsnrKJpAIX",
"last_setup_error": null,
"latest_attempt": "setatt_1Ow3qBDEQaroqDjsKEDti6XU",
"livemode": false,
"mandate": null,
"metadata": {},
"next_action": null,
"object": "setup_intent",
"on_behalf_of": null,
"payment_method": "pm_1Ow3qBDEQaroqDjsLa7hmrS7",
"payment_method_configuration_details": null,
"payment_method_options": {
"card": {
"mandate_options": null,
"network": null,
"request_three_d_secure": "automatic"
}
},
"payment_method_types": [
"card"
],
"single_use_mandate": null,
"status": "succeeded",
"usage": "off_session"
}

View File

@@ -0,0 +1,79 @@
{
"after_expiration": null,
"allow_promotion_codes": null,
"amount_subtotal": null,
"amount_total": null,
"automatic_tax": {
"enabled": false,
"liability": null,
"status": null
},
"billing_address_collection": "required",
"cancel_url": "http://zulip.testserver/upgrade/?manual_license_management=false&tier=1",
"client_reference_id": null,
"client_secret": null,
"consent": null,
"consent_collection": null,
"created": 1010000004,
"currency": null,
"currency_conversion": null,
"custom_fields": [],
"custom_text": {
"after_submit": null,
"shipping_address": null,
"submit": null,
"terms_of_service_acceptance": null
},
"customer": "cus_NORMALIZED0001",
"customer_creation": null,
"customer_details": {
"address": null,
"email": "hamlet@zulip.com",
"name": null,
"phone": null,
"tax_exempt": null,
"tax_ids": null
},
"customer_email": null,
"expires_at": 1000000000,
"id": "cs_test_NORMALIZED01cr4T7FOrHtgOFP2d7qBOx5Y2UqNeBjmaPvkABpntoX5MHu",
"invoice": null,
"invoice_creation": null,
"livemode": false,
"locale": null,
"metadata": {
"type": "card_update",
"user_id": "10"
},
"mode": "setup",
"object": "checkout.session",
"payment_intent": null,
"payment_link": null,
"payment_method_collection": "always",
"payment_method_configuration_details": null,
"payment_method_options": {
"card": {
"request_three_d_secure": "automatic"
}
},
"payment_method_types": [
"card"
],
"payment_status": "no_payment_required",
"phone_number_collection": {
"enabled": false
},
"recovered_from": null,
"setup_intent": "seti_1Ow3q9DEQaroqDjsI0TDS8mb",
"shipping": null,
"shipping_address_collection": null,
"shipping_options": [],
"shipping_rate": null,
"status": "open",
"submit_type": null,
"subscription": null,
"success_url": "http://zulip.testserver/billing/event_status/?stripe_session_id={CHECKOUT_SESSION_ID}",
"total_details": null,
"ui_mode": "hosted",
"url": "https://checkout.stripe.com/c/pay/cs_test_NORMALIZED01cr4T7FOrHtgOFP2d7qBOx5Y2UqNeBjmaPvkABpntoX5MHu#fid1d2BpamRhQ2prcSc%2FJ1ZqcHdmYCVWZGt2JVV3aicpJ2R1bE5gfCc%2FJ3VuWnFgdnFaXVRmMU5zNkldQTY9SnNRY09XZml2UXNQJyknY3dqaFZgd3Ngdyc%2FcXdwYCknaWR8anBxUXx1YCc%2FJ3Zsa2JpYFpmamlwaGsnKSdga2RnaWBVaWRmYG1qaWFgd3YnP3F3cGB4JSUl"
}

View File

@@ -0,0 +1,86 @@
{
"data": [
{
"after_expiration": null,
"allow_promotion_codes": null,
"amount_subtotal": null,
"amount_total": null,
"automatic_tax": {
"enabled": false,
"liability": null,
"status": null
},
"billing_address_collection": "required",
"cancel_url": "http://zulip.testserver/upgrade/?manual_license_management=false&tier=1",
"client_reference_id": null,
"client_secret": null,
"consent": null,
"consent_collection": null,
"created": 1010000004,
"currency": null,
"currency_conversion": null,
"custom_fields": [],
"custom_text": {
"after_submit": null,
"shipping_address": null,
"submit": null,
"terms_of_service_acceptance": null
},
"customer": "cus_NORMALIZED0001",
"customer_creation": null,
"customer_details": {
"address": null,
"email": "hamlet@zulip.com",
"name": null,
"phone": null,
"tax_exempt": null,
"tax_ids": null
},
"customer_email": null,
"expires_at": 1000000000,
"id": "cs_test_NORMALIZED01cr4T7FOrHtgOFP2d7qBOx5Y2UqNeBjmaPvkABpntoX5MHu",
"invoice": null,
"invoice_creation": null,
"livemode": false,
"locale": null,
"metadata": {
"type": "card_update",
"user_id": "10"
},
"mode": "setup",
"object": "checkout.session",
"payment_intent": null,
"payment_link": null,
"payment_method_collection": "always",
"payment_method_configuration_details": null,
"payment_method_options": {
"card": {
"request_three_d_secure": "automatic"
}
},
"payment_method_types": [
"card"
],
"payment_status": "no_payment_required",
"phone_number_collection": {
"enabled": false
},
"recovered_from": null,
"setup_intent": "seti_1Ow3q9DEQaroqDjsI0TDS8mb",
"shipping": null,
"shipping_address_collection": null,
"shipping_options": [],
"shipping_rate": null,
"status": "open",
"submit_type": null,
"subscription": null,
"success_url": "http://zulip.testserver/billing/event_status/?stripe_session_id={CHECKOUT_SESSION_ID}",
"total_details": null,
"ui_mode": "hosted",
"url": "https://checkout.stripe.com/c/pay/cs_test_NORMALIZED01cr4T7FOrHtgOFP2d7qBOx5Y2UqNeBjmaPvkABpntoX5MHu#fid1d2BpamRhQ2prcSc%2FJ1ZqcHdmYCVWZGt2JVV3aicpJ2R1bE5gfCc%2FJ3VuWnFgdnFaXVRmMU5zNkldQTY9SnNRY09XZml2UXNQJyknY3dqaFZgd3Ngdyc%2FcXdwYCknaWR8anBxUXx1YCc%2FJ3Zsa2JpYFpmamlwaGsnKSdga2RnaWBVaWRmYG1qaWFgd3YnP3F3cGB4JSUl"
}
],
"has_more": true,
"object": "list",
"url": "/v1/checkout/sessions"
}

View File

@@ -0,0 +1,33 @@
{
"address": null,
"balance": 0,
"created": 1000000000,
"currency": null,
"default_currency": null,
"default_source": null,
"delinquent": false,
"description": "zulip.testserver 66c64ff1-94c",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_NORMALIZED0001",
"invoice_prefix": "NORMA01",
"invoice_settings": {
"custom_fields": null,
"default_payment_method": null,
"footer": null,
"rendering_options": null
},
"livemode": false,
"metadata": {
"remote_realm_host": "zulip.testserver",
"remote_realm_uuid": "66c64ff1-94c6-48d0-b6f6-d1fbce7f2b1e"
},
"name": null,
"next_invoice_sequence": 1,
"object": "customer",
"phone": null,
"preferred_locales": [],
"shipping": null,
"tax_exempt": "none",
"test_clock": null
}

View File

@@ -0,0 +1,33 @@
{
"address": null,
"balance": 0,
"created": 1000000000,
"currency": null,
"default_currency": null,
"default_source": null,
"delinquent": false,
"description": "zulip.testserver 66c64ff1-94c",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_NORMALIZED0001",
"invoice_prefix": "NORMA01",
"invoice_settings": {
"custom_fields": null,
"default_payment_method": "pm_1Ow3lpDEQaroqDjsK2hHcrKn",
"footer": null,
"rendering_options": null
},
"livemode": false,
"metadata": {
"remote_realm_host": "zulip.testserver",
"remote_realm_uuid": "66c64ff1-94c6-48d0-b6f6-d1fbce7f2b1e"
},
"name": null,
"next_invoice_sequence": 1,
"object": "customer",
"phone": null,
"preferred_locales": [],
"shipping": null,
"tax_exempt": "none",
"test_clock": null
}

View File

@@ -0,0 +1,80 @@
{
"address": null,
"balance": 0,
"created": 1000000000,
"currency": null,
"default_currency": null,
"default_source": null,
"delinquent": false,
"description": "zulip.testserver 66c64ff1-94c",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_NORMALIZED0001",
"invoice_prefix": "NORMA01",
"invoice_settings": {
"custom_fields": null,
"default_payment_method": {
"billing_details": {
"address": {
"city": null,
"country": null,
"line1": null,
"line2": null,
"postal_code": null,
"state": null
},
"email": null,
"name": null,
"phone": null
},
"card": {
"brand": "visa",
"checks": {
"address_line1_check": null,
"address_postal_code_check": null,
"cvc_check": "pass"
},
"country": "US",
"display_brand": "visa",
"exp_month": 3,
"exp_year": 2025,
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"generated_from": null,
"last4": "4242",
"networks": {
"available": [
"visa"
],
"preferred": null
},
"three_d_secure_usage": {
"supported": true
},
"wallet": null
},
"created": 1000000000,
"customer": "cus_NORMALIZED0001",
"id": "pm_1Ow3lpDEQaroqDjsK2hHcrKn",
"livemode": false,
"metadata": {},
"object": "payment_method",
"type": "card"
},
"footer": null,
"rendering_options": null
},
"livemode": false,
"metadata": {
"remote_realm_host": "zulip.testserver",
"remote_realm_uuid": "66c64ff1-94c6-48d0-b6f6-d1fbce7f2b1e"
},
"name": null,
"next_invoice_sequence": 1,
"object": "customer",
"phone": null,
"preferred_locales": [],
"shipping": null,
"tax_exempt": "none",
"test_clock": null
}

View File

@@ -0,0 +1,80 @@
{
"address": null,
"balance": 0,
"created": 1000000000,
"currency": null,
"default_currency": null,
"default_source": null,
"delinquent": false,
"description": "zulip.testserver 66c64ff1-94c",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_NORMALIZED0001",
"invoice_prefix": "NORMA01",
"invoice_settings": {
"custom_fields": null,
"default_payment_method": {
"billing_details": {
"address": {
"city": null,
"country": null,
"line1": null,
"line2": null,
"postal_code": null,
"state": null
},
"email": null,
"name": null,
"phone": null
},
"card": {
"brand": "visa",
"checks": {
"address_line1_check": null,
"address_postal_code_check": null,
"cvc_check": "pass"
},
"country": "US",
"display_brand": "visa",
"exp_month": 3,
"exp_year": 2025,
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"generated_from": null,
"last4": "4242",
"networks": {
"available": [
"visa"
],
"preferred": null
},
"three_d_secure_usage": {
"supported": true
},
"wallet": null
},
"created": 1000000000,
"customer": "cus_NORMALIZED0001",
"id": "pm_1Ow3lpDEQaroqDjsK2hHcrKn",
"livemode": false,
"metadata": {},
"object": "payment_method",
"type": "card"
},
"footer": null,
"rendering_options": null
},
"livemode": false,
"metadata": {
"remote_realm_host": "zulip.testserver",
"remote_realm_uuid": "66c64ff1-94c6-48d0-b6f6-d1fbce7f2b1e"
},
"name": null,
"next_invoice_sequence": 1,
"object": "customer",
"phone": null,
"preferred_locales": [],
"shipping": null,
"tax_exempt": "none",
"test_clock": null
}

View File

@@ -0,0 +1,80 @@
{
"address": null,
"balance": 0,
"created": 1000000000,
"currency": null,
"default_currency": null,
"default_source": null,
"delinquent": false,
"description": "zulip.testserver 66c64ff1-94c",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_NORMALIZED0001",
"invoice_prefix": "NORMA01",
"invoice_settings": {
"custom_fields": null,
"default_payment_method": {
"billing_details": {
"address": {
"city": null,
"country": null,
"line1": null,
"line2": null,
"postal_code": null,
"state": null
},
"email": null,
"name": null,
"phone": null
},
"card": {
"brand": "visa",
"checks": {
"address_line1_check": null,
"address_postal_code_check": null,
"cvc_check": "pass"
},
"country": "US",
"display_brand": "visa",
"exp_month": 3,
"exp_year": 2025,
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"generated_from": null,
"last4": "4242",
"networks": {
"available": [
"visa"
],
"preferred": null
},
"three_d_secure_usage": {
"supported": true
},
"wallet": null
},
"created": 1000000000,
"customer": "cus_NORMALIZED0001",
"id": "pm_1Ow3lpDEQaroqDjsK2hHcrKn",
"livemode": false,
"metadata": {},
"object": "payment_method",
"type": "card"
},
"footer": null,
"rendering_options": null
},
"livemode": false,
"metadata": {
"remote_realm_host": "zulip.testserver",
"remote_realm_uuid": "66c64ff1-94c6-48d0-b6f6-d1fbce7f2b1e"
},
"name": null,
"next_invoice_sequence": 1,
"object": "customer",
"phone": null,
"preferred_locales": [],
"shipping": null,
"tax_exempt": "none",
"test_clock": null
}

View File

@@ -0,0 +1,80 @@
{
"address": null,
"balance": 0,
"created": 1000000000,
"currency": null,
"default_currency": null,
"default_source": null,
"delinquent": false,
"description": "zulip.testserver 66c64ff1-94c",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_NORMALIZED0001",
"invoice_prefix": "NORMA01",
"invoice_settings": {
"custom_fields": null,
"default_payment_method": {
"billing_details": {
"address": {
"city": null,
"country": null,
"line1": null,
"line2": null,
"postal_code": null,
"state": null
},
"email": null,
"name": null,
"phone": null
},
"card": {
"brand": "visa",
"checks": {
"address_line1_check": null,
"address_postal_code_check": null,
"cvc_check": "pass"
},
"country": "US",
"display_brand": "visa",
"exp_month": 3,
"exp_year": 2025,
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"generated_from": null,
"last4": "4242",
"networks": {
"available": [
"visa"
],
"preferred": null
},
"three_d_secure_usage": {
"supported": true
},
"wallet": null
},
"created": 1000000000,
"customer": "cus_NORMALIZED0001",
"id": "pm_1Ow3lpDEQaroqDjsK2hHcrKn",
"livemode": false,
"metadata": {},
"object": "payment_method",
"type": "card"
},
"footer": null,
"rendering_options": null
},
"livemode": false,
"metadata": {
"remote_realm_host": "zulip.testserver",
"remote_realm_uuid": "66c64ff1-94c6-48d0-b6f6-d1fbce7f2b1e"
},
"name": null,
"next_invoice_sequence": 1,
"object": "customer",
"phone": null,
"preferred_locales": [],
"shipping": null,
"tax_exempt": "none",
"test_clock": null
}

View File

@@ -0,0 +1,80 @@
{
"address": null,
"balance": 0,
"created": 1000000000,
"currency": null,
"default_currency": null,
"default_source": null,
"delinquent": false,
"description": "zulip.testserver 66c64ff1-94c",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_NORMALIZED0001",
"invoice_prefix": "NORMA01",
"invoice_settings": {
"custom_fields": null,
"default_payment_method": {
"billing_details": {
"address": {
"city": null,
"country": null,
"line1": null,
"line2": null,
"postal_code": null,
"state": null
},
"email": null,
"name": null,
"phone": null
},
"card": {
"brand": "visa",
"checks": {
"address_line1_check": null,
"address_postal_code_check": null,
"cvc_check": "pass"
},
"country": "US",
"display_brand": "visa",
"exp_month": 3,
"exp_year": 2025,
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"generated_from": null,
"last4": "4242",
"networks": {
"available": [
"visa"
],
"preferred": null
},
"three_d_secure_usage": {
"supported": true
},
"wallet": null
},
"created": 1000000000,
"customer": "cus_NORMALIZED0001",
"id": "pm_1Ow3lpDEQaroqDjsK2hHcrKn",
"livemode": false,
"metadata": {},
"object": "payment_method",
"type": "card"
},
"footer": null,
"rendering_options": null
},
"livemode": false,
"metadata": {
"remote_realm_host": "zulip.testserver",
"remote_realm_uuid": "66c64ff1-94c6-48d0-b6f6-d1fbce7f2b1e"
},
"name": null,
"next_invoice_sequence": 1,
"object": "customer",
"phone": null,
"preferred_locales": [],
"shipping": null,
"tax_exempt": "none",
"test_clock": null
}

View File

@@ -0,0 +1,60 @@
{
"data": [
{
"api_version": "2020-08-27",
"created": 1000000000,
"data": {
"object": {
"address": null,
"balance": 0,
"created": 1000000000,
"currency": null,
"default_currency": null,
"default_source": null,
"delinquent": false,
"description": "zulip.testserver 66c64ff1-94c",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_NORMALIZED0001",
"invoice_prefix": "NORMA01",
"invoice_settings": {
"custom_fields": null,
"default_payment_method": "pm_1Ow3lpDEQaroqDjsK2hHcrKn",
"footer": null,
"rendering_options": null
},
"livemode": false,
"metadata": {
"remote_realm_host": "zulip.testserver",
"remote_realm_uuid": "66c64ff1-94c6-48d0-b6f6-d1fbce7f2b1e"
},
"name": null,
"next_invoice_sequence": 1,
"object": "customer",
"phone": null,
"preferred_locales": [],
"shipping": null,
"tax_exempt": "none",
"test_clock": null
},
"previous_attributes": {
"invoice_settings": {
"default_payment_method": null
}
}
},
"id": "evt_1Ow3lrDEQaroqDjs3HG4bgvV",
"livemode": false,
"object": "event",
"pending_webhooks": 0,
"request": {
"id": "req_NORMALIZED0001",
"idempotency_key": "77fe86a8-7b74-4a46-9619-f3ce57d1e86b"
},
"type": "customer.updated"
}
],
"has_more": true,
"object": "list",
"url": "/v1/events"
}

View File

@@ -0,0 +1,6 @@
{
"data": [],
"has_more": false,
"object": "list",
"url": "/v1/invoices"
}

View File

@@ -0,0 +1,34 @@
{
"application": null,
"automatic_payment_methods": null,
"cancellation_reason": null,
"client_secret": "seti_1Ow3lpDEQaroqDjsMP6ScuTg_secret_PlaxIphSVQGpnBM8m0Ij8DJ6rtL2t36",
"created": 1000000000,
"customer": "cus_NORMALIZED0001",
"description": null,
"flow_directions": null,
"id": "seti_1Ow3lpDEQaroqDjsMP6ScuTg",
"last_setup_error": null,
"latest_attempt": "setatt_1Ow3lpDEQaroqDjs6RapEvaP",
"livemode": false,
"mandate": null,
"metadata": {},
"next_action": null,
"object": "setup_intent",
"on_behalf_of": null,
"payment_method": "pm_1Ow3lpDEQaroqDjsK2hHcrKn",
"payment_method_configuration_details": null,
"payment_method_options": {
"card": {
"mandate_options": null,
"network": null,
"request_three_d_secure": "automatic"
}
},
"payment_method_types": [
"card"
],
"single_use_mandate": null,
"status": "succeeded",
"usage": "off_session"
}

View File

@@ -0,0 +1,41 @@
{
"data": [
{
"application": null,
"automatic_payment_methods": null,
"cancellation_reason": null,
"client_secret": "seti_1Ow3loDEQaroqDjsC8yb78W3_secret_PlaxtVLbkFkLOs4QB545IK0dwKogKwq",
"created": 1000000000,
"customer": "cus_NORMALIZED0001",
"description": null,
"flow_directions": null,
"id": "seti_1Ow3loDEQaroqDjsC8yb78W3",
"last_setup_error": null,
"latest_attempt": null,
"livemode": false,
"mandate": null,
"metadata": {},
"next_action": null,
"object": "setup_intent",
"on_behalf_of": null,
"payment_method": null,
"payment_method_configuration_details": null,
"payment_method_options": {
"card": {
"mandate_options": null,
"network": null,
"request_three_d_secure": "automatic"
}
},
"payment_method_types": [
"card"
],
"single_use_mandate": null,
"status": "requires_payment_method",
"usage": "off_session"
}
],
"has_more": true,
"object": "list",
"url": "/v1/setup_intents"
}

View File

@@ -0,0 +1,34 @@
{
"application": null,
"automatic_payment_methods": null,
"cancellation_reason": null,
"client_secret": "seti_1Ow3lpDEQaroqDjsMP6ScuTg_secret_PlaxIphSVQGpnBM8m0Ij8DJ6rtL2t36",
"created": 1000000000,
"customer": "cus_NORMALIZED0001",
"description": null,
"flow_directions": null,
"id": "seti_1Ow3lpDEQaroqDjsMP6ScuTg",
"last_setup_error": null,
"latest_attempt": "setatt_1Ow3lpDEQaroqDjs6RapEvaP",
"livemode": false,
"mandate": null,
"metadata": {},
"next_action": null,
"object": "setup_intent",
"on_behalf_of": null,
"payment_method": "pm_1Ow3lpDEQaroqDjsK2hHcrKn",
"payment_method_configuration_details": null,
"payment_method_options": {
"card": {
"mandate_options": null,
"network": null,
"request_three_d_secure": "automatic"
}
},
"payment_method_types": [
"card"
],
"single_use_mandate": null,
"status": "succeeded",
"usage": "off_session"
}

View File

@@ -0,0 +1,79 @@
{
"after_expiration": null,
"allow_promotion_codes": null,
"amount_subtotal": null,
"amount_total": null,
"automatic_tax": {
"enabled": false,
"liability": null,
"status": null
},
"billing_address_collection": "required",
"cancel_url": "http://selfhosting.testserver/realm/66c64ff1-94c6-48d0-b6f6-d1fbce7f2b1e/upgrade/?manual_license_management=false&tier=1",
"client_reference_id": null,
"client_secret": null,
"consent": null,
"consent_collection": null,
"created": 1000000000,
"currency": null,
"currency_conversion": null,
"custom_fields": [],
"custom_text": {
"after_submit": null,
"shipping_address": null,
"submit": null,
"terms_of_service_acceptance": null
},
"customer": "cus_NORMALIZED0001",
"customer_creation": null,
"customer_details": {
"address": null,
"email": "hamlet@zulip.com",
"name": null,
"phone": null,
"tax_exempt": null,
"tax_ids": null
},
"customer_email": null,
"expires_at": 1000000000,
"id": "cs_test_NORMALIZED01mzSwMCFGHAds3lpuPuOQOX1JtdpEaRpBY6C8Gv1fNFNezN",
"invoice": null,
"invoice_creation": null,
"livemode": false,
"locale": null,
"metadata": {
"remote_realm_user_id": "1",
"type": "card_update"
},
"mode": "setup",
"object": "checkout.session",
"payment_intent": null,
"payment_link": null,
"payment_method_collection": "always",
"payment_method_configuration_details": null,
"payment_method_options": {
"card": {
"request_three_d_secure": "automatic"
}
},
"payment_method_types": [
"card"
],
"payment_status": "no_payment_required",
"phone_number_collection": {
"enabled": false
},
"recovered_from": null,
"setup_intent": "seti_1Ow3loDEQaroqDjsC8yb78W3",
"shipping": null,
"shipping_address_collection": null,
"shipping_options": [],
"shipping_rate": null,
"status": "open",
"submit_type": null,
"subscription": null,
"success_url": "http://selfhosting.testserver/realm/66c64ff1-94c6-48d0-b6f6-d1fbce7f2b1e/billing/event_status/?stripe_session_id={CHECKOUT_SESSION_ID}",
"total_details": null,
"ui_mode": "hosted",
"url": "https://checkout.stripe.com/c/pay/cs_test_NORMALIZED01mzSwMCFGHAds3lpuPuOQOX1JtdpEaRpBY6C8Gv1fNFNezN#fid1d2BpamRhQ2prcSc%2FJ1ZqcHdmYCVWZGt2JVV3aicpJ2R1bE5gfCc%2FJ3VuWnFgdnFaXVRmMU5zNkldQTY9SnNRY09XZml2UXNQJyknY3dqaFZgd3Ngdyc%2FcXdwYCknaWR8anBxUXx1YCc%2FJ3Zsa2JpYFpmamlwaGsnKSdga2RnaWBVaWRmYG1qaWFgd3YnP3F3cGB4JSUl"
}

View File

@@ -0,0 +1,86 @@
{
"data": [
{
"after_expiration": null,
"allow_promotion_codes": null,
"amount_subtotal": null,
"amount_total": null,
"automatic_tax": {
"enabled": false,
"liability": null,
"status": null
},
"billing_address_collection": "required",
"cancel_url": "http://selfhosting.testserver/realm/66c64ff1-94c6-48d0-b6f6-d1fbce7f2b1e/upgrade/?manual_license_management=false&tier=1",
"client_reference_id": null,
"client_secret": null,
"consent": null,
"consent_collection": null,
"created": 1000000000,
"currency": null,
"currency_conversion": null,
"custom_fields": [],
"custom_text": {
"after_submit": null,
"shipping_address": null,
"submit": null,
"terms_of_service_acceptance": null
},
"customer": "cus_NORMALIZED0001",
"customer_creation": null,
"customer_details": {
"address": null,
"email": "hamlet@zulip.com",
"name": null,
"phone": null,
"tax_exempt": null,
"tax_ids": null
},
"customer_email": null,
"expires_at": 1000000000,
"id": "cs_test_NORMALIZED01mzSwMCFGHAds3lpuPuOQOX1JtdpEaRpBY6C8Gv1fNFNezN",
"invoice": null,
"invoice_creation": null,
"livemode": false,
"locale": null,
"metadata": {
"remote_realm_user_id": "1",
"type": "card_update"
},
"mode": "setup",
"object": "checkout.session",
"payment_intent": null,
"payment_link": null,
"payment_method_collection": "always",
"payment_method_configuration_details": null,
"payment_method_options": {
"card": {
"request_three_d_secure": "automatic"
}
},
"payment_method_types": [
"card"
],
"payment_status": "no_payment_required",
"phone_number_collection": {
"enabled": false
},
"recovered_from": null,
"setup_intent": "seti_1Ow3loDEQaroqDjsC8yb78W3",
"shipping": null,
"shipping_address_collection": null,
"shipping_options": [],
"shipping_rate": null,
"status": "open",
"submit_type": null,
"subscription": null,
"success_url": "http://selfhosting.testserver/realm/66c64ff1-94c6-48d0-b6f6-d1fbce7f2b1e/billing/event_status/?stripe_session_id={CHECKOUT_SESSION_ID}",
"total_details": null,
"ui_mode": "hosted",
"url": "https://checkout.stripe.com/c/pay/cs_test_NORMALIZED01mzSwMCFGHAds3lpuPuOQOX1JtdpEaRpBY6C8Gv1fNFNezN#fid1d2BpamRhQ2prcSc%2FJ1ZqcHdmYCVWZGt2JVV3aicpJ2R1bE5gfCc%2FJ3VuWnFgdnFaXVRmMU5zNkldQTY9SnNRY09XZml2UXNQJyknY3dqaFZgd3Ngdyc%2FcXdwYCknaWR8anBxUXx1YCc%2FJ3Zsa2JpYFpmamlwaGsnKSdga2RnaWBVaWRmYG1qaWFgd3YnP3F3cGB4JSUl"
}
],
"has_more": true,
"object": "list",
"url": "/v1/checkout/sessions"
}

View File

@@ -0,0 +1,33 @@
{
"address": null,
"balance": 0,
"created": 1000000000,
"currency": null,
"default_currency": null,
"default_source": null,
"delinquent": false,
"description": "demo.example.com 6cde5f7a-1f7",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_NORMALIZED0001",
"invoice_prefix": "NORMA01",
"invoice_settings": {
"custom_fields": null,
"default_payment_method": null,
"footer": null,
"rendering_options": null
},
"livemode": false,
"metadata": {
"remote_server_str": "demo.example.com 6cde5f7a-1f7",
"remote_server_uuid": "6cde5f7a-1f7e-4978-9716-49f69ebfc9fe"
},
"name": null,
"next_invoice_sequence": 1,
"object": "customer",
"phone": null,
"preferred_locales": [],
"shipping": null,
"tax_exempt": "none",
"test_clock": null
}

View File

@@ -0,0 +1,33 @@
{
"address": null,
"balance": 0,
"created": 1000000000,
"currency": null,
"default_currency": null,
"default_source": null,
"delinquent": false,
"description": "demo.example.com 6cde5f7a-1f7",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_NORMALIZED0001",
"invoice_prefix": "NORMA01",
"invoice_settings": {
"custom_fields": null,
"default_payment_method": "pm_1Ow3lJDEQaroqDjs0BfOcLA5",
"footer": null,
"rendering_options": null
},
"livemode": false,
"metadata": {
"remote_server_str": "demo.example.com 6cde5f7a-1f7",
"remote_server_uuid": "6cde5f7a-1f7e-4978-9716-49f69ebfc9fe"
},
"name": null,
"next_invoice_sequence": 1,
"object": "customer",
"phone": null,
"preferred_locales": [],
"shipping": null,
"tax_exempt": "none",
"test_clock": null
}

View File

@@ -0,0 +1,80 @@
{
"address": null,
"balance": 0,
"created": 1000000000,
"currency": null,
"default_currency": null,
"default_source": null,
"delinquent": false,
"description": "demo.example.com 6cde5f7a-1f7",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_NORMALIZED0001",
"invoice_prefix": "NORMA01",
"invoice_settings": {
"custom_fields": null,
"default_payment_method": {
"billing_details": {
"address": {
"city": null,
"country": null,
"line1": null,
"line2": null,
"postal_code": null,
"state": null
},
"email": null,
"name": null,
"phone": null
},
"card": {
"brand": "visa",
"checks": {
"address_line1_check": null,
"address_postal_code_check": null,
"cvc_check": "pass"
},
"country": "US",
"display_brand": "visa",
"exp_month": 3,
"exp_year": 2025,
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"generated_from": null,
"last4": "4242",
"networks": {
"available": [
"visa"
],
"preferred": null
},
"three_d_secure_usage": {
"supported": true
},
"wallet": null
},
"created": 1000000000,
"customer": "cus_NORMALIZED0001",
"id": "pm_1Ow3lJDEQaroqDjs0BfOcLA5",
"livemode": false,
"metadata": {},
"object": "payment_method",
"type": "card"
},
"footer": null,
"rendering_options": null
},
"livemode": false,
"metadata": {
"remote_server_str": "demo.example.com 6cde5f7a-1f7",
"remote_server_uuid": "6cde5f7a-1f7e-4978-9716-49f69ebfc9fe"
},
"name": null,
"next_invoice_sequence": 1,
"object": "customer",
"phone": null,
"preferred_locales": [],
"shipping": null,
"tax_exempt": "none",
"test_clock": null
}

View File

@@ -0,0 +1,80 @@
{
"address": null,
"balance": 0,
"created": 1000000000,
"currency": null,
"default_currency": null,
"default_source": null,
"delinquent": false,
"description": "demo.example.com 6cde5f7a-1f7",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_NORMALIZED0001",
"invoice_prefix": "NORMA01",
"invoice_settings": {
"custom_fields": null,
"default_payment_method": {
"billing_details": {
"address": {
"city": null,
"country": null,
"line1": null,
"line2": null,
"postal_code": null,
"state": null
},
"email": null,
"name": null,
"phone": null
},
"card": {
"brand": "visa",
"checks": {
"address_line1_check": null,
"address_postal_code_check": null,
"cvc_check": "pass"
},
"country": "US",
"display_brand": "visa",
"exp_month": 3,
"exp_year": 2025,
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"generated_from": null,
"last4": "4242",
"networks": {
"available": [
"visa"
],
"preferred": null
},
"three_d_secure_usage": {
"supported": true
},
"wallet": null
},
"created": 1000000000,
"customer": "cus_NORMALIZED0001",
"id": "pm_1Ow3lJDEQaroqDjs0BfOcLA5",
"livemode": false,
"metadata": {},
"object": "payment_method",
"type": "card"
},
"footer": null,
"rendering_options": null
},
"livemode": false,
"metadata": {
"remote_server_str": "demo.example.com 6cde5f7a-1f7",
"remote_server_uuid": "6cde5f7a-1f7e-4978-9716-49f69ebfc9fe"
},
"name": null,
"next_invoice_sequence": 1,
"object": "customer",
"phone": null,
"preferred_locales": [],
"shipping": null,
"tax_exempt": "none",
"test_clock": null
}

View File

@@ -0,0 +1,80 @@
{
"address": null,
"balance": 0,
"created": 1000000000,
"currency": null,
"default_currency": null,
"default_source": null,
"delinquent": false,
"description": "demo.example.com 6cde5f7a-1f7",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_NORMALIZED0001",
"invoice_prefix": "NORMA01",
"invoice_settings": {
"custom_fields": null,
"default_payment_method": {
"billing_details": {
"address": {
"city": null,
"country": null,
"line1": null,
"line2": null,
"postal_code": null,
"state": null
},
"email": null,
"name": null,
"phone": null
},
"card": {
"brand": "visa",
"checks": {
"address_line1_check": null,
"address_postal_code_check": null,
"cvc_check": "pass"
},
"country": "US",
"display_brand": "visa",
"exp_month": 3,
"exp_year": 2025,
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"generated_from": null,
"last4": "4242",
"networks": {
"available": [
"visa"
],
"preferred": null
},
"three_d_secure_usage": {
"supported": true
},
"wallet": null
},
"created": 1000000000,
"customer": "cus_NORMALIZED0001",
"id": "pm_1Ow3lJDEQaroqDjs0BfOcLA5",
"livemode": false,
"metadata": {},
"object": "payment_method",
"type": "card"
},
"footer": null,
"rendering_options": null
},
"livemode": false,
"metadata": {
"remote_server_str": "demo.example.com 6cde5f7a-1f7",
"remote_server_uuid": "6cde5f7a-1f7e-4978-9716-49f69ebfc9fe"
},
"name": null,
"next_invoice_sequence": 1,
"object": "customer",
"phone": null,
"preferred_locales": [],
"shipping": null,
"tax_exempt": "none",
"test_clock": null
}

View File

@@ -0,0 +1,80 @@
{
"address": null,
"balance": 0,
"created": 1000000000,
"currency": null,
"default_currency": null,
"default_source": null,
"delinquent": false,
"description": "demo.example.com 6cde5f7a-1f7",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_NORMALIZED0001",
"invoice_prefix": "NORMA01",
"invoice_settings": {
"custom_fields": null,
"default_payment_method": {
"billing_details": {
"address": {
"city": null,
"country": null,
"line1": null,
"line2": null,
"postal_code": null,
"state": null
},
"email": null,
"name": null,
"phone": null
},
"card": {
"brand": "visa",
"checks": {
"address_line1_check": null,
"address_postal_code_check": null,
"cvc_check": "pass"
},
"country": "US",
"display_brand": "visa",
"exp_month": 3,
"exp_year": 2025,
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"generated_from": null,
"last4": "4242",
"networks": {
"available": [
"visa"
],
"preferred": null
},
"three_d_secure_usage": {
"supported": true
},
"wallet": null
},
"created": 1000000000,
"customer": "cus_NORMALIZED0001",
"id": "pm_1Ow3lJDEQaroqDjs0BfOcLA5",
"livemode": false,
"metadata": {},
"object": "payment_method",
"type": "card"
},
"footer": null,
"rendering_options": null
},
"livemode": false,
"metadata": {
"remote_server_str": "demo.example.com 6cde5f7a-1f7",
"remote_server_uuid": "6cde5f7a-1f7e-4978-9716-49f69ebfc9fe"
},
"name": null,
"next_invoice_sequence": 1,
"object": "customer",
"phone": null,
"preferred_locales": [],
"shipping": null,
"tax_exempt": "none",
"test_clock": null
}

View File

@@ -0,0 +1,80 @@
{
"address": null,
"balance": 0,
"created": 1000000000,
"currency": null,
"default_currency": null,
"default_source": null,
"delinquent": false,
"description": "demo.example.com 6cde5f7a-1f7",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_NORMALIZED0001",
"invoice_prefix": "NORMA01",
"invoice_settings": {
"custom_fields": null,
"default_payment_method": {
"billing_details": {
"address": {
"city": null,
"country": null,
"line1": null,
"line2": null,
"postal_code": null,
"state": null
},
"email": null,
"name": null,
"phone": null
},
"card": {
"brand": "visa",
"checks": {
"address_line1_check": null,
"address_postal_code_check": null,
"cvc_check": "pass"
},
"country": "US",
"display_brand": "visa",
"exp_month": 3,
"exp_year": 2025,
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"generated_from": null,
"last4": "4242",
"networks": {
"available": [
"visa"
],
"preferred": null
},
"three_d_secure_usage": {
"supported": true
},
"wallet": null
},
"created": 1000000000,
"customer": "cus_NORMALIZED0001",
"id": "pm_1Ow3lJDEQaroqDjs0BfOcLA5",
"livemode": false,
"metadata": {},
"object": "payment_method",
"type": "card"
},
"footer": null,
"rendering_options": null
},
"livemode": false,
"metadata": {
"remote_server_str": "demo.example.com 6cde5f7a-1f7",
"remote_server_uuid": "6cde5f7a-1f7e-4978-9716-49f69ebfc9fe"
},
"name": null,
"next_invoice_sequence": 1,
"object": "customer",
"phone": null,
"preferred_locales": [],
"shipping": null,
"tax_exempt": "none",
"test_clock": null
}

View File

@@ -0,0 +1,60 @@
{
"data": [
{
"api_version": "2020-08-27",
"created": 1000000000,
"data": {
"object": {
"address": null,
"balance": 0,
"created": 1000000000,
"currency": null,
"default_currency": null,
"default_source": null,
"delinquent": false,
"description": "demo.example.com 6cde5f7a-1f7",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_NORMALIZED0001",
"invoice_prefix": "NORMA01",
"invoice_settings": {
"custom_fields": null,
"default_payment_method": "pm_1Ow3lJDEQaroqDjs0BfOcLA5",
"footer": null,
"rendering_options": null
},
"livemode": false,
"metadata": {
"remote_server_str": "demo.example.com 6cde5f7a-1f7",
"remote_server_uuid": "6cde5f7a-1f7e-4978-9716-49f69ebfc9fe"
},
"name": null,
"next_invoice_sequence": 1,
"object": "customer",
"phone": null,
"preferred_locales": [],
"shipping": null,
"tax_exempt": "none",
"test_clock": null
},
"previous_attributes": {
"invoice_settings": {
"default_payment_method": null
}
}
},
"id": "evt_1Ow3lMDEQaroqDjsAWFrCMeC",
"livemode": false,
"object": "event",
"pending_webhooks": 0,
"request": {
"id": "req_NORMALIZED0001",
"idempotency_key": "9466b416-4c72-44a8-8712-b62bd0616f02"
},
"type": "customer.updated"
}
],
"has_more": true,
"object": "list",
"url": "/v1/events"
}

View File

@@ -0,0 +1,6 @@
{
"data": [],
"has_more": false,
"object": "list",
"url": "/v1/invoices"
}

View File

@@ -0,0 +1,34 @@
{
"application": null,
"automatic_payment_methods": null,
"cancellation_reason": null,
"client_secret": "seti_1Ow3lJDEQaroqDjsHu7H05RV_secret_PlaxEQM1vJHEjhmpOfERmmbIC7Kp0IP",
"created": 1000000000,
"customer": "cus_NORMALIZED0001",
"description": null,
"flow_directions": null,
"id": "seti_1Ow3lJDEQaroqDjsHu7H05RV",
"last_setup_error": null,
"latest_attempt": "setatt_1Ow3lJDEQaroqDjsM7JCRnVk",
"livemode": false,
"mandate": null,
"metadata": {},
"next_action": null,
"object": "setup_intent",
"on_behalf_of": null,
"payment_method": "pm_1Ow3lJDEQaroqDjs0BfOcLA5",
"payment_method_configuration_details": null,
"payment_method_options": {
"card": {
"mandate_options": null,
"network": null,
"request_three_d_secure": "automatic"
}
},
"payment_method_types": [
"card"
],
"single_use_mandate": null,
"status": "succeeded",
"usage": "off_session"
}

View File

@@ -0,0 +1,41 @@
{
"data": [
{
"application": null,
"automatic_payment_methods": null,
"cancellation_reason": null,
"client_secret": "seti_1Ow3lIDEQaroqDjsK3i3Fcae_secret_PlaxpWWox8gmU3W9Aa3RhRjuNURIhYA",
"created": 1000000000,
"customer": "cus_NORMALIZED0001",
"description": null,
"flow_directions": null,
"id": "seti_1Ow3lIDEQaroqDjsK3i3Fcae",
"last_setup_error": null,
"latest_attempt": null,
"livemode": false,
"mandate": null,
"metadata": {},
"next_action": null,
"object": "setup_intent",
"on_behalf_of": null,
"payment_method": null,
"payment_method_configuration_details": null,
"payment_method_options": {
"card": {
"mandate_options": null,
"network": null,
"request_three_d_secure": "automatic"
}
},
"payment_method_types": [
"card"
],
"single_use_mandate": null,
"status": "requires_payment_method",
"usage": "off_session"
}
],
"has_more": true,
"object": "list",
"url": "/v1/setup_intents"
}

View File

@@ -0,0 +1,34 @@
{
"application": null,
"automatic_payment_methods": null,
"cancellation_reason": null,
"client_secret": "seti_1Ow3lJDEQaroqDjsHu7H05RV_secret_PlaxEQM1vJHEjhmpOfERmmbIC7Kp0IP",
"created": 1000000000,
"customer": "cus_NORMALIZED0001",
"description": null,
"flow_directions": null,
"id": "seti_1Ow3lJDEQaroqDjsHu7H05RV",
"last_setup_error": null,
"latest_attempt": "setatt_1Ow3lJDEQaroqDjsM7JCRnVk",
"livemode": false,
"mandate": null,
"metadata": {},
"next_action": null,
"object": "setup_intent",
"on_behalf_of": null,
"payment_method": "pm_1Ow3lJDEQaroqDjs0BfOcLA5",
"payment_method_configuration_details": null,
"payment_method_options": {
"card": {
"mandate_options": null,
"network": null,
"request_three_d_secure": "automatic"
}
},
"payment_method_types": [
"card"
],
"single_use_mandate": null,
"status": "succeeded",
"usage": "off_session"
}

View File

@@ -0,0 +1,79 @@
{
"after_expiration": null,
"allow_promotion_codes": null,
"amount_subtotal": null,
"amount_total": null,
"automatic_tax": {
"enabled": false,
"liability": null,
"status": null
},
"billing_address_collection": "required",
"cancel_url": "http://selfhosting.testserver/server/6cde5f7a-1f7e-4978-9716-49f69ebfc9fe/upgrade/?manual_license_management=false&tier=1",
"client_reference_id": null,
"client_secret": null,
"consent": null,
"consent_collection": null,
"created": 1000000000,
"currency": null,
"currency_conversion": null,
"custom_fields": [],
"custom_text": {
"after_submit": null,
"shipping_address": null,
"submit": null,
"terms_of_service_acceptance": null
},
"customer": "cus_NORMALIZED0001",
"customer_creation": null,
"customer_details": {
"address": null,
"email": "hamlet@zulip.com",
"name": null,
"phone": null,
"tax_exempt": null,
"tax_ids": null
},
"customer_email": null,
"expires_at": 1000000000,
"id": "cs_test_NORMALIZED015MlE8nIXMCkncu4kwGDdaSTq5BaWqooqDAFv0fpSAdI9If",
"invoice": null,
"invoice_creation": null,
"livemode": false,
"locale": null,
"metadata": {
"remote_server_user_id": "1",
"type": "card_update"
},
"mode": "setup",
"object": "checkout.session",
"payment_intent": null,
"payment_link": null,
"payment_method_collection": "always",
"payment_method_configuration_details": null,
"payment_method_options": {
"card": {
"request_three_d_secure": "automatic"
}
},
"payment_method_types": [
"card"
],
"payment_status": "no_payment_required",
"phone_number_collection": {
"enabled": false
},
"recovered_from": null,
"setup_intent": "seti_1Ow3lIDEQaroqDjsK3i3Fcae",
"shipping": null,
"shipping_address_collection": null,
"shipping_options": [],
"shipping_rate": null,
"status": "open",
"submit_type": null,
"subscription": null,
"success_url": "http://selfhosting.testserver/server/6cde5f7a-1f7e-4978-9716-49f69ebfc9fe/billing/event_status/?stripe_session_id={CHECKOUT_SESSION_ID}",
"total_details": null,
"ui_mode": "hosted",
"url": "https://checkout.stripe.com/c/pay/cs_test_NORMALIZED015MlE8nIXMCkncu4kwGDdaSTq5BaWqooqDAFv0fpSAdI9If#fid1d2BpamRhQ2prcSc%2FJ1ZqcHdmYCVWZGt2JVV3aicpJ2R1bE5gfCc%2FJ3VuWnFgdnFaXVRmMU5zNkldQTY9SnNRY09XZml2UXNQJyknY3dqaFZgd3Ngdyc%2FcXdwYCknaWR8anBxUXx1YCc%2FJ3Zsa2JpYFpmamlwaGsnKSdga2RnaWBVaWRmYG1qaWFgd3YnP3F3cGB4JSUl"
}

View File

@@ -0,0 +1,86 @@
{
"data": [
{
"after_expiration": null,
"allow_promotion_codes": null,
"amount_subtotal": null,
"amount_total": null,
"automatic_tax": {
"enabled": false,
"liability": null,
"status": null
},
"billing_address_collection": "required",
"cancel_url": "http://selfhosting.testserver/server/6cde5f7a-1f7e-4978-9716-49f69ebfc9fe/upgrade/?manual_license_management=false&tier=1",
"client_reference_id": null,
"client_secret": null,
"consent": null,
"consent_collection": null,
"created": 1000000000,
"currency": null,
"currency_conversion": null,
"custom_fields": [],
"custom_text": {
"after_submit": null,
"shipping_address": null,
"submit": null,
"terms_of_service_acceptance": null
},
"customer": "cus_NORMALIZED0001",
"customer_creation": null,
"customer_details": {
"address": null,
"email": "hamlet@zulip.com",
"name": null,
"phone": null,
"tax_exempt": null,
"tax_ids": null
},
"customer_email": null,
"expires_at": 1000000000,
"id": "cs_test_NORMALIZED015MlE8nIXMCkncu4kwGDdaSTq5BaWqooqDAFv0fpSAdI9If",
"invoice": null,
"invoice_creation": null,
"livemode": false,
"locale": null,
"metadata": {
"remote_server_user_id": "1",
"type": "card_update"
},
"mode": "setup",
"object": "checkout.session",
"payment_intent": null,
"payment_link": null,
"payment_method_collection": "always",
"payment_method_configuration_details": null,
"payment_method_options": {
"card": {
"request_three_d_secure": "automatic"
}
},
"payment_method_types": [
"card"
],
"payment_status": "no_payment_required",
"phone_number_collection": {
"enabled": false
},
"recovered_from": null,
"setup_intent": "seti_1Ow3lIDEQaroqDjsK3i3Fcae",
"shipping": null,
"shipping_address_collection": null,
"shipping_options": [],
"shipping_rate": null,
"status": "open",
"submit_type": null,
"subscription": null,
"success_url": "http://selfhosting.testserver/server/6cde5f7a-1f7e-4978-9716-49f69ebfc9fe/billing/event_status/?stripe_session_id={CHECKOUT_SESSION_ID}",
"total_details": null,
"ui_mode": "hosted",
"url": "https://checkout.stripe.com/c/pay/cs_test_NORMALIZED015MlE8nIXMCkncu4kwGDdaSTq5BaWqooqDAFv0fpSAdI9If#fid1d2BpamRhQ2prcSc%2FJ1ZqcHdmYCVWZGt2JVV3aicpJ2R1bE5gfCc%2FJ3VuWnFgdnFaXVRmMU5zNkldQTY9SnNRY09XZml2UXNQJyknY3dqaFZgd3Ngdyc%2FcXdwYCknaWR8anBxUXx1YCc%2FJ3Zsa2JpYFpmamlwaGsnKSdga2RnaWBVaWRmYG1qaWFgd3YnP3F3cGB4JSUl"
}
],
"has_more": true,
"object": "list",
"url": "/v1/checkout/sessions"
}

View File

@@ -2062,6 +2062,81 @@ class StripeTest(StripeTestCase):
response = self.client_get("/billing/")
self.assertNotEqual("/sponsorship/", response["Location"])
@mock_stripe(tested_timestamp_fields=["created"])
def test_redirect_for_billing_page_downgrade_at_free_trial_end(self, *mocks: Mock) -> None:
user = self.example_user("hamlet")
self.login_user(user)
with self.settings(CLOUD_FREE_TRIAL_DAYS=30):
response = self.client_get("/upgrade/")
free_trial_end_date = self.now + timedelta(days=30)
self.assert_in_success_response(
["Your card will not be charged", "free trial", "30-day"], response
)
self.assertNotEqual(user.realm.plan_type, Realm.PLAN_TYPE_STANDARD)
self.assertFalse(Customer.objects.filter(realm=user.realm).exists())
stripe_customer = self.add_card_and_upgrade(user)
customer = Customer.objects.get(stripe_customer_id=stripe_customer.id, realm=user.realm)
plan = CustomerPlan.objects.get(
customer=customer,
automanage_licenses=True,
price_per_license=8000,
fixed_price=None,
discount=None,
billing_cycle_anchor=self.now,
billing_schedule=CustomerPlan.BILLING_SCHEDULE_ANNUAL,
invoiced_through=LicenseLedger.objects.first(),
next_invoice_date=free_trial_end_date,
tier=CustomerPlan.TIER_CLOUD_STANDARD,
status=CustomerPlan.FREE_TRIAL,
# For payment through card.
charge_automatically=True,
)
LicenseLedger.objects.get(
plan=plan,
is_renewal=True,
event_time=self.now,
licenses=self.seat_count,
licenses_at_next_renewal=self.seat_count,
)
realm = get_realm("zulip")
self.assertEqual(realm.plan_type, Realm.PLAN_TYPE_STANDARD)
with time_machine.travel(self.now, tick=False):
response = self.client_get("/billing/")
self.assert_not_in_success_response(["Pay annually"], response)
for substring in [
"Zulip Cloud Standard <i>(free trial)</i>",
"Your plan will automatically renew on",
"February 1, 2012",
"Visa ending in 4242",
"Update card",
]:
self.assert_in_response(substring, response)
# schedule downgrade
with time_machine.travel(self.now + timedelta(days=3), tick=False), self.assertLogs(
"corporate.stripe", "INFO"
) as m:
response = self.client_billing_patch(
"/billing/plan",
{"status": CustomerPlan.DOWNGRADE_AT_END_OF_FREE_TRIAL},
)
self.assert_json_success(response)
plan.refresh_from_db()
self.assertEqual(plan.status, CustomerPlan.DOWNGRADE_AT_END_OF_FREE_TRIAL)
expected_log = f"INFO:corporate.stripe:Change plan status: Customer.id: {customer.id}, CustomerPlan.id: {plan.id}, status: {CustomerPlan.DOWNGRADE_AT_END_OF_FREE_TRIAL}"
self.assertEqual(m.output[0], expected_log)
# Visit /billing on free-trial end date before the invoice cron runs.
with time_machine.travel(free_trial_end_date, tick=False):
response = self.client_get("/billing/")
self.assertEqual(response.status_code, 302)
self.assertEqual("/plans/", response["Location"])
def test_upgrade_page_for_demo_organizations(self) -> None:
user = self.example_user("hamlet")
user.realm.demo_organization_scheduled_deletion_date = timezone_now() + timedelta(days=30)
@@ -6287,6 +6362,93 @@ class TestRemoteRealmBillingFlow(StripeTestCase, RemoteRealmBillingTestCase):
# TODO: Add test for invoice generation once that's implemented.
@responses.activate
@mock_stripe()
def test_redirect_for_remote_realm_billing_page_downgrade_at_free_trial_end(
self, *mocks: Mock
) -> None:
with self.settings(SELF_HOSTING_FREE_TRIAL_DAYS=30):
self.login("hamlet")
hamlet = self.example_user("hamlet")
self.add_mock_response()
with time_machine.travel(self.now, tick=False):
send_server_data_to_push_bouncer(consider_usage_statistics=False)
result = self.execute_remote_billing_authentication_flow(hamlet)
self.assertEqual(result.status_code, 302)
self.assertEqual(result["Location"], f"{self.billing_session.billing_base_url}/plans/")
# upgrade to basic plan
with time_machine.travel(self.now, tick=False):
result = self.client_get(
f"{self.billing_session.billing_base_url}/upgrade/?tier={CustomerPlan.TIER_SELF_HOSTED_BASIC}",
subdomain="selfhosting",
)
self.assertEqual(result.status_code, 200)
self.assert_in_success_response(
[
"Start free trial",
"Zulip Basic",
"Due",
"on February 1, 2012",
"Add card",
"Start 30-day free trial",
],
result,
)
self.assertFalse(Customer.objects.exists())
self.assertFalse(CustomerPlan.objects.exists())
self.assertFalse(LicenseLedger.objects.exists())
with time_machine.travel(self.now, tick=False):
stripe_customer = self.add_card_and_upgrade(
tier=CustomerPlan.TIER_SELF_HOSTED_BASIC, schedule="monthly"
)
self.assertEqual(Invoice.objects.count(), 0)
customer = Customer.objects.get(stripe_customer_id=stripe_customer.id)
plan = CustomerPlan.objects.get(customer=customer)
LicenseLedger.objects.get(plan=plan)
with time_machine.travel(self.now + timedelta(days=1), tick=False):
response = self.client_get(
f"{self.billing_session.billing_base_url}/billing/", subdomain="selfhosting"
)
for substring in [
"Zulip Basic",
"(free trial)",
"Your plan will automatically renew on",
"February 1, 2012",
]:
self.assert_in_response(substring, response)
# schedule downgrade
with time_machine.travel(self.now + timedelta(days=3), tick=False), self.assertLogs(
"corporate.stripe", "INFO"
) as m:
response = self.client_billing_patch(
"/billing/plan",
{"status": CustomerPlan.DOWNGRADE_AT_END_OF_FREE_TRIAL},
)
self.assert_json_success(response)
plan.refresh_from_db()
self.assertEqual(plan.status, CustomerPlan.DOWNGRADE_AT_END_OF_FREE_TRIAL)
expected_log = f"INFO:corporate.stripe:Change plan status: Customer.id: {customer.id}, CustomerPlan.id: {plan.id}, status: {CustomerPlan.DOWNGRADE_AT_END_OF_FREE_TRIAL}"
self.assertEqual(m.output[0], expected_log)
# Visit /billing on free-trial end date before the invoice cron runs.
with time_machine.travel(self.now + timedelta(days=30), tick=False):
response = self.client_get(
f"{self.billing_session.billing_base_url}/billing/", subdomain="selfhosting"
)
self.assertEqual(response.status_code, 302)
self.assertEqual(
f"{self.billing_session.billing_base_url}/plans/", response["Location"]
)
@responses.activate
@mock_stripe()
def test_upgrade_remote_realm_user_to_monthly_basic_plan(self, *mocks: Mock) -> None:
@@ -8066,6 +8228,95 @@ class TestRemoteServerBillingFlow(StripeTestCase, RemoteServerTestCase):
# TODO: Add test for invoice generation once that's implemented.
@responses.activate
@mock_stripe()
def test_redirect_for_remote_server_billing_page_downgrade_at_free_trial_end(
self, *mocks: Mock
) -> None:
with self.settings(SELF_HOSTING_FREE_TRIAL_DAYS=30):
self.login("hamlet")
hamlet = self.example_user("hamlet")
self.add_mock_response()
with time_machine.travel(self.now, tick=False):
send_server_data_to_push_bouncer(consider_usage_statistics=False)
result = self.execute_remote_billing_authentication_flow(
hamlet.delivery_email, hamlet.full_name
)
self.assertEqual(result.status_code, 302)
self.assertEqual(result["Location"], f"{self.billing_session.billing_base_url}/plans/")
# upgrade to basic plan
with time_machine.travel(self.now, tick=False):
result = self.client_get(
f"{self.billing_session.billing_base_url}/upgrade/?tier={CustomerPlan.TIER_SELF_HOSTED_BASIC}",
subdomain="selfhosting",
)
self.assertEqual(result.status_code, 200)
self.assert_in_success_response(
[
"Start free trial",
"Zulip Basic",
"Due",
"on February 1, 2012",
"Add card",
"Start 30-day free trial",
],
result,
)
self.assertFalse(Customer.objects.exists())
self.assertFalse(CustomerPlan.objects.exists())
self.assertFalse(LicenseLedger.objects.exists())
with time_machine.travel(self.now, tick=False):
stripe_customer = self.add_card_and_upgrade(
tier=CustomerPlan.TIER_SELF_HOSTED_BASIC, schedule="monthly"
)
self.assertEqual(Invoice.objects.count(), 0)
customer = Customer.objects.get(stripe_customer_id=stripe_customer.id)
plan = CustomerPlan.objects.get(customer=customer)
LicenseLedger.objects.get(plan=plan)
with time_machine.travel(self.now + timedelta(days=1), tick=False):
response = self.client_get(
f"{self.billing_session.billing_base_url}/billing/", subdomain="selfhosting"
)
for substring in [
"Zulip Basic",
"(free trial)",
"Your plan will automatically renew on",
"February 1, 2012",
]:
self.assert_in_response(substring, response)
# schedule downgrade
with time_machine.travel(self.now + timedelta(days=3), tick=False), self.assertLogs(
"corporate.stripe", "INFO"
) as m:
response = self.client_billing_patch(
"/billing/plan",
{"status": CustomerPlan.DOWNGRADE_AT_END_OF_FREE_TRIAL},
)
self.assert_json_success(response)
plan.refresh_from_db()
self.assertEqual(plan.status, CustomerPlan.DOWNGRADE_AT_END_OF_FREE_TRIAL)
expected_log = f"INFO:corporate.stripe:Change plan status: Customer.id: {customer.id}, CustomerPlan.id: {plan.id}, status: {CustomerPlan.DOWNGRADE_AT_END_OF_FREE_TRIAL}"
self.assertEqual(m.output[0], expected_log)
# Visit /billing on free-trial end date before the invoice cron runs.
with time_machine.travel(self.now + timedelta(days=30), tick=False):
response = self.client_get(
f"{self.billing_session.billing_base_url}/billing/", subdomain="selfhosting"
)
self.assertEqual(response.status_code, 302)
self.assertEqual(
f"{self.billing_session.billing_base_url}/plans/", response["Location"]
)
@responses.activate
@mock_stripe()
def test_upgrade_server_user_to_monthly_basic_plan(self, *mocks: Mock) -> None:

View File

@@ -83,6 +83,8 @@ def billing_page(
main_context = billing_session.get_billing_page_context()
if main_context:
if main_context.get("current_plan_downgraded") is True:
return HttpResponseRedirect(reverse("plans"))
context.update(main_context)
context["success_message"] = success_message
@@ -142,6 +144,8 @@ def remote_realm_billing_page(
return billing_session.missing_data_error_page(request)
if main_context:
if main_context.get("current_plan_downgraded") is True:
return HttpResponseRedirect(reverse("remote_realm_plans_page", args=(realm_uuid,)))
context.update(main_context)
context["success_message"] = success_message
@@ -215,6 +219,13 @@ def remote_server_billing_page(
return billing_session.missing_data_error_page(request)
if main_context:
if main_context.get("current_plan_downgraded") is True:
return HttpResponseRedirect(
reverse(
"remote_server_plans_page",
kwargs={"server_uuid": billing_session.remote_server.uuid},
)
)
context.update(main_context)
context["success_message"] = success_message