Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(console): Billing and Invoicing - Invoice and payments integration #2457

Merged

Conversation

Cosmin-Parvulescu
Copy link
Contributor

@Cosmin-Parvulescu Cosmin-Parvulescu commented Jul 3, 2023

Description

  • Added Invoices to billing screen
  • Added reconciliation function for automagically downgrading apps if entitlements get removed through Stripe subscription
  • Added two new e-mail templates for reconciliation (billing + dev)
  • Added Portal endpoint for redirecting users to their Stripe Customer Portal
  • Parametrized getEntitlements to be able to be used from public webhook

Related Issues

Testing

  • Did some small local testing, would need to do additional testing in dev

Checklist

  • I have read the CONTRIBUTING guidelines
  • I have tested my code (manually and/or automated if applicable)
  • I have updated the documentation (if necessary)

@Cosmin-Parvulescu Cosmin-Parvulescu added the enhancement Indicates new feature requests label Jul 3, 2023
@Cosmin-Parvulescu Cosmin-Parvulescu self-assigned this Jul 3, 2023
@Cosmin-Parvulescu Cosmin-Parvulescu force-pushed the feat/console/billing-and-invoicing-invoice-and-payments-integration branch 2 times, most recently from 8717089 to 0e0c57d Compare July 5, 2023 15:17
invoices: {
amount: number
timestamp: number
status: string | null
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to have a default value?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, it's currently string | null to cast nicely from Stripe client's types:

      /**
       * The status of the invoice, one of `draft`, `open`, `paid`, `uncollectible`, or `void`. [Learn more](https://stripe.com/docs/billing/invoices/workflow#workflow-overview)
       */
      status: Invoice.Status | null;

I guess there could be some default value, but we'd need to handle the casting from the stripe res, not sure if better:

      invoices = stripeInvoices.invoices.data.map((i) => ({
        amount: i.total / 100,
        timestamp: i.created * 1000,
        status: i.status, // Here
        url: i.hosted_invoice_url ?? undefined,
      }))

returnURL,
}: CustomerPortalParams) => {
const stripeClient = new Stripe(STRIPE_API_SECRET, {
apiVersion: '2022-11-15',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be a good idea to make this an environment variable.

Copy link
Contributor Author

@Cosmin-Parvulescu Cosmin-Parvulescu Jul 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

    export type LatestApiVersion = '2022-11-15';
    export type HttpAgent = Agent;
    export type HttpProtocol = 'http' | 'https';

    export interface StripeConfig {
      /**
       * This library's types only reflect the latest API version.
       *
       * We recommend upgrading your account's API Version to the latest version
       * if you wish to use TypeScript with this library.
       *
       * If you wish to remain on your account's default API version,
       * you may pass `null` or another version instead of the latest version,
       * and add a `@ts-ignore` comment here and anywhere the types differ between API versions.
       *
       * @docs https://stripe.com/docs/api/versioning
       */
      apiVersion: LatestApiVersion;

If we put an env variable, we'd still need to cast it to the actual string value, not sure that's worth it or cleaner.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant it for updating the value actually.


import { Context } from '../../context'
import { ServicePlanType } from '@proofzero/types/account'
import { ReconciliationNotificationType } from '../../../../email/src/jsonrpc/methods/sendReconciliationNotification'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@proofzero/platform.client?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! I extracted the enum into the types package as it spans both e-mail and address workers.

const planApps = apps.filter((app) => app.appPlan === plan)
if (planApps.length > count) {
const targetApps = planApps
.sort((a, b) => +b.createdTimestamp! - +a.createdTimestamp!)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to avoid !? undefined might not work well with subtraction.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Due to undefined being a possibility, there's a condition (L53) when adding items to the apps list:

    if (appDetails.createdTimestamp != null) {

so we'd expect only items with a timestamp to be present in the planApps. I think it's a case of Typescript not picking it up, so the ! is mostly to stop it from crying. 😁

@Cosmin-Parvulescu Cosmin-Parvulescu force-pushed the feat/console/billing-and-invoicing-invoice-and-payments-integration branch from e6d0039 to 2053546 Compare July 10, 2023 07:33
@Cosmin-Parvulescu Cosmin-Parvulescu marked this pull request as ready for review July 10, 2023 10:29
@szkl szkl merged commit 7905d22 into main Jul 10, 2023
12 checks passed
@szkl szkl deleted the feat/console/billing-and-invoicing-invoice-and-payments-integration branch July 10, 2023 11:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Indicates new feature requests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

feat(console): Billing and Invoicing - Invoice and payments integration
2 participants