Exemple #1
0
def handle_payment_intent_succeeded_event(
        stripe_payment_intent: stripe.PaymentIntent,
        payment_intent: PaymentIntent) -> None:
    payment_intent.status = PaymentIntent.SUCCEEDED
    payment_intent.save()
    metadata: Dict[str, Any] = stripe_payment_intent.metadata
    assert payment_intent.customer.realm is not None
    user_id = metadata.get("user_id")
    assert user_id is not None
    user = get_active_user_profile_by_id_in_realm(
        user_id, payment_intent.customer.realm)

    description = ""
    for charge in stripe_payment_intent.charges:
        description = f"Payment (Card ending in {charge.payment_method_details.card.last4})"
        break

    stripe.InvoiceItem.create(
        amount=stripe_payment_intent.amount * -1,
        currency="usd",
        customer=stripe_payment_intent.customer,
        description=description,
        discountable=False,
    )
    try:
        ensure_realm_does_not_have_active_plan(user.realm)
    except UpgradeWithExistingPlanError as e:
        stripe_invoice = stripe.Invoice.create(
            auto_advance=True,
            collection_method="charge_automatically",
            customer=stripe_payment_intent.customer,
            days_until_due=None,
            statement_descriptor="Zulip Cloud Standard Credit",
        )
        stripe.Invoice.finalize_invoice(stripe_invoice)
        raise e

    process_initial_upgrade(
        user,
        int(metadata["licenses"]),
        metadata["license_management"] == "automatic",
        int(metadata["billing_schedule"]),
        True,
        False,
    )
Exemple #2
0
def handle_payment_intent_payment_failed_event(
        stripe_payment_intent: stripe.PaymentIntent,
        payment_intent: Event) -> None:
    payment_intent.status = PaymentIntent.get_status_integer_from_status_text(
        stripe_payment_intent.status)
    billing_logger.info(
        "Stripe payment intent failed: %s %s %s %s",
        payment_intent.customer.realm.string_id,
        stripe_payment_intent.last_payment_error.get("type"),
        stripe_payment_intent.last_payment_error.get("code"),
        stripe_payment_intent.last_payment_error.get("param"),
    )
    payment_intent.last_payment_error = {
        "description": stripe_payment_intent.last_payment_error.get("type"),
    }
    payment_intent.last_payment_error[
        "message"] = stripe_payment_intent.last_payment_error.get("message")
    payment_intent.save(update_fields=["status", "last_payment_error"])
Exemple #3
0
def setup_upgrade_checkout_session_and_payment_intent(
    user: UserProfile,
    seat_count: int,
    licenses: int,
    license_management: str,
    billing_schedule: int,
    billing_modality: str,
    onboarding: bool,
) -> stripe.checkout.Session:
    customer = update_or_create_stripe_customer(user)
    assert customer is not None  # for mypy
    free_trial = is_free_trial_offer_enabled()
    _, _, _, price_per_license = compute_plan_parameters(
        CustomerPlan.STANDARD,
        license_management == "automatic",
        billing_schedule,
        customer.default_discount,
        free_trial,
    )
    metadata = {
        "billing_modality": billing_modality,
        "billing_schedule": billing_schedule,
        "licenses": licenses,
        "license_management": license_management,
        "price_per_license": price_per_license,
        "seat_count": seat_count,
        "type": "upgrade",
        "user_email": user.delivery_email,
        "realm_id": user.realm.id,
        "realm_str": user.realm.string_id,
        "user_id": user.id,
    }
    if free_trial:
        if onboarding:
            session_type = Session.FREE_TRIAL_UPGRADE_FROM_ONBOARDING_PAGE
        else:
            session_type = Session.FREE_TRIAL_UPGRADE_FROM_BILLING_PAGE
        payment_intent = None
    else:
        session_type = Session.UPGRADE_FROM_BILLING_PAGE
        stripe_payment_intent = stripe.PaymentIntent.create(
            amount=price_per_license * licenses,
            currency="usd",
            customer=customer.stripe_customer_id,
            description=
            f"Upgrade to Zulip Cloud Standard, ${price_per_license/100} x {licenses}",
            receipt_email=user.delivery_email,
            confirm=False,
            statement_descriptor="Zulip Cloud Standard",
            metadata=metadata,
        )
        payment_intent = PaymentIntent.objects.create(
            customer=customer,
            stripe_payment_intent_id=stripe_payment_intent.id,
            status=PaymentIntent.get_status_integer_from_status_text(
                stripe_payment_intent.status),
        )
    stripe_session = stripe.checkout.Session.create(
        cancel_url=f"{user.realm.uri}/upgrade/",
        customer=customer.stripe_customer_id,
        mode="setup",
        payment_method_types=["card"],
        metadata=metadata,
        setup_intent_data={"metadata": metadata},
        success_url=
        f"{user.realm.uri}/billing/event_status?stripe_session_id={{CHECKOUT_SESSION_ID}}",
    )
    session = Session.objects.create(customer=customer,
                                     stripe_session_id=stripe_session.id,
                                     type=session_type)
    if payment_intent is not None:
        session.payment_intent = payment_intent
        session.save(update_fields=["payment_intent"])
    return stripe_session