Stripe Subscriptions module API explorer

/api/administrator/subscriptions/update-tax-rate (PATCH)

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

await global.api.administrator.subscriptions.UpdateTaxRate.patch(req)

Returns object

{
  "taxrateid": "txr_1LEOYCHHqepMFuCXotS7PoKr",
  "object": "taxrate",
  "stripeObject": {
    "id": "txr_1LEOYCHHqepMFuCXotS7PoKr",
    "object": "tax_rate",
    "active": true,
    "country": "US",
    "created": 1656123404,
    "description": "GST tax in KY",
    "display_name": "NY Sales Tax",
    "inclusive": true,
    "jurisdiction": "US",
    "livemode": false,
    "metadata": {},
    "percentage": 17.5,
    "state": "NY",
    "tax_type": "sales_tax"
  },
  "appid": "tests_1656123404",
  "createdAt": "2022-06-25T02:16:44.834Z",
  "updatedAt": "2022-06-25T02:16:45.186Z"
}

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 required POST
display_name string required POST
inclusive string required POST
jurisdiction string required 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-taxrateid missing querystring taxrateid
invalid querystring taxrateid

NodeJS source (view on github)

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

module.exports = {
  patch: async (req) => {
    if (!req.query || !req.query.taxrateid) {
      throw new Error('invalid-taxrateid')
    }
    const taxRate = await global.api.administrator.subscriptions.TaxRate.get(req)
    if (!taxRate) {
      throw new Error('invalid-taxrateid')
    }
    if (req.body.inclusive !== 'true' && req.body.inclusive !== 'false') {
      throw new Error('invalid-inclusive')
    }
    const updateInfo = {}
    // TODO: stripe docs say state is an optional parameter but
    // the stripe api is throwing an exception saying it cannot
    // be updated:
    // "You cannot change `state` via API once it has been set."
    // https://stripe.com/docs/api/tax_rates/update
    // TODO: stripe docs say tax_type is an optional parameter but
    // the stripe api is throwing an exception saying it cannot
    // be updated:
    // "You cannot change `tax_type` via API once it has been set."
    // https://stripe.com/docs/api/tax_rates/update
    const optionalFields = ['active', 'description', 'jurisdiction']
    for (const field of optionalFields) {
      if (!req.body[field] || !req.body[field].length) {
        throw new Error(`invalid-${field}`)
      }
      updateInfo[field] = req.body[field]
    }
    const taxRateNow = await stripeCache.execute('taxRates', 'update', req.query.taxrateid, updateInfo, req.stripeKey)
    await subscriptions.Storage.TaxRate.update({
      stripeObject: taxRateNow
    }, {
      where: {
        taxrateid: req.query.taxrateid,
        appid: req.appid || global.appid
      }
    })
    await dashboard.StorageCache.remove(req.query.taxrateid)
    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/update-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()
    await TestHelper.createTaxRate(administrator)
    const req = TestHelper.createRequest(`/api/administrator/subscriptions/update-tax-rate?taxrateid=${administrator.taxRate.taxrateid}`)
    req.account = administrator.account
    req.session = administrator.session
    req.body = {
      display_name: 'US Sales Tax',
      active: 'true',
      description: 'GST tax in KY',
      jurisdiction: 'US'
    }
    // invalid display name
    req.body.display_name = ''
    try {
      await req.patch()
    } catch (error) {
      cachedResponses.invalidDisplayName = error.message
    }
    req.body.display_name = 'US Sales TAx'
    try {
      await req.patch()
    } catch (error) {
      cachedResponses.invalidInclusive = error.message
    }
    req.body.inclusive = true
    // invalid state
    // TODO: stripe docs say state is an optional parameter but
    // the stripe api is throwing an exception saying it cannot
    // be updated:
    // "You cannot change `state` via API once it has been set."
    // https://stripe.com/docs/api/tax_rates/update
    // req.body.state = 'invalid'
    // try {
    //   await req.patch()
    // } catch (error) {
    //   cachedResponses.invalidState = error.message
    // }
    // req.body.state = 'NY'
    // invalid tax type
    // TODO: stripe docs say tax_type is an optional parameter but
    // the stripe api is throwing an exception saying it cannot
    // be updated:
    // "You cannot change `tax_type` via API once it has been set."
    // https://stripe.com/docs/api/tax_rates/update
    // req.body.tax_type = 'invalid'
    // try {
    //   await req.patch()
    // } catch (error) {
    //   cachedResponses.invalidTaxType = error.message
    // }
    req.body.tax_type = 'sales_tax'
    // good
    req.filename = __filename
    req.saveResponse = true
    cachedResponses.returns = await req.patch()
    cachedResponses.finished = true
  }

  describe('exceptions', () => {
    describe('invalid-taxrateid', () => {
      it('missing querystring taxrateid', async function () {
        const administrator = await TestHelper.createOwner()
        const req = TestHelper.createRequest('/api/administrator/subscriptions/update-tax-rate')
        req.account = administrator.account
        req.session = administrator.session
        let errorMessage
        try {
          await req.patch()
        } catch (error) {
          errorMessage = error.message
        }
        assert.strictEqual(errorMessage, 'invalid-taxrateid')
      })

      it('invalid querystring taxrateid', async function () {
        const administrator = await TestHelper.createOwner()
        const req = TestHelper.createRequest('/api/administrator/subscriptions/update-tax-rate?taxrateid=invalid')
        req.account = administrator.account
        req.session = administrator.session
        let errorMessage
        try {
          await req.patch()
        } catch (error) {
          errorMessage = error.message
        }
        assert.strictEqual(errorMessage, 'invalid-taxrateid')
      })
    })

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

    // TODO: stripe docs say state is an optional parameter but
    // the stripe api is throwing an exception saying it cannot
    // be updated:
    // "You cannot change `state` via API once it has been set."
    // https://stripe.com/docs/api/tax_rates/update
    // describe('invalid-state', () => {
    //   it('invalid posted state', async function () {
    //     await bundledData(this.test.currentRetry())
    //     const errorMessage = cachedResponses.invalidState
    //     assert.strictEqual(errorMessage, 'invalid-state')
    //   })
    // })

    // TODO: stripe docs say tax_type is an optional parameter but
    // the stripe api is throwing an exception saying it cannot
    // be updated:
    // "You cannot change `tax_type` via API once it has been set."
    // https://stripe.com/docs/api/tax_rates/update
    // 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 () {
      await bundledData(this.test.currentRetry())
      const taxRate = cachedResponses.returns
      assert.strictEqual(taxRate.stripeObject.display_name, 'NY Sales Tax')
    })

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

    // it('optional posted tax_type', async function () {
    //   await bundledData(this.test.currentRetry())
    //   const taxRate = cachedResponses.returns
    //   assert.strictEqual(taxRate.stripeObject.tax_type, 'sales_tax')
    // })

    it('required posted description', async function () {
      await bundledData(this.test.currentRetry())
      const taxRate = cachedResponses.returns
      assert.strictEqual(taxRate.stripeObject.description, 'GST tax in KY')
    })

    it('required posted jurisdiction', async function () {
      await bundledData(this.test.currentRetry())
      const taxRate = cachedResponses.returns
      assert.strictEqual(taxRate.stripeObject.jurisdiction, 'US')
    })

    // it('optional posted state', async function () {
    //   await bundledData(this.test.currentRetry())
    //   const taxRate = cachedResponses.returns
    //   assert.strictEqual(taxRate.stripeObject.state, 'NY')
    // })

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

  describe('returns', () => {
    it('object', async function () {
      await bundledData(this.test.currentRetry())
      const taxRate = cachedResponses.returns
      assert.strictEqual(taxRate.object, 'taxrate')
    })
  })
})