mirror of
https://github.com/zulip/zulip.git
synced 2025-11-09 08:26:11 +00:00
billing: Add functions for automatic invoicing of plans.
This commit is contained in:
@@ -91,6 +91,21 @@ def next_renewal_date(plan: CustomerPlan, event_time: datetime) -> datetime:
|
||||
periods += 1
|
||||
return dt
|
||||
|
||||
# TODO take downgrade into account
|
||||
def next_invoice_date(plan: CustomerPlan) -> datetime:
|
||||
months_per_period = {
|
||||
CustomerPlan.ANNUAL: 12,
|
||||
CustomerPlan.MONTHLY: 1,
|
||||
}[plan.billing_schedule]
|
||||
if plan.automanage_licenses:
|
||||
months_per_period = 1
|
||||
periods = 1
|
||||
dt = plan.billing_cycle_anchor
|
||||
while dt <= plan.next_invoice_date:
|
||||
dt = add_months(plan.billing_cycle_anchor, months_per_period * periods)
|
||||
periods += 1
|
||||
return dt
|
||||
|
||||
def renewal_amount(plan: CustomerPlan) -> Optional[int]: # nocoverage: TODO
|
||||
if plan.fixed_price is not None:
|
||||
return plan.fixed_price
|
||||
@@ -356,6 +371,77 @@ def update_license_ledger_if_needed(realm: Realm, event_time: datetime) -> None:
|
||||
return
|
||||
update_license_ledger_for_automanaged_plan(realm, plan, event_time)
|
||||
|
||||
def invoice_plan(plan: CustomerPlan, event_time: datetime) -> None:
|
||||
if plan.invoicing_status == CustomerPlan.STARTED:
|
||||
raise NotImplementedError('Plan with invoicing_status==STARTED needs manual resolution.')
|
||||
add_plan_renewal_to_license_ledger_if_needed(plan, event_time)
|
||||
assert(plan.invoiced_through is not None)
|
||||
licenses_base = plan.invoiced_through.licenses
|
||||
invoice_item_created = False
|
||||
for ledger_entry in LicenseLedger.objects.filter(plan=plan, id__gt=plan.invoiced_through.id,
|
||||
event_time__lte=event_time).order_by('id'):
|
||||
price_args = {} # type: Dict[str, int]
|
||||
if ledger_entry.is_renewal:
|
||||
if plan.fixed_price is not None:
|
||||
price_args = {'amount': plan.fixed_price}
|
||||
else:
|
||||
assert(plan.price_per_license is not None) # needed for mypy
|
||||
price_args = {'unit_amount': plan.price_per_license,
|
||||
'quantity': ledger_entry.licenses}
|
||||
description = "Zulip Standard - renewal"
|
||||
elif ledger_entry.licenses != licenses_base:
|
||||
assert(plan.price_per_license)
|
||||
last_renewal = LicenseLedger.objects.filter(
|
||||
plan=plan, is_renewal=True, event_time__lte=ledger_entry.event_time) \
|
||||
.order_by('-id').first().event_time
|
||||
period_end = next_renewal_date(plan, ledger_entry.event_time)
|
||||
proration_fraction = (period_end - ledger_entry.event_time) / (period_end - last_renewal)
|
||||
price_args = {'unit_amount': int(plan.price_per_license * proration_fraction + .5),
|
||||
'quantity': ledger_entry.licenses - licenses_base}
|
||||
description = "Additional license ({} - {})".format(
|
||||
ledger_entry.event_time.strftime('%b %-d, %Y'), period_end.strftime('%b %-d, %Y'))
|
||||
|
||||
if price_args:
|
||||
plan.invoiced_through = ledger_entry
|
||||
plan.invoicing_status = CustomerPlan.STARTED
|
||||
plan.save(update_fields=['invoicing_status', 'invoiced_through'])
|
||||
stripe.InvoiceItem.create(
|
||||
currency='usd',
|
||||
customer=plan.customer.stripe_customer_id,
|
||||
description=description,
|
||||
discountable=False,
|
||||
period = {'start': datetime_to_timestamp(ledger_entry.event_time),
|
||||
'end': datetime_to_timestamp(next_renewal_date(plan, ledger_entry.event_time))},
|
||||
idempotency_key='ledger_entry:{}'.format(ledger_entry.id),
|
||||
**price_args)
|
||||
invoice_item_created = True
|
||||
plan.invoiced_through = ledger_entry
|
||||
plan.invoicing_status = CustomerPlan.DONE
|
||||
plan.save(update_fields=['invoicing_status', 'invoiced_through'])
|
||||
licenses_base = ledger_entry.licenses
|
||||
|
||||
if invoice_item_created:
|
||||
if plan.charge_automatically:
|
||||
billing_method = 'charge_automatically'
|
||||
days_until_due = None
|
||||
else:
|
||||
billing_method = 'send_invoice'
|
||||
days_until_due = DEFAULT_INVOICE_DAYS_UNTIL_DUE
|
||||
stripe_invoice = stripe.Invoice.create(
|
||||
auto_advance=True,
|
||||
billing=billing_method,
|
||||
customer=plan.customer.stripe_customer_id,
|
||||
days_until_due=days_until_due,
|
||||
statement_descriptor='Zulip Standard')
|
||||
stripe.Invoice.finalize_invoice(stripe_invoice)
|
||||
|
||||
plan.next_invoice_date = next_invoice_date(plan)
|
||||
plan.save(update_fields=['next_invoice_date'])
|
||||
|
||||
def invoice_plans_as_needed(event_time: datetime) -> None:
|
||||
for plan in CustomerPlan.objects.filter(next_invoice_date__lte=event_time):
|
||||
invoice_plan(plan, event_time)
|
||||
|
||||
def attach_discount_to_realm(user: UserProfile, discount: Decimal) -> None:
|
||||
customer = Customer.objects.filter(realm=user.realm).first()
|
||||
if customer is None:
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"account_balance": 0,
|
||||
"created": 1000000000,
|
||||
"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,
|
||||
"footer": null
|
||||
},
|
||||
"livemode": false,
|
||||
"metadata": {
|
||||
"realm_id": "1",
|
||||
"realm_str": "zulip"
|
||||
},
|
||||
"object": "customer",
|
||||
"shipping": null,
|
||||
"sources": {
|
||||
"data": [],
|
||||
"has_more": false,
|
||||
"object": "list",
|
||||
"total_count": 0,
|
||||
"url": "/v1/customers/cus_NORMALIZED0001/sources"
|
||||
},
|
||||
"subscriptions": {
|
||||
"data": [],
|
||||
"has_more": false,
|
||||
"object": "list",
|
||||
"total_count": 0,
|
||||
"url": "/v1/customers/cus_NORMALIZED0001/subscriptions"
|
||||
},
|
||||
"tax_info": null,
|
||||
"tax_info_verification": null
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"amount_due": 984000,
|
||||
"amount_paid": 0,
|
||||
"amount_remaining": 984000,
|
||||
"application_fee": null,
|
||||
"attempt_count": 0,
|
||||
"attempted": false,
|
||||
"auto_advance": true,
|
||||
"billing": "send_invoice",
|
||||
"billing_reason": "manual",
|
||||
"charge": null,
|
||||
"currency": "usd",
|
||||
"custom_fields": null,
|
||||
"customer": "cus_NORMALIZED0001",
|
||||
"date": 1000000000,
|
||||
"default_source": null,
|
||||
"description": "",
|
||||
"discount": null,
|
||||
"due_date": 1000000000,
|
||||
"ending_balance": null,
|
||||
"finalized_at": null,
|
||||
"footer": null,
|
||||
"hosted_invoice_url": null,
|
||||
"id": "in_NORMALIZED00000000000001",
|
||||
"invoice_pdf": null,
|
||||
"lines": {
|
||||
"data": [
|
||||
{
|
||||
"amount": 984000,
|
||||
"currency": "usd",
|
||||
"description": "Zulip Standard",
|
||||
"discountable": false,
|
||||
"id": "ii_NORMALIZED00000000000001",
|
||||
"invoice_item": "ii_NORMALIZED00000000000001",
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "line_item",
|
||||
"period": {
|
||||
"end": 1357095845,
|
||||
"start": 1325473445
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 123,
|
||||
"subscription": null,
|
||||
"type": "invoiceitem"
|
||||
}
|
||||
],
|
||||
"has_more": false,
|
||||
"object": "list",
|
||||
"total_count": 1,
|
||||
"url": "/v1/invoices/in_NORMALIZED00000000000001/lines"
|
||||
},
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"next_payment_attempt": null,
|
||||
"number": "NORMALI-0001",
|
||||
"object": "invoice",
|
||||
"paid": false,
|
||||
"period_end": 1000000000,
|
||||
"period_start": 1000000000,
|
||||
"receipt_number": null,
|
||||
"starting_balance": 0,
|
||||
"statement_descriptor": "Zulip Standard",
|
||||
"status": "draft",
|
||||
"subscription": null,
|
||||
"subtotal": 984000,
|
||||
"tax": 0,
|
||||
"tax_percent": null,
|
||||
"total": 984000,
|
||||
"webhooks_delivered_at": null
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"amount_due": 100,
|
||||
"amount_paid": 0,
|
||||
"amount_remaining": 100,
|
||||
"application_fee": null,
|
||||
"attempt_count": 0,
|
||||
"attempted": false,
|
||||
"auto_advance": true,
|
||||
"billing": "send_invoice",
|
||||
"billing_reason": "manual",
|
||||
"charge": null,
|
||||
"currency": "usd",
|
||||
"custom_fields": null,
|
||||
"customer": "cus_NORMALIZED0001",
|
||||
"date": 1000000000,
|
||||
"default_source": null,
|
||||
"description": "",
|
||||
"discount": null,
|
||||
"due_date": 1000000000,
|
||||
"ending_balance": null,
|
||||
"finalized_at": null,
|
||||
"footer": null,
|
||||
"hosted_invoice_url": null,
|
||||
"id": "in_NORMALIZED00000000000002",
|
||||
"invoice_pdf": null,
|
||||
"lines": {
|
||||
"data": [
|
||||
{
|
||||
"amount": 100,
|
||||
"currency": "usd",
|
||||
"description": "Zulip Standard - renewal",
|
||||
"discountable": false,
|
||||
"id": "ii_NORMALIZED00000000000002",
|
||||
"invoice_item": "ii_NORMALIZED00000000000002",
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "line_item",
|
||||
"period": {
|
||||
"end": 1388631845,
|
||||
"start": 1357095845
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 1,
|
||||
"subscription": null,
|
||||
"type": "invoiceitem"
|
||||
}
|
||||
],
|
||||
"has_more": false,
|
||||
"object": "list",
|
||||
"total_count": 1,
|
||||
"url": "/v1/invoices/in_NORMALIZED00000000000002/lines"
|
||||
},
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"next_payment_attempt": null,
|
||||
"number": "NORMALI-0002",
|
||||
"object": "invoice",
|
||||
"paid": false,
|
||||
"period_end": 1000000000,
|
||||
"period_start": 1000000000,
|
||||
"receipt_number": null,
|
||||
"starting_balance": 0,
|
||||
"statement_descriptor": "Zulip Standard",
|
||||
"status": "draft",
|
||||
"subscription": null,
|
||||
"subtotal": 100,
|
||||
"tax": 0,
|
||||
"tax_percent": null,
|
||||
"total": 100,
|
||||
"webhooks_delivered_at": null
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"amount_due": 984000,
|
||||
"amount_paid": 0,
|
||||
"amount_remaining": 984000,
|
||||
"application_fee": null,
|
||||
"attempt_count": 0,
|
||||
"attempted": false,
|
||||
"auto_advance": true,
|
||||
"billing": "send_invoice",
|
||||
"billing_reason": "manual",
|
||||
"charge": null,
|
||||
"currency": "usd",
|
||||
"custom_fields": null,
|
||||
"customer": "cus_NORMALIZED0001",
|
||||
"date": 1000000000,
|
||||
"default_source": null,
|
||||
"description": "",
|
||||
"discount": null,
|
||||
"due_date": 1000000000,
|
||||
"ending_balance": 0,
|
||||
"finalized_at": 1000000000,
|
||||
"footer": null,
|
||||
"hosted_invoice_url": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000001",
|
||||
"id": "in_NORMALIZED00000000000001",
|
||||
"invoice_pdf": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000001/pdf",
|
||||
"lines": {
|
||||
"data": [
|
||||
{
|
||||
"amount": 984000,
|
||||
"currency": "usd",
|
||||
"description": "Zulip Standard",
|
||||
"discountable": false,
|
||||
"id": "ii_NORMALIZED00000000000001",
|
||||
"invoice_item": "ii_NORMALIZED00000000000001",
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "line_item",
|
||||
"period": {
|
||||
"end": 1357095845,
|
||||
"start": 1325473445
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 123,
|
||||
"subscription": null,
|
||||
"type": "invoiceitem"
|
||||
}
|
||||
],
|
||||
"has_more": false,
|
||||
"object": "list",
|
||||
"total_count": 1,
|
||||
"url": "/v1/invoices/in_NORMALIZED00000000000001/lines"
|
||||
},
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"next_payment_attempt": null,
|
||||
"number": "NORMALI-0001",
|
||||
"object": "invoice",
|
||||
"paid": false,
|
||||
"period_end": 1000000000,
|
||||
"period_start": 1000000000,
|
||||
"receipt_number": null,
|
||||
"starting_balance": 0,
|
||||
"statement_descriptor": "Zulip Standard",
|
||||
"status": "open",
|
||||
"subscription": null,
|
||||
"subtotal": 984000,
|
||||
"tax": 0,
|
||||
"tax_percent": null,
|
||||
"total": 984000,
|
||||
"webhooks_delivered_at": 1000000000
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"amount_due": 100,
|
||||
"amount_paid": 0,
|
||||
"amount_remaining": 100,
|
||||
"application_fee": null,
|
||||
"attempt_count": 0,
|
||||
"attempted": false,
|
||||
"auto_advance": true,
|
||||
"billing": "send_invoice",
|
||||
"billing_reason": "manual",
|
||||
"charge": null,
|
||||
"currency": "usd",
|
||||
"custom_fields": null,
|
||||
"customer": "cus_NORMALIZED0001",
|
||||
"date": 1000000000,
|
||||
"default_source": null,
|
||||
"description": "",
|
||||
"discount": null,
|
||||
"due_date": 1000000000,
|
||||
"ending_balance": 0,
|
||||
"finalized_at": 1000000000,
|
||||
"footer": null,
|
||||
"hosted_invoice_url": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000002",
|
||||
"id": "in_NORMALIZED00000000000002",
|
||||
"invoice_pdf": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000002/pdf",
|
||||
"lines": {
|
||||
"data": [
|
||||
{
|
||||
"amount": 100,
|
||||
"currency": "usd",
|
||||
"description": "Zulip Standard - renewal",
|
||||
"discountable": false,
|
||||
"id": "ii_NORMALIZED00000000000002",
|
||||
"invoice_item": "ii_NORMALIZED00000000000002",
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "line_item",
|
||||
"period": {
|
||||
"end": 1388631845,
|
||||
"start": 1357095845
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 1,
|
||||
"subscription": null,
|
||||
"type": "invoiceitem"
|
||||
}
|
||||
],
|
||||
"has_more": false,
|
||||
"object": "list",
|
||||
"total_count": 1,
|
||||
"url": "/v1/invoices/in_NORMALIZED00000000000002/lines"
|
||||
},
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"next_payment_attempt": null,
|
||||
"number": "NORMALI-0002",
|
||||
"object": "invoice",
|
||||
"paid": false,
|
||||
"period_end": 1000000000,
|
||||
"period_start": 1000000000,
|
||||
"receipt_number": null,
|
||||
"starting_balance": 0,
|
||||
"statement_descriptor": "Zulip Standard",
|
||||
"status": "open",
|
||||
"subscription": null,
|
||||
"subtotal": 100,
|
||||
"tax": 0,
|
||||
"tax_percent": null,
|
||||
"total": 100,
|
||||
"webhooks_delivered_at": 1000000000
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
{
|
||||
"data": [
|
||||
{
|
||||
"amount_due": 100,
|
||||
"amount_paid": 0,
|
||||
"amount_remaining": 100,
|
||||
"application_fee": null,
|
||||
"attempt_count": 0,
|
||||
"attempted": false,
|
||||
"auto_advance": true,
|
||||
"billing": "send_invoice",
|
||||
"billing_reason": "manual",
|
||||
"charge": null,
|
||||
"currency": "usd",
|
||||
"custom_fields": null,
|
||||
"customer": "cus_NORMALIZED0001",
|
||||
"date": 1000000000,
|
||||
"default_source": null,
|
||||
"description": "",
|
||||
"discount": null,
|
||||
"due_date": 1000000000,
|
||||
"ending_balance": 0,
|
||||
"finalized_at": 1000000000,
|
||||
"footer": null,
|
||||
"hosted_invoice_url": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000002",
|
||||
"id": "in_NORMALIZED00000000000002",
|
||||
"invoice_pdf": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000002/pdf",
|
||||
"lines": {
|
||||
"data": [
|
||||
{
|
||||
"amount": 100,
|
||||
"currency": "usd",
|
||||
"description": "Zulip Standard - renewal",
|
||||
"discountable": false,
|
||||
"id": "ii_NORMALIZED00000000000002",
|
||||
"invoice_item": "ii_NORMALIZED00000000000002",
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "line_item",
|
||||
"period": {
|
||||
"end": 1388631845,
|
||||
"start": 1357095845
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 1,
|
||||
"subscription": null,
|
||||
"type": "invoiceitem"
|
||||
}
|
||||
],
|
||||
"has_more": false,
|
||||
"object": "list",
|
||||
"total_count": 1,
|
||||
"url": "/v1/invoices/in_NORMALIZED00000000000002/lines"
|
||||
},
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"next_payment_attempt": null,
|
||||
"number": "NORMALI-0002",
|
||||
"object": "invoice",
|
||||
"paid": false,
|
||||
"period_end": 1000000000,
|
||||
"period_start": 1000000000,
|
||||
"receipt_number": null,
|
||||
"starting_balance": 0,
|
||||
"statement_descriptor": "Zulip Standard",
|
||||
"status": "open",
|
||||
"subscription": null,
|
||||
"subtotal": 100,
|
||||
"tax": 0,
|
||||
"tax_percent": null,
|
||||
"total": 100,
|
||||
"webhooks_delivered_at": 1000000000
|
||||
},
|
||||
{
|
||||
"amount_due": 984000,
|
||||
"amount_paid": 0,
|
||||
"amount_remaining": 984000,
|
||||
"application_fee": null,
|
||||
"attempt_count": 0,
|
||||
"attempted": false,
|
||||
"auto_advance": true,
|
||||
"billing": "send_invoice",
|
||||
"billing_reason": "manual",
|
||||
"charge": null,
|
||||
"currency": "usd",
|
||||
"custom_fields": null,
|
||||
"customer": "cus_NORMALIZED0001",
|
||||
"date": 1000000000,
|
||||
"default_source": null,
|
||||
"description": "",
|
||||
"discount": null,
|
||||
"due_date": 1000000000,
|
||||
"ending_balance": 0,
|
||||
"finalized_at": 1000000000,
|
||||
"footer": null,
|
||||
"hosted_invoice_url": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000001",
|
||||
"id": "in_NORMALIZED00000000000001",
|
||||
"invoice_pdf": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000001/pdf",
|
||||
"lines": {
|
||||
"data": [
|
||||
{
|
||||
"amount": 984000,
|
||||
"currency": "usd",
|
||||
"description": "Zulip Standard",
|
||||
"discountable": false,
|
||||
"id": "ii_NORMALIZED00000000000001",
|
||||
"invoice_item": "ii_NORMALIZED00000000000001",
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "line_item",
|
||||
"period": {
|
||||
"end": 1357095845,
|
||||
"start": 1325473445
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 123,
|
||||
"subscription": null,
|
||||
"type": "invoiceitem"
|
||||
}
|
||||
],
|
||||
"has_more": false,
|
||||
"object": "list",
|
||||
"total_count": 1,
|
||||
"url": "/v1/invoices/in_NORMALIZED00000000000001/lines"
|
||||
},
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"next_payment_attempt": null,
|
||||
"number": "NORMALI-0001",
|
||||
"object": "invoice",
|
||||
"paid": false,
|
||||
"period_end": 1000000000,
|
||||
"period_start": 1000000000,
|
||||
"receipt_number": null,
|
||||
"starting_balance": 0,
|
||||
"statement_descriptor": "Zulip Standard",
|
||||
"status": "open",
|
||||
"subscription": null,
|
||||
"subtotal": 984000,
|
||||
"tax": 0,
|
||||
"tax_percent": null,
|
||||
"total": 984000,
|
||||
"webhooks_delivered_at": 1000000000
|
||||
}
|
||||
],
|
||||
"has_more": false,
|
||||
"object": "list",
|
||||
"url": "/v1/invoices"
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"amount": 984000,
|
||||
"currency": "usd",
|
||||
"customer": "cus_NORMALIZED0001",
|
||||
"date": 1000000000,
|
||||
"description": "Zulip Standard",
|
||||
"discountable": false,
|
||||
"id": "ii_NORMALIZED00000000000001",
|
||||
"invoice": null,
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "invoiceitem",
|
||||
"period": {
|
||||
"end": 1357095845,
|
||||
"start": 1325473445
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 123,
|
||||
"subscription": null,
|
||||
"unit_amount": 8000
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"amount": 100,
|
||||
"currency": "usd",
|
||||
"customer": "cus_NORMALIZED0001",
|
||||
"date": 1000000000,
|
||||
"description": "Zulip Standard - renewal",
|
||||
"discountable": false,
|
||||
"id": "ii_NORMALIZED00000000000002",
|
||||
"invoice": null,
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "invoiceitem",
|
||||
"period": {
|
||||
"end": 1388631845,
|
||||
"start": 1357095845
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 1,
|
||||
"subscription": null,
|
||||
"unit_amount": 100
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
{
|
||||
"amount": 64000,
|
||||
"amount_refunded": 0,
|
||||
"application": null,
|
||||
"application_fee": null,
|
||||
"application_fee_amount": null,
|
||||
"balance_transaction": "txn_1DxdruGh0CmXqmnwJQIcAlGj",
|
||||
"captured": true,
|
||||
"created": 1548696358,
|
||||
"currency": "usd",
|
||||
"customer": "cus_EQUrCdXCP2oqIF",
|
||||
"description": "Upgrade to Zulip Standard, $80.0 x 8",
|
||||
"destination": null,
|
||||
"dispute": null,
|
||||
"failure_code": null,
|
||||
"failure_message": null,
|
||||
"fraud_details": {},
|
||||
"id": "ch_1DxdruGh0CmXqmnwSwEPHAI6",
|
||||
"invoice": null,
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "charge",
|
||||
"on_behalf_of": null,
|
||||
"order": null,
|
||||
"outcome": {
|
||||
"network_status": "approved_by_network",
|
||||
"reason": null,
|
||||
"risk_level": "normal",
|
||||
"risk_score": 6,
|
||||
"seller_message": "Payment complete.",
|
||||
"type": "authorized"
|
||||
},
|
||||
"paid": true,
|
||||
"payment_intent": null,
|
||||
"receipt_email": "hamlet@zulip.com",
|
||||
"receipt_number": null,
|
||||
"receipt_url": "https://pay.stripe.com/receipts/acct_1BWYgHGh0CmXqmnw/ch_1DxdruGh0CmXqmnwSwEPHAI6/rcpt_EQUr7TAzRbJU3vjRTVdNKpnyUvWTXz2",
|
||||
"refunded": false,
|
||||
"refunds": {
|
||||
"data": [],
|
||||
"has_more": false,
|
||||
"object": "list",
|
||||
"total_count": 0,
|
||||
"url": "/v1/charges/ch_1DxdruGh0CmXqmnwSwEPHAI6/refunds"
|
||||
},
|
||||
"review": null,
|
||||
"shipping": null,
|
||||
"source": {
|
||||
"address_city": "Pacific",
|
||||
"address_country": "United States",
|
||||
"address_line1": "Under the sea,",
|
||||
"address_line1_check": "pass",
|
||||
"address_line2": null,
|
||||
"address_state": null,
|
||||
"address_zip": "33333",
|
||||
"address_zip_check": "pass",
|
||||
"brand": "Visa",
|
||||
"country": "US",
|
||||
"customer": "cus_EQUrCdXCP2oqIF",
|
||||
"cvc_check": "pass",
|
||||
"dynamic_last4": null,
|
||||
"exp_month": 3,
|
||||
"exp_year": 2033,
|
||||
"fingerprint": "6dAXT9VZvwro65EK",
|
||||
"funding": "credit",
|
||||
"id": "card_1DxdrtGh0CmXqmnw1LvZ0cL4",
|
||||
"last4": "4242",
|
||||
"metadata": {},
|
||||
"name": "Ada Starr",
|
||||
"object": "card",
|
||||
"tokenization_method": null
|
||||
},
|
||||
"source_transfer": null,
|
||||
"statement_descriptor": "Zulip Standard",
|
||||
"status": "succeeded",
|
||||
"transfer_data": null,
|
||||
"transfer_group": null
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"account_balance": 0,
|
||||
"created": 1548696357,
|
||||
"currency": null,
|
||||
"default_source": "card_1DxdrtGh0CmXqmnw1LvZ0cL4",
|
||||
"delinquent": false,
|
||||
"description": "zulip (Zulip Dev)",
|
||||
"discount": null,
|
||||
"email": "hamlet@zulip.com",
|
||||
"id": "cus_EQUrCdXCP2oqIF",
|
||||
"invoice_prefix": "81F7A21",
|
||||
"invoice_settings": {
|
||||
"custom_fields": null,
|
||||
"footer": null
|
||||
},
|
||||
"livemode": false,
|
||||
"metadata": {
|
||||
"realm_id": "1",
|
||||
"realm_str": "zulip"
|
||||
},
|
||||
"object": "customer",
|
||||
"shipping": null,
|
||||
"sources": {
|
||||
"data": [
|
||||
{
|
||||
"address_city": "Pacific",
|
||||
"address_country": "United States",
|
||||
"address_line1": "Under the sea,",
|
||||
"address_line1_check": "pass",
|
||||
"address_line2": null,
|
||||
"address_state": null,
|
||||
"address_zip": "33333",
|
||||
"address_zip_check": "pass",
|
||||
"brand": "Visa",
|
||||
"country": "US",
|
||||
"customer": "cus_EQUrCdXCP2oqIF",
|
||||
"cvc_check": "pass",
|
||||
"dynamic_last4": null,
|
||||
"exp_month": 3,
|
||||
"exp_year": 2033,
|
||||
"fingerprint": "6dAXT9VZvwro65EK",
|
||||
"funding": "credit",
|
||||
"id": "card_1DxdrtGh0CmXqmnw1LvZ0cL4",
|
||||
"last4": "4242",
|
||||
"metadata": {},
|
||||
"name": "Ada Starr",
|
||||
"object": "card",
|
||||
"tokenization_method": null
|
||||
}
|
||||
],
|
||||
"has_more": false,
|
||||
"object": "list",
|
||||
"total_count": 1,
|
||||
"url": "/v1/customers/cus_EQUrCdXCP2oqIF/sources"
|
||||
},
|
||||
"subscriptions": {
|
||||
"data": [],
|
||||
"has_more": false,
|
||||
"object": "list",
|
||||
"total_count": 0,
|
||||
"url": "/v1/customers/cus_EQUrCdXCP2oqIF/subscriptions"
|
||||
},
|
||||
"tax_info": null,
|
||||
"tax_info_verification": null
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
{
|
||||
"amount_due": 0,
|
||||
"amount_paid": 0,
|
||||
"amount_remaining": 0,
|
||||
"application_fee": null,
|
||||
"attempt_count": 0,
|
||||
"attempted": false,
|
||||
"auto_advance": true,
|
||||
"billing": "charge_automatically",
|
||||
"billing_reason": "manual",
|
||||
"charge": null,
|
||||
"currency": "usd",
|
||||
"custom_fields": null,
|
||||
"customer": "cus_EQUrCdXCP2oqIF",
|
||||
"date": 1548696360,
|
||||
"default_source": null,
|
||||
"description": "",
|
||||
"discount": null,
|
||||
"due_date": null,
|
||||
"ending_balance": null,
|
||||
"finalized_at": null,
|
||||
"footer": null,
|
||||
"hosted_invoice_url": null,
|
||||
"id": "in_1DxdrwGh0CmXqmnw7x9G2rWd",
|
||||
"invoice_pdf": null,
|
||||
"lines": {
|
||||
"data": [
|
||||
{
|
||||
"amount": 64000,
|
||||
"currency": "usd",
|
||||
"description": "Zulip Standard",
|
||||
"discountable": false,
|
||||
"id": "ii_1DxdrvGh0CmXqmnwhHM5DcR1",
|
||||
"invoice_item": "ii_1DxdrvGh0CmXqmnwhHM5DcR1",
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "line_item",
|
||||
"period": {
|
||||
"end": 1357095845,
|
||||
"start": 1325473445
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 8,
|
||||
"subscription": null,
|
||||
"type": "invoiceitem"
|
||||
},
|
||||
{
|
||||
"amount": -64000,
|
||||
"currency": "usd",
|
||||
"description": "Payment (Card ending in 4242)",
|
||||
"discountable": false,
|
||||
"id": "ii_1DxdrvGh0CmXqmnwg0R6ha8n",
|
||||
"invoice_item": "ii_1DxdrvGh0CmXqmnwg0R6ha8n",
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "line_item",
|
||||
"period": {
|
||||
"end": 1548696359,
|
||||
"start": 1548696359
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 1,
|
||||
"subscription": null,
|
||||
"type": "invoiceitem"
|
||||
}
|
||||
],
|
||||
"has_more": false,
|
||||
"object": "list",
|
||||
"total_count": 2,
|
||||
"url": "/v1/invoices/in_1DxdrwGh0CmXqmnw7x9G2rWd/lines"
|
||||
},
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"next_payment_attempt": 1548699960,
|
||||
"number": "81F7A21-0001",
|
||||
"object": "invoice",
|
||||
"paid": false,
|
||||
"period_end": 1548696360,
|
||||
"period_start": 1548696360,
|
||||
"receipt_number": null,
|
||||
"starting_balance": 0,
|
||||
"statement_descriptor": "Zulip Standard",
|
||||
"status": "draft",
|
||||
"subscription": null,
|
||||
"subtotal": 0,
|
||||
"tax": 0,
|
||||
"tax_percent": null,
|
||||
"total": 0,
|
||||
"webhooks_delivered_at": null
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
{
|
||||
"amount_due": 96697,
|
||||
"amount_paid": 0,
|
||||
"amount_remaining": 96697,
|
||||
"application_fee": null,
|
||||
"attempt_count": 0,
|
||||
"attempted": false,
|
||||
"auto_advance": true,
|
||||
"billing": "charge_automatically",
|
||||
"billing_reason": "manual",
|
||||
"charge": null,
|
||||
"currency": "usd",
|
||||
"custom_fields": null,
|
||||
"customer": "cus_EQUrCdXCP2oqIF",
|
||||
"date": 1548696362,
|
||||
"default_source": null,
|
||||
"description": "",
|
||||
"discount": null,
|
||||
"due_date": null,
|
||||
"ending_balance": null,
|
||||
"finalized_at": null,
|
||||
"footer": null,
|
||||
"hosted_invoice_url": null,
|
||||
"id": "in_1DxdryGh0CmXqmnwqSArnOBA",
|
||||
"invoice_pdf": null,
|
||||
"lines": {
|
||||
"data": [
|
||||
{
|
||||
"amount": 7255,
|
||||
"currency": "usd",
|
||||
"description": "Additional license (Feb 5, 2013 - Jan 2, 2014)",
|
||||
"discountable": false,
|
||||
"id": "ii_1DxdryGh0CmXqmnwXSzdImK3",
|
||||
"invoice_item": "ii_1DxdryGh0CmXqmnwXSzdImK3",
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "line_item",
|
||||
"period": {
|
||||
"end": 1388631845,
|
||||
"start": 1360033445
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 1,
|
||||
"subscription": null,
|
||||
"type": "invoiceitem"
|
||||
},
|
||||
{
|
||||
"amount": 72000,
|
||||
"currency": "usd",
|
||||
"description": "Zulip Standard - renewal",
|
||||
"discountable": false,
|
||||
"id": "ii_1DxdrxGh0CmXqmnw183j11lw",
|
||||
"invoice_item": "ii_1DxdrxGh0CmXqmnw183j11lw",
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "line_item",
|
||||
"period": {
|
||||
"end": 1388631845,
|
||||
"start": 1357095845
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 9,
|
||||
"subscription": null,
|
||||
"type": "invoiceitem"
|
||||
},
|
||||
{
|
||||
"amount": 17442,
|
||||
"currency": "usd",
|
||||
"description": "Additional license (Apr 11, 2012 - Jan 2, 2013)",
|
||||
"discountable": false,
|
||||
"id": "ii_1DxdrxGh0CmXqmnwSpeA2crG",
|
||||
"invoice_item": "ii_1DxdrxGh0CmXqmnwSpeA2crG",
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "line_item",
|
||||
"period": {
|
||||
"end": 1357095845,
|
||||
"start": 1334113445
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 3,
|
||||
"subscription": null,
|
||||
"type": "invoiceitem"
|
||||
}
|
||||
],
|
||||
"has_more": false,
|
||||
"object": "list",
|
||||
"total_count": 3,
|
||||
"url": "/v1/invoices/in_1DxdryGh0CmXqmnwqSArnOBA/lines"
|
||||
},
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"next_payment_attempt": 1548699962,
|
||||
"number": "81F7A21-0002",
|
||||
"object": "invoice",
|
||||
"paid": false,
|
||||
"period_end": 1548696362,
|
||||
"period_start": 1548696362,
|
||||
"receipt_number": null,
|
||||
"starting_balance": 0,
|
||||
"statement_descriptor": "Zulip Standard",
|
||||
"status": "draft",
|
||||
"subscription": null,
|
||||
"subtotal": 96697,
|
||||
"tax": 0,
|
||||
"tax_percent": null,
|
||||
"total": 96697,
|
||||
"webhooks_delivered_at": null
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
{
|
||||
"amount_due": 0,
|
||||
"amount_paid": 0,
|
||||
"amount_remaining": 0,
|
||||
"application_fee": null,
|
||||
"attempt_count": 0,
|
||||
"attempted": true,
|
||||
"auto_advance": false,
|
||||
"billing": "charge_automatically",
|
||||
"billing_reason": "manual",
|
||||
"charge": null,
|
||||
"currency": "usd",
|
||||
"custom_fields": null,
|
||||
"customer": "cus_EQUrCdXCP2oqIF",
|
||||
"date": 1548696360,
|
||||
"default_source": null,
|
||||
"description": "",
|
||||
"discount": null,
|
||||
"due_date": 1551288360,
|
||||
"ending_balance": 0,
|
||||
"finalized_at": 1548696360,
|
||||
"footer": null,
|
||||
"hosted_invoice_url": "https://pay.stripe.com/invoice/invst_QWWFlNhg4YyUdnWxVhUvuDs8TZ",
|
||||
"id": "in_1DxdrwGh0CmXqmnw7x9G2rWd",
|
||||
"invoice_pdf": "https://pay.stripe.com/invoice/invst_QWWFlNhg4YyUdnWxVhUvuDs8TZ/pdf",
|
||||
"lines": {
|
||||
"data": [
|
||||
{
|
||||
"amount": 64000,
|
||||
"currency": "usd",
|
||||
"description": "Zulip Standard",
|
||||
"discountable": false,
|
||||
"id": "ii_1DxdrvGh0CmXqmnwhHM5DcR1",
|
||||
"invoice_item": "ii_1DxdrvGh0CmXqmnwhHM5DcR1",
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "line_item",
|
||||
"period": {
|
||||
"end": 1357095845,
|
||||
"start": 1325473445
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 8,
|
||||
"subscription": null,
|
||||
"type": "invoiceitem"
|
||||
},
|
||||
{
|
||||
"amount": -64000,
|
||||
"currency": "usd",
|
||||
"description": "Payment (Card ending in 4242)",
|
||||
"discountable": false,
|
||||
"id": "ii_1DxdrvGh0CmXqmnwg0R6ha8n",
|
||||
"invoice_item": "ii_1DxdrvGh0CmXqmnwg0R6ha8n",
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "line_item",
|
||||
"period": {
|
||||
"end": 1548696359,
|
||||
"start": 1548696359
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 1,
|
||||
"subscription": null,
|
||||
"type": "invoiceitem"
|
||||
}
|
||||
],
|
||||
"has_more": false,
|
||||
"object": "list",
|
||||
"total_count": 2,
|
||||
"url": "/v1/invoices/in_1DxdrwGh0CmXqmnw7x9G2rWd/lines"
|
||||
},
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"next_payment_attempt": null,
|
||||
"number": "81F7A21-0001",
|
||||
"object": "invoice",
|
||||
"paid": true,
|
||||
"period_end": 1548696360,
|
||||
"period_start": 1548696360,
|
||||
"receipt_number": null,
|
||||
"starting_balance": 0,
|
||||
"statement_descriptor": "Zulip Standard",
|
||||
"status": "paid",
|
||||
"subscription": null,
|
||||
"subtotal": 0,
|
||||
"tax": 0,
|
||||
"tax_percent": null,
|
||||
"total": 0,
|
||||
"webhooks_delivered_at": 1548696360
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
{
|
||||
"amount_due": 96697,
|
||||
"amount_paid": 0,
|
||||
"amount_remaining": 96697,
|
||||
"application_fee": null,
|
||||
"attempt_count": 0,
|
||||
"attempted": false,
|
||||
"auto_advance": true,
|
||||
"billing": "charge_automatically",
|
||||
"billing_reason": "manual",
|
||||
"charge": null,
|
||||
"currency": "usd",
|
||||
"custom_fields": null,
|
||||
"customer": "cus_EQUrCdXCP2oqIF",
|
||||
"date": 1548696362,
|
||||
"default_source": null,
|
||||
"description": "",
|
||||
"discount": null,
|
||||
"due_date": 1551288363,
|
||||
"ending_balance": 0,
|
||||
"finalized_at": 1548696363,
|
||||
"footer": null,
|
||||
"hosted_invoice_url": "https://pay.stripe.com/invoice/invst_sT02SUZUJrLO3QmdmKIAQwQi9F",
|
||||
"id": "in_1DxdryGh0CmXqmnwqSArnOBA",
|
||||
"invoice_pdf": "https://pay.stripe.com/invoice/invst_sT02SUZUJrLO3QmdmKIAQwQi9F/pdf",
|
||||
"lines": {
|
||||
"data": [
|
||||
{
|
||||
"amount": 7255,
|
||||
"currency": "usd",
|
||||
"description": "Additional license (Feb 5, 2013 - Jan 2, 2014)",
|
||||
"discountable": false,
|
||||
"id": "ii_1DxdryGh0CmXqmnwXSzdImK3",
|
||||
"invoice_item": "ii_1DxdryGh0CmXqmnwXSzdImK3",
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "line_item",
|
||||
"period": {
|
||||
"end": 1388631845,
|
||||
"start": 1360033445
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 1,
|
||||
"subscription": null,
|
||||
"type": "invoiceitem"
|
||||
},
|
||||
{
|
||||
"amount": 72000,
|
||||
"currency": "usd",
|
||||
"description": "Zulip Standard - renewal",
|
||||
"discountable": false,
|
||||
"id": "ii_1DxdrxGh0CmXqmnw183j11lw",
|
||||
"invoice_item": "ii_1DxdrxGh0CmXqmnw183j11lw",
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "line_item",
|
||||
"period": {
|
||||
"end": 1388631845,
|
||||
"start": 1357095845
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 9,
|
||||
"subscription": null,
|
||||
"type": "invoiceitem"
|
||||
},
|
||||
{
|
||||
"amount": 17442,
|
||||
"currency": "usd",
|
||||
"description": "Additional license (Apr 11, 2012 - Jan 2, 2013)",
|
||||
"discountable": false,
|
||||
"id": "ii_1DxdrxGh0CmXqmnwSpeA2crG",
|
||||
"invoice_item": "ii_1DxdrxGh0CmXqmnwSpeA2crG",
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "line_item",
|
||||
"period": {
|
||||
"end": 1357095845,
|
||||
"start": 1334113445
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 3,
|
||||
"subscription": null,
|
||||
"type": "invoiceitem"
|
||||
}
|
||||
],
|
||||
"has_more": false,
|
||||
"object": "list",
|
||||
"total_count": 3,
|
||||
"url": "/v1/invoices/in_1DxdryGh0CmXqmnwqSArnOBA/lines"
|
||||
},
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"next_payment_attempt": 1548699962,
|
||||
"number": "81F7A21-0002",
|
||||
"object": "invoice",
|
||||
"paid": false,
|
||||
"period_end": 1548696362,
|
||||
"period_start": 1548696362,
|
||||
"receipt_number": null,
|
||||
"starting_balance": 0,
|
||||
"statement_descriptor": "Zulip Standard",
|
||||
"status": "open",
|
||||
"subscription": null,
|
||||
"subtotal": 96697,
|
||||
"tax": 0,
|
||||
"tax_percent": null,
|
||||
"total": 96697,
|
||||
"webhooks_delivered_at": 1548696362
|
||||
}
|
||||
211
corporate/tests/stripe_fixtures/invoice_plan:Invoice.list.1.json
Normal file
211
corporate/tests/stripe_fixtures/invoice_plan:Invoice.list.1.json
Normal file
@@ -0,0 +1,211 @@
|
||||
{
|
||||
"data": [
|
||||
{
|
||||
"amount_due": 96697,
|
||||
"amount_paid": 0,
|
||||
"amount_remaining": 96697,
|
||||
"application_fee": null,
|
||||
"attempt_count": 0,
|
||||
"attempted": false,
|
||||
"auto_advance": true,
|
||||
"billing": "charge_automatically",
|
||||
"billing_reason": "manual",
|
||||
"charge": null,
|
||||
"currency": "usd",
|
||||
"custom_fields": null,
|
||||
"customer": "cus_EQUrCdXCP2oqIF",
|
||||
"date": 1548696362,
|
||||
"default_source": null,
|
||||
"description": "",
|
||||
"discount": null,
|
||||
"due_date": 1551288363,
|
||||
"ending_balance": 0,
|
||||
"finalized_at": 1548696363,
|
||||
"footer": null,
|
||||
"hosted_invoice_url": "https://pay.stripe.com/invoice/invst_sT02SUZUJrLO3QmdmKIAQwQi9F",
|
||||
"id": "in_1DxdryGh0CmXqmnwqSArnOBA",
|
||||
"invoice_pdf": "https://pay.stripe.com/invoice/invst_sT02SUZUJrLO3QmdmKIAQwQi9F/pdf",
|
||||
"lines": {
|
||||
"data": [
|
||||
{
|
||||
"amount": 7255,
|
||||
"currency": "usd",
|
||||
"description": "Additional license (Feb 5, 2013 - Jan 2, 2014)",
|
||||
"discountable": false,
|
||||
"id": "ii_1DxdryGh0CmXqmnwXSzdImK3",
|
||||
"invoice_item": "ii_1DxdryGh0CmXqmnwXSzdImK3",
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "line_item",
|
||||
"period": {
|
||||
"end": 1388631845,
|
||||
"start": 1360033445
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 1,
|
||||
"subscription": null,
|
||||
"type": "invoiceitem"
|
||||
},
|
||||
{
|
||||
"amount": 72000,
|
||||
"currency": "usd",
|
||||
"description": "Zulip Standard - renewal",
|
||||
"discountable": false,
|
||||
"id": "ii_1DxdrxGh0CmXqmnw183j11lw",
|
||||
"invoice_item": "ii_1DxdrxGh0CmXqmnw183j11lw",
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "line_item",
|
||||
"period": {
|
||||
"end": 1388631845,
|
||||
"start": 1357095845
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 9,
|
||||
"subscription": null,
|
||||
"type": "invoiceitem"
|
||||
},
|
||||
{
|
||||
"amount": 17442,
|
||||
"currency": "usd",
|
||||
"description": "Additional license (Apr 11, 2012 - Jan 2, 2013)",
|
||||
"discountable": false,
|
||||
"id": "ii_1DxdrxGh0CmXqmnwSpeA2crG",
|
||||
"invoice_item": "ii_1DxdrxGh0CmXqmnwSpeA2crG",
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "line_item",
|
||||
"period": {
|
||||
"end": 1357095845,
|
||||
"start": 1334113445
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 3,
|
||||
"subscription": null,
|
||||
"type": "invoiceitem"
|
||||
}
|
||||
],
|
||||
"has_more": false,
|
||||
"object": "list",
|
||||
"total_count": 3,
|
||||
"url": "/v1/invoices/in_1DxdryGh0CmXqmnwqSArnOBA/lines"
|
||||
},
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"next_payment_attempt": 1548699962,
|
||||
"number": "81F7A21-0002",
|
||||
"object": "invoice",
|
||||
"paid": false,
|
||||
"period_end": 1548696362,
|
||||
"period_start": 1548696362,
|
||||
"receipt_number": null,
|
||||
"starting_balance": 0,
|
||||
"statement_descriptor": "Zulip Standard",
|
||||
"status": "open",
|
||||
"subscription": null,
|
||||
"subtotal": 96697,
|
||||
"tax": 0,
|
||||
"tax_percent": null,
|
||||
"total": 96697,
|
||||
"webhooks_delivered_at": 1548696362
|
||||
},
|
||||
{
|
||||
"amount_due": 0,
|
||||
"amount_paid": 0,
|
||||
"amount_remaining": 0,
|
||||
"application_fee": null,
|
||||
"attempt_count": 0,
|
||||
"attempted": true,
|
||||
"auto_advance": false,
|
||||
"billing": "charge_automatically",
|
||||
"billing_reason": "manual",
|
||||
"charge": null,
|
||||
"currency": "usd",
|
||||
"custom_fields": null,
|
||||
"customer": "cus_EQUrCdXCP2oqIF",
|
||||
"date": 1548696360,
|
||||
"default_source": null,
|
||||
"description": "",
|
||||
"discount": null,
|
||||
"due_date": 1551288360,
|
||||
"ending_balance": 0,
|
||||
"finalized_at": 1548696360,
|
||||
"footer": null,
|
||||
"hosted_invoice_url": "https://pay.stripe.com/invoice/invst_QWWFlNhg4YyUdnWxVhUvuDs8TZ",
|
||||
"id": "in_1DxdrwGh0CmXqmnw7x9G2rWd",
|
||||
"invoice_pdf": "https://pay.stripe.com/invoice/invst_QWWFlNhg4YyUdnWxVhUvuDs8TZ/pdf",
|
||||
"lines": {
|
||||
"data": [
|
||||
{
|
||||
"amount": 64000,
|
||||
"currency": "usd",
|
||||
"description": "Zulip Standard",
|
||||
"discountable": false,
|
||||
"id": "ii_1DxdrvGh0CmXqmnwhHM5DcR1",
|
||||
"invoice_item": "ii_1DxdrvGh0CmXqmnwhHM5DcR1",
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "line_item",
|
||||
"period": {
|
||||
"end": 1357095845,
|
||||
"start": 1325473445
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 8,
|
||||
"subscription": null,
|
||||
"type": "invoiceitem"
|
||||
},
|
||||
{
|
||||
"amount": -64000,
|
||||
"currency": "usd",
|
||||
"description": "Payment (Card ending in 4242)",
|
||||
"discountable": false,
|
||||
"id": "ii_1DxdrvGh0CmXqmnwg0R6ha8n",
|
||||
"invoice_item": "ii_1DxdrvGh0CmXqmnwg0R6ha8n",
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "line_item",
|
||||
"period": {
|
||||
"end": 1548696359,
|
||||
"start": 1548696359
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 1,
|
||||
"subscription": null,
|
||||
"type": "invoiceitem"
|
||||
}
|
||||
],
|
||||
"has_more": false,
|
||||
"object": "list",
|
||||
"total_count": 2,
|
||||
"url": "/v1/invoices/in_1DxdrwGh0CmXqmnw7x9G2rWd/lines"
|
||||
},
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"next_payment_attempt": null,
|
||||
"number": "81F7A21-0001",
|
||||
"object": "invoice",
|
||||
"paid": true,
|
||||
"period_end": 1548696360,
|
||||
"period_start": 1548696360,
|
||||
"receipt_number": null,
|
||||
"starting_balance": 0,
|
||||
"statement_descriptor": "Zulip Standard",
|
||||
"status": "paid",
|
||||
"subscription": null,
|
||||
"subtotal": 0,
|
||||
"tax": 0,
|
||||
"tax_percent": null,
|
||||
"total": 0,
|
||||
"webhooks_delivered_at": 1548696360
|
||||
}
|
||||
],
|
||||
"has_more": false,
|
||||
"object": "list",
|
||||
"url": "/v1/invoices"
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"amount": -64000,
|
||||
"currency": "usd",
|
||||
"customer": "cus_EQUrCdXCP2oqIF",
|
||||
"date": 1548696359,
|
||||
"description": "Payment (Card ending in 4242)",
|
||||
"discountable": false,
|
||||
"id": "ii_1DxdrvGh0CmXqmnwg0R6ha8n",
|
||||
"invoice": null,
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "invoiceitem",
|
||||
"period": {
|
||||
"end": 1548696359,
|
||||
"start": 1548696359
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 1,
|
||||
"subscription": null,
|
||||
"unit_amount": -64000
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"amount": 64000,
|
||||
"currency": "usd",
|
||||
"customer": "cus_EQUrCdXCP2oqIF",
|
||||
"date": 1548696359,
|
||||
"description": "Zulip Standard",
|
||||
"discountable": false,
|
||||
"id": "ii_1DxdrvGh0CmXqmnwhHM5DcR1",
|
||||
"invoice": null,
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "invoiceitem",
|
||||
"period": {
|
||||
"end": 1357095845,
|
||||
"start": 1325473445
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 8,
|
||||
"subscription": null,
|
||||
"unit_amount": 8000
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"amount": 17442,
|
||||
"currency": "usd",
|
||||
"customer": "cus_EQUrCdXCP2oqIF",
|
||||
"date": 1548696361,
|
||||
"description": "Additional license (Apr 11, 2012 - Jan 2, 2013)",
|
||||
"discountable": false,
|
||||
"id": "ii_1DxdrxGh0CmXqmnwSpeA2crG",
|
||||
"invoice": null,
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "invoiceitem",
|
||||
"period": {
|
||||
"end": 1357095845,
|
||||
"start": 1334113445
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 3,
|
||||
"subscription": null,
|
||||
"unit_amount": 5814
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"amount": 72000,
|
||||
"currency": "usd",
|
||||
"customer": "cus_EQUrCdXCP2oqIF",
|
||||
"date": 1548696361,
|
||||
"description": "Zulip Standard - renewal",
|
||||
"discountable": false,
|
||||
"id": "ii_1DxdrxGh0CmXqmnw183j11lw",
|
||||
"invoice": null,
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "invoiceitem",
|
||||
"period": {
|
||||
"end": 1388631845,
|
||||
"start": 1357095845
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 9,
|
||||
"subscription": null,
|
||||
"unit_amount": 8000
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"amount": 7255,
|
||||
"currency": "usd",
|
||||
"customer": "cus_EQUrCdXCP2oqIF",
|
||||
"date": 1548696362,
|
||||
"description": "Additional license (Feb 5, 2013 - Jan 2, 2014)",
|
||||
"discountable": false,
|
||||
"id": "ii_1DxdryGh0CmXqmnwXSzdImK3",
|
||||
"invoice": null,
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "invoiceitem",
|
||||
"period": {
|
||||
"end": 1388631845,
|
||||
"start": 1360033445
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 1,
|
||||
"subscription": null,
|
||||
"unit_amount": 7255
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"card": {
|
||||
"address_city": "Pacific",
|
||||
"address_country": "United States",
|
||||
"address_line1": "Under the sea,",
|
||||
"address_line1_check": "unchecked",
|
||||
"address_line2": null,
|
||||
"address_state": null,
|
||||
"address_zip": "33333",
|
||||
"address_zip_check": "unchecked",
|
||||
"brand": "Visa",
|
||||
"country": "US",
|
||||
"cvc_check": "unchecked",
|
||||
"dynamic_last4": null,
|
||||
"exp_month": 3,
|
||||
"exp_year": 2033,
|
||||
"fingerprint": "6dAXT9VZvwro65EK",
|
||||
"funding": "credit",
|
||||
"id": "card_1DxdrtGh0CmXqmnw1LvZ0cL4",
|
||||
"last4": "4242",
|
||||
"metadata": {},
|
||||
"name": "Ada Starr",
|
||||
"object": "card",
|
||||
"tokenization_method": null
|
||||
},
|
||||
"client_ip": "107.202.144.213",
|
||||
"created": 1548696357,
|
||||
"id": "tok_1DxdrtGh0CmXqmnw94EYeDen",
|
||||
"livemode": false,
|
||||
"object": "token",
|
||||
"type": "card",
|
||||
"used": false
|
||||
}
|
||||
78
corporate/tests/stripe_fixtures/renewal:Charge.create.1.json
Normal file
78
corporate/tests/stripe_fixtures/renewal:Charge.create.1.json
Normal file
@@ -0,0 +1,78 @@
|
||||
{
|
||||
"amount": 64000,
|
||||
"amount_refunded": 0,
|
||||
"application": null,
|
||||
"application_fee": null,
|
||||
"application_fee_amount": null,
|
||||
"balance_transaction": "txn_1DxdeSGh0CmXqmnw9I7ziL6D",
|
||||
"captured": true,
|
||||
"created": 1548695524,
|
||||
"currency": "usd",
|
||||
"customer": "cus_EQUd48LphR5ahk",
|
||||
"description": "Upgrade to Zulip Standard, $80.0 x 8",
|
||||
"destination": null,
|
||||
"dispute": null,
|
||||
"failure_code": null,
|
||||
"failure_message": null,
|
||||
"fraud_details": {},
|
||||
"id": "ch_1DxdeSGh0CmXqmnwsw80Rn8n",
|
||||
"invoice": null,
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "charge",
|
||||
"on_behalf_of": null,
|
||||
"order": null,
|
||||
"outcome": {
|
||||
"network_status": "approved_by_network",
|
||||
"reason": null,
|
||||
"risk_level": "normal",
|
||||
"risk_score": 46,
|
||||
"seller_message": "Payment complete.",
|
||||
"type": "authorized"
|
||||
},
|
||||
"paid": true,
|
||||
"payment_intent": null,
|
||||
"receipt_email": "hamlet@zulip.com",
|
||||
"receipt_number": null,
|
||||
"receipt_url": "https://pay.stripe.com/receipts/acct_1BWYgHGh0CmXqmnw/ch_1DxdeSGh0CmXqmnwsw80Rn8n/rcpt_EQUda9O5I5cYpJL0yxiRbxnPbWZ415D",
|
||||
"refunded": false,
|
||||
"refunds": {
|
||||
"data": [],
|
||||
"has_more": false,
|
||||
"object": "list",
|
||||
"total_count": 0,
|
||||
"url": "/v1/charges/ch_1DxdeSGh0CmXqmnwsw80Rn8n/refunds"
|
||||
},
|
||||
"review": null,
|
||||
"shipping": null,
|
||||
"source": {
|
||||
"address_city": "Pacific",
|
||||
"address_country": "United States",
|
||||
"address_line1": "Under the sea,",
|
||||
"address_line1_check": "pass",
|
||||
"address_line2": null,
|
||||
"address_state": null,
|
||||
"address_zip": "33333",
|
||||
"address_zip_check": "pass",
|
||||
"brand": "Visa",
|
||||
"country": "US",
|
||||
"customer": "cus_EQUd48LphR5ahk",
|
||||
"cvc_check": "pass",
|
||||
"dynamic_last4": null,
|
||||
"exp_month": 3,
|
||||
"exp_year": 2033,
|
||||
"fingerprint": "6dAXT9VZvwro65EK",
|
||||
"funding": "credit",
|
||||
"id": "card_1DxdeRGh0CmXqmnwu3BibWtM",
|
||||
"last4": "4242",
|
||||
"metadata": {},
|
||||
"name": "Ada Starr",
|
||||
"object": "card",
|
||||
"tokenization_method": null
|
||||
},
|
||||
"source_transfer": null,
|
||||
"statement_descriptor": "Zulip Standard",
|
||||
"status": "succeeded",
|
||||
"transfer_data": null,
|
||||
"transfer_group": null
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"account_balance": 0,
|
||||
"created": 1548695523,
|
||||
"currency": null,
|
||||
"default_source": "card_1DxdeRGh0CmXqmnwu3BibWtM",
|
||||
"delinquent": false,
|
||||
"description": "zulip (Zulip Dev)",
|
||||
"discount": null,
|
||||
"email": "hamlet@zulip.com",
|
||||
"id": "cus_EQUd48LphR5ahk",
|
||||
"invoice_prefix": "9F53235",
|
||||
"invoice_settings": {
|
||||
"custom_fields": null,
|
||||
"footer": null
|
||||
},
|
||||
"livemode": false,
|
||||
"metadata": {
|
||||
"realm_id": "1",
|
||||
"realm_str": "zulip"
|
||||
},
|
||||
"object": "customer",
|
||||
"shipping": null,
|
||||
"sources": {
|
||||
"data": [
|
||||
{
|
||||
"address_city": "Pacific",
|
||||
"address_country": "United States",
|
||||
"address_line1": "Under the sea,",
|
||||
"address_line1_check": "pass",
|
||||
"address_line2": null,
|
||||
"address_state": null,
|
||||
"address_zip": "33333",
|
||||
"address_zip_check": "pass",
|
||||
"brand": "Visa",
|
||||
"country": "US",
|
||||
"customer": "cus_EQUd48LphR5ahk",
|
||||
"cvc_check": "pass",
|
||||
"dynamic_last4": null,
|
||||
"exp_month": 3,
|
||||
"exp_year": 2033,
|
||||
"fingerprint": "6dAXT9VZvwro65EK",
|
||||
"funding": "credit",
|
||||
"id": "card_1DxdeRGh0CmXqmnwu3BibWtM",
|
||||
"last4": "4242",
|
||||
"metadata": {},
|
||||
"name": "Ada Starr",
|
||||
"object": "card",
|
||||
"tokenization_method": null
|
||||
}
|
||||
],
|
||||
"has_more": false,
|
||||
"object": "list",
|
||||
"total_count": 1,
|
||||
"url": "/v1/customers/cus_EQUd48LphR5ahk/sources"
|
||||
},
|
||||
"subscriptions": {
|
||||
"data": [],
|
||||
"has_more": false,
|
||||
"object": "list",
|
||||
"total_count": 0,
|
||||
"url": "/v1/customers/cus_EQUd48LphR5ahk/subscriptions"
|
||||
},
|
||||
"tax_info": null,
|
||||
"tax_info_verification": null
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
{
|
||||
"amount_due": 0,
|
||||
"amount_paid": 0,
|
||||
"amount_remaining": 0,
|
||||
"application_fee": null,
|
||||
"attempt_count": 0,
|
||||
"attempted": false,
|
||||
"auto_advance": true,
|
||||
"billing": "charge_automatically",
|
||||
"billing_reason": "manual",
|
||||
"charge": null,
|
||||
"currency": "usd",
|
||||
"custom_fields": null,
|
||||
"customer": "cus_EQUd48LphR5ahk",
|
||||
"date": 1548695526,
|
||||
"default_source": null,
|
||||
"description": "",
|
||||
"discount": null,
|
||||
"due_date": null,
|
||||
"ending_balance": null,
|
||||
"finalized_at": null,
|
||||
"footer": null,
|
||||
"hosted_invoice_url": null,
|
||||
"id": "in_1DxdeUGh0CmXqmnwoowtAcQW",
|
||||
"invoice_pdf": null,
|
||||
"lines": {
|
||||
"data": [
|
||||
{
|
||||
"amount": 64000,
|
||||
"currency": "usd",
|
||||
"description": "Zulip Standard",
|
||||
"discountable": false,
|
||||
"id": "ii_1DxdeTGh0CmXqmnw7MfZoBVx",
|
||||
"invoice_item": "ii_1DxdeTGh0CmXqmnw7MfZoBVx",
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "line_item",
|
||||
"period": {
|
||||
"end": 1357095845,
|
||||
"start": 1325473445
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 8,
|
||||
"subscription": null,
|
||||
"type": "invoiceitem"
|
||||
},
|
||||
{
|
||||
"amount": -64000,
|
||||
"currency": "usd",
|
||||
"description": "Payment (Card ending in 4242)",
|
||||
"discountable": false,
|
||||
"id": "ii_1DxdeTGh0CmXqmnwDYYlalDE",
|
||||
"invoice_item": "ii_1DxdeTGh0CmXqmnwDYYlalDE",
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "line_item",
|
||||
"period": {
|
||||
"end": 1548695525,
|
||||
"start": 1548695525
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 1,
|
||||
"subscription": null,
|
||||
"type": "invoiceitem"
|
||||
}
|
||||
],
|
||||
"has_more": false,
|
||||
"object": "list",
|
||||
"total_count": 2,
|
||||
"url": "/v1/invoices/in_1DxdeUGh0CmXqmnwoowtAcQW/lines"
|
||||
},
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"next_payment_attempt": 1548699126,
|
||||
"number": "9F53235-0001",
|
||||
"object": "invoice",
|
||||
"paid": false,
|
||||
"period_end": 1548695526,
|
||||
"period_start": 1548695526,
|
||||
"receipt_number": null,
|
||||
"starting_balance": 0,
|
||||
"statement_descriptor": "Zulip Standard",
|
||||
"status": "draft",
|
||||
"subscription": null,
|
||||
"subtotal": 0,
|
||||
"tax": 0,
|
||||
"tax_percent": null,
|
||||
"total": 0,
|
||||
"webhooks_delivered_at": null
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
{
|
||||
"amount_due": 0,
|
||||
"amount_paid": 0,
|
||||
"amount_remaining": 0,
|
||||
"application_fee": null,
|
||||
"attempt_count": 0,
|
||||
"attempted": true,
|
||||
"auto_advance": false,
|
||||
"billing": "charge_automatically",
|
||||
"billing_reason": "manual",
|
||||
"charge": null,
|
||||
"currency": "usd",
|
||||
"custom_fields": null,
|
||||
"customer": "cus_EQUd48LphR5ahk",
|
||||
"date": 1548695526,
|
||||
"default_source": null,
|
||||
"description": "",
|
||||
"discount": null,
|
||||
"due_date": 1551287527,
|
||||
"ending_balance": 0,
|
||||
"finalized_at": 1548695527,
|
||||
"footer": null,
|
||||
"hosted_invoice_url": "https://pay.stripe.com/invoice/invst_8N3Zw202aBfkZSHzyjUVcv9vrE",
|
||||
"id": "in_1DxdeUGh0CmXqmnwoowtAcQW",
|
||||
"invoice_pdf": "https://pay.stripe.com/invoice/invst_8N3Zw202aBfkZSHzyjUVcv9vrE/pdf",
|
||||
"lines": {
|
||||
"data": [
|
||||
{
|
||||
"amount": 64000,
|
||||
"currency": "usd",
|
||||
"description": "Zulip Standard",
|
||||
"discountable": false,
|
||||
"id": "ii_1DxdeTGh0CmXqmnw7MfZoBVx",
|
||||
"invoice_item": "ii_1DxdeTGh0CmXqmnw7MfZoBVx",
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "line_item",
|
||||
"period": {
|
||||
"end": 1357095845,
|
||||
"start": 1325473445
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 8,
|
||||
"subscription": null,
|
||||
"type": "invoiceitem"
|
||||
},
|
||||
{
|
||||
"amount": -64000,
|
||||
"currency": "usd",
|
||||
"description": "Payment (Card ending in 4242)",
|
||||
"discountable": false,
|
||||
"id": "ii_1DxdeTGh0CmXqmnwDYYlalDE",
|
||||
"invoice_item": "ii_1DxdeTGh0CmXqmnwDYYlalDE",
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "line_item",
|
||||
"period": {
|
||||
"end": 1548695525,
|
||||
"start": 1548695525
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 1,
|
||||
"subscription": null,
|
||||
"type": "invoiceitem"
|
||||
}
|
||||
],
|
||||
"has_more": false,
|
||||
"object": "list",
|
||||
"total_count": 2,
|
||||
"url": "/v1/invoices/in_1DxdeUGh0CmXqmnwoowtAcQW/lines"
|
||||
},
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"next_payment_attempt": null,
|
||||
"number": "9F53235-0001",
|
||||
"object": "invoice",
|
||||
"paid": true,
|
||||
"period_end": 1548695526,
|
||||
"period_start": 1548695526,
|
||||
"receipt_number": null,
|
||||
"starting_balance": 0,
|
||||
"statement_descriptor": "Zulip Standard",
|
||||
"status": "paid",
|
||||
"subscription": null,
|
||||
"subtotal": 0,
|
||||
"tax": 0,
|
||||
"tax_percent": null,
|
||||
"total": 0,
|
||||
"webhooks_delivered_at": 1548695526
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"amount": -64000,
|
||||
"currency": "usd",
|
||||
"customer": "cus_EQUd48LphR5ahk",
|
||||
"date": 1548695525,
|
||||
"description": "Payment (Card ending in 4242)",
|
||||
"discountable": false,
|
||||
"id": "ii_1DxdeTGh0CmXqmnwDYYlalDE",
|
||||
"invoice": null,
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "invoiceitem",
|
||||
"period": {
|
||||
"end": 1548695525,
|
||||
"start": 1548695525
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 1,
|
||||
"subscription": null,
|
||||
"unit_amount": -64000
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"amount": 64000,
|
||||
"currency": "usd",
|
||||
"customer": "cus_EQUd48LphR5ahk",
|
||||
"date": 1548695525,
|
||||
"description": "Zulip Standard",
|
||||
"discountable": false,
|
||||
"id": "ii_1DxdeTGh0CmXqmnw7MfZoBVx",
|
||||
"invoice": null,
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "invoiceitem",
|
||||
"period": {
|
||||
"end": 1357095845,
|
||||
"start": 1325473445
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 8,
|
||||
"subscription": null,
|
||||
"unit_amount": 8000
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"amount": 17442,
|
||||
"currency": "usd",
|
||||
"customer": "cus_EQUd48LphR5ahk",
|
||||
"date": 1548695527,
|
||||
"description": "Additional license (Apr 11, 2012 - Jan 2, 2013)",
|
||||
"discountable": false,
|
||||
"id": "ii_1DxdeVGh0CmXqmnwf6cLlEA7",
|
||||
"invoice": null,
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"object": "invoiceitem",
|
||||
"period": {
|
||||
"end": 1357095845,
|
||||
"start": 1334113445
|
||||
},
|
||||
"plan": null,
|
||||
"proration": false,
|
||||
"quantity": 3,
|
||||
"subscription": null,
|
||||
"unit_amount": 5814
|
||||
}
|
||||
33
corporate/tests/stripe_fixtures/renewal:Token.create.1.json
Normal file
33
corporate/tests/stripe_fixtures/renewal:Token.create.1.json
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"card": {
|
||||
"address_city": "Pacific",
|
||||
"address_country": "United States",
|
||||
"address_line1": "Under the sea,",
|
||||
"address_line1_check": "unchecked",
|
||||
"address_line2": null,
|
||||
"address_state": null,
|
||||
"address_zip": "33333",
|
||||
"address_zip_check": "unchecked",
|
||||
"brand": "Visa",
|
||||
"country": "US",
|
||||
"cvc_check": "unchecked",
|
||||
"dynamic_last4": null,
|
||||
"exp_month": 3,
|
||||
"exp_year": 2033,
|
||||
"fingerprint": "6dAXT9VZvwro65EK",
|
||||
"funding": "credit",
|
||||
"id": "card_1DxdeRGh0CmXqmnwu3BibWtM",
|
||||
"last4": "4242",
|
||||
"metadata": {},
|
||||
"name": "Ada Starr",
|
||||
"object": "card",
|
||||
"tokenization_method": null
|
||||
},
|
||||
"client_ip": "107.202.144.213",
|
||||
"created": 1548695523,
|
||||
"id": "tok_1DxdeRGh0CmXqmnw5X6CeYnC",
|
||||
"livemode": false,
|
||||
"object": "token",
|
||||
"type": "card",
|
||||
"used": false
|
||||
}
|
||||
@@ -30,7 +30,8 @@ from corporate.lib.stripe import catch_stripe_errors, attach_discount_to_realm,
|
||||
add_months, next_month, next_renewal_date, renewal_amount, \
|
||||
compute_plan_parameters, update_or_create_stripe_customer, \
|
||||
process_initial_upgrade, add_plan_renewal_to_license_ledger_if_needed, \
|
||||
update_license_ledger_if_needed, update_license_ledger_for_automanaged_plan
|
||||
update_license_ledger_if_needed, update_license_ledger_for_automanaged_plan, \
|
||||
invoice_plan, invoice_plans_as_needed
|
||||
from corporate.models import Customer, CustomerPlan, LicenseLedger
|
||||
from corporate.views import payment_method_string
|
||||
import corporate.urls
|
||||
@@ -1027,3 +1028,127 @@ class LicenseLedgerTest(StripeTestCase):
|
||||
(False, self.seat_count + 1, self.seat_count),
|
||||
(False, self.seat_count + 1, self.seat_count + 1),
|
||||
(False, self.seat_count + 1, self.seat_count + 1)])
|
||||
|
||||
class InvoiceTest(StripeTestCase):
|
||||
def test_invoicing_status_is_started(self) -> None:
|
||||
self.local_upgrade(self.seat_count, True, CustomerPlan.ANNUAL, 'token')
|
||||
plan = CustomerPlan.objects.first()
|
||||
plan.invoicing_status = CustomerPlan.STARTED
|
||||
plan.save(update_fields=['invoicing_status'])
|
||||
with self.assertRaises(NotImplementedError):
|
||||
invoice_plan(CustomerPlan.objects.first(), self.now)
|
||||
|
||||
@mock_stripe()
|
||||
def test_invoice_plan(self, *mocks: Mock) -> None:
|
||||
user = self.example_user("hamlet")
|
||||
self.login(user.email)
|
||||
with patch('corporate.lib.stripe.timezone_now', return_value=self.now):
|
||||
self.upgrade()
|
||||
# Increase
|
||||
with patch('corporate.lib.stripe.get_seat_count', return_value=self.seat_count + 3):
|
||||
update_license_ledger_if_needed(get_realm('zulip'), self.now + timedelta(days=100))
|
||||
# Decrease
|
||||
with patch('corporate.lib.stripe.get_seat_count', return_value=self.seat_count):
|
||||
update_license_ledger_if_needed(get_realm('zulip'), self.now + timedelta(days=200))
|
||||
# Increase, but not past high watermark
|
||||
with patch('corporate.lib.stripe.get_seat_count', return_value=self.seat_count + 1):
|
||||
update_license_ledger_if_needed(get_realm('zulip'), self.now + timedelta(days=300))
|
||||
# Increase, but after renewal date, and below last year's high watermark
|
||||
with patch('corporate.lib.stripe.get_seat_count', return_value=self.seat_count + 2):
|
||||
update_license_ledger_if_needed(get_realm('zulip'), self.now + timedelta(days=400))
|
||||
# Increase, but after event_time
|
||||
with patch('corporate.lib.stripe.get_seat_count', return_value=self.seat_count + 3):
|
||||
update_license_ledger_if_needed(get_realm('zulip'), self.now + timedelta(days=500))
|
||||
plan = CustomerPlan.objects.first()
|
||||
invoice_plan(plan, self.now + timedelta(days=400))
|
||||
|
||||
stripe_invoices = [invoice for invoice in stripe.Invoice.list(
|
||||
customer=plan.customer.stripe_customer_id)]
|
||||
self.assertEqual(len(stripe_invoices), 2)
|
||||
self.assertIsNotNone(stripe_invoices[0].finalized_at)
|
||||
stripe_line_items = [item for item in stripe_invoices[0].lines]
|
||||
self.assertEqual(len(stripe_line_items), 3)
|
||||
line_item_params = {
|
||||
'amount': int(8000 * (1 - ((400-366) / 365)) + .5),
|
||||
'description': 'Additional license (Feb 5, 2013 - Jan 2, 2014)',
|
||||
'discountable': False,
|
||||
'period': {
|
||||
'start': datetime_to_timestamp(self.now + timedelta(days=400)),
|
||||
'end': datetime_to_timestamp(self.now + timedelta(days=2*365 + 1))},
|
||||
'quantity': 1}
|
||||
for key, value in line_item_params.items():
|
||||
self.assertEqual(stripe_line_items[0].get(key), value)
|
||||
line_item_params = {
|
||||
'amount': 8000 * (self.seat_count + 1),
|
||||
'description': 'Zulip Standard - renewal',
|
||||
'discountable': False,
|
||||
'period': {
|
||||
'start': datetime_to_timestamp(self.now + timedelta(days=366)),
|
||||
'end': datetime_to_timestamp(self.now + timedelta(days=2*365 + 1))},
|
||||
'quantity': (self.seat_count + 1)}
|
||||
for key, value in line_item_params.items():
|
||||
self.assertEqual(stripe_line_items[1].get(key), value)
|
||||
line_item_params = {
|
||||
'amount': 3 * int(8000 * (366-100) / 366 + .5),
|
||||
'description': 'Additional license (Apr 11, 2012 - Jan 2, 2013)',
|
||||
'discountable': False,
|
||||
'period': {
|
||||
'start': datetime_to_timestamp(self.now + timedelta(days=100)),
|
||||
'end': datetime_to_timestamp(self.now + timedelta(days=366))},
|
||||
'quantity': 3}
|
||||
for key, value in line_item_params.items():
|
||||
self.assertEqual(stripe_line_items[2].get(key), value)
|
||||
|
||||
@mock_stripe()
|
||||
def test_fixed_price_plans(self, *mocks: Mock) -> None:
|
||||
# Also tests charge_automatically=False
|
||||
user = self.example_user("hamlet")
|
||||
self.login(user.email)
|
||||
with patch('corporate.lib.stripe.timezone_now', return_value=self.now):
|
||||
self.upgrade(invoice=True)
|
||||
plan = CustomerPlan.objects.first()
|
||||
plan.fixed_price = 100
|
||||
plan.price_per_license = 0
|
||||
plan.save(update_fields=['fixed_price', 'price_per_license'])
|
||||
invoice_plan(plan, self.next_year)
|
||||
stripe_invoices = [invoice for invoice in stripe.Invoice.list(
|
||||
customer=plan.customer.stripe_customer_id)]
|
||||
self.assertEqual(len(stripe_invoices), 2)
|
||||
self.assertEqual(stripe_invoices[0].billing, 'send_invoice')
|
||||
stripe_line_items = [item for item in stripe_invoices[0].lines]
|
||||
self.assertEqual(len(stripe_line_items), 1)
|
||||
line_item_params = {
|
||||
'amount': 100,
|
||||
'description': 'Zulip Standard - renewal',
|
||||
'discountable': False,
|
||||
'period': {
|
||||
'start': datetime_to_timestamp(self.next_year),
|
||||
'end': datetime_to_timestamp(self.next_year + timedelta(days=365))},
|
||||
'quantity': 1}
|
||||
for key, value in line_item_params.items():
|
||||
self.assertEqual(stripe_line_items[0].get(key), value)
|
||||
|
||||
def test_no_invoice_needed(self) -> None:
|
||||
with patch('corporate.lib.stripe.timezone_now', return_value=self.now):
|
||||
self.local_upgrade(self.seat_count, True, CustomerPlan.ANNUAL, 'token')
|
||||
plan = CustomerPlan.objects.first()
|
||||
self.assertEqual(plan.next_invoice_date, self.next_month)
|
||||
# Test this doesn't make any calls to stripe.Invoice or stripe.InvoiceItem
|
||||
invoice_plan(plan, self.next_month)
|
||||
plan = CustomerPlan.objects.first()
|
||||
# Test that we still update next_invoice_date
|
||||
self.assertEqual(plan.next_invoice_date, self.next_month + timedelta(days=29))
|
||||
|
||||
def test_invoice_plans_as_needed(self) -> None:
|
||||
with patch('corporate.lib.stripe.timezone_now', return_value=self.now):
|
||||
self.local_upgrade(self.seat_count, True, CustomerPlan.ANNUAL, 'token')
|
||||
plan = CustomerPlan.objects.first()
|
||||
self.assertEqual(plan.next_invoice_date, self.next_month)
|
||||
# Test nothing needed to be done
|
||||
with patch('corporate.lib.stripe.invoice_plan') as mocked:
|
||||
invoice_plans_as_needed(self.next_month - timedelta(days=1))
|
||||
mocked.assert_not_called()
|
||||
# Test something needing to be done
|
||||
invoice_plans_as_needed(self.next_month)
|
||||
plan = CustomerPlan.objects.first()
|
||||
self.assertEqual(plan.next_invoice_date, self.next_month + timedelta(days=29))
|
||||
|
||||
@@ -173,7 +173,7 @@ class InvoiceItem:
|
||||
@staticmethod
|
||||
def create(amount: int=..., currency: str=..., customer: str=..., description: str=...,
|
||||
discountable: bool=..., period: Dict[str, int]=..., quantity: int=...,
|
||||
unit_amount: int=...) -> InvoiceItem:
|
||||
unit_amount: int=..., idempotency_key: str=...) -> InvoiceItem:
|
||||
...
|
||||
|
||||
@staticmethod
|
||||
|
||||
Reference in New Issue
Block a user