Finbaze
Provide tax quoting, and automated invoice creation with Finbaze.
@finbaze/medusa
Medusa v2 plugin that connects a merchant store to Finbaze:
- Tax Module Provider — checkout tax lines via Finbaze Copy to clipboard
quoteSalesTax(profile obligations + imported products) - Product sync — Medusa variants → Finbaze products (Copy to clipboard
ProductLinkby Copy to clipboardmedusa_variant_id, HS → Copy to clipboardtaxCodesByCountry) - Order sync — Shopify-parity invoices: draft on place/update, close+send when fulfilled, historical close without send, cancel/refund credits. Invoice Copy to clipboard
numberis left empty (Finbaze assigns on close); Medusa Copy to clipboarddisplay_idgoes in Copy to clipboardreference. Amounts are converted from Medusa major units to Finbaze minor units.
Install
In your Medusa application:
12345npm install @finbaze/medusapnpm add @finbaze/medusa# or, from this monorepo during development:# npx medusa plugin:add @finbaze/medusa# pnpm exec medusa plugin:add @finbaze/medusa
Copy to clipboardmedusa-config.ts
1234567891011121314151617181920import { defineConfig } from "@medusajs/framework/utils"module.exports = defineConfig({// ...plugins: [{resolve: "@finbaze/medusa",options: {storeKey: process.env.FINBAZE_STORE_KEY || "default",// Optional — public/OSS installs use PKCE only (omit secret)clientSecret: process.env.FINBAZE_APP_CLIENT_SECRET,backendUrl: process.env.MEDUSA_BACKEND_URL,},},],modules: [{resolve: "@medusajs/medusa/tax",options: {providers: [
Then migrate:
12npx medusa db:migratepnpm exec medusa db:migrate
Assign each tax region that should use Finbaze to provider id Copy to clipboardtp_finbaze_finbaze (Medusa stores providers as Copy to clipboardtp_{identifier}_{id}).
Environment
See Copy to clipboard.env.example.
Copy to clipboardFINBAZE_API_URL, Copy to clipboardFINBAZE_WEB_BASE_URL, and Copy to clipboardFINBAZE_APP_CLIENT_ID default to production (Copy to clipboardhttps://api.platform.finbaze.com, Copy to clipboardhttps://platform.finbaze.com, Copy to clipboardfinbaze-medusa). Override only for local Finbaze or a custom client.
Variable Purpose Copy to clipboardMEDUSA_BACKEND_URL Public Medusa URL for OAuth callback Copy to clipboardFINBAZE_STORE_KEY Logical store key for link tables Copy to clipboardFINBAZE_APP_CLIENT_SECRET Optional. Only for client-credentials refresh on hosted installs
Public / open-source installs (no client secret)
OAuth uses PKCE (Copy to clipboardclient_id + Copy to clipboardcode_verifier). You do not need a published Copy to clipboardFINBAZE_APP_CLIENT_SECRET.
Minimum env:
1MEDUSA_BACKEND_URL=https://your-medusa.example.com
When the access token expires without a secret configured, reconnect via Admin (no silent client_credentials refresh).
OAuth redirect URI (seeded on Copy to clipboardfinbaze-medusa):
Copy to clipboardhttp://localhost:9000/app/finbaze/callback
(or Copy to clipboard{MEDUSA_BACKEND_URL}/app/finbaze/callback)
Admin
Open Finbaze in Medusa Admin (Copy to clipboard/app/finbaze):
- Connect Finbaze — PKCE OAuth against Copy to clipboard
{WEB}/oauth/authorize(public client: no secret) - Sync products — one Finbaze product per Medusa variant + Copy to clipboard
ProductLink(prices via Query / Pricing Module) - Import historical orders — draft/close with Copy to clipboard
send: falsewhen fulfilled - Imported invoices (Copy to clipboard
/app/finbaze/invoices) — paginated list of synced orders (Shopify-parity) - Settings (Copy to clipboard
/app/finbaze/settings) — after disconnect, Clear local DB links wipes Medusa-side Copy to clipboardProductLink/ Copy to clipboardOrderLink/ credits / cursors / connection (debug only; does not delete Finbaze data)
Product / variant mapping
Finbaze has no variant entity: each Medusa variant becomes its own Finbaze product (SKU, EAN, prices). Copy to clipboardProductLink stores both Copy to clipboardmedusa_variant_id (unique) and Copy to clipboardmedusa_product_id (tax fallback when Medusa only passes Copy to clipboardproduct_id).
Product HS metadata
On Medusa products (or variants), set metadata:
- Copy to clipboard
hs_codeor Copy to clipboardfinbaze_hs_code
On first create of each variant, the plugin calls Copy to clipboardsuggestTaxCodesForHsCode for the profile’s sell-to countries.
Tax quote contract
1234567891011121314151617query quoteSalesTax($profileId: ID!, $input: QuoteSalesTaxInput!): QuoteSalesTaxResult!input QuoteSalesTaxInput {destinationCountry: String!customerVatNumber: Stringlines: [QuoteSalesTaxLineInput!]!}input QuoteSalesTaxLineInput {externalLineId: String!productId: IDhsCode: Stringquantity: FloatunitPriceMinor: Floatcurrency: StringisShipping: Boolean}
- Auth: Copy to clipboard
sales_invoices:writefor quote; Copy to clipboardproducts:writefor product CRUD - Shipping lines are sent with Copy to clipboard
isShipping: true - Item lines map Medusa Copy to clipboard
variant_id→ Finbaze Copy to clipboardproductIdvia Copy to clipboardProductLink(tax provider falls back to Copy to clipboardproduct_idwhen variant is unavailable)
Lifecycle (orders)
Event Behavior Copy to clipboardorder.placed / Copy to clipboardorder.updated Create/update draft sales invoice (+ Copy to clipboardproductId on lines when linked) Fulfillment / completed Copy to clipboardcloseSalesInvoice(send: true) Historical import + fulfilled Close with Copy to clipboardsend: false Copy to clipboardorder.canceled Credit closed invoice / delete draft Refund Credit invoice + Copy to clipboardOrderCreditLink
Package layout
12345678integrations/medusa/src/modules/finbaze/ # FinbazeLink, ProductLink, OrderLink, OrderCreditLink, SyncCursorproviders/finbaze-tax/lib/ # finbaze-client, product-sync, order-sync, invoice-linessubscribers/api/admin/finbaze/ # status, sync, invoices listadmin/routes/finbaze/ # setup + nested Imported invoices
Development (this repo)
12345678# From the monorepo root (preferred):pnpm installpnpm --filter @finbaze/medusa run dev# Or from this package:cd integrations/medusapnpm installpnpm exec medusa plugin:develop
In the Medusa app: Copy to clipboardpnpm exec medusa plugin:add @finbaze/medusa.

