Invoices

Stripe Subscriptions, and standalone Stripe invoices, are tightly integrated with NetSuite.


Here's how the NetSuite Stripe Subscription integration works:

  • Stripe Subscriptions are represented as NetSuite invoices with one or more line items. Each period (1 month, 1 year, etc), a new invoice is created in Stripe, which triggers the creation of a invoice in NetSuite to represent the subscription.
  • If the Stripe invoice is paid, a NetSuite CustomerPayment is created and applied against the NetSuite invoice.
  • If there is a refund, a CreditMemo and CustomerRefund is created.
  • If a subscription is changed (different plan or quantity/seats purchased), that plan change is not represented on the current subscription's invoice. Prorations and plan changes are included in the next subscription cycle's invoice. This functionality can be customized (more information on this below).
  • If an invoice remains unpaid (if a customer's card fails and they do not update it, for example) the invoice in NetSuite can either be automatically closed or remain open.

Here's what a Stripe invoice looks like in NetSuite:

Example NetSuite Invoice

Here are some technical details to keep in mind:

  • Subscription invoices are not "finalized" until one hour after they are created. During this period the invoice is not created in NetSuite. Once a invoice is finalized (after that one hour period) it is sent over to NetSuite.
  • Zero dollar line items are not removed from the invoice. They are included just like any other line item.
  • Non-plan line items (i.e. additional InvoiceItems) are supported. There's some extra work to ensure they are mapped to the right item in NetSuite.

Manual Invoice Payments

Invoices paid "manually" (cash, check, wire, or any other payment method not supported by Stripe) are also supported. Stripe has a feature available to set up a subscription for "manual" payment.

Here's how subscriptions paid on terms (manually) work:

  1. If an invoice (or subscription) is marked for manual payment it is brought over to NetSuite as an unpaid invoice. Note that it takes ~hour for Stripe to "finalize" the invoice, after an invoice is finalized it is brought over to NetSuite.
  2. The due date based on the payment terms specified in Stripe is brought over as the due date on the NetSuite invoice.
  3. When the invoice is marked as paid in NetSuite, SuiteSync marks invoice in Stripe as paid and adds the transaction ID of the NetSuite payment to the Stripe invoice metadata. Note that if an invoice is partially paid in NetSuite it is not marked as paid in Stripe.
  4. Stripe automatically updates the subscription status in Stripe when the invoice is updated by SuiteSync

This enables you to use Stripe subscriptions to manage subscription status in—regardless of the payment method—but manage collections on those invoices from a single source in NetSuite.

Example Code Creating a Manual Invoice on Terms with Stripe

How Plans & Products are Represented in NetSuite

Products in Stripe are essentially records which organize groups of price levels. Each prive level (a "plan") have a corresponding item in NetSuite, while products (price level grouping records) do not.

There are a couple of different ways SuiteSync can represent Stripe plans in NetSuite:

  1. Each plan in Stripe can be connected to a single item in NetSuite. This approach keeps your item master clean and simple, but limits the amount of control you have over revenue reporting. Every single plan in Stripe can only post to a single revenue account in NetSuite and rev rec cannot be customized across different plans.
  2. Each plan in Stripe can have a unique item in NetSuite. This approach adds more entries to your item master, but gives you detailed reporting and control over rev rec, revenue accounts, etc for each Stripe plan.
  3. Define a custom mapping. You can provide us with a sheet of the mapping you'd like to use between Stripe and NetSuite. During the onboarding process, we can setup this custom mapping for you.

Plan changes

If a customer is switching from a higher cost plan to a lower cost plan a customer balance is created. No refund is given to the customer and this balance is applied to any future invoices.

Here's all of the nitty-gritty details on how plan changes are represented in NetSuite.

If don't want customers to carry a credit/balance, or if you want to refund a customer for unused time, check out this example code.

Coupons

Stripe Coupons are supported in the integration. They are represented as NetSuite discount items. You can either create a unique discount item in NetSuite for each coupon in Stripe or use a single discount item for all coupons in Stripe (you can also develop a custom mapping). As with all Stripe records, you can map them directly to a particular item in NetSuite using metadata.

In Stripe, coupons are represented as a separate line item on the invoice. In NetSuite, there are two options for representing coupons:

  1. An additional line item on the invoice, just like Stripe.
  2. On the header level of the invoice, using the "Discount" drop-down in NetSuite.
Using coupons with revenue recognition

Coupons do not have a revenue period. If you are using revenue recognition, you'll want to use non-posting discounts. This causes the discount amount to be subtracted from the total revenue recognized for the item representing the subscription.

If you choose to use posting discount items, the revenue account used can be customized.

Trial Invoices

Stripe trial periods create $0 invoices in Stripe. The integration allows you to pull these trial period invoices into NetSuite, or ignore them. Trial invoices can be created by using the trial_end and trial_period_days parameters in Stripe.

Note that trial invoices use a special invoice structure in Stripe. All line items on the invoice are set to zero, so the invoice has no accounting impact at all. This is different from using a coupon/discount, or another method that creates an invoice with a net total of zero. We don't skip invoices that have line items with a non-zero value since there are many cases where an invoice may have a net total of zero but contains line items which have a GL impact that you'll want to be recorded in NetSuite.

Customers with lower cost plans usually opt to prevent trial invoices from being pulled into NetSuite. These trial invoices don't have any accounting impact and simply create noise in high-volume scenarios.

However, if you have scripts or other automation that you'd like to run in NetSuite when a customer creates a subscription in Stripe, you may want to keep this option enabled.

Standalone Invoice Items

Stripe's Invoice Items can be used to add one-time charges to a customer's next recurring invoice. This is helpful for implementing usage based billing, overage charges, bonus pack purchases, one-time service charges, etc. These "add on" invoice items are not associated with a plan or pricing level and therefore do not have a direct mapping to a NetSuite item.

Here's an example of how to add one using the Stripe dashboard:

Invoice items in Stripe

Each standalone invoice item you create in Stripe has a unique ID, even if the line item represents a consistent type of charge that you add to a customer's invoice. In most cases, you'll want to map an invoice item to an existing NetSuite item. If you don't, the integration uses a generic item for all standalone invoice items.

The integration provides two ways to match a invoice item to specific item in NetSuite:

  1. When you add the line item to the customer you can map it to an existing NetSuite item using metadata. Here's a full list of the mappings available.
  2. A NetSuite item can be matched using the description of the Stripe line item or a metadata field. The Stripe line item description is used to search for a NetSuite item whose "Display Name" (or another NetSuite field, the matching operation is flexible) matches the Stripe description. If a match is not found a fallback item is used. The match is not case sensitive.

Customer Balance or Credit

Paying an invoice with a a Stripe customer's account balance is fully supported in the integration. Learn more about how this works..

It is possible for a customer to have a negative account balance. This often occurs when there is a plan change that creates a balance less than the minimum payment amount in the invoice's currency. If this is the case, the balance amount is included as a separate line item on the next upcoming invoice for payment. The integration uses a unique item ("Stripe Customer Balance Item") to represent this balance on the invoice.

How invoice payment failures are handled

If your card fails to charge the invoice will remain unpaid in Stripe and therefore remain open in NetSuite. Here's more information on how failed payments operate in Stripe.

Stripe retries the payment on an invoice a couple times, after it fails for the final time it moves to a "unpaid and closed" state, which is detailed out here.

Unpaid and closed, or forgiven invoices

If a customer's card fails to charge the subscription is past_due and the invoice associated with the billing period is unpaid. At this point, you can choose to "forgive" or close the unpaid invoices in Stripe.

Here's an example of a closed invoice in Stripe:

Closed Invoice in Stripe

If an invoice is open and unpaid, you'll see a "Close" button on the Stripe invoice.

Here's how this works in Stripe:

  • Forgiving a Stripe invoice instructs Stripe to treat the users subscription as if they had paid the invoice. Stripe will stop attempting to collect payment, but the user's subscription will continue to function normally
  • Closing an invoice instructs Stripe to stop attempting to charge the user's card, but the user's subscription status remains past_due.
  • If your Stripe subscription payment retry strategy cancels a subscription, associated invoices are closed.

By default, invoices that are closed and unpaid, or invoices that are forgiven, remain open in NetSuite. This enables you to create processes around handling "bad debt" in a way that works for your business.

There's an option available that automatically creates a credit memo against any closed or forgiven invoices that are not paid. This closes the invoice in NetSuite and reverses the entries to A/R and makes an entry to an income account.

On the credit memo which closes out the "bad debt" created by the invoice, you can either use the original item(s) on the invoice, or override the default item with a unique item to represent all "bad debt" that is closed out. Using this "bad debt" item allows you to customize the account that this bad debt posts to. If you are using revenue recognition in NetSuite, the schedule from the original invoice is copied over to the CreditMemo if you use the original items on the invoice.

If you aren't automatically cancelling subscriptions when the last payment attempt fails, you'll need to manually manage closing out open Stripe invoices for a customer when you are sure you won't be attempting collection on those invoices. Here's an example of how to manually close Stripe invoices for a customer.

If you are automatically cancelling subscriptions when you visit this Stripe settings page you should see something similar to:

Invoice items in Stripe

Note that SuiteSync is not effected by the number of failed card retries. Only the "Finally then" rule effects how SuiteSync works.

Stripe does not record the date when the invoice was closed or forgiven. Since this information does not exist, we use the date of the last failed payment against the invoice as the date of the (optional) credit memo that is created to automatically close the invoice. In most cases, the date of the last failed payment on the invoice is the date that the invoice is closed. This is the case in the Stripe retry configuration shown in the above screenshot. If you are handling payment retries and invoice status changes using a customized dunning system (either home-grown or a 3rd party service) they may not close the invoice on the same day as the last failed charge.

Can I prevent a invoice that is not paid successfully from being sent to NetSuite?

No, we don't allow invoices to be brought over only when they are paid. This would cause accounting inaccuracies. Not every invoice which fails to be paid the first time, will remain unpaid. Actually, many (most in some cases) eventually get paid due to Stripe's recovery tools. For instance, an invoice payment may fail on the first attempt but Stripe automatically retries the payment at a later day and it may succeed.

It's important that we bring over the invoice immediately when it is created so we can book revenue accurately. Take this example:

  1. A subscription renews and an invoice is created on the 25th of January. The payment on the invoice fails.
  2. It's a monthly subscription, and revenue recognition is enabled in NetSuite. SuiteSync creates an invoice in NetSuite and revenue is spread over January and February.
  3. On the 5th of February a payment is successfully created for the invoice. The invoice for January is unchanged.
  4. On the 25th of February the subscription renews again, booking revenue for February and March.

If we only brought over the invoice when it was paid, revenue for February would be incorrectly overstated.

How can I close out Stripe invoices in batches?

You may run into a situation where you have past invoices which were accidentally left open and you want to close them out.

In Stripe, there's no way in the dashboard to batch close invoices. You'll need to either:

  1. Close them out manually in the Stripe dashboard
  2. Use a script to close out invoices in batches. You'll want to the closed parameter to true.

Can CashSales be used instead of Invoices?

Each billing period of a Stripe subscription (i.e. a Stripe invoice) can only be represented by a NetSuite invoice.

CashSales represent an order and collected cash. Since Stripe invoices (created at the beginning of each billing cycle) are not always paid (in the case of a failed card payment) representing a Stripe invoice as a CashSale would incorrectly indicate that cash has been collected from the customer.

Are NetSuite invoices synced to Stripe as Invoices?

No. Stripe invoices are pushed to NetSuite, but NetSuite invoices are not pushed to Stripe as invoices. If you create an invoice in NetSuite and pay it off, only the payment on the invoice is created in Stripe. The payment for the invoice contains a reference and link to the NetSuite invoice, but the invoice and corresponding line items are not replicated in NetSuite.