Stripe Subscriptions module API explorer

/api/administrator/subscriptions/create-tax-rate (POST)

Account information like email addresses is generated with faker-js it is not real user information.

await global.api.administrator.subscriptions.CreateTaxRate.post(req)

Returns object

{
  "taxrateid": "txr_1LEOIEHHqepMFuCXCU1qNre5",
  "object": "taxrate",
  "stripeObject": {
    "id": "txr_1LEOIEHHqepMFuCXCU1qNre5",
    "object": "tax_rate",
    "active": true,
    "country": "US",
    "created": 1656122414,
    "description": "Sales tax in NY",
    "display_name": "GST (US)",
    "inclusive": true,
    "jurisdiction": "US",
    "livemode": false,
    "metadata": {},
    "percentage": 12.5,
    "state": "NY",
    "tax_type": "sales_tax"
  },
  "appid": "tests_1656122414",
  "createdAt": "2022-06-25T02:00:14.918Z",
  "updatedAt": "2022-06-25T02:00:14.918Z"
}

Receives

API routes may receive parameters from the URL and POST supporting simple and multipart:

Field Value Required Type
country string optional POST
description string optional POST
display_name string required POST
inclusive string required POST
jurisdiction string optional POST
percentage string required POST
state string optional POST
tax_type string optional POST

Exceptions

These exceptions are thrown (NodeJS) or returned as JSON (HTTP) if you provide incorrect data or do not meet the requirements:

Exception Circumstances
invalid-country invalid posted country
invalid-display_name missing posted display_name
invalid-inclusive missing posted inclusive
invalid posted inclusive
invalid-percentage missing posted percentage
invalid posted percentage
invalid posted percentage is negative
invalid posted percentage exceeds 100
invalid-state invalid posted state
invalid-tax_type invalid posted tax_type

NodeJS source (view on github)

const stripeCache = require('../../../../stripe-cache.js')
const subscriptions = require('../../../../../index.js')

module.exports = {
  post: async (req) => {
    if (!req.body || !req.body.display_name) {
      throw new Error('invalid-display_name')
    }
    if (req.body.inclusive !== 'true' && req.body.inclusive !== 'false') {
      throw new Error('invalid-inclusive')
    }
    try {
      const percentage = parseFloat(req.body.percentage)
      if (!percentage || percentage < 0 | percentage > 100 || percentage.toString() !== req.body.percentage) {
        throw new Error('invalid-percentage')
      }
    } catch (error) {
      throw new Error('invalid-percentage')
    }
    if (req.body.active !== 'true' && req.body.active !== 'false') {
      throw new Error('invalid-active')
    }
    if (!req.body.country || !subscriptions.countryDivisions[req.body.country]) {
      throw new Error('invalid-country')
    }
    if (req.body.state && !req.body.country) {
      throw new Error('invalid-country')
    }
    if (req.body.state && subscriptions.countryDivisions[req.body.country].indexOf(req.body.state) === -1) {
      throw new Error('invalid-state')
    }
    if (req.body.tax_type &&
        req.body.tax_type !== 'sales_tax' &&
        req.body.tax_type !== 'vat' &&
        req.body.tax_type !== 'gst' &&
        req.body.tax_type !== 'hst' &&
        req.body.tax_type !== 'pst' &&
        req.body.tax_type !== 'qst' &&
        req.body.tax_type !== 'rst' &&
        req.body.tax_type !== 'jct') {
      throw new Error('invalid-tax_type')
    }
    const taxRateInfo = {
      display_name: req.body.display_name,
      inclusive: req.body.inclusive === 'true',
      percentage: req.body.percentage
    }
    const optionalFields = ['active', 'country', 'description', 'jurisdiction', 'state', 'tax_type']
    for (const field of optionalFields) {
      if (!req.body[field] || !req.body[field].length) {
        throw new Error(`invalid-${field}`)
      }
      taxRateInfo[field] = req.body[field]
    }
    const taxRate = await stripeCache.execute('taxRates', 'create', taxRateInfo, req.stripeKey)
    await subscriptions.Storage.TaxRate.create({
      appid: req.appid || global.appid,
      taxrateid: taxRate.id,
      stripeObject: taxRate
    })
    req.query = {}
    req.query.taxrateid = taxRate.id
    return global.api.administrator.subscriptions.TaxRate.get(req)
  }
}

Test source (view on github)

/* eslint-env mocha */
const assert = require('assert')
const TestHelper = require('../../../../../test-helper.js')
const DashboardTestHelper = require('@layeredapps/dashboard/test-helper.js')

describe('/api/administrator/subscriptions/create-tax-rate', function () {
  before(TestHelper.disableMetrics)
  after(TestHelper.enableMetrics)
  let cachedResponses
  async function bundledData (retryNumber) {
    if (retryNumber > 0) {
      cachedResponses = {}
    }
    if (cachedResponses && cachedResponses.finished) {
      return
    }
    cachedResponses = {}
    await TestHelper.setupBefore()
    await DashboardTestHelper.setupBeforeEach()
    await TestHelper.setupBeforeEach()
    const administrator = await TestHelper.createOwner()
    const req = TestHelper.createRequest('/api/administrator/subscriptions/create-tax-rate')
    req.account = administrator.account
    req.session = administrator.session
    req.body = {
      display_name: 'NY Sales Tax',
      percentage: '',
      inclusive: 'true',
      active: 'true',
      state: 'NY',
      country: 'US',
      description: 'Sales tax in NY',
      jurisdiction: 'US',
      tax_type: 'sales_tax'
    }
    // invalid percentage
    try {
      await req.post()
    } catch (error) {
      cachedResponses.missingPercentage = error.message
    }
    req.body.percentage = 'invalid'
    try {
      await req.post()
    } catch (error) {
      cachedResponses.invalidPercentage = error.message
    }
    req.body.percentage = '-7'
    try {
      await req.post()
    } catch (error) {
      cachedResponses.negativePercentage = error.message
    }
    req.body.percentage = '105'
    try {
      await req.post()
    } catch (error) {
      cachedResponses.excessivePercentage = error.message
    }
    req.body.percentage = '12.5'
    // invalid display name
    req.body.display_name = ''
    try {
      await req.post()
    } catch (error) {
      cachedResponses.invalidDisplayName = error.message
    }
    req.body.display_name = 'GST (US)'
    // invalid inclusive
    req.body.inclusive = ''
    try {
      await req.post()
    } catch (error) {
      cachedResponses.missingInclusive = error.message
    }
    req.body.inclusive = 'invalid'
    try {
      await req.post()
    } catch (error) {
      cachedResponses.invalidInclusive = error.message
    }
    req.body.inclusive = true
    // invalid country
    req.body.country = 'ivnalid'
    try {
      await req.post()
    } catch (error) {
      cachedResponses.invalidCountry = error.message
    }
    req.body.country = 'US'
    // invalid state
    req.body.state = 'invalid'
    try {
      await req.post()
    } catch (error) {
      cachedResponses.invalidState = error.message
    }
    req.body.state = 'NY'
    // invalid tax type
    req.body.tax_type = 'invalid'
    try {
      await req.post()
    } catch (error) {
      cachedResponses.invalidTaxType = error.message
    }
    req.body.tax_type = 'sales_tax'
    // good
    req.filename = __filename
    req.saveResponse = true
    cachedResponses.returns = await req.post()
    cachedResponses.finished = true
  }

  describe('exceptions', () => {
    describe('invalid-percentage', () => {
      it('missing posted percentage', async function () {
        await bundledData(this.test.currentRetry())
        const errorMessage = cachedResponses.missingPercentage
        assert.strictEqual(errorMessage, 'invalid-percentage')
      })

      it('invalid posted percentage', async function () {
        await bundledData(this.test.currentRetry())
        const errorMessage = cachedResponses.invalidPercentage
        assert.strictEqual(errorMessage, 'invalid-percentage')
      })

      it('invalid posted percentage is negative', async function () {
        await bundledData(this.test.currentRetry())
        const errorMessage = cachedResponses.negativePercentage
        assert.strictEqual(errorMessage, 'invalid-percentage')
      })

      it('invalid posted percentage exceeds 100', async function () {
        await bundledData(this.test.currentRetry())
        const errorMessage = cachedResponses.excessivePercentage
        assert.strictEqual(errorMessage, 'invalid-percentage')
      })
    })

    describe('invalid-display_name', () => {
      it('missing posted display_name', async function () {
        await bundledData(this.test.currentRetry())
        const errorMessage = cachedResponses.invalidDisplayName
        assert.strictEqual(errorMessage, 'invalid-display_name')
      })
    })

    describe('invalid-inclusive', () => {
      it('missing posted inclusive', async function () {
        await bundledData(this.test.currentRetry())
        const errorMessage = cachedResponses.missingInclusive
        assert.strictEqual(errorMessage, 'invalid-inclusive')
      })

      it('invalid posted inclusive', async function () {
        await bundledData(this.test.currentRetry())
        const errorMessage = cachedResponses.invalidInclusive
        assert.strictEqual(errorMessage, 'invalid-inclusive')
      })
    })

    describe('invalid-country', () => {
      it('invalid posted country', async function () {
        await bundledData(this.test.currentRetry())
        const errorMessage = cachedResponses.invalidCountry
        assert.strictEqual(errorMessage, 'invalid-country')
      })
    })

    describe('invalid-state', () => {
      it('invalid posted state', async function () {
        await bundledData(this.test.currentRetry())
        const errorMessage = cachedResponses.invalidState
        assert.strictEqual(errorMessage, 'invalid-state')
      })
    })

    describe('invalid-tax_type', () => {
      it('invalid posted tax_type', async function () {
        await bundledData(this.test.currentRetry())
        const errorMessage = cachedResponses.invalidTaxType
        assert.strictEqual(errorMessage, 'invalid-tax_type')
      })
    })
  })

  describe('receives', () => {
    it('required posted display_name', async function () {
      const taxRate = cachedResponses.returns
      assert.strictEqual(taxRate.stripeObject.display_name, 'GST (US)')
    })

    it('required posted percentage', async function () {
      const taxRate = cachedResponses.returns
      assert.strictEqual(taxRate.stripeObject.percentage, 12.5)
    })

    it('required posted inclusive', async function () {
      const taxRate = cachedResponses.returns
      assert.strictEqual(taxRate.stripeObject.inclusive, true)
    })

    it('optional posted tax_type', async function () {
      const taxRate = cachedResponses.returns
      assert.strictEqual(taxRate.stripeObject.tax_type, 'sales_tax')
    })

    it('optional posted description', async function () {
      const taxRate = cachedResponses.returns
      assert.strictEqual(taxRate.stripeObject.description, 'Sales tax in NY')
    })

    it('optional posted jurisdiction', async function () {
      const taxRate = cachedResponses.returns
      assert.strictEqual(taxRate.stripeObject.jurisdiction, 'US')
    })

    it('optional posted state', async function () {
      const taxRate = cachedResponses.returns
      assert.strictEqual(taxRate.stripeObject.state, 'NY')
    })

    it('optional posted country', async function () {
      const taxRate = cachedResponses.returns
      assert.strictEqual(taxRate.stripeObject.country, 'US')
    })
  })

  describe('returns', () => {
    it('object', async () => {
      const taxRate = cachedResponses.returns
      assert.strictEqual(taxRate.object, 'taxrate')
    })
  })
})