@movmo_app/payments 0.2.1 → 0.4.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.
- package/dist/index.cjs.js +10 -10
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +142 -0
- package/dist/index.es.js +1235 -984
- package/dist/index.es.js.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -37,6 +37,103 @@ export declare interface CardholderTokenizeData {
|
|
|
37
37
|
zip?: string;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
/**
|
|
41
|
+
* Builds an auth-aware `fetch` that the payments package (or any other
|
|
42
|
+
* consumer that registers it via `setPaymentsConfig({ fetch })`) can call.
|
|
43
|
+
* See file header for the full contract.
|
|
44
|
+
*/
|
|
45
|
+
export declare const createMovmoAuthFetch: (options: CreateMovmoAuthFetchOptions) => typeof fetch;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Auth-aware `fetch` wrapper for `@movmo_app/payments`. The package's API
|
|
49
|
+
* helpers call through `getPaymentsConfig().fetch`, bypassing whatever axios
|
|
50
|
+
* interceptor stack the consumer wires up. Without this wrapper:
|
|
51
|
+
*
|
|
52
|
+
* - Session cookie expiry → silent 401/403 (no refresh, no logout).
|
|
53
|
+
* - State-mutating endpoints → 403 because the CSRF cookie isn't echoed.
|
|
54
|
+
* - Local-dev / multi-tenant flows → missing per-request headers like
|
|
55
|
+
* `X-Movmo-Proxy-Auth` or `movmo-customer-id`.
|
|
56
|
+
*
|
|
57
|
+
* This factory replaces a ~95-line `paymentsFetch.ts` copy that was
|
|
58
|
+
* duplicated across consumer apps. The contract:
|
|
59
|
+
*
|
|
60
|
+
* 1. CSRF token from `csrfCookieName` is set on every request as
|
|
61
|
+
* `X-CSRF-Token` (matching the axios interceptor's unconditional set).
|
|
62
|
+
* 2. `extraHeaders(input, init)` is invoked per-request to allow dynamic
|
|
63
|
+
* headers (proxy-auth, customer id, etc.). Headers the caller already
|
|
64
|
+
* set on `init.headers` win — `extraHeaders` only fills gaps.
|
|
65
|
+
* 3. `credentials: 'include'` is forced so the session cookie travels.
|
|
66
|
+
* 4. On a 401/403 from a non-auth endpoint, the wrapper calls
|
|
67
|
+
* `refreshSession()` once (concurrent failures share one in-flight
|
|
68
|
+
* promise) and retries the original request. If refresh ITSELF fails,
|
|
69
|
+
* `onRefreshFailed(err)` fires so the consumer can drive a sign-out —
|
|
70
|
+
* silently swallowing here would strand the user on a broken page.
|
|
71
|
+
* Failures on the *retry* fetch are logged and the original response is
|
|
72
|
+
* returned so the SDK still sees a Response to render an error from.
|
|
73
|
+
* 5. The original fetch's network errors (offline, CORS, DNS) propagate.
|
|
74
|
+
* Only retry-path failures are caught; pre-refresh errors are left for
|
|
75
|
+
* the consumer to surface.
|
|
76
|
+
*
|
|
77
|
+
* The duplicated copies that this replaces both silently swallowed refresh
|
|
78
|
+
* failure (see review issue #1 on both PR #47 + PR #180). Making
|
|
79
|
+
* `onRefreshFailed` *required* enforces at the type level that consumers
|
|
80
|
+
* wire up a logout path.
|
|
81
|
+
*/
|
|
82
|
+
export declare interface CreateMovmoAuthFetchOptions {
|
|
83
|
+
/**
|
|
84
|
+
* Refreshes the session cookie. Called once on the first 401/403; concurrent
|
|
85
|
+
* 401/403s share the same in-flight promise. Resolved value is ignored — the
|
|
86
|
+
* wrapper only cares about success vs. rejection. Must rotate the session
|
|
87
|
+
* cookie (and CSRF cookie, if applicable) such that a retry with the same
|
|
88
|
+
* request will succeed.
|
|
89
|
+
*/
|
|
90
|
+
refreshSession: () => Promise<unknown>;
|
|
91
|
+
/**
|
|
92
|
+
* Fired when `refreshSession()` itself rejects. The consumer MUST treat this
|
|
93
|
+
* as a terminal auth failure and trigger a sign-out + redirect — otherwise
|
|
94
|
+
* the user is stranded on a broken page with `authState.isAuthenticated`
|
|
95
|
+
* still true.
|
|
96
|
+
*
|
|
97
|
+
* Receives the underlying rejection so the consumer can log it.
|
|
98
|
+
*/
|
|
99
|
+
onRefreshFailed: (error: unknown) => void;
|
|
100
|
+
/**
|
|
101
|
+
* Cookie name carrying the CSRF token. Defaults to `movmo_csrf_token`.
|
|
102
|
+
*/
|
|
103
|
+
csrfCookieName?: string;
|
|
104
|
+
/**
|
|
105
|
+
* Optional per-request header builder. Evaluated on every call (not cached)
|
|
106
|
+
* so dynamically-changing headers (e.g. `movmo-customer-id` driven by a
|
|
107
|
+
* route param) reflect the current value. Headers the caller already set
|
|
108
|
+
* on `init.headers` always win — `extraHeaders` only fills gaps.
|
|
109
|
+
*/
|
|
110
|
+
extraHeaders?: (input: RequestInfo | URL, init?: RequestInit) => Record<string, string>;
|
|
111
|
+
/**
|
|
112
|
+
* Substring used to detect requests that must NOT trigger the refresh
|
|
113
|
+
* retry — typically the auth-refresh endpoint itself, to avoid an
|
|
114
|
+
* infinite recursion when refresh returns 401. Defaults to `/v1/auth/`.
|
|
115
|
+
*/
|
|
116
|
+
authPathFragment?: string;
|
|
117
|
+
/**
|
|
118
|
+
* Underlying fetch impl. Defaults to `globalThis.fetch.bind(globalThis)`.
|
|
119
|
+
* Override only for tests or non-browser environments.
|
|
120
|
+
*/
|
|
121
|
+
baseFetch?: typeof fetch;
|
|
122
|
+
/**
|
|
123
|
+
* Cookie reader. Defaults to reading `document.cookie`. Override only in
|
|
124
|
+
* non-browser test environments — the default works in jsdom.
|
|
125
|
+
*/
|
|
126
|
+
readCookie?: (name: string) => string | null;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* The cardholder/zip subset of {@link UpdatePaymentMethodPatch} that the Edit
|
|
131
|
+
* flow (MOVMO-381) can mutate. Derived via `Pick` so it stays in sync if the
|
|
132
|
+
* editable field set grows — shared by the modal, the manager, and
|
|
133
|
+
* `useUpdatePaymentMethod` so the patch shape isn't restated in three places.
|
|
134
|
+
*/
|
|
135
|
+
declare type EditablePaymentMethodFields = Pick<UpdatePaymentMethodPatch, 'cardholderName' | 'zip'>;
|
|
136
|
+
|
|
40
137
|
export declare const getPaymentsConfig: () => InternalPaymentsConfig;
|
|
41
138
|
|
|
42
139
|
/* Excluded from this release type: InternalPaymentsConfig */
|
|
@@ -207,6 +304,22 @@ export declare interface PaymentMethodSummary {
|
|
|
207
304
|
expMonth: number;
|
|
208
305
|
expYear: number;
|
|
209
306
|
isDefault: boolean;
|
|
307
|
+
/**
|
|
308
|
+
* Which vault the row lives in. monolith-api returns this on every row
|
|
309
|
+
* post-MOVMO-381. Only `'spreedly'` rows accept cardholder/zip metadata
|
|
310
|
+
* edits — Stripe rows are immutable on those fields and the backend rejects
|
|
311
|
+
* the patch (4xx). The Edit menu item in PaymentMethodsManager is gated on
|
|
312
|
+
* this value.
|
|
313
|
+
*
|
|
314
|
+
* Optional so the UI doesn't crash on pre-MOVMO-381 monolith deployments
|
|
315
|
+
* that haven't shipped the new field yet — those rows behave as if
|
|
316
|
+
* Edit isn't available.
|
|
317
|
+
*/
|
|
318
|
+
vault?: 'stripe' | 'spreedly';
|
|
319
|
+
/** Current cardholder name (MOVMO-381). Empty/absent for legacy rows. */
|
|
320
|
+
cardholderName?: string;
|
|
321
|
+
/** Current billing ZIP (MOVMO-381). Empty/absent for legacy rows. */
|
|
322
|
+
zip?: string;
|
|
210
323
|
}
|
|
211
324
|
|
|
212
325
|
export declare interface PaymentsConfig {
|
|
@@ -230,6 +343,14 @@ export declare interface PaymentsConfig {
|
|
|
230
343
|
|
|
231
344
|
export declare const setPaymentsConfig: (config: Partial<PaymentsConfig>) => void;
|
|
232
345
|
|
|
346
|
+
export declare interface UpdatePaymentMethodPatch {
|
|
347
|
+
isDefault?: boolean;
|
|
348
|
+
/** MOVMO-381 — editable on Spreedly rows only; monolith-api rejects (4xx) Stripe rows. */
|
|
349
|
+
cardholderName?: string;
|
|
350
|
+
/** MOVMO-381 — editable on Spreedly rows only; monolith-api rejects (4xx) Stripe rows. */
|
|
351
|
+
zip?: string;
|
|
352
|
+
}
|
|
353
|
+
|
|
233
354
|
/**
|
|
234
355
|
* Calls `DELETE /v1/users/:userId/payment-methods/:methodId`.
|
|
235
356
|
*
|
|
@@ -318,6 +439,27 @@ export declare interface UseSetDefaultPaymentMethodResult {
|
|
|
318
439
|
|
|
319
440
|
export declare type UseSetDefaultPaymentMethodStatus = 'idle' | 'pending' | 'error';
|
|
320
441
|
|
|
442
|
+
/**
|
|
443
|
+
* Calls `PUT /v1/users/:userId/payment-methods/:methodId` with the
|
|
444
|
+
* cardholder-name + zip subset (MOVMO-381). The backend forwards to Spreedly
|
|
445
|
+
* for vault-backed rows and rejects the request (4xx) for Stripe-backed rows;
|
|
446
|
+
* the resulting `Error` carries the server's message so callers can surface it
|
|
447
|
+
* in the modal.
|
|
448
|
+
*
|
|
449
|
+
* Follows the same idle→pending→idle/error contract as
|
|
450
|
+
* `useSetDefaultPaymentMethod` (throws on failure so optimistic-update
|
|
451
|
+
* consumers can roll back), with a `(methodId, patch)` signature.
|
|
452
|
+
*/
|
|
453
|
+
export declare const useUpdatePaymentMethod: (userId: string) => UseUpdatePaymentMethodResult;
|
|
454
|
+
|
|
455
|
+
export declare interface UseUpdatePaymentMethodResult {
|
|
456
|
+
updatePaymentMethod: (methodId: string, patch: EditablePaymentMethodFields) => Promise<void>;
|
|
457
|
+
status: UseUpdatePaymentMethodStatus;
|
|
458
|
+
error: string | null;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
export declare type UseUpdatePaymentMethodStatus = 'idle' | 'pending' | 'error';
|
|
462
|
+
|
|
321
463
|
/**
|
|
322
464
|
* Fetches a user's saved payment methods from monolith-api.
|
|
323
465
|
*
|