Skip to content

Instantly share code, notes, and snippets.

@jeff-r-koyaltech
Created May 6, 2020 05:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jeff-r-koyaltech/deae2759131298ede9f85a16952de790 to your computer and use it in GitHub Desktop.
Save jeff-r-koyaltech/deae2759131298ede9f85a16952de790 to your computer and use it in GitHub Desktop.
// example:
// curl -X POST -H 'Content-Type: application/json' http://localhost:4000/stripe/customers/byCard \
// --data '{ "email": "user@host.com", "last4": "4242", "exp_month": 4, "exp_year":"22" }' | jq
const util = require('util')
let stripe_key = process.env.STRIPE_SK
let stripe = require('stripe')(stripe_key)
let use = (app) => {
app.post('/stripe/customers/byCard', customersByCard)
}
let isEmptyParam = (val) => {
if((val || '').length === 0) {
return true
} else {
return false
}
}
let customersByCard = (req, res, next) => {
let params = req.body
//validation
if(isEmptyParam(params.email) ||
isEmptyParam(params.last4) ||
isEmptyParam(params.exp_year) ||
isEmptyParam(params.exp_month)) {
res.status(400).send({ message: 'Invalid parameters supplied', params: params })
next()
return
}
if((typeof params.exp_month) === 'string') {
params.exp_month = parseInt(params.exp_month)
}
if((typeof params.exp_year) === 'string') {
params.exp_year = parseInt(params.exp_year)
}
//YY -> YYYY (watch out for Y3K :) )
if(params.exp_year < 1000) {
params.exp_year += 2000
}
// get customers
stripe.customers.list({
email: params.email,
limit: 5
})
.then((customerListResp) => {
let custs = customerListResp.data
let matchingCusts = custs.filter((cust) => {
let matchedSources = cust.sources.data.filter((source) => {
return source.card.last4 == params.last4
&& source.card.exp_month == params.exp_month
&& source.card.exp_year == params.exp_year
})
if(matchedSources.length > 0) {
cust.sources.data = matchedSources
return true
} else {
return false
}
})
return Promise.all(
matchingCusts.map((matchingCust) => {
return customerContext(stripe, matchingCust).withDependentData()
})
)
})
.then((customerContexts) => {
let customers = customerContexts.map((customerContext) => {
return customerContext.data
})
res.send(customers)
next()
})
.catch(next)
}
let customerContext = (stripeClient, customer) => {
return {
_stripeClient: stripeClient,
data: {
customer: customer,
invoices: [],
products: []
},
withDependentData() {
return new Promise((resolve, reject) => {
Promise.all([
this.withInvoices(),
this.withProducts()
])
.then(() => {
resolve(this)
})
.catch((err) => reject(err))
})
},
withInvoices() {
let invoicePromises = this.data.customer.subscriptions.data.map((subscription) => {
return this._stripeClient.invoices.retrieve(subscription.latest_invoice)
.then((invoiceResp) => {
this.data.invoices.push(invoiceResp)
return this
})
})
return Promise.all(invoicePromises)
},
withProducts() {
let productPromises = this.data.customer.subscriptions.data.map((subscription) => {
return this._stripeClient.products.retrieve(subscription.plan.product)
.then((productResp) => {
this.data.products.push(productResp)
return this
})
})
return Promise.all(productPromises)
}
}
}
module.exports = {
customersByCard,
use,
_internal: {
customerContext
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment