Creating Stripe Refunds from NetSuite
SuiteSync enables your support and finance teams to create a Stripe refund from within NetSuite. This automates refund reconciliation, in addition to decreasing the possibility of a mistake being made and eliminating process friction by keeping the refund flow in NetSuite
This feature can be used with any of the supported flows, enabling your support or accounting team to issue refunds to payments in Stripe without leaving NetSuite. Since the refunds are created by SuiteSync, they are automatically reconciled to a bank deposit along with any fee refunds.
Here's how it works:
- Your team, or an automated process on your end, creates a unapplied CreditMemo in NetSuite. This CreditMemo contains a reference to the Stripe charge you'd like to refund. If you are using the eCommerce, auth-capture, or subscription flows this is done automatically.
- When the CreditMemo is created, SuiteSync creates a refund in Stripe for the unapplied amount of the credit memo.
- A CustomerRefund is created and applied to the unapplied CreditMemo (just like a standard refund).
Here's a short video walkthrough:
Here's a visual overview:
Technical Overview
- When the Invoice was created, the Stripe Charge ID was associated with it using the "SuiteSync Authorization Code" custom field.
- In most cases, when you create a CreditMemo, this Stripe Charge ID will be copied to the CreditMemo from the Invoice the CreditMemo is created from.
- SuiteSync looks for CreditMemos linked to Stripe Charge IDs via the custom field, and creates a Stripe refund for the unapplied amount of the CreditMemo.
- The Stripe refund is brought over to NetSuite as a CustomerRefund, and is applied to the CreditMemo.
- The CreditMemo’s "Stripe Transaction ID" field is set to the newly created Stripe refund ID.
Here's a couple of details to keep in mind:
- If the "Stripe Transaction ID" is blank, or does not contain a valid Stripe Charge ID, or Payment Intent ID, no refund is created in Stripe
- The unapplied amount of the CreditMemo (not the total) is used for the refund amount. If you partially apply a CreditMemo to a Invoice in NetSuite it does affect the amount that is refunded in Stripe.
- If a credit memo is fully applied no refund is issued.
- The Stripe charge ID does not need to be in place when the CreditMemo is created. You can update the "Stripe Transaction ID" with the Stripe Charge you'd like to refund at any point after the CreditMemo is created.
- If you fully refund a charge in Stripe, either directly through Stripe or using the CreditMemo, do not void the associated CustomerPayment in NetSuite. This will cause issues during the reconciliation process: the amount in Stripe will not match the amount in NetSuite.
- There's an option available to add a "delay" to refund processing. This allows a window of time where your customer service representatives can edit the amount you'd like to refund (or cancel the refund completely) before the refund is issued in Stripe (once a refund is issued, it cannot be reversed). The delay can be configured to be as long as you'd like.
- Adding the Payment Intent ID to the "Stripe Transaction ID" triggers a refund in the same way as adding the Charge ID.
eCommerce Example
Here's an example of how this can be used with a standard NetSuite eCommerce workflow.
Without SuiteSync in place, here's what the return and refund workflow would look like in NetSuite:
- Create a Return Authorization. This transaction is non-posting. A return authorization is only required if 1) the items the customer purchased are tied to inventory and 2) the customer is returning those items.
- Create a Credit Memo. This transaction posts to your income and A/R accounts based on the items contained with the Credit Memo.
- Create a Customer Refund. This transaction posts to your A/R and cash accounts and should be created once the payment is returned to the customer.
With SuiteSync, step #1 and #2 is handled by your sales personnel, or an automated system on your end; SuiteSync will handle #3.
When a CreditMemo is created, if the original charge ID is specified in the "Stripe Transaction ID" field, SuiteSync will automatically create a CustomerRefund. This CustomerRefund is then applied to the CreditMemo.
By default, the CreditMemo will copy the charge ID from the Invoice it was created from. This means there is no manual work or scripting that needs to be done to automatically refund a Stripe charge from within NetSuite.
Note that the custom form your invoice and credit memo is using must expose the "Stripe Transaction ID" field otherwise this process will not work.
Creating a Partial Refund
Partial refunds issued from NetSuite are supported. The unapplied amount of the credit memo is issued as a refund, so simply ensure the unapplied amount on the credit memo matches the partial amount you'd like to refund in Stripe.
Multiple partial refunds are also supported, as long at the total refund amount is less than the amount of the charge. Just create a credit memo for the partial amount you'd like to refund.
Credit Memos Without Refunds
You may run into a situation where you want to issue a credit memo without triggering a refund. The most common cases you'll want to create a credit memo without a refund are:
- Creating a credit memo for immediate application to an invoice
- Creating a credit memo for application to a future invoice
If you create a credit memo and would like to keep it around for application to a future invoice or apply it to an invoice immediately, but don't want to issue funds back to the customer via Stripe, you'll need to ensure the "Stripe Transaction ID" field on the credit memo is blank before saving the credit memo.
Here are the two ways to do this:
- Manually delete the value in "Stripe Transaction ID" before saving the credit memo.
- Create a new credit memo custom form "Credit without refund" and hide the "Stripe Transaction ID" on that custom form. This has the same effect as clearing the "Stripe Transaction ID" field but is a bit more user friendly. If you're unsure how to create a new Credit Memo form in NetSuite, check out this quick walkthrough.
Here is a short video on how to create a NettSuite credit memo without issuing a Stripe refund.
Refunding an Unapplied Payment or Customer Deposit
To issue a refund for an unapplied payment, don't create a CreditMemo. Instead, create a CustomerRefund for the amount you'd like to refund and make sure it's applied to the payment you'd like to refund. The payment you'd like to refund must have been created by the integration.
After the refund is created in NetSuite, SuiteSync creates a refund in Stripe for the amount of the CustomerRefund in NetSuite automatically.
Here are some details to keep in mind:
- A refund is only issued if the CustomerRefund is applied to a CustomerPayment which represents a Stripe payment.
- A refund will not be issued if the CustomerRefund is applied to more than one CustomerPayment. Only apply the refund to a single NetSuite payment.
Refunding a CashSale
Issuing refunds from CashSales by creating a CashRefund is also supported.
How are failures handled?
Some failures simply cause a delay (if the NetSuite or Stripe API is down, for instance) and are handled automatically. However, there are some errors that cannot be recovered from automatically and require intervention on your end to resolve.
Charge is already refunded
If the charge specified on the CreditMemo is already fully refunded in Stripe, Stripe Refund Error: charge is already refunded
is to the memo of the CreditMemo.
Requested refund exceeds original charge amount
If the refund amount specified is greater than the original charge amount, a message is added to the memo of the CreditMemo Stripe Refund Error: refund is greater than original charge amount 10.00
.
Requested refund exceeds available refund amount
If the refund amount specified on the CreditMemo is greater than the amount of the original charge, Stripe Refund Error: refund is greater than remaining unrefunded amount
is added to the memo of the CreditMemo. For instance, if the original charge was for $120 but the CreditMemo total is $130 you will encounter this error.
Currency of the CreditMemo does not match the currency of the charge
Stripe Refund Error: currency mismatch
is added to the memo of the CreditMemo.
Refund requested, but charge is not linked to a invoice
In most cases, this is not a hard failure. The refund will still be processed in Stripe.
However, the refund cannot be pulled into NetSuite until the charge is linked with a NetSuite Invoice. This will be noted on the credit memo with the following message Stripe Refund Error: charge is not linked to invoice.
In most cases, to fix this issue add the charge ID to the "SuiteSync Authorization Code" of the corresponding invoice.
Note that if you are using netsuite_block_integration
then this case is a hard failure. You will need to ensure the charge is linked to the invoice before the refund is processed. In some cases, eCommerce workflows will use the netsuite_block_integration
feature. contact support if you are not sure if this is enabled on your account.
Refund requested, but a chargeback has already been issued on the charge
Once a chargeback is issued, a payment cannot be refunded. If you issue a refund after a chargeback has already occurred Stripe Refund Error: charge is disputed
is added to the memo of the CreditMemo (or CustomerRefund).
Refund is applied to multiple transactions
This error is only applicable when unapplied customer payments or deposits are refunded.
When issuing a refund for a Stripe charge, the CustomerRefund should only contain a single apply item: the Stripe charge you would like to refund. If you create a refund for multiple payments at once, Stripe Refund Error: refund request detected, but refund is connected to multiple transactions
is added to the memo of the CustomerRefund.
Generic Failure
The error message from Stripe is indicated on the CreditMemo's memo field.
Network or API Errors
If there is a Stripe or NetSuite outage, or if there are network errors the refund operation is retried. Retries are run every hour for the next 72 hours until it succeeds. If it fails after 72 attempts, you must manually retry the operation in the SuiteSync dashboard.