@fantastic.dev/better-stripe 0.28.3 → 0.28.5
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 +12 -0
- package/README.md +5 -1
- package/dist/client/connect/payoutAdoptionTestHelpers.d.ts +102 -4
- package/dist/client/connect/payoutAdoptionTestHelpers.d.ts.map +1 -1
- package/dist/client/connect/payoutExecutionTestHelpers.d.ts +51 -2
- package/dist/client/connect/payoutExecutionTestHelpers.d.ts.map +1 -1
- package/dist/client/connect/payoutExpiry.d.ts +42 -0
- package/dist/client/connect/payoutExpiry.d.ts.map +1 -0
- package/dist/client/connect/payoutExpiry.js +93 -0
- package/dist/client/connect/payoutExpiry.js.map +1 -0
- package/dist/client/connect/payoutSyncTestHelpers.d.ts +41 -2
- package/dist/client/connect/payoutSyncTestHelpers.d.ts.map +1 -1
- package/dist/client/connect/payoutWorker.d.ts +4 -1
- package/dist/client/connect/payoutWorker.d.ts.map +1 -1
- package/dist/client/connect/payoutWorker.js +35 -1
- package/dist/client/connect/payoutWorker.js.map +1 -1
- package/dist/client/payoutPolicy.d.ts +20 -2
- package/dist/client/payoutPolicy.d.ts.map +1 -1
- package/dist/client/payoutPolicy.js +5 -25
- package/dist/client/payoutPolicy.js.map +1 -1
- package/dist/component/_generated/component.d.ts +120 -0
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/core/resetSafety.d.ts.map +1 -1
- package/dist/component/core/resetSafety.js +7 -1
- package/dist/component/core/resetSafety.js.map +1 -1
- package/dist/component/earnings/triggers.d.ts +26 -4
- package/dist/component/earnings/triggers.d.ts.map +1 -1
- package/dist/component/payoutPolicy/expiry.d.ts +78 -0
- package/dist/component/payoutPolicy/expiry.d.ts.map +1 -0
- package/dist/component/payoutPolicy/expiry.js +57 -0
- package/dist/component/payoutPolicy/expiry.js.map +1 -0
- package/dist/component/payoutPolicy/helpers.d.ts +10 -0
- package/dist/component/payoutPolicy/helpers.d.ts.map +1 -1
- package/dist/component/payoutPolicy/mutations.d.ts +77 -0
- package/dist/component/payoutPolicy/mutations.d.ts.map +1 -1
- package/dist/component/payoutPolicy/mutations.js +36 -3
- package/dist/component/payoutPolicy/mutations.js.map +1 -1
- package/dist/component/payoutPolicy/queries.d.ts +20 -0
- package/dist/component/payoutPolicy/queries.d.ts.map +1 -1
- package/dist/component/payoutPolicy/schema.d.ts +139 -2
- package/dist/component/payoutPolicy/schema.d.ts.map +1 -1
- package/dist/component/payoutPolicy/schema.js +12 -0
- package/dist/component/payoutPolicy/schema.js.map +1 -1
- package/dist/component/payoutRelease/helpers.d.ts +10 -0
- package/dist/component/payoutRelease/helpers.d.ts.map +1 -1
- package/dist/component/payoutWorker/helpers.d.ts +1 -0
- package/dist/component/payoutWorker/helpers.d.ts.map +1 -1
- package/dist/component/payoutWorker/mutations.d.ts +2 -0
- package/dist/component/payoutWorker/mutations.d.ts.map +1 -1
- package/dist/component/payoutWorker/mutations.js +3 -0
- package/dist/component/payoutWorker/mutations.js.map +1 -1
- package/dist/component/payoutWorker/queries.d.ts +22 -0
- package/dist/component/payoutWorker/queries.d.ts.map +1 -1
- package/dist/component/payoutWorker/schema.d.ts +18 -2
- package/dist/component/payoutWorker/schema.d.ts.map +1 -1
- package/dist/component/payoutWorker/schema.js +7 -0
- package/dist/component/payoutWorker/schema.js.map +1 -1
- package/dist/component/schema.d.ts +41 -2
- package/dist/react/workflows/PayoutAttemptStatus.d.ts +14 -0
- package/dist/react/workflows/PayoutAttemptStatus.d.ts.map +1 -0
- package/dist/react/workflows/PayoutAttemptStatus.js +13 -0
- package/dist/react/workflows/PayoutAttemptStatus.js.map +1 -0
- package/dist/react/workflows/PayoutProgress.d.ts.map +1 -1
- package/dist/react/workflows/PayoutProgress.js +3 -2
- package/dist/react/workflows/PayoutProgress.js.map +1 -1
- package/dist/react/workflows/index.d.ts +2 -0
- package/dist/react/workflows/index.d.ts.map +1 -1
- package/dist/react/workflows/index.js +1 -0
- package/dist/react/workflows/index.js.map +1 -1
- package/dist/react/workflows/payout-attempt-state.d.ts +9 -0
- package/dist/react/workflows/payout-attempt-state.d.ts.map +1 -0
- package/dist/react/workflows/payout-attempt-state.js +47 -0
- package/dist/react/workflows/payout-attempt-state.js.map +1 -0
- package/dist/react/workflows/payout-progress-state.d.ts +16 -2
- package/dist/react/workflows/payout-progress-state.d.ts.map +1 -1
- package/dist/react/workflows/payout-progress-state.js +37 -2
- package/dist/react/workflows/payout-progress-state.js.map +1 -1
- package/docs/react-workflows.md +30 -0
- package/docs/settlement.md +47 -3
- package/package.json +1 -1
- package/src/client/connect/payoutDeadline.test.ts +70 -0
- package/src/client/connect/payoutExpiry.ts +132 -0
- package/src/client/connect/payoutWorker.test.ts +57 -1
- package/src/client/connect/payoutWorker.ts +46 -2
- package/src/client/payoutPolicy.test.ts +196 -0
- package/src/client/payoutPolicy.ts +11 -23
- package/src/component/_generated/api.ts +2 -0
- package/src/component/_generated/component.ts +147 -0
- package/src/component/core/resetSafety.ts +49 -33
- package/src/component/payout-reset-safety.test.ts +28 -0
- package/src/component/payoutPolicy/expiry.ts +80 -0
- package/src/component/payoutPolicy/mutations.ts +47 -2
- package/src/component/payoutPolicy/schema.ts +17 -0
- package/src/component/payoutWorker/mutations.ts +3 -0
- package/src/component/payoutWorker/schema.ts +15 -0
- package/src/react/workflows/PayoutAttemptStatus.tsx +44 -0
- package/src/react/workflows/PayoutProgress.test.tsx +90 -0
- package/src/react/workflows/PayoutProgress.tsx +31 -1
- package/src/react/workflows/index.ts +6 -0
- package/src/react/workflows/payout-attempt-state.ts +70 -0
- package/src/react/workflows/payout-progress-state.ts +62 -2
|
@@ -264,3 +264,93 @@ it("explains the deadline waiver without a minimum progress bar", () => {
|
|
|
264
264
|
expect(screen.queryByRole("progressbar")).toBeNull();
|
|
265
265
|
expect(screen.getByText("Combined payout minimum")).toBeTruthy();
|
|
266
266
|
});
|
|
267
|
+
|
|
268
|
+
it("shows expiry recovery after automatic schedule restoration without claiming disbursement", () => {
|
|
269
|
+
render(
|
|
270
|
+
<PayoutProgress
|
|
271
|
+
policy={{
|
|
272
|
+
...policy,
|
|
273
|
+
mode: "stripe_managed",
|
|
274
|
+
thresholds: [],
|
|
275
|
+
holdingExpiry: {
|
|
276
|
+
deadline: policy.holdDeadline,
|
|
277
|
+
status: "balance_remaining",
|
|
278
|
+
observedAt: 1800000000000,
|
|
279
|
+
balances: [{ currency: "usd", available: 999, pending: 25 }],
|
|
280
|
+
},
|
|
281
|
+
}}
|
|
282
|
+
currency="usd"
|
|
283
|
+
/>,
|
|
284
|
+
);
|
|
285
|
+
expect(screen.getByRole("status").textContent).toContain(
|
|
286
|
+
"does not confirm disbursement",
|
|
287
|
+
);
|
|
288
|
+
expect(screen.queryByText(/Stripe manages automatic payouts/)).toBeNull();
|
|
289
|
+
expect(screen.queryByRole("progressbar")).toBeNull();
|
|
290
|
+
expect(screen.getByText("$9.99")).toBeTruthy();
|
|
291
|
+
expect(screen.getByText("$0.25")).toBeTruthy();
|
|
292
|
+
});
|
|
293
|
+
it("keeps unavailable expiry balances unverified instead of showing fabricated zero", () => {
|
|
294
|
+
render(
|
|
295
|
+
<PayoutProgress
|
|
296
|
+
policy={{
|
|
297
|
+
...policy,
|
|
298
|
+
mode: "stripe_managed",
|
|
299
|
+
holdingExpiry: { deadline: policy.holdDeadline, status: "unverified" },
|
|
300
|
+
}}
|
|
301
|
+
currency="usd"
|
|
302
|
+
/>,
|
|
303
|
+
);
|
|
304
|
+
expect(screen.getByRole("status").textContent).toContain(
|
|
305
|
+
"verification is unavailable",
|
|
306
|
+
);
|
|
307
|
+
expect(screen.queryByText("$0.00")).toBeNull();
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
it("shows a previous Stripe rejection separately from informational eligibility", () => {
|
|
311
|
+
render(
|
|
312
|
+
<PayoutProgress
|
|
313
|
+
policy={policy}
|
|
314
|
+
preview={{
|
|
315
|
+
...preview,
|
|
316
|
+
status: "qualified",
|
|
317
|
+
reason: undefined,
|
|
318
|
+
amount: 999,
|
|
319
|
+
minimumWaived: true,
|
|
320
|
+
holdDeadline: policy.holdDeadline,
|
|
321
|
+
}}
|
|
322
|
+
currency="usd"
|
|
323
|
+
lastAttempt={{
|
|
324
|
+
currency: "usd",
|
|
325
|
+
status: "rejected",
|
|
326
|
+
reason: "balance_insufficient",
|
|
327
|
+
at: 1800000000000,
|
|
328
|
+
}}
|
|
329
|
+
nextAttemptAt={1800000300000}
|
|
330
|
+
timeZone="UTC"
|
|
331
|
+
/>,
|
|
332
|
+
);
|
|
333
|
+
expect(
|
|
334
|
+
screen.getByText(
|
|
335
|
+
/Stripe rejected the payout because the available balance changed/,
|
|
336
|
+
),
|
|
337
|
+
).toBeTruthy();
|
|
338
|
+
expect(screen.getByText(/Next automatic attempt/)).toBeTruthy();
|
|
339
|
+
});
|
|
340
|
+
it("does not display an old paid result or stale retry time while a new check is running", () => {
|
|
341
|
+
render(
|
|
342
|
+
<PayoutProgress
|
|
343
|
+
policy={policy}
|
|
344
|
+
preview={preview}
|
|
345
|
+
currency="usd"
|
|
346
|
+
lastAttempt={{
|
|
347
|
+
currency: "usd",
|
|
348
|
+
status: "running",
|
|
349
|
+
reason: "pending_claim",
|
|
350
|
+
}}
|
|
351
|
+
nextAttemptAt={1800000000000}
|
|
352
|
+
/>,
|
|
353
|
+
);
|
|
354
|
+
expect(screen.getByText(/automatic payout check is running/)).toBeTruthy();
|
|
355
|
+
expect(screen.queryByText(/Next automatic attempt/)).toBeNull();
|
|
356
|
+
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import { PayoutAttemptStatus } from "./PayoutAttemptStatus.js";
|
|
2
3
|
import { useMemo } from "react";
|
|
3
4
|
import {
|
|
4
5
|
payoutProgressState,
|
|
@@ -28,7 +29,31 @@ export function PayoutProgress(props: PayoutProgressProps) {
|
|
|
28
29
|
<section className={className} data-better-stripe="payout-progress">
|
|
29
30
|
<h2>Automatic payout progress ({currency.toUpperCase()})</h2>
|
|
30
31
|
<p role="status">{state.message}</p>
|
|
32
|
+
<PayoutAttemptStatus
|
|
33
|
+
attempt={state.lastAttempt}
|
|
34
|
+
locale={locale}
|
|
35
|
+
timeZone={timeZone}
|
|
36
|
+
/>
|
|
31
37
|
<p>Stripe enforces its payout floor; a numeric amount is unavailable.</p>
|
|
38
|
+
{state.recovery?.balances && (
|
|
39
|
+
<div>
|
|
40
|
+
<h3>Stripe balances at last expiry check</h3>
|
|
41
|
+
<p>
|
|
42
|
+
Provider balances are not a payable earnings assessment. Currencies
|
|
43
|
+
remain separate.
|
|
44
|
+
</p>
|
|
45
|
+
<dl>
|
|
46
|
+
{state.recovery.balances.map((balance) => (
|
|
47
|
+
<div key={balance.currency}>
|
|
48
|
+
<dt>{balance.currency.toUpperCase()} available</dt>
|
|
49
|
+
<dd>{balance.availableLabel}</dd>
|
|
50
|
+
<dt>{balance.currency.toUpperCase()} pending</dt>
|
|
51
|
+
<dd>{balance.pendingLabel}</dd>
|
|
52
|
+
</div>
|
|
53
|
+
))}
|
|
54
|
+
</dl>
|
|
55
|
+
</div>
|
|
56
|
+
)}
|
|
32
57
|
{state.progress && (
|
|
33
58
|
<progress
|
|
34
59
|
aria-label="Combined payout minimum"
|
|
@@ -102,7 +127,12 @@ export function PayoutProgress(props: PayoutProgressProps) {
|
|
|
102
127
|
{state.holdDeadline !== null && (
|
|
103
128
|
<p>Custom holding deadline: {date(state.holdDeadline)}</p>
|
|
104
129
|
)}
|
|
105
|
-
{state.observedAt !== null &&
|
|
130
|
+
{state.observedAt !== null && (
|
|
131
|
+
<p>
|
|
132
|
+
{state.recovery ? "Last recovery check" : "Assessed"}:{" "}
|
|
133
|
+
{date(state.observedAt)}
|
|
134
|
+
</p>
|
|
135
|
+
)}
|
|
106
136
|
</section>
|
|
107
137
|
);
|
|
108
138
|
}
|
|
@@ -290,3 +290,9 @@ export type {
|
|
|
290
290
|
|
|
291
291
|
export { EvidenceUpload } from "./EvidenceUpload.js";
|
|
292
292
|
export type { EvidenceUploadProps } from "./EvidenceUpload.js";
|
|
293
|
+
|
|
294
|
+
export { PayoutAttemptStatus } from "./PayoutAttemptStatus.js";
|
|
295
|
+
export type {
|
|
296
|
+
PayoutAttemptStatusProps,
|
|
297
|
+
PayoutAttemptState,
|
|
298
|
+
} from "./PayoutAttemptStatus.js";
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { PayoutAttempt } from "../../client/connect/payoutWorker.js";
|
|
2
|
+
const messages: Record<string, string> = {
|
|
3
|
+
balance_insufficient:
|
|
4
|
+
"Stripe rejected the payout because the available balance changed. Remaining unpaid entitlement is preserved; any retry requires fresh balance verification.",
|
|
5
|
+
amount_too_small:
|
|
6
|
+
"Stripe rejected the payout below its supported minimum. A numeric provider floor is unavailable. Review payout settings promptly; holding limits still apply.",
|
|
7
|
+
worker_error:
|
|
8
|
+
"The automatic payout check could not complete. An uncertain outcome must be reconciled before another payout can be created.",
|
|
9
|
+
returned:
|
|
10
|
+
"The bank returned the payout. Returned funds will be assessed again when available.",
|
|
11
|
+
bank_destination_unavailable:
|
|
12
|
+
"Add or verify a supported payout bank account before the worker can retry.",
|
|
13
|
+
affiliate_recovery_pending:
|
|
14
|
+
"Commission recovery must settle before a new automatic payout can qualify.",
|
|
15
|
+
below_threshold:
|
|
16
|
+
"No payout was requested because the combined balance is below the application minimum.",
|
|
17
|
+
insufficient_available:
|
|
18
|
+
"No payout was requested because the supported available Stripe balance is insufficient.",
|
|
19
|
+
schedule_drift:
|
|
20
|
+
"Payout scheduling changed outside the application. Contact platform support to verify controls.",
|
|
21
|
+
snapshot_limit:
|
|
22
|
+
"History reconciliation is incomplete. No payout was requested from a partial balance.",
|
|
23
|
+
policy_inactive:
|
|
24
|
+
"The application-managed payout policy is inactive. No new application payout was requested.",
|
|
25
|
+
};
|
|
26
|
+
export type PayoutAttemptState = PayoutAttempt & {
|
|
27
|
+
message: string;
|
|
28
|
+
tone: "warning" | "neutral" | "success";
|
|
29
|
+
formattedAt?: string;
|
|
30
|
+
timeLabel?: string;
|
|
31
|
+
};
|
|
32
|
+
export function payoutAttemptState(
|
|
33
|
+
attempt: PayoutAttempt | null | undefined,
|
|
34
|
+
locale = "en-US",
|
|
35
|
+
timeZone?: string,
|
|
36
|
+
): PayoutAttemptState | undefined {
|
|
37
|
+
if (!attempt) return undefined;
|
|
38
|
+
const message =
|
|
39
|
+
attempt.status === "running"
|
|
40
|
+
? "An automatic payout check is running. Its outcome is not verified yet."
|
|
41
|
+
: attempt.status === "reconciling"
|
|
42
|
+
? "The payout outcome needs verification. The same operation will be reconciled before any new payout."
|
|
43
|
+
: attempt.status === "paid"
|
|
44
|
+
? "The latest application payout was verified as paid by Stripe."
|
|
45
|
+
: (messages[attempt.reason] ??
|
|
46
|
+
"The latest automatic payout check did not complete. Review account settings or contact platform support.");
|
|
47
|
+
return {
|
|
48
|
+
...attempt,
|
|
49
|
+
message,
|
|
50
|
+
tone:
|
|
51
|
+
attempt.status === "paid"
|
|
52
|
+
? "success"
|
|
53
|
+
: ["rejected", "failed", "reconciling"].includes(attempt.status)
|
|
54
|
+
? "warning"
|
|
55
|
+
: "neutral",
|
|
56
|
+
...(attempt.at === undefined
|
|
57
|
+
? {}
|
|
58
|
+
: {
|
|
59
|
+
formattedAt: new Intl.DateTimeFormat(locale, {
|
|
60
|
+
dateStyle: "medium",
|
|
61
|
+
timeStyle: "short",
|
|
62
|
+
timeZone,
|
|
63
|
+
}).format(attempt.at),
|
|
64
|
+
timeLabel:
|
|
65
|
+
attempt.status === "running"
|
|
66
|
+
? "Attempt started"
|
|
67
|
+
: "Result recorded",
|
|
68
|
+
}),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import {
|
|
2
|
+
payoutAttemptState,
|
|
3
|
+
type PayoutAttemptState,
|
|
4
|
+
} from "./payout-attempt-state.js";
|
|
5
|
+
import type { PayoutAttempt } from "../../client/connect/payoutWorker.js";
|
|
1
6
|
import type { ReactNode } from "react";
|
|
2
7
|
import type { PayoutPolicy, PayoutPreview } from "../../client/payoutPolicy.js";
|
|
3
8
|
import { formatPrice } from "../lib/price-helpers.js";
|
|
@@ -42,13 +47,28 @@ export type PayoutProgressState = {
|
|
|
42
47
|
nextAttemptAt: number | null;
|
|
43
48
|
holdDeadline: number | null;
|
|
44
49
|
observedAt: number | null;
|
|
50
|
+
lastAttempt?: PayoutAttemptState;
|
|
51
|
+
recovery?: {
|
|
52
|
+
status: NonNullable<PayoutPolicy["holdingExpiry"]>["status"];
|
|
53
|
+
balances?: {
|
|
54
|
+
currency: string;
|
|
55
|
+
available: number;
|
|
56
|
+
pending: number;
|
|
57
|
+
availableLabel: string;
|
|
58
|
+
pendingLabel: string;
|
|
59
|
+
}[];
|
|
60
|
+
};
|
|
45
61
|
};
|
|
46
62
|
export type PayoutProgressProps = {
|
|
47
63
|
policy:
|
|
48
|
-
| Pick<
|
|
64
|
+
| Pick<
|
|
65
|
+
PayoutPolicy,
|
|
66
|
+
"mode" | "status" | "thresholds" | "holdDeadline" | "holdingExpiry"
|
|
67
|
+
>
|
|
49
68
|
| null
|
|
50
69
|
| undefined;
|
|
51
70
|
preview?: PayoutPreview | null;
|
|
71
|
+
lastAttempt?: PayoutAttempt | null;
|
|
52
72
|
currency: string;
|
|
53
73
|
/** Application worker attempt time, never a bank arrival estimate. */
|
|
54
74
|
nextAttemptAt?: number | null;
|
|
@@ -83,8 +103,14 @@ export function payoutProgressState({
|
|
|
83
103
|
preview,
|
|
84
104
|
currency,
|
|
85
105
|
nextAttemptAt,
|
|
106
|
+
lastAttempt,
|
|
107
|
+
timeZone,
|
|
86
108
|
locale = "en-US",
|
|
87
109
|
}: PayoutProgressProps): PayoutProgressState {
|
|
110
|
+
if (lastAttempt && lastAttempt.currency !== currency)
|
|
111
|
+
throw new Error(
|
|
112
|
+
"Payout attempt currency does not match the selected currency.",
|
|
113
|
+
);
|
|
88
114
|
const amount = (value: number) => formatPrice(value, currency, locale);
|
|
89
115
|
const state: PayoutProgressState = {
|
|
90
116
|
status: "loading",
|
|
@@ -98,18 +124,52 @@ export function payoutProgressState({
|
|
|
98
124
|
holdDeadline:
|
|
99
125
|
policy?.mode === "custom" ? (policy.holdDeadline ?? null) : null,
|
|
100
126
|
observedAt: null,
|
|
127
|
+
lastAttempt:
|
|
128
|
+
policy === undefined
|
|
129
|
+
? undefined
|
|
130
|
+
: payoutAttemptState(lastAttempt, locale, timeZone),
|
|
101
131
|
};
|
|
102
132
|
if (policy !== undefined) {
|
|
103
133
|
if (policy?.status === "changing") {
|
|
104
134
|
state.status = "changing";
|
|
105
135
|
state.message =
|
|
106
136
|
"Payout settings are being verified. Eligibility is unavailable until the change completes.";
|
|
137
|
+
} else if (
|
|
138
|
+
policy?.holdingExpiry &&
|
|
139
|
+
policy.holdingExpiry.status !== "no_held_balance"
|
|
140
|
+
) {
|
|
141
|
+
const expiry = policy.holdingExpiry;
|
|
142
|
+
state.status = "unavailable";
|
|
143
|
+
state.reason = "holding_expiry_unresolved";
|
|
144
|
+
state.holdDeadline = expiry.deadline;
|
|
145
|
+
state.observedAt = expiry.observedAt ?? null;
|
|
146
|
+
state.message =
|
|
147
|
+
"The holding deadline has passed. Schedule restoration does not confirm disbursement. " +
|
|
148
|
+
(expiry.status === "unverified"
|
|
149
|
+
? "Stripe balance verification is unavailable. "
|
|
150
|
+
: "Stripe balances or payout claims still require recovery. ") +
|
|
151
|
+
"Contact platform support; automatic recovery checks will retry.";
|
|
152
|
+
state.recovery = {
|
|
153
|
+
status: expiry.status,
|
|
154
|
+
...(expiry.balances
|
|
155
|
+
? {
|
|
156
|
+
balances: expiry.balances.map((b) => ({
|
|
157
|
+
...b,
|
|
158
|
+
availableLabel: formatPrice(b.available, b.currency, locale),
|
|
159
|
+
pendingLabel: formatPrice(b.pending, b.currency, locale),
|
|
160
|
+
})),
|
|
161
|
+
}
|
|
162
|
+
: {}),
|
|
163
|
+
};
|
|
107
164
|
} else if (!policy || policy.mode === "stripe_managed") {
|
|
108
165
|
state.status = "stripe_managed";
|
|
109
166
|
state.message =
|
|
110
167
|
"Stripe manages automatic payouts. No additional application minimum is set.";
|
|
111
168
|
} else if (preview !== undefined) {
|
|
112
|
-
state.nextAttemptAt =
|
|
169
|
+
state.nextAttemptAt =
|
|
170
|
+
state.lastAttempt?.status === "running"
|
|
171
|
+
? null
|
|
172
|
+
: (nextAttemptAt ?? null);
|
|
113
173
|
if (!preview || !("currency" in preview)) {
|
|
114
174
|
state.status = "unavailable";
|
|
115
175
|
state.reason = preview?.reason ?? "assessment_unavailable";
|