@happyvertical/accounting 0.100.3 → 0.101.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.
- package/README.md +81 -2
- package/dist/chunks/{OAuthClient-CF65pAW_.js → OAuthClient-x9rUYj0b.js} +2 -2
- package/dist/chunks/{OAuthClient-CF65pAW_.js.map → OAuthClient-x9rUYj0b.js.map} +1 -1
- package/dist/chunks/{errors-Dt7tUtsB.js → errors-BHWEFjkq.js} +20 -2
- package/dist/chunks/{errors-Dt7tUtsB.js.map → errors-BHWEFjkq.js.map} +1 -1
- package/dist/chunks/invoice-request-C_z10JiX.js +94 -0
- package/dist/chunks/invoice-request-C_z10JiX.js.map +1 -0
- package/dist/chunks/{quickbooks-DLkypnT9.js → quickbooks-DxvEmXav.js} +6 -50
- package/dist/chunks/{quickbooks-DLkypnT9.js.map → quickbooks-DxvEmXav.js.map} +1 -1
- package/dist/chunks/rolldown-runtime-D1cXj70v.js +46 -0
- package/dist/chunks/{stripe-Dpp7VB-7.js → stripe-CECceZH5.js} +2 -2
- package/dist/chunks/{stripe-Dpp7VB-7.js.map → stripe-CECceZH5.js.map} +1 -1
- package/dist/errors.d.ts +6 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +130 -5
- package/dist/index.js.map +1 -1
- package/dist/providers/quickbooks/invoice-request.d.ts +10 -0
- package/dist/providers/quickbooks/invoice-request.d.ts.map +1 -1
- package/dist/providers/quickbooks/oauth.d.ts +4 -0
- package/dist/providers/quickbooks/oauth.d.ts.map +1 -0
- package/dist/types.d.ts +46 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/chunks/invoice-request-D6XcgNzI.js +0 -51
- package/dist/chunks/invoice-request-D6XcgNzI.js.map +0 -1
package/README.md
CHANGED
|
@@ -2,8 +2,88 @@
|
|
|
2
2
|
|
|
3
3
|
Provider-neutral accounting synchronization with Stripe billing support.
|
|
4
4
|
|
|
5
|
+
## QuickBooks connection OAuth
|
|
6
|
+
|
|
7
|
+
Use the public connection helper to generate an accounting authorization URL,
|
|
8
|
+
exchange Intuit's callback, and revoke a refresh token:
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
import { createQuickBooksOAuthClient } from '@happyvertical/accounting';
|
|
12
|
+
|
|
13
|
+
const oauth = await createQuickBooksOAuthClient({
|
|
14
|
+
clientId: process.env.QBO_CLIENT_ID!,
|
|
15
|
+
clientSecret: process.env.QBO_CLIENT_SECRET!,
|
|
16
|
+
environment: 'sandbox',
|
|
17
|
+
redirectUri: 'https://app.example.com/api/accounting/quickbooks/callback',
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const url = oauth.authorizationUrl({ state: oneUseOpaqueState });
|
|
21
|
+
const connection = await oauth.exchangeCallback({
|
|
22
|
+
callbackUrl: request.url,
|
|
23
|
+
expectedState: oneUseOpaqueState,
|
|
24
|
+
});
|
|
25
|
+
await oauth.revoke({ refreshToken: connection.tokens.refreshToken });
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The helper requests only Intuit's QuickBooks accounting scope. Before the
|
|
29
|
+
official client receives a callback, it requires the configured origin and
|
|
30
|
+
path, exactly one nonempty state, code, and realm ID, and a constant-time state
|
|
31
|
+
match. Returned failures have stable `QuickBooksOAuthError.code` values and do
|
|
32
|
+
not retain provider errors that may contain callback URLs or credentials.
|
|
33
|
+
|
|
34
|
+
The application owns one-use state bound to its authenticated principal,
|
|
35
|
+
tenant, and environment; authorization to connect the returned realm;
|
|
36
|
+
encrypted token storage; and atomic connection persistence. The helper does
|
|
37
|
+
not make those application decisions. The redirect URI must also be registered
|
|
38
|
+
in Intuit's developer portal. See Intuit's [OAuth client authorization-code flow](https://github.com/intuit/oauth-jsclient#authorization-code-flow)
|
|
39
|
+
and [revocation helper](https://github.com/intuit/oauth-jsclient#revoke-access_token).
|
|
40
|
+
|
|
5
41
|
## QuickBooks invoice creation and retries
|
|
6
42
|
|
|
43
|
+
QuickBooks sales lines can carry explicit references to existing entities in the
|
|
44
|
+
target company:
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
const invoice = {
|
|
48
|
+
// ...provider-neutral invoice fields...
|
|
49
|
+
currency: 'CAD',
|
|
50
|
+
subtotal: 100,
|
|
51
|
+
taxAmount: 5,
|
|
52
|
+
totalAmount: 105,
|
|
53
|
+
quickbooksMapping: { globalTaxCalculation: 'TaxExcluded' },
|
|
54
|
+
lineItems: [
|
|
55
|
+
{
|
|
56
|
+
description: 'Reviewed work',
|
|
57
|
+
quantity: 1,
|
|
58
|
+
unitPrice: 100,
|
|
59
|
+
quickbooksMapping: {
|
|
60
|
+
itemRef: '123', // Item.Id in this QuickBooks company
|
|
61
|
+
taxCodeRef: 'GST', // TaxCode.Id in this QuickBooks company
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
};
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The QuickBooks adapter maps these values to `SalesItemLineDetail.ItemRef`,
|
|
69
|
+
`SalesItemLineDetail.TaxCodeRef`, `GlobalTaxCalculation`, and
|
|
70
|
+
`TxnTaxDetail.TotalTax`. It supports `TaxExcluded` and zero-tax
|
|
71
|
+
`NotApplicable`; tax-inclusive inputs are rejected because the provider-neutral
|
|
72
|
+
line model does not allocate included tax. Every mapped line must supply both
|
|
73
|
+
realm-specific references. The caller must validate that those IDs belong to
|
|
74
|
+
the configured company. See Intuit's [invoice API](https://developer.intuit.com/app/developer/qbo/docs/api/accounting/most-commonly-used/invoice)
|
|
75
|
+
and [item API](https://developer.intuit.com/app/developer/qbo/docs/api/accounting/all-entities/item).
|
|
76
|
+
|
|
77
|
+
Legacy untaxed invoices without `quickbooksMapping` remain supported. The
|
|
78
|
+
adapter fails before authentication or HTTP when an input would otherwise be
|
|
79
|
+
silently discarded: nonzero line `discount`, nonzero numeric `taxRate`, generic
|
|
80
|
+
`taxCode`, `automaticTax`, inconsistent totals, partial mappings, or invalid
|
|
81
|
+
references. Explicit zero `discount` and `taxRate` are accepted. This mapping
|
|
82
|
+
API has no discount representation and does not silently net discounts into
|
|
83
|
+
prices. An explicit line `amount` must agree with `quantity × unitPrice`; the
|
|
84
|
+
adapter compares ordinary decimal calculations without assuming a fixed number
|
|
85
|
+
of decimal places for every currency.
|
|
86
|
+
|
|
7
87
|
Prepare a caller-owned request descriptor **once**, persist it with the approved
|
|
8
88
|
invoice in your durable outbox, then pass it on every create attempt:
|
|
9
89
|
|
|
@@ -76,8 +156,7 @@ The [static documentation](https://static.developer.intuit.com/output_html/qbo/d
|
|
|
76
156
|
confirms the 50-character limit and per-realm uniqueness requirement.
|
|
77
157
|
Our regression tests mock remote acceptance and response loss; they prove SDK
|
|
78
158
|
identity/byte preservation and retry policy, **not live Intuit deduplication**.
|
|
79
|
-
|
|
80
|
-
idempotency, verify in an authorized sandbox: send a uniquely identified invoice,
|
|
159
|
+
Before relying on remote idempotency, verify in an authorized sandbox: send a uniquely identified invoice,
|
|
81
160
|
repeat the identical request with the same ID, confirm the same Invoice.Id and
|
|
82
161
|
one invoice, and simulate a lost response before replaying it. Record realm,
|
|
83
162
|
environment, request ID, timestamps, and returned IDs without credentials.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as __toCommonJS, i as __require, n as __esmMin, r as __exportAll, t as __commonJSMin } from "./
|
|
1
|
+
import { a as __toCommonJS, i as __require, n as __esmMin, r as __exportAll, t as __commonJSMin } from "./rolldown-runtime-D1cXj70v.js";
|
|
2
2
|
//#region ../../node_modules/.pnpm/atob@2.1.2/node_modules/atob/browser-atob.js
|
|
3
3
|
var require_browser_atob = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
4
4
|
(function(w) {
|
|
@@ -18261,4 +18261,4 @@ var require_OAuthClient = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
18261
18261
|
//#endregion
|
|
18262
18262
|
export default require_OAuthClient();
|
|
18263
18263
|
|
|
18264
|
-
//# sourceMappingURL=OAuthClient-
|
|
18264
|
+
//# sourceMappingURL=OAuthClient-x9rUYj0b.js.map
|