@unifiedcommerce/adapter-taxjar 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,15 @@
1
+ import { type TaxAdapter } from "@unifiedcommerce/core";
2
+ export interface TaxJarAdapterOptions {
3
+ apiKey: string;
4
+ apiBaseUrl?: string;
5
+ fromAddress?: {
6
+ country?: string;
7
+ postalCode?: string;
8
+ state?: string;
9
+ city?: string;
10
+ line1?: string;
11
+ };
12
+ fetchImpl?: typeof fetch;
13
+ }
14
+ export declare function taxjarAdapter(options: TaxJarAdapterOptions): TaxAdapter;
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEjE,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE;QACZ,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAMD,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,UAAU,CAsJvE"}
package/dist/index.js ADDED
@@ -0,0 +1,141 @@
1
+ import { Err, Ok } from "@unifiedcommerce/core";
2
+ function safeDate(date) {
3
+ return date.toISOString();
4
+ }
5
+ export function taxjarAdapter(options) {
6
+ const fetchImpl = options.fetchImpl ?? fetch;
7
+ const baseUrl = options.apiBaseUrl ?? "https://api.taxjar.com/v2";
8
+ async function post(path, payload) {
9
+ return fetchImpl(`${baseUrl}${path}`, {
10
+ method: "POST",
11
+ headers: {
12
+ authorization: `Bearer ${options.apiKey}`,
13
+ "content-type": "application/json",
14
+ },
15
+ body: JSON.stringify(payload),
16
+ });
17
+ }
18
+ async function del(path) {
19
+ return fetchImpl(`${baseUrl}${path}`, {
20
+ method: "DELETE",
21
+ headers: {
22
+ authorization: `Bearer ${options.apiKey}`,
23
+ },
24
+ });
25
+ }
26
+ return {
27
+ providerId: "taxjar",
28
+ async calculateTax(params) {
29
+ try {
30
+ const fromAddress = params.fromAddress ?? options.fromAddress;
31
+ const payload = {
32
+ from_country: fromAddress?.country,
33
+ from_zip: fromAddress?.postalCode,
34
+ from_state: fromAddress?.state,
35
+ from_city: fromAddress?.city,
36
+ from_street: fromAddress?.line1,
37
+ to_country: params.toAddress?.country,
38
+ to_zip: params.toAddress?.postalCode,
39
+ to_state: params.toAddress?.state,
40
+ to_city: params.toAddress?.city,
41
+ to_street: params.toAddress?.line1,
42
+ amount: params.lineItems.reduce((sum, lineItem) => sum + lineItem.unitPrice * lineItem.quantity - (lineItem.discount ?? 0), 0) + params.shippingAmount,
43
+ shipping: params.shippingAmount,
44
+ line_items: params.lineItems.map((lineItem) => ({
45
+ id: lineItem.id,
46
+ quantity: lineItem.quantity,
47
+ product_identifier: lineItem.entityId,
48
+ description: lineItem.description,
49
+ unit_price: lineItem.unitPrice,
50
+ discount: lineItem.discount,
51
+ product_tax_code: lineItem.productTaxCode,
52
+ })),
53
+ };
54
+ const response = await post("/taxes", payload);
55
+ if (!response.ok) {
56
+ return Err({
57
+ code: "TAX_CALCULATION_FAILED",
58
+ message: `TaxJar tax calculation failed (${response.status}).`,
59
+ });
60
+ }
61
+ const body = (await response.json());
62
+ const tax = body.tax ?? {};
63
+ return Ok({
64
+ amountToCollect: Math.round(Number(tax.amount_to_collect ?? 0)),
65
+ taxableAmount: Number(tax.taxable_amount ?? 0),
66
+ rate: Number(tax.rate ?? 0),
67
+ ...(tax.breakdown !== undefined ? { breakdown: { taxjar: tax.breakdown } } : {}),
68
+ });
69
+ }
70
+ catch (error) {
71
+ return Err({
72
+ code: "TAX_CALCULATION_FAILED",
73
+ message: error instanceof Error ? error.message : "TaxJar tax calculation failed.",
74
+ });
75
+ }
76
+ },
77
+ async reportTransaction(params) {
78
+ try {
79
+ const fromAddress = params.fromAddress ?? options.fromAddress;
80
+ const response = await post("/transactions/order", {
81
+ transaction_id: params.transactionId,
82
+ transaction_date: safeDate(params.transactionDate),
83
+ from_country: fromAddress?.country,
84
+ from_zip: fromAddress?.postalCode,
85
+ from_state: fromAddress?.state,
86
+ from_city: fromAddress?.city,
87
+ from_street: fromAddress?.line1,
88
+ to_country: params.toAddress?.country,
89
+ to_zip: params.toAddress?.postalCode,
90
+ to_state: params.toAddress?.state,
91
+ to_city: params.toAddress?.city,
92
+ to_street: params.toAddress?.line1,
93
+ amount: params.amount,
94
+ shipping: params.shipping,
95
+ sales_tax: params.salesTax,
96
+ customer_id: params.customerId,
97
+ line_items: params.lineItems.map((lineItem) => ({
98
+ id: lineItem.id,
99
+ quantity: lineItem.quantity,
100
+ product_identifier: lineItem.entityId,
101
+ description: lineItem.description,
102
+ unit_price: lineItem.unitPrice,
103
+ discount: lineItem.discount,
104
+ product_tax_code: lineItem.productTaxCode,
105
+ })),
106
+ });
107
+ if (!response.ok) {
108
+ return Err({
109
+ code: "TAX_REPORT_FAILED",
110
+ message: `TaxJar transaction report failed (${response.status}).`,
111
+ });
112
+ }
113
+ return Ok({ transactionId: params.transactionId });
114
+ }
115
+ catch (error) {
116
+ return Err({
117
+ code: "TAX_REPORT_FAILED",
118
+ message: error instanceof Error ? error.message : "TaxJar transaction report failed.",
119
+ });
120
+ }
121
+ },
122
+ async voidTransaction(params) {
123
+ try {
124
+ const response = await del(`/transactions/orders/${encodeURIComponent(params.transactionId)}`);
125
+ if (!response.ok) {
126
+ return Err({
127
+ code: "TAX_VOID_FAILED",
128
+ message: `TaxJar transaction void failed (${response.status}).`,
129
+ });
130
+ }
131
+ return Ok({ transactionId: params.transactionId });
132
+ }
133
+ catch (error) {
134
+ return Err({
135
+ code: "TAX_VOID_FAILED",
136
+ message: error instanceof Error ? error.message : "TaxJar transaction void failed.",
137
+ });
138
+ }
139
+ },
140
+ };
141
+ }