@fantastic.dev/better-stripe 0.28.1 → 0.28.2
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/CHANGELOG.md +6 -0
- package/README.md +1 -1
- package/dist/react/workflows/payout-progress-state.d.ts.map +1 -1
- package/dist/react/workflows/payout-progress-state.js +7 -6
- package/dist/react/workflows/payout-progress-state.js.map +1 -1
- package/docs/react-workflows.md +6 -1
- package/package.json +1 -1
- package/src/client/payoutPolicy.test.ts +34 -0
- package/src/react/workflows/PayoutProgress.test.tsx +40 -5
- package/src/react/workflows/payout-progress-state.ts +7 -5
package/CHANGELOG.md
CHANGED
|
@@ -26,6 +26,12 @@
|
|
|
26
26
|
- Remove internal tracker references from public documentation and add a
|
|
27
27
|
regression check that prevents their reintroduction.
|
|
28
28
|
|
|
29
|
+
## [0.28.2](https://github.com/FantasticDevHQ/better-stripe/compare/v0.28.1...v0.28.2) (2026-10-15)
|
|
30
|
+
|
|
31
|
+
### Bug Fixes
|
|
32
|
+
|
|
33
|
+
- **react:** keep payout policy activation unverified until confirmed ([#212](https://github.com/FantasticDevHQ/better-stripe/issues/212)) ([9bf310f](https://github.com/FantasticDevHQ/better-stripe/commit/9bf310f28bd2e690a1f1543b4e15569196b3ba5e))
|
|
34
|
+
|
|
29
35
|
## [0.28.1](https://github.com/FantasticDevHQ/better-stripe/compare/v0.28.0...v0.28.1) (2026-10-15)
|
|
30
36
|
|
|
31
37
|
### Bug Fixes
|
package/README.md
CHANGED
|
@@ -70,7 +70,7 @@ claim execution are completed.
|
|
|
70
70
|
|
|
71
71
|
## Status
|
|
72
72
|
|
|
73
|
-
**Version**: `0.28.
|
|
73
|
+
**Version**: `0.28.2` <!-- x-release-please-version --> (pre-1.0). API may change between minor versions until 1.0.
|
|
74
74
|
|
|
75
75
|
Used in production by its authors. Webhook pipeline is covered by unit tests and a live E2E harness (`npm run e2e:webhooks`) that fires real Stripe-signed events and asserts the ledger.
|
|
76
76
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payout-progress-state.d.ts","sourceRoot":"","sources":["../../../src/react/workflows/payout-progress-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAEhF,MAAM,MAAM,oBAAoB,GAAG;IACjC,GAAG,EACC,YAAY,GACZ,SAAS,GACT,SAAS,GACT,UAAU,GACV,MAAM,GACN,aAAa,GACb,SAAS,GACT,UAAU,GACV,UAAU,GACV,UAAU,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AACF,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EACJ,SAAS,GAAG,gBAAgB,GAAG,UAAU,GAAG,aAAa,GAAG,UAAU,CAAC;IACzE,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,oBAAoB,EAAE,CAAC;IAChC,UAAU,CAAC,EAAE,WAAW,CACtB,OAAO,CAAC,aAAa,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,YAAY,CAAC,CAC3D,CAAC;IACF,OAAO,EAAE;QACP,IAAI,EAAE,OAAO,GAAG,WAAW,GAAG,OAAO,CAAC;QACtC,YAAY,EAAE,MAAM,CAAC;QACrB,cAAc,EAAE,MAAM,CAAC;QACvB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,EAAE,CAAC;IACJ,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAChD,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,CAAC;AACF,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EACF,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,QAAQ,GAAG,YAAY,GAAG,cAAc,CAAC,GACrE,IAAI,GACJ,SAAS,CAAC;IACd,OAAO,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,SAAS,CAAC;CACtD,CAAC;
|
|
1
|
+
{"version":3,"file":"payout-progress-state.d.ts","sourceRoot":"","sources":["../../../src/react/workflows/payout-progress-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAEhF,MAAM,MAAM,oBAAoB,GAAG;IACjC,GAAG,EACC,YAAY,GACZ,SAAS,GACT,SAAS,GACT,UAAU,GACV,MAAM,GACN,aAAa,GACb,SAAS,GACT,UAAU,GACV,UAAU,GACV,UAAU,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AACF,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EACJ,SAAS,GAAG,gBAAgB,GAAG,UAAU,GAAG,aAAa,GAAG,UAAU,CAAC;IACzE,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,oBAAoB,EAAE,CAAC;IAChC,UAAU,CAAC,EAAE,WAAW,CACtB,OAAO,CAAC,aAAa,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,YAAY,CAAC,CAC3D,CAAC;IACF,OAAO,EAAE;QACP,IAAI,EAAE,OAAO,GAAG,WAAW,GAAG,OAAO,CAAC;QACtC,YAAY,EAAE,MAAM,CAAC;QACrB,cAAc,EAAE,MAAM,CAAC;QACvB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,EAAE,CAAC;IACJ,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAChD,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,CAAC;AACF,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EACF,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,QAAQ,GAAG,YAAY,GAAG,cAAc,CAAC,GACrE,IAAI,GACJ,SAAS,CAAC;IACd,OAAO,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,SAAS,CAAC;CACtD,CAAC;AAqBF,wBAAgB,mBAAmB,CAAC,EAClC,MAAM,EACN,OAAO,EACP,QAAQ,EACR,aAAa,EACb,MAAgB,GACjB,EAAE,mBAAmB,GAAG,mBAAmB,CAkH3C"}
|
|
@@ -7,6 +7,7 @@ const reasons = {
|
|
|
7
7
|
pending_claim: "An existing payout is being reconciled before another payout can qualify.",
|
|
8
8
|
payout_unidentified: "A previous payout outcome needs reconciliation. No replacement payout will be created blindly.",
|
|
9
9
|
observations_stale: "Provider observations expired. Refresh the assessment.",
|
|
10
|
+
expired: "The custom holding deadline has passed. Eligibility is unavailable until the payout schedule is restored and verified.",
|
|
10
11
|
snapshot_limit: "This account needs continued history reconciliation before eligibility can be assessed.",
|
|
11
12
|
policy_changed: "Payout settings changed. Refresh the assessment.",
|
|
12
13
|
};
|
|
@@ -25,16 +26,16 @@ export function payoutProgressState({ policy, preview, currency, nextAttemptAt,
|
|
|
25
26
|
observedAt: null,
|
|
26
27
|
};
|
|
27
28
|
if (policy !== undefined) {
|
|
28
|
-
if (
|
|
29
|
-
state.status = "stripe_managed";
|
|
30
|
-
state.message =
|
|
31
|
-
"Stripe manages automatic payouts. No additional application minimum is set.";
|
|
32
|
-
}
|
|
33
|
-
else if (policy.status === "changing") {
|
|
29
|
+
if (policy?.status === "changing") {
|
|
34
30
|
state.status = "changing";
|
|
35
31
|
state.message =
|
|
36
32
|
"Payout settings are being verified. Eligibility is unavailable until the change completes.";
|
|
37
33
|
}
|
|
34
|
+
else if (!policy || policy.mode === "stripe_managed") {
|
|
35
|
+
state.status = "stripe_managed";
|
|
36
|
+
state.message =
|
|
37
|
+
"Stripe manages automatic payouts. No additional application minimum is set.";
|
|
38
|
+
}
|
|
38
39
|
else if (preview !== undefined) {
|
|
39
40
|
state.nextAttemptAt = nextAttemptAt ?? null;
|
|
40
41
|
if (!preview || !("currency" in preview)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payout-progress-state.js","sourceRoot":"","sources":["../../../src/react/workflows/payout-progress-state.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AA0DtD,MAAM,OAAO,GAA2B;IACtC,eAAe,EACb,iFAAiF;IACnF,sBAAsB,EACpB,gGAAgG;IAClG,0BAA0B,EACxB,4EAA4E;IAC9E,mBAAmB,EACjB,0FAA0F;IAC5F,aAAa,EACX,2EAA2E;IAC7E,mBAAmB,EACjB,gGAAgG;IAClG,kBAAkB,EAAE,wDAAwD;IAC5E,cAAc,EACZ,yFAAyF;IAC3F,cAAc,EAAE,kDAAkD;CACnE,CAAC;AACF,MAAM,UAAU,mBAAmB,CAAC,EAClC,MAAM,EACN,OAAO,EACP,QAAQ,EACR,aAAa,EACb,MAAM,GAAG,OAAO,GACI;IACpB,MAAM,MAAM,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IACvE,MAAM,KAAK,GAAwB;QACjC,MAAM,EAAE,SAAS;QACjB,QAAQ;QACR,MAAM,EAAE,IAAI;QACZ,OAAO,EAAE,6BAA6B;QACtC,OAAO,EAAE,EAAE;QACX,OAAO,EAAE,EAAE;QACX,QAAQ,EAAE,IAAI;QACd,aAAa,EAAE,IAAI;QACnB,YAAY,EACV,MAAM,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI;QAClE,UAAU,EAAE,IAAI;KACjB,CAAC;IACF,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,IAAI,
|
|
1
|
+
{"version":3,"file":"payout-progress-state.js","sourceRoot":"","sources":["../../../src/react/workflows/payout-progress-state.ts"],"names":[],"mappings":"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"}
|
package/docs/react-workflows.md
CHANGED
|
@@ -677,7 +677,12 @@ fields. They are never inferred from the current Stripe available balance.
|
|
|
677
677
|
|
|
678
678
|
`policy={undefined}` means loading. A null policy or `stripe_managed` mode shows
|
|
679
679
|
Stripe-managed defaults without inventing a numeric provider floor. Changing
|
|
680
|
-
policies suppress prior financial progress
|
|
680
|
+
policies suppress prior financial progress during activation, opt-out and expiry
|
|
681
|
+
restoration. A policy preserves its prior mode until confirmation, so mode alone
|
|
682
|
+
does not establish verified controls while status is `changing`.
|
|
683
|
+
An expired assessment explains the holding deadline and withholds financial
|
|
684
|
+
progress until the schedule is restored and verified.
|
|
685
|
+
For a ready custom policy, an
|
|
681
686
|
undefined preview means loading; a null or minimal held preview shows an
|
|
682
687
|
unavailable assessment rather than fabricated zero balances. A mismatched
|
|
683
688
|
currency or configured minimum rejects the display.
|
package/package.json
CHANGED
|
@@ -242,6 +242,40 @@ it("restores original settings at the holding deadline, without extending it", a
|
|
|
242
242
|
expect((await client.get(ctx, scope))!.mode).toBe("stripe_managed");
|
|
243
243
|
expect(provider.balanceSettings.update).toHaveBeenCalledTimes(2);
|
|
244
244
|
});
|
|
245
|
+
it("retains pending expiry restoration and retries the same provider operation", async () => {
|
|
246
|
+
const { client, ctx, t, provider } = await setup();
|
|
247
|
+
await client.prepare(ctx, options);
|
|
248
|
+
await client.apply(ctx, { ...scope, operationKey: "enable" });
|
|
249
|
+
await t.run(async (c) => {
|
|
250
|
+
const p = await c.db.query("payoutPolicies").first();
|
|
251
|
+
await c.db.patch(p!._id, { holdDeadline: Date.now() - 1 });
|
|
252
|
+
});
|
|
253
|
+
provider.balanceSettings.update.mockRejectedValueOnce(
|
|
254
|
+
new Error("restoration timeout"),
|
|
255
|
+
);
|
|
256
|
+
await expect(client.expire(ctx, scope)).rejects.toThrow(
|
|
257
|
+
"restoration timeout",
|
|
258
|
+
);
|
|
259
|
+
const pending = await client.get(ctx, scope);
|
|
260
|
+
expect(pending).toMatchObject({
|
|
261
|
+
mode: "custom",
|
|
262
|
+
status: "changing",
|
|
263
|
+
previousSchedule: { interval: "weekly", weeklyDays: ["monday"] },
|
|
264
|
+
});
|
|
265
|
+
expect(pending!.holdDeadline).toBeLessThan(Date.now());
|
|
266
|
+
await client.expire(ctx, scope);
|
|
267
|
+
expect(await client.get(ctx, scope)).toMatchObject({
|
|
268
|
+
mode: "stripe_managed",
|
|
269
|
+
status: "ready",
|
|
270
|
+
});
|
|
271
|
+
expect(provider.balanceSettings.update).toHaveBeenCalledTimes(3);
|
|
272
|
+
expect(provider.balanceSettings.update.mock.calls[1][1]).toEqual(
|
|
273
|
+
provider.balanceSettings.update.mock.calls[2][1],
|
|
274
|
+
);
|
|
275
|
+
expect(
|
|
276
|
+
(await provider.balanceSettings.retrieve()).payments.payouts.schedule,
|
|
277
|
+
).toMatchObject({ interval: "weekly", weekly_payout_days: ["monday"] });
|
|
278
|
+
});
|
|
245
279
|
it("re-checks live control on every payout-policy verification", async () => {
|
|
246
280
|
const { client, ctx, setSchedule } = await setup();
|
|
247
281
|
await client.prepare(ctx, options);
|
|
@@ -90,6 +90,20 @@ it("shows verified carry forward, withholding, in-flight and paid totals separat
|
|
|
90
90
|
expect(screen.getByRole("columnheader", { name: "Paid out" })).toBeTruthy();
|
|
91
91
|
expect(screen.getByRole("columnheader", { name: "In flight" })).toBeTruthy();
|
|
92
92
|
});
|
|
93
|
+
it("explains an expired holding deadline without inventing a payable balance", () => {
|
|
94
|
+
render(
|
|
95
|
+
<PayoutProgress
|
|
96
|
+
policy={policy}
|
|
97
|
+
currency="usd"
|
|
98
|
+
preview={{ status: "held", reason: "expired", amount: 0 }}
|
|
99
|
+
/>,
|
|
100
|
+
);
|
|
101
|
+
expect(screen.getByRole("status").textContent).toContain(
|
|
102
|
+
"holding deadline has passed",
|
|
103
|
+
);
|
|
104
|
+
expect(screen.queryByRole("progressbar")).toBeNull();
|
|
105
|
+
expect(screen.queryByText("$0.00")).toBeNull();
|
|
106
|
+
});
|
|
93
107
|
it("does not invent new accounting totals for a legacy assessment", () => {
|
|
94
108
|
render(<PayoutProgress policy={policy} preview={preview} currency="usd" />);
|
|
95
109
|
expect(screen.queryByText("Carried forward")).toBeNull();
|
|
@@ -103,16 +117,37 @@ it("keeps Stripe-managed defaults distinct from a custom application minimum", (
|
|
|
103
117
|
expect(screen.queryByRole("progressbar")).toBeNull();
|
|
104
118
|
expect(screen.queryByText("$1.00")).toBeNull();
|
|
105
119
|
});
|
|
106
|
-
it("
|
|
120
|
+
it.each(["custom", "stripe_managed"] as const)(
|
|
121
|
+
"keeps %s mode unverified while the schedule change is pending",
|
|
122
|
+
(mode) => {
|
|
123
|
+
render(
|
|
124
|
+
<PayoutProgress
|
|
125
|
+
policy={{ ...policy, mode, status: "changing" }}
|
|
126
|
+
preview={preview}
|
|
127
|
+
currency="usd"
|
|
128
|
+
/>,
|
|
129
|
+
);
|
|
130
|
+
expect(screen.getByRole("status").textContent).toContain("being verified");
|
|
131
|
+
expect(screen.queryByRole("progressbar")).toBeNull();
|
|
132
|
+
expect(screen.queryByText(/Stripe manages automatic payouts/)).toBeNull();
|
|
133
|
+
expect(screen.queryByText("Combined qualifying balance")).toBeNull();
|
|
134
|
+
},
|
|
135
|
+
);
|
|
136
|
+
it("gives host cards an unverified state during activation from Stripe-managed defaults", () => {
|
|
107
137
|
render(
|
|
108
138
|
<PayoutProgress
|
|
109
|
-
policy={{ ...policy, status: "changing" }}
|
|
139
|
+
policy={{ ...policy, mode: "stripe_managed", status: "changing" }}
|
|
110
140
|
preview={preview}
|
|
111
141
|
currency="usd"
|
|
112
|
-
|
|
142
|
+
>
|
|
143
|
+
{(state) => (
|
|
144
|
+
<span data-testid="restoration">
|
|
145
|
+
{state.status}:{state.metrics.length}
|
|
146
|
+
</span>
|
|
147
|
+
)}
|
|
148
|
+
</PayoutProgress>,
|
|
113
149
|
);
|
|
114
|
-
expect(screen.
|
|
115
|
-
expect(screen.queryByRole("progressbar")).toBeNull();
|
|
150
|
+
expect(screen.getByTestId("restoration").textContent).toBe("changing:0");
|
|
116
151
|
});
|
|
117
152
|
it("preserves negative entitlement while clamping only the visual progress", () => {
|
|
118
153
|
render(
|
|
@@ -72,6 +72,8 @@ const reasons: Record<string, string> = {
|
|
|
72
72
|
payout_unidentified:
|
|
73
73
|
"A previous payout outcome needs reconciliation. No replacement payout will be created blindly.",
|
|
74
74
|
observations_stale: "Provider observations expired. Refresh the assessment.",
|
|
75
|
+
expired:
|
|
76
|
+
"The custom holding deadline has passed. Eligibility is unavailable until the payout schedule is restored and verified.",
|
|
75
77
|
snapshot_limit:
|
|
76
78
|
"This account needs continued history reconciliation before eligibility can be assessed.",
|
|
77
79
|
policy_changed: "Payout settings changed. Refresh the assessment.",
|
|
@@ -98,14 +100,14 @@ export function payoutProgressState({
|
|
|
98
100
|
observedAt: null,
|
|
99
101
|
};
|
|
100
102
|
if (policy !== undefined) {
|
|
101
|
-
if (
|
|
102
|
-
state.status = "stripe_managed";
|
|
103
|
-
state.message =
|
|
104
|
-
"Stripe manages automatic payouts. No additional application minimum is set.";
|
|
105
|
-
} else if (policy.status === "changing") {
|
|
103
|
+
if (policy?.status === "changing") {
|
|
106
104
|
state.status = "changing";
|
|
107
105
|
state.message =
|
|
108
106
|
"Payout settings are being verified. Eligibility is unavailable until the change completes.";
|
|
107
|
+
} else if (!policy || policy.mode === "stripe_managed") {
|
|
108
|
+
state.status = "stripe_managed";
|
|
109
|
+
state.message =
|
|
110
|
+
"Stripe manages automatic payouts. No additional application minimum is set.";
|
|
109
111
|
} else if (preview !== undefined) {
|
|
110
112
|
state.nextAttemptAt = nextAttemptAt ?? null;
|
|
111
113
|
if (!preview || !("currency" in preview)) {
|