@fantastic.dev/better-stripe 0.14.0 → 0.16.0

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.
Files changed (138) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/MIGRATION.md +6 -0
  3. package/README.md +40 -1
  4. package/dist/client/billing/checkoutOptions.d.ts +27 -0
  5. package/dist/client/billing/checkoutOptions.d.ts.map +1 -0
  6. package/dist/client/billing/checkoutOptions.js +2 -0
  7. package/dist/client/billing/checkoutOptions.js.map +1 -0
  8. package/dist/client/billing/intents.d.ts +32 -0
  9. package/dist/client/billing/intents.d.ts.map +1 -0
  10. package/dist/client/billing/intents.js +71 -0
  11. package/dist/client/billing/intents.js.map +1 -0
  12. package/dist/client/connect/payoutSnapshot.d.ts +2 -0
  13. package/dist/client/connect/payoutSnapshot.d.ts.map +1 -1
  14. package/dist/client/connect/payoutSnapshot.js +2 -0
  15. package/dist/client/connect/payoutSnapshot.js.map +1 -1
  16. package/dist/client/core/fees.d.ts +2 -0
  17. package/dist/client/core/fees.d.ts.map +1 -1
  18. package/dist/client/core/fees.js +7 -0
  19. package/dist/client/core/fees.js.map +1 -1
  20. package/dist/client/index.d.ts +18 -26
  21. package/dist/client/index.d.ts.map +1 -1
  22. package/dist/client/index.js +18 -16
  23. package/dist/client/index.js.map +1 -1
  24. package/dist/client/readContracts.d.ts +50 -0
  25. package/dist/client/readContracts.d.ts.map +1 -0
  26. package/dist/client/readContracts.js +24 -0
  27. package/dist/client/readContracts.js.map +1 -0
  28. package/dist/client/types/documents.d.ts +2 -0
  29. package/dist/client/types/documents.d.ts.map +1 -1
  30. package/dist/client/webhooks/processors.js +2 -0
  31. package/dist/client/webhooks/processors.js.map +1 -1
  32. package/dist/component/_generated/component.d.ts +177 -0
  33. package/dist/component/_generated/component.d.ts.map +1 -1
  34. package/dist/component/connect/mutations.d.ts +2 -0
  35. package/dist/component/connect/mutations.d.ts.map +1 -1
  36. package/dist/component/connect/mutations.js +8 -8
  37. package/dist/component/connect/mutations.js.map +1 -1
  38. package/dist/component/connect/queries.d.ts +102 -2
  39. package/dist/component/connect/queries.d.ts.map +1 -1
  40. package/dist/component/connect/queries.js +88 -45
  41. package/dist/component/connect/queries.js.map +1 -1
  42. package/dist/component/connect/schema.d.ts +12 -2
  43. package/dist/component/connect/schema.d.ts.map +1 -1
  44. package/dist/component/connect/schema.js +10 -1
  45. package/dist/component/connect/schema.js.map +1 -1
  46. package/dist/component/connect/validators.d.ts +13 -2
  47. package/dist/component/connect/validators.d.ts.map +1 -1
  48. package/dist/component/connect/validators.js +4 -0
  49. package/dist/component/connect/validators.js.map +1 -1
  50. package/dist/component/earnings/legacyReads.d.ts +51 -0
  51. package/dist/component/earnings/legacyReads.d.ts.map +1 -0
  52. package/dist/component/earnings/legacyReads.js +43 -0
  53. package/dist/component/earnings/legacyReads.js.map +1 -0
  54. package/dist/component/earnings/mutations.d.ts +9 -0
  55. package/dist/component/earnings/mutations.d.ts.map +1 -0
  56. package/dist/component/earnings/mutations.js +23 -0
  57. package/dist/component/earnings/mutations.js.map +1 -0
  58. package/dist/component/earnings/reads.d.ts +14 -0
  59. package/dist/component/earnings/reads.d.ts.map +1 -0
  60. package/dist/component/earnings/reads.js +28 -0
  61. package/dist/component/earnings/reads.js.map +1 -0
  62. package/dist/component/earnings/schema.d.ts +20 -0
  63. package/dist/component/earnings/schema.d.ts.map +1 -0
  64. package/dist/component/earnings/schema.js +12 -0
  65. package/dist/component/earnings/schema.js.map +1 -0
  66. package/dist/component/earnings/triggers.d.ts +1290 -0
  67. package/dist/component/earnings/triggers.d.ts.map +1 -0
  68. package/dist/component/earnings/triggers.js +68 -0
  69. package/dist/component/earnings/triggers.js.map +1 -0
  70. package/dist/component/products/queries.d.ts +47 -0
  71. package/dist/component/products/queries.d.ts.map +1 -1
  72. package/dist/component/products/queries.js +59 -0
  73. package/dist/component/products/queries.js.map +1 -1
  74. package/dist/component/schema.d.ts +31 -2
  75. package/dist/component/schema.js +2 -0
  76. package/dist/component/schema.js.map +1 -1
  77. package/dist/react/components/EarningsSummary.d.ts +3 -1
  78. package/dist/react/components/EarningsSummary.d.ts.map +1 -1
  79. package/dist/react/components/EarningsSummary.js +3 -3
  80. package/dist/react/components/EarningsSummary.js.map +1 -1
  81. package/dist/react/hooks/useConfirmPayment.d.ts +1 -1
  82. package/dist/react/hooks/useConfirmPayment.d.ts.map +1 -1
  83. package/dist/react/hooks/useConfirmPayment.js +13 -2
  84. package/dist/react/hooks/useConfirmPayment.js.map +1 -1
  85. package/dist/react/hooks/useCurrencyEarnings.d.ts +31 -0
  86. package/dist/react/hooks/useCurrencyEarnings.d.ts.map +1 -0
  87. package/dist/react/hooks/useCurrencyEarnings.js +30 -0
  88. package/dist/react/hooks/useCurrencyEarnings.js.map +1 -0
  89. package/dist/react/index.d.ts +5 -0
  90. package/dist/react/index.d.ts.map +1 -1
  91. package/dist/react/index.js +4 -0
  92. package/dist/react/index.js.map +1 -1
  93. package/dist/react/workflows/SaveCard.d.ts +27 -0
  94. package/dist/react/workflows/SaveCard.d.ts.map +1 -0
  95. package/dist/react/workflows/SaveCard.js +56 -0
  96. package/dist/react/workflows/SaveCard.js.map +1 -0
  97. package/docs/react-workflows.md +47 -0
  98. package/docs/read-contracts.md +136 -0
  99. package/package.json +3 -2
  100. package/src/client/billing/checkoutOptions.ts +27 -0
  101. package/src/client/billing/intents.test.ts +216 -0
  102. package/src/client/billing/intents.ts +120 -0
  103. package/src/client/billing/intentsTransport.test.ts +94 -0
  104. package/src/client/connect/payoutSnapshot.test.ts +27 -0
  105. package/src/client/connect/payoutSnapshot.ts +4 -0
  106. package/src/client/core/fees.ts +8 -0
  107. package/src/client/index.ts +40 -43
  108. package/src/client/readContracts.ts +90 -0
  109. package/src/client/readPagination.test.ts +62 -0
  110. package/src/client/types/documents.ts +2 -0
  111. package/src/client/webhooks/payout-canceled.integration.test.ts +25 -0
  112. package/src/client/webhooks/processors.ts +2 -0
  113. package/src/component/_generated/api.ts +8 -0
  114. package/src/component/_generated/component.ts +201 -0
  115. package/src/component/connect/mutations.ts +8 -8
  116. package/src/component/connect/queries.ts +110 -48
  117. package/src/component/connect/schema.ts +10 -1
  118. package/src/component/connect/validators.ts +4 -0
  119. package/src/component/currency-migration.test.ts +119 -0
  120. package/src/component/currency-totals.test.ts +95 -0
  121. package/src/component/earnings/legacyReads.ts +59 -0
  122. package/src/component/earnings/mutations.ts +21 -0
  123. package/src/component/earnings/reads.ts +41 -0
  124. package/src/component/earnings/schema.ts +11 -0
  125. package/src/component/earnings/triggers.ts +91 -0
  126. package/src/component/products/queries.ts +74 -0
  127. package/src/component/public.test.ts +1 -1
  128. package/src/component/read-pagination.test.ts +193 -0
  129. package/src/component/schema.ts +2 -0
  130. package/src/react/components/EarningsSummary.tsx +5 -2
  131. package/src/react/hooks/useConfirmPayment.test.tsx +47 -0
  132. package/src/react/hooks/useConfirmPayment.ts +16 -2
  133. package/src/react/hooks/useCurrencyEarnings.test.ts +59 -0
  134. package/src/react/hooks/useCurrencyEarnings.ts +73 -0
  135. package/src/react/index.ts +15 -0
  136. package/src/react/read-contracts.render.test.tsx +20 -0
  137. package/src/react/workflows/SaveCard.test.tsx +127 -0
  138. package/src/react/workflows/SaveCard.tsx +117 -0
@@ -0,0 +1,117 @@
1
+ "use client";
2
+ import { useRef, useState, type ReactNode } from "react";
3
+ import { PaymentElement } from "@stripe/react-stripe-js";
4
+ import {
5
+ StripeProvider,
6
+ type StripeProviderProps,
7
+ } from "../components/StripeProvider.js";
8
+ import { useConfirmPayment } from "../hooks/useConfirmPayment.js";
9
+ import { useWorkflowResource } from "./useWorkflowResource.js";
10
+ import { useWorkflowAction } from "./useWorkflowAction.js";
11
+ export type SaveCardFormState = {
12
+ paymentElement: ReactNode;
13
+ consent: boolean;
14
+ setConsent: (value: boolean) => void;
15
+ submit: () => Promise<void>;
16
+ isPending: boolean;
17
+ error: string | null;
18
+ };
19
+ export type SaveCardProps = Pick<
20
+ StripeProviderProps,
21
+ "publishableKey" | "appearance"
22
+ > & {
23
+ scopeKey: string;
24
+ requestId?: string;
25
+ returnUrl: string;
26
+ /** Authenticated callback authorizes customer, records usage consent and durable request identity. */
27
+ createSetupIntent: (request: {
28
+ requestId: string;
29
+ }) => Promise<{ setupIntentId: string; clientSecret: string }>;
30
+ onSuccess?: (setupIntentId: string) => void;
31
+ renderForm?: (state: SaveCardFormState) => ReactNode;
32
+ };
33
+ /** Unstyled card setup. Host owns usage disclosures and authorization. */
34
+ export function SaveCard(props: SaveCardProps) {
35
+ return (
36
+ <SaveCardBody
37
+ key={`${props.scopeKey}:${props.requestId ?? ""}`}
38
+ {...props}
39
+ />
40
+ );
41
+ }
42
+ function SaveCardBody(props: SaveCardProps) {
43
+ const [requestId] = useState(() => props.requestId ?? crypto.randomUUID());
44
+ const state = useWorkflowResource(() =>
45
+ props.createSetupIntent({ requestId }),
46
+ );
47
+ if (state.error)
48
+ return (
49
+ <div role="alert">
50
+ {state.error}
51
+ <button type="button" onClick={state.refresh}>
52
+ Retry
53
+ </button>
54
+ </div>
55
+ );
56
+ if (!state.data || state.isLoading)
57
+ return <p role="status">Preparing card setup…</p>;
58
+ return (
59
+ <StripeProvider
60
+ publishableKey={props.publishableKey}
61
+ appearance={props.appearance}
62
+ elementsOptions={{ clientSecret: state.data.clientSecret }}
63
+ >
64
+ <SaveCardForm {...props} setupIntentId={state.data.setupIntentId} />
65
+ </StripeProvider>
66
+ );
67
+ }
68
+ function SaveCardForm(props: SaveCardProps & { setupIntentId: string }) {
69
+ const { confirmSetup, isReady, hasElements } = useConfirmPayment();
70
+ const [consent, setConsent] = useState(false);
71
+ const completed = useRef(false);
72
+ const action = useWorkflowAction(async () => {
73
+ if (completed.current) return false;
74
+ if (!consent) throw new Error("Consent is required to save this card.");
75
+ const result = await confirmSetup(props.returnUrl, "always");
76
+ if (!result.success) throw new Error(result.error);
77
+ completed.current = true;
78
+ return true;
79
+ });
80
+ const state: SaveCardFormState = {
81
+ paymentElement: <PaymentElement />,
82
+ consent,
83
+ setConsent,
84
+ submit: async () => {
85
+ const saved = await action.run();
86
+ if (saved) props.onSuccess?.(props.setupIntentId);
87
+ },
88
+ isPending:
89
+ action.isPending ||
90
+ !isReady ||
91
+ !hasElements ||
92
+ action.result !== undefined,
93
+ error: action.error,
94
+ };
95
+ if (props.renderForm) return <>{props.renderForm(state)}</>;
96
+ return (
97
+ <div>
98
+ {state.paymentElement}
99
+ <label>
100
+ <input
101
+ type="checkbox"
102
+ checked={consent}
103
+ onChange={(e) => setConsent(e.target.checked)}
104
+ />
105
+ Save this card for future payments and show it at checkout.
106
+ </label>
107
+ {state.error && <p role="alert">{state.error}</p>}
108
+ <button
109
+ type="button"
110
+ disabled={!consent || state.isPending}
111
+ onClick={() => void state.submit()}
112
+ >
113
+ Save card
114
+ </button>
115
+ </div>
116
+ );
117
+ }