Created
October 24, 2016 20:24
-
-
Save iloveitaly/be605467336b0ed82002ae0558937a0d to your computer and use it in GitHub Desktop.
Demonstrates how to pull open invoices from NetSuite for a given customer and pay them off using Stripe and http://SuiteSync.io/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Author: <mike@suitesync.io> | |
# Description: Demonstrates pulling open invoices from NetSuite for a customer, and paying them off with Stripe. | |
# requires the following environment variables: | |
# | |
# STRIPE_KEY | |
# NETSUITE_EMAIL | |
# NETSUITE_PASSWORD | |
# NETSUITE_ACCOUNT | |
require 'stripe' | |
require 'netsuite' | |
Stripe.api_key = ENV['STRIPE_TEST_KEY'] | |
NetSuite.configure do | |
reset! | |
# NOTE that API versions > 2015_1 require a more complicated authentication setup | |
api_version '2015_1' | |
read_timeout 60 * 3 | |
silent ENV['NETSUITE_SILENT'].nil? || ENV['NETSUITE_SILENT'] == 'true' | |
email ENV['NETSUITE_EMAIL'] | |
password ENV['NETSUITE_PASSWORD'] | |
account ENV['NETSUITE_ACCOUNT'] | |
soap_header({ | |
'platformMsgs:preferences' => { | |
'platformMsgs:ignoreReadOnlyFields' => true, | |
} | |
}) | |
end | |
# In the application's backend, all open invoices will be pulled down from NetSuite for easy display and payment in NetSuite | |
# There are two steps to this process: | |
# | |
# 1. Finding the associated NetSuite customer through the Stripe Customer | |
# 2. Pulling all open invoices down | |
def find_netsuite_customer(user) | |
stripe_customer_id = user.stripe_customer_id | |
stripe_customer = Stripe::Customer.retrieve(stripe_customer_id) | |
# the `netsuite_customer_id` field is set by SuiteSync | |
# https://dashboard.suitesync.io/docs/field-customization#using-existing-records-or-existing-integrations | |
# note that an existing or custom customer integration can be used in place of SuiteSync's customer integration | |
ns_customer_id = stripe_customer.metadata['netsuite_customer_id'] | |
ns_customer = NetSuite::Utilities.get_record(NetSuite::Records::Customer, ns_customer_id) | |
end | |
def netsuite_invoices_for_customer(ns_customer) | |
search = NetSuite::Records::Invoice.search( | |
basic: [ | |
{ | |
field: 'type', | |
operator: 'anyOf', | |
value: ['_invoice'] | |
}, | |
{ | |
field: 'mainLine', | |
value: true | |
}, | |
{ | |
field: 'status', | |
operator: 'anyOf', | |
value: [ '_invoiceOpen' ] | |
}, | |
{ | |
field: 'entity', | |
operator: 'anyOf', | |
value: [ NetSuite::Records::RecordRef.new(internal_id: ns_customer.internal_id) ] | |
} | |
] | |
) | |
if !search | |
fail "error running search" | |
end | |
search.results | |
end | |
def pay_netsuite_invoice_with_stripe(stripe_customer_id, ns_invoice_id, stripe_token, amount) | |
stripe_customer = Stripe::Customer.retrieve(stripe_customer_id) | |
stripe_card = stripe_customer.sources.create(card: stripe_token.id) | |
Stripe::Charge.create( | |
currency: 'usd', | |
amount: (amount * 100).to_i, | |
# customer ID is required when specifying a source! | |
customer: stripe_customer.id, | |
source: stripe_card.id, | |
metadata: { | |
netsuite_invoice_id: ns_invoice_id | |
} | |
) | |
end | |
# A link between your local user database and the associated Stripe or NetSuite customer should be stored locally. | |
# Storing a reference to the Stripe customer using a `stripe_customer_id` field is recommended. | |
user = OpenStruct.new( | |
# NOTE you'll need to replace this ID with a Stripe Customer ID from your Stripe test account | |
stripe_customer_id: 'cus_9Q0rnKSyak25Th' | |
) | |
# Pulling open NetSuite invoices is slow. It's best to ensure this is handled in the background. | |
ns_customer = find_netsuite_customer(user) | |
open_netsuite_invoices = netsuite_invoices_for_customer(ns_customer) | |
# In this case, the first open invoice is chosen. This can easily be modified to allow payment for many invoices. | |
invoice_to_pay = open_netsuite_invoices.first | |
# Using Stripe checkout or a custom payment form, the amount due should be displayed to the user along with | |
# a form allowing the user to pay with credit card, ACH, or other payment type. | |
# Below is the bare-bones information that needs to be passed back to Stripe via your backend in order to successfully pay the NetSuite invoice | |
payment_data = { | |
total: invoice_to_pay.total.to_f, | |
stripe_customer_id: user.stripe_customer_id, | |
ns_invoice_id: invoice_to_pay.internal_id | |
} | |
# Generating this card token will either be handled by Stripe.js or Stripe checkout | |
card_token = Stripe::Token.create( | |
:card => { | |
:number => '4242424242424242', | |
:exp_month => 8, | |
:exp_year => (Date.today>>24).year, | |
:cvc => "314", | |
} | |
) | |
# After the card token is generated on your frontend, the resulting token will be passed to your backend | |
# to create the payment in Stripe and pay off the NetSuite invoice | |
pay_netsuite_invoice_with_stripe( | |
payment_data[:stripe_customer_id], | |
payment_data[:ns_invoice_id], | |
card_token, | |
payment_data[:total] | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment