Skip to content

Commit

Permalink
feat: avoid to use geolocation api
Browse files Browse the repository at this point in the history
  • Loading branch information
Kikobeats committed Mar 4, 2021
1 parent b8c867f commit 0d93af1
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 67 deletions.
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,14 @@
"compression": "~1.7.4",
"cors": "~2.8.5",
"cosmiconfig": "~7.0.0",
"country-vat": "~1.0.0",
"emittery": "~0.8.1",
"express": "~4.17.1",
"got": "~11.8.2",
"helmet": "~4.4.1",
"import-modules": "~2.1.0",
"is-buffer": "~2.0.5",
"is-european": "~1.0.3",
"jsendp": "~2.1.0",
"lodash": "~4.17.21",
"mailgen": "~2.0.14",
Expand All @@ -59,6 +61,7 @@
"p-retry": "~4.4.0",
"p-waterfall": "~2.1.1",
"pretty-ms": "~7.0.1",
"req-country": "~1.0.0",
"request-ip": "~2.1.3",
"stripe": "^8.137.0",
"time-span": "~4.0.0",
Expand Down
10 changes: 8 additions & 2 deletions src/commands/payment/session.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,19 @@ module.exports = ({ config }) => {
const stripe = createStripe(get(config, 'payment.stripe_key'))
const getTaxRate = createGetTaxRate({ config, stripe })

const session = async ({ ipAddress, planId, successUrl, cancelUrl }) => {
const session = async ({
ipAddress,
headers,
planId,
successUrl,
cancelUrl
}) => {
ward(planId, {
label: 'planId',
test: is.string.nonEmpty
})

const metadata = await getMetadata(ipAddress)
const metadata = await getMetadata({ ipAddress, headers })
const taxRate = await getTaxRate(metadata)

const session = await stripe.checkout.sessions.create({
Expand Down
4 changes: 2 additions & 2 deletions src/commands/payment/update.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ module.exports = ({ config }) => {

const stripe = createStripe(get(config, 'payment.stripe_key'))

const update = async ({ token, customerId, ipAddress }) => {
const update = async ({ token, customerId, ipAddress, headers }) => {
ward(token, {
label: 'token',
test: is.object.is(token => !!token.id),
Expand All @@ -29,7 +29,7 @@ module.exports = ({ config }) => {
const { id: source, client_ip: clientIp } = token

const [newMetadata, { metadata: oldMetadata, email }] = await Promise.all([
getMetadata(clientIp || ipAddress),
getMetadata({ ipAddress: clientIp || ipAddress, headers }),
stripe.customers.retrieve(customerId)
])

Expand Down
43 changes: 4 additions & 39 deletions src/get-metadata.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,8 @@
'use strict'

const { get, pickBy } = require('lodash')
const got = require('got')
const reqCountry = require('req-country')

module.exports = async ipAddress => {
if (!ipAddress) return

try {
const { body } = await got(
`https://api.ipgeolocationapi.com/geolocate/${ipAddress}`,
{
responseType: 'json'
}
)

return pickBy({
ipAddress,
continent: get(body, 'continent'),
region: get(body, 'region'),
subregion: get(body, 'subregion'),
worldRegion: get(body, 'world_region'),
unLocode: get(body, 'un_locode'),
alpha2: get(body, 'alpha2'),
alpha3: get(body, 'alpha3'),
countryCode: get(body, 'country_code'),
internationalPrefix: get(body, 'international_prefix'),
ioc: get(body, 'ioc'),
gec: get(body, 'gec'),
country: get(body, 'name'),
vatRate: get(body, 'vat_rates.standard'),
currencyCode: get(body, 'currency_code'),
latitude: get(body, 'geo.latitude'),
longitude: get(body, 'geo.longitude'),
euMember: get(body, 'eu_member'),
eeaMember: get(body, 'eea_member')
})
} catch (err) {
return {
ipAddress
}
}
module.exports = async ({ ipAddress, headers }) => {
const country = reqCountry({ ipAddress, headers })
return { ipAddress, country }
}
49 changes: 25 additions & 24 deletions src/get-tax-rate.js
Original file line number Diff line number Diff line change
@@ -1,55 +1,56 @@
'use strict'

const { get, noop } = require('lodash')
const got = require('got')
const { eeaMember, getCountry } = require('is-european')
const countryVat = require('country-vat')
const { noop } = require('lodash')

const MAX_TAX_RATES_LIMIT = 100
const CACHE = new Map()

const getCountryTaxRate = async countryCode =>
got(`https://api.ipgeolocationapi.com/countries/${countryCode}`, {
cache: CACHE,
responseType: 'json',
resolveBodyOnly: true
const getCountryTaxRate = country => countryVat(country) * 100

const createTaxRateFactory = stripe => ({ name, alpha2, percentage }) =>
stripe.taxRates.create({
display_name: 'VAT',
description: `VAT ${name}`,
jurisdiction: alpha2,
percentage,
inclusive: true
})

const vatmoss = ({ config, stripe, getCountryTaxRate }) => {
const createTaxRate = countryTaxRate =>
stripe.taxRates.create({
display_name: 'VAT',
description: `VAT ${countryTaxRate.name}`,
jurisdiction: countryTaxRate.alpha2,
percentage: get(countryTaxRate, 'vat_rates.standard'),
inclusive: true
})

const { company } = config
const createTaxRate = createTaxRateFactory(stripe)

return async (customerMeta = {}) => {
if (!customerMeta.eeaMember) return
return async ({ country } = {}) => {
if (!eeaMember(country)) return

const companyTaxRate = await getCountryTaxRate(company.country)
const companyCountry = getCountry(config.company.country)

const { data: taxRates } = await stripe.taxRates.list({
limit: MAX_TAX_RATES_LIMIT
})

const taxRate = taxRates.find(
taxRate =>
taxRate.active &&
taxRate.inclusive &&
taxRate.display_name === 'VAT' &&
taxRate.jurisdiction === companyTaxRate.alpha2
taxRate.jurisdiction === companyCountry.alpha2
)

return taxRate || createTaxRate(companyTaxRate)
return (
taxRate ||
createTaxRate({
...companyCountry,
percentage: getCountryTaxRate(config.company.country)
})
)
}
}

const strategies = { vatmoss }

module.exports = ({ config, stripe }) => {
const { tax_type: taxType } = config.company

if (taxType === undefined) return noop

const createStrategy = strategies[taxType]
Expand Down

0 comments on commit 0d93af1

Please sign in to comment.