From 0d93af1e66182c08ba806a71cf781b28b0e31050 Mon Sep 17 00:00:00 2001 From: Kiko Beats Date: Thu, 4 Mar 2021 12:18:42 +0100 Subject: [PATCH 1/2] feat: avoid to use geolocation api --- package.json | 3 ++ src/commands/payment/session.js | 10 +++++-- src/commands/payment/update.js | 4 +-- src/get-metadata.js | 43 +++-------------------------- src/get-tax-rate.js | 49 +++++++++++++++++---------------- 5 files changed, 42 insertions(+), 67 deletions(-) diff --git a/package.json b/package.json index 4d2346c..57dce1d 100644 --- a/package.json +++ b/package.json @@ -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", @@ -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", diff --git a/src/commands/payment/session.js b/src/commands/payment/session.js index 86e12d2..4e5af51 100644 --- a/src/commands/payment/session.js +++ b/src/commands/payment/session.js @@ -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({ diff --git a/src/commands/payment/update.js b/src/commands/payment/update.js index 3c548ef..69d4cd3 100644 --- a/src/commands/payment/update.js +++ b/src/commands/payment/update.js @@ -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), @@ -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) ]) diff --git a/src/get-metadata.js b/src/get-metadata.js index a87fa34..86e5f93 100644 --- a/src/get-metadata.js +++ b/src/get-metadata.js @@ -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 } } diff --git a/src/get-tax-rate.js b/src/get-tax-rate.js index 20f9e72..65a92c0 100644 --- a/src/get-tax-rate.js +++ b/src/get-tax-rate.js @@ -1,34 +1,29 @@ '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 @@ -36,12 +31,19 @@ const vatmoss = ({ config, stripe, getCountryTaxRate }) => { 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) + }) + ) } } @@ -49,7 +51,6 @@ const strategies = { vatmoss } module.exports = ({ config, stripe }) => { const { tax_type: taxType } = config.company - if (taxType === undefined) return noop const createStrategy = strategies[taxType] From ec6ca46452cca14ca9a3f5131699070c52bffb06 Mon Sep 17 00:00:00 2001 From: Kiko Beats Date: Fri, 5 Mar 2021 17:58:45 +0100 Subject: [PATCH 2/2] fix: wait promise --- src/get-metadata.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/get-metadata.js b/src/get-metadata.js index 86e5f93..b82870d 100644 --- a/src/get-metadata.js +++ b/src/get-metadata.js @@ -3,6 +3,6 @@ const reqCountry = require('req-country') module.exports = async ({ ipAddress, headers }) => { - const country = reqCountry({ ipAddress, headers }) + const country = await reqCountry({ ipAddress, headers }) return { ipAddress, country } }