@zkp2p/pay-shared 1.0.0 → 3.0.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/rails.js CHANGED
@@ -51,18 +51,49 @@ export const DEFAULT_FIAT_RAILS = [
51
51
  export const SUPPORTED_RAILS = Object.values(SupportedRail);
52
52
  export const SUPPORTED_RELAY_RAILS = Object.values(SupportedRelayRail);
53
53
  const SUPPORTED_RAIL_SET = new Set(SUPPORTED_RAILS);
54
- const FIAT_RAIL_DISPLAY_NAMES = {
54
+ // Globally runtime-disabled fiat rails: removed from new offers/acceptance
55
+ // everywhere isRailRuntimeEnabled / filterRuntimeEnabledRails are consumed,
56
+ // while staying recognized for historical orders. Empty by default; the API
57
+ // seeds this from the DISABLED_RAILS env at boot via setRuntimeDisabledFiatRails.
58
+ // The frontend never sets it, so the browser bundle keeps an empty (no-op) set.
59
+ let runtimeDisabledFiatRails = new Set();
60
+ export const FIAT_SUPPORTED_RAILS = [
61
+ 'venmo',
62
+ 'cashapp',
63
+ 'revolut',
64
+ 'wise',
65
+ 'zelle',
66
+ 'paypal',
67
+ 'monzo',
68
+ 'n26',
69
+ 'chime',
70
+ ];
71
+ const PAYMENT_PLATFORM_LABEL_ENTRIES = {
55
72
  [SupportedRail.VENMO]: 'Venmo',
56
73
  [SupportedRail.CASHAPP]: 'Cash App',
57
74
  [SupportedRail.REVOLUT]: 'Revolut',
75
+ [SupportedRail.WISE]: 'Wise',
58
76
  [SupportedRail.ZELLE]: 'Zelle',
59
77
  [SupportedRail.PAYPAL]: 'PayPal',
60
- [SupportedRail.WISE]: 'Wise',
61
78
  [SupportedRail.MONZO]: 'Monzo',
62
79
  [SupportedRail.N26]: 'N26',
63
80
  [SupportedRail.CHIME]: 'Chime',
64
81
  };
65
- const RELAY_CHAIN_DISPLAY_NAMES = {
82
+ export const PAYMENT_PLATFORM_LABELS = PAYMENT_PLATFORM_LABEL_ENTRIES;
83
+ export const FIAT_RAIL_DISPLAY_NAMES = PAYMENT_PLATFORM_LABEL_ENTRIES;
84
+ // Shared FE/BE minimum so queries too short for the pg_trgm trigram index are no-ops.
85
+ export const ORDER_SEARCH_MIN_QUERY_LENGTH = 3;
86
+ export function railKeysForQuery(query) {
87
+ const normalizedQuery = query.trim().toLowerCase();
88
+ if (normalizedQuery.length === 0) {
89
+ return [];
90
+ }
91
+ return Object.entries(PAYMENT_PLATFORM_LABELS)
92
+ .filter(([, label]) => label.toLowerCase().includes(normalizedQuery))
93
+ .map(([key]) => key);
94
+ }
95
+ const SUPPORTED_FIAT_RAILS = new Set(Object.keys(FIAT_RAIL_DISPLAY_NAMES));
96
+ export const RELAY_CHAIN_DISPLAY_NAMES = {
66
97
  1: 'Ethereum',
67
98
  10: 'Optimism',
68
99
  56: 'BNB Smart Chain',
@@ -75,6 +106,22 @@ const RELAY_CHAIN_DISPLAY_NAMES = {
75
106
  728126428: 'Tron',
76
107
  792703809: 'Solana',
77
108
  };
109
+ const CRYPTO_METHOD_ALIASES = [
110
+ 'crypto',
111
+ 'usdc',
112
+ 'usdt',
113
+ ...Object.values(RELAY_CHAIN_DISPLAY_NAMES).map((name) => name.toLowerCase()),
114
+ ];
115
+ /**
116
+ * Surfaces crypto-settled orders for token, chain, and "crypto" prefix queries.
117
+ */
118
+ export function isCryptoMethodQuery(query) {
119
+ const normalizedQuery = query.trim().toLowerCase();
120
+ if (normalizedQuery.length === 0) {
121
+ return false;
122
+ }
123
+ return CRYPTO_METHOD_ALIASES.some((alias) => alias.startsWith(normalizedQuery));
124
+ }
78
125
  /**
79
126
  * Normalizes a rail string into a crypto chain id.
80
127
  *
@@ -105,6 +152,45 @@ export function parseCryptoRailChainId(rail) {
105
152
  export function isSupportedRail(rail) {
106
153
  return SUPPORTED_RAIL_SET.has(rail);
107
154
  }
155
+ export function isFiatSupportedRail(rail) {
156
+ return FIAT_SUPPORTED_RAILS.includes(rail);
157
+ }
158
+ /** Returns false for rails that remain recognized but are disabled at runtime. */
159
+ export function isRailRuntimeEnabled(rail) {
160
+ const normalizedFiatRail = normalizeFiatRail(rail);
161
+ return normalizedFiatRail === null || !runtimeDisabledFiatRails.has(normalizedFiatRail);
162
+ }
163
+ /** Filters out globally disabled runtime rails while preserving caller ordering. */
164
+ export function filterRuntimeEnabledRails(rails) {
165
+ return rails.filter((rail) => isRailRuntimeEnabled(rail));
166
+ }
167
+ /**
168
+ * Replaces the set of globally runtime-disabled fiat rails. Only EXACT base
169
+ * fiat rails are honored (e.g. `venmo`, `paypal`, `zelle`); rail variants
170
+ * (e.g. `zelle-chase`, or an env typo like `paypal-test`), crypto/relay rails,
171
+ * and unknown strings are ignored so a malformed env value cannot silently
172
+ * disable a live rail. Disable is base-granular: disabling `zelle` also
173
+ * disables its variants at check time (isRailRuntimeEnabled normalizes the
174
+ * checked rail to its base). Backend-only: the API applies the `DISABLED_RAILS`
175
+ * env at boot; the frontend never calls this, so its disabled set stays empty.
176
+ */
177
+ export function setRuntimeDisabledFiatRails(rails) {
178
+ const next = new Set();
179
+ for (const rail of rails) {
180
+ if (typeof rail !== 'string') {
181
+ continue;
182
+ }
183
+ const normalized = rail.trim().toLowerCase();
184
+ if (isFiatSupportedRail(normalized)) {
185
+ next.add(normalized);
186
+ }
187
+ }
188
+ runtimeDisabledFiatRails = next;
189
+ }
190
+ /** Returns the currently runtime-disabled fiat rails (canonical base rails). */
191
+ export function getRuntimeDisabledFiatRails() {
192
+ return [...runtimeDisabledFiatRails];
193
+ }
108
194
  /** Returns true when the rail targets a crypto chain (legacy numeric or relay-prefixed format). */
109
195
  export function isCryptoRail(rail) {
110
196
  return parseCryptoRailChainId(rail) !== null;
@@ -121,6 +207,97 @@ export function normalizeCryptoRail(rail) {
121
207
  const chainId = parseCryptoRailChainId(rail);
122
208
  return chainId === null ? null : formatRelayRail(chainId);
123
209
  }
210
+ /** Returns the canonical base fiat rail for base rails and supported variants such as `zelle-chase`. */
211
+ export function normalizeFiatRail(rail) {
212
+ if (typeof rail !== 'string') {
213
+ return null;
214
+ }
215
+ const trimmed = rail.trim().toLowerCase();
216
+ if (trimmed === '') {
217
+ return null;
218
+ }
219
+ if (SUPPORTED_FIAT_RAILS.has(trimmed)) {
220
+ return trimmed;
221
+ }
222
+ for (const baseRail of SUPPORTED_FIAT_RAILS) {
223
+ if (trimmed.startsWith(`${baseRail}-`)) {
224
+ return baseRail;
225
+ }
226
+ }
227
+ return null;
228
+ }
229
+ /**
230
+ * Fiat rails that support Seller Automated Release (SAR). Merchants in
231
+ * EXCLUSIVE_SAR mode may only offer these rails; every other fiat rail is
232
+ * force-disabled in the merchant and admin dashboards.
233
+ */
234
+ export const SAR_SUPPORTED_FIAT_RAILS = ['venmo', 'cashapp', 'wise', 'paypal'];
235
+ const SAR_SUPPORTED_FIAT_RAIL_SET = new Set(SAR_SUPPORTED_FIAT_RAILS);
236
+ /** Returns true when the fiat rail (incl. variants like `zelle-chase`) supports SAR. */
237
+ export function isSarSupportedFiatRail(rail) {
238
+ const normalized = normalizeFiatRail(rail);
239
+ return normalized !== null && SAR_SUPPORTED_FIAT_RAIL_SET.has(normalized);
240
+ }
241
+ /**
242
+ * Returns `rails` with non-SAR fiat rails removed, preserving crypto/relay rails,
243
+ * SAR-supported fiat rails, and original ordering. Used to keep an EXCLUSIVE_SAR
244
+ * merchant's `enabledRails` in sync with their quote preference: non-SAR fiat
245
+ * rails (e.g. `zelle`, `revolut`, incl. variants like `zelle-chase`) are dropped
246
+ * while crypto rails and SAR rails (venmo/cashapp/wise/paypal) are kept.
247
+ */
248
+ export function filterRailsForExclusiveSar(rails) {
249
+ return rails.filter((rail) => {
250
+ const normalizedFiat = normalizeFiatRail(rail);
251
+ // Non-fiat (crypto/relay) or unrecognized rails are preserved verbatim.
252
+ if (normalizedFiat === null) {
253
+ return true;
254
+ }
255
+ // Recognized fiat rail: keep only if it supports SAR.
256
+ return SAR_SUPPORTED_FIAT_RAIL_SET.has(normalizedFiat);
257
+ });
258
+ }
259
+ /** Canonical Zelle paymentMethodId -> attestation-service actionType suffix. */
260
+ export const ZELLE_METHOD_ACTION_SUFFIX = {
261
+ 'zelle-bofa': 'bofa',
262
+ 'zelle-chase': 'chase',
263
+ 'zelle-citi': 'citi',
264
+ };
265
+ /** Strict create-boundary set for Zelle method ids and transitional variant rails. */
266
+ export const ZELLE_PAYMENT_METHOD_IDS = new Set(Object.keys(ZELLE_METHOD_ACTION_SUFFIX));
267
+ /** Bank-qualified buyer TEE action types accepted for generic Zelle proofs. */
268
+ export const ZELLE_BUYER_TEE_ACTION_TYPES = new Set(Object.values(ZELLE_METHOD_ACTION_SUFFIX).map((suffix) => `transfer_zelle_${suffix}`));
269
+ /**
270
+ * Resolves the attestation-service verifier route (`platform` + `actionType`)
271
+ * for a persisted `payment.rail` value.
272
+ *
273
+ * Zelle variants map to the new generic `zelle` platform with a bank-qualified
274
+ * actionType. Legacy bank-specific verifier routes are drain-only and should
275
+ * stay outside shared core. Non-Zelle fiat rails use the base rail as platform
276
+ * and `transfer_{rail}` as actionType. Unknown / crypto rails fall back to the
277
+ * raw trimmed rail so callers still surface a verifier mismatch via the
278
+ * attestation response rather than silently mis-routing.
279
+ */
280
+ export function resolveAttestationRoute(rail) {
281
+ const trimmed = typeof rail === 'string' ? rail.trim().toLowerCase() : '';
282
+ // TRANSITIONAL: rail-variant fold, delete after drain window.
283
+ const zelleVariantSuffix = ZELLE_METHOD_ACTION_SUFFIX[trimmed];
284
+ if (zelleVariantSuffix !== undefined) {
285
+ return { platform: 'zelle', actionType: `transfer_zelle_${zelleVariantSuffix}` };
286
+ }
287
+ const baseRail = normalizeFiatRail(trimmed) ?? trimmed;
288
+ return { platform: baseRail, actionType: `transfer_${baseRail}` };
289
+ }
290
+ /** Canonical generic Zelle on-chain method hash: keccak256("zelle"), lowercase. */
291
+ export const GENERIC_ZELLE_PAYMENT_METHOD_HASH = '0xf752c7d19698ecb0bb8988abf9b9a53a4c3657f3bc8850a6fb59fdf3e3ce8cd3';
292
+ /** Case-insensitive check that a hash is the canonical generic Zelle on-chain method hash. */
293
+ export function isGenericZellePaymentMethodHash(hash) {
294
+ return typeof hash === 'string'
295
+ && hash.trim().toLowerCase() === GENERIC_ZELLE_PAYMENT_METHOD_HASH;
296
+ }
297
+ /** True when the rail is Zelle (generic or a bank variant). */
298
+ export function isZelleRail(rail) {
299
+ return normalizeFiatRail(rail) === 'zelle';
300
+ }
124
301
  /** Formats a rail value for human-readable UI labels. */
125
302
  export function getRailDisplayName(rail) {
126
303
  if (typeof rail !== 'string') {
@@ -131,9 +308,8 @@ export function getRailDisplayName(rail) {
131
308
  return 'Unknown';
132
309
  }
133
310
  const normalized = trimmed.toLowerCase();
134
- const fiatDisplayName = FIAT_RAIL_DISPLAY_NAMES[normalized];
135
- if (fiatDisplayName) {
136
- return fiatDisplayName;
311
+ if (isFiatSupportedRail(normalized)) {
312
+ return FIAT_RAIL_DISPLAY_NAMES[normalized];
137
313
  }
138
314
  const chainId = parseCryptoRailChainId(trimmed);
139
315
  if (chainId !== null) {
package/dist/types.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { PayCryptoTokenSymbol } from './crypto.js';
2
+ import type { ProofMode } from './buyerTee.js';
2
3
  export declare const PaymentPlatform: {
3
4
  readonly VENMO: "venmo";
4
5
  readonly CASHAPP: "cashapp";
@@ -11,6 +12,11 @@ export declare const PaymentPlatform: {
11
12
  readonly CHIME: "chime";
12
13
  };
13
14
  export type PaymentPlatformType = typeof PaymentPlatform[keyof typeof PaymentPlatform];
15
+ /**
16
+ * Type guard for PaymentPlatform values.
17
+ * Returns true if `value` is one of the known PaymentPlatform enum values.
18
+ */
19
+ export declare function isPaymentPlatform(value: unknown): value is PaymentPlatformType;
14
20
  export declare const SupportedChains: Record<number, string>;
15
21
  export type SupportedChainId = keyof typeof SupportedChains;
16
22
  export declare const CheckoutMode: {
@@ -57,6 +63,13 @@ export declare const FeePayer: {
57
63
  readonly PAYEE: "PAYEE";
58
64
  };
59
65
  export type FeePayerType = typeof FeePayer[keyof typeof FeePayer];
66
+ export declare const MerchantPaymentFlowMode: {
67
+ readonly EXCLUSIVE_SAR: "EXCLUSIVE_SAR";
68
+ readonly PREFER_SAR: "PREFER_SAR";
69
+ readonly PREFER_BUYER_TEE: "PREFER_BUYER_TEE";
70
+ readonly EXCLUSIVE_BUYER_TEE: "EXCLUSIVE_BUYER_TEE";
71
+ };
72
+ export type MerchantPaymentFlowModeType = typeof MerchantPaymentFlowMode[keyof typeof MerchantPaymentFlowMode];
60
73
  export declare const CheckoutOrderStatus: {
61
74
  readonly CREATED: "CREATED";
62
75
  readonly PARTIALLY_FULFILLED: "PARTIALLY_FULFILLED";
@@ -64,6 +77,12 @@ export declare const CheckoutOrderStatus: {
64
77
  readonly CANCELLED: "CANCELLED";
65
78
  };
66
79
  export type CheckoutOrderStatusType = typeof CheckoutOrderStatus[keyof typeof CheckoutOrderStatus];
80
+ export declare const CheckoutOrderRefundStatus: {
81
+ readonly NONE: "NONE";
82
+ readonly PENDING: "PENDING";
83
+ readonly COMPLETED: "COMPLETED";
84
+ };
85
+ export type CheckoutOrderRefundStatusType = typeof CheckoutOrderRefundStatus[keyof typeof CheckoutOrderRefundStatus];
67
86
  export declare const CheckoutPaymentStatus: {
68
87
  readonly CREATED: "CREATED";
69
88
  readonly SETTLED: "SETTLED";
@@ -72,6 +91,12 @@ export declare const CheckoutPaymentStatus: {
72
91
  readonly FAILED: "FAILED";
73
92
  };
74
93
  export type CheckoutPaymentStatusType = typeof CheckoutPaymentStatus[keyof typeof CheckoutPaymentStatus];
94
+ export declare const CheckoutPaymentMemoPolicy: {
95
+ readonly NONE: "NONE";
96
+ readonly REQUIRED: "REQUIRED";
97
+ readonly EMPTY: "EMPTY";
98
+ };
99
+ export type CheckoutPaymentMemoPolicyType = typeof CheckoutPaymentMemoPolicy[keyof typeof CheckoutPaymentMemoPolicy];
75
100
  export type ReferralFeeEntry = {
76
101
  recipient: string;
77
102
  feeBps: number;
@@ -87,6 +112,7 @@ type CreateOrderRequestBase = {
87
112
  destinationChainId?: number;
88
113
  feePayer?: FeePayerType;
89
114
  enabledRails?: string[];
115
+ dynamicOrdersEnabled?: boolean;
90
116
  successUrl?: string | null;
91
117
  cancelUrl?: string | null;
92
118
  notes?: Record<string, unknown> | null;
@@ -115,6 +141,7 @@ export type MerchantCheckoutTheme = {
115
141
  buttonTextColor?: string | null;
116
142
  defaultMaxFeePercentage?: number;
117
143
  payWithCryptoEnabled?: boolean;
144
+ currencySelectorEnabled?: boolean;
118
145
  [key: string]: unknown;
119
146
  };
120
147
  export type CheckoutMerchant = {
@@ -125,11 +152,19 @@ export type CheckoutMerchant = {
125
152
  disableBranding: boolean;
126
153
  checkoutTheme: MerchantCheckoutTheme | null;
127
154
  defaultPaymentCurrency?: string | null;
155
+ /** Whether the merchant has been verified by ZKP2P. */
156
+ verified: boolean;
128
157
  };
129
158
  export type CheckoutOrder = {
130
159
  id: string;
131
160
  merchantId: string;
132
161
  status: CheckoutOrderStatusType;
162
+ refundStatus: CheckoutOrderRefundStatusType;
163
+ refundAmountUsdc: string | null;
164
+ refundDepositId: string | null;
165
+ refundTransactionHash: string | null;
166
+ refundMetadata: unknown | null;
167
+ inPersonCheckout: boolean;
133
168
  requestedUsdcAmount: string;
134
169
  remainingUsdcAmount: string;
135
170
  destinationAddress: string;
@@ -141,6 +176,11 @@ export type CheckoutOrder = {
141
176
  cancelUrl: string | null;
142
177
  notes: unknown | null;
143
178
  metadata: unknown | null;
179
+ /** Merchant-requested fiat price; non-null only for pristine, un-resized fiat-input orders. */
180
+ requestedFiat?: {
181
+ amount: string;
182
+ currency: string;
183
+ } | null;
144
184
  bridgeInfo?: OrderBridgeInfo | null;
145
185
  referralSplitConfig: ReferralSplitConfig | null;
146
186
  cancelledAt: string | null;
@@ -156,6 +196,7 @@ export type CheckoutPaymentQuote = {
156
196
  amount: string;
157
197
  toAddress: string;
158
198
  escrowAddress?: string;
199
+ orchestratorAddress?: string;
159
200
  fiatCurrencyCode?: string;
160
201
  payeeDetails: string;
161
202
  };
@@ -163,6 +204,7 @@ export type CheckoutPaymentQuote = {
163
204
  depositData: Record<string, string>;
164
205
  };
165
206
  intentHash?: string;
207
+ sellerAutomatedReleaseAvailable?: boolean;
166
208
  };
167
209
  export type CheckoutQuote = {
168
210
  displayAmount: string;
@@ -172,21 +214,45 @@ export type CheckoutQuoteEntry = {
172
214
  platform: string;
173
215
  displayAmount: string;
174
216
  spreadPercentage: number;
217
+ sellerAutomatedReleaseAvailable?: boolean;
218
+ };
219
+ export type CheckoutNearbySuggestion = {
220
+ resizeAmountUsdc: string;
221
+ paymentAmount: string;
222
+ paymentCurrency: string;
223
+ tokenAmount: string;
224
+ percentDifference: string;
225
+ rail: string;
226
+ };
227
+ export type CheckoutNearbySuggestions = {
228
+ status: 'suggestions' | 'none' | 'ineligible' | 'unavailable';
229
+ below: CheckoutNearbySuggestion[];
230
+ above: CheckoutNearbySuggestion[];
175
231
  };
176
232
  export type CheckoutQuotes = {
177
233
  orderId: string;
178
234
  fiatCurrency: string;
179
235
  platforms: CheckoutQuoteEntry[];
236
+ nearbySuggestions?: CheckoutNearbySuggestions;
180
237
  };
181
238
  export type CheckoutPayment = {
182
239
  id: string;
183
240
  orderId: string;
184
241
  status: CheckoutPaymentStatusType;
185
242
  rail: string;
243
+ paymentMethodId: string | null;
244
+ proofMode: ProofMode;
245
+ attestation: {
246
+ serviceUrl: string;
247
+ };
186
248
  currency: string;
187
249
  payTo: string;
250
+ /** Recipient rating in the 1.0–5.0 range, rounded to one decimal. */
251
+ recipientRating: number;
188
252
  quote: CheckoutPaymentQuote;
189
253
  quoteExpiresAt: string;
254
+ memoPolicy: CheckoutPaymentMemoPolicyType;
255
+ suggestedMemo: string | null;
190
256
  paymentAmount: string;
191
257
  currencyPerUsdRate: string;
192
258
  netSettledUsdcAmount: string | null;
@@ -194,28 +260,33 @@ export type CheckoutPayment = {
194
260
  referralFees: SettlementReferralFeeEntry[] | null;
195
261
  railIdentifier: string | null;
196
262
  fulfillTransaction: string | null;
263
+ errorCode?: string | null;
264
+ errorMessage?: string | null;
197
265
  completedAt: string | null;
198
266
  createdAt: string;
199
267
  updatedAt: string | null;
200
268
  };
269
+ export type CheckoutAggregatePayment = Omit<CheckoutPayment, 'paymentMethodId'> & {
270
+ paymentMethodId?: string | null;
271
+ };
201
272
  export type CheckoutAggregate = {
202
273
  order: CheckoutOrder;
203
274
  merchant: CheckoutMerchant;
204
- currentPayment: CheckoutPayment | null;
275
+ currentPayment: CheckoutAggregatePayment | null;
205
276
  };
206
277
  export type CreateOrderResponse = {
207
278
  order: CheckoutOrder;
208
279
  orderToken: string;
209
280
  };
210
- export type CreateCheckoutResponse = CreateOrderResponse;
211
- export type CheckoutCreateResponse = CreateOrderResponse;
212
281
  export type CreatePaymentRequest = {
213
282
  rail: string;
283
+ paymentMethodId?: string;
214
284
  fiatCurrency?: string;
215
285
  currency?: string;
216
286
  replacementPaymentId?: string;
217
287
  quoteLimit?: number;
218
288
  excludedPayToValues?: string[];
289
+ refundTo?: string;
219
290
  };
220
291
  export type CheckoutPaymentCreationResponse = CheckoutPayment & {
221
292
  relayerTransactionId?: string;
@@ -227,6 +298,7 @@ export type PaymentDeeplinkResponse = {
227
298
  url: string;
228
299
  proofSubmissionUrl: string;
229
300
  checkoutReturnUrl: string;
301
+ linkKind?: 'app_clip' | 'deeplink';
230
302
  };
231
303
  export type CheckoutDeeplinkResponse = PaymentDeeplinkResponse;
232
304
  export type MerchantConfig = {
@@ -240,17 +312,20 @@ export type MerchantConfig = {
240
312
  sweepEnabled: boolean;
241
313
  recipientOverrideEnabled: boolean;
242
314
  disableBranding: boolean;
315
+ dynamicOrdersEnabled: boolean;
243
316
  merchantCheckoutTheme: MerchantCheckoutTheme;
244
317
  platformReferralFeeConfig: ReferralFeeConfig | null;
245
318
  referralSplitConfig: ReferralSplitConfig | null;
319
+ flatFeePricing: boolean;
246
320
  createdAt: string;
247
321
  updatedAt: string | null;
248
322
  };
249
323
  export type MerchantUser = {
250
324
  id: string;
251
325
  email: string | null;
252
- privyUserId: string;
253
- role: 'OWNER' | 'MANAGER';
326
+ privyUserId: string | null;
327
+ v1PrivyUserId: string | null;
328
+ role: 'OWNER' | 'MANAGER' | 'CASHIER';
254
329
  merchantId: string | null;
255
330
  createdAt: string;
256
331
  updatedAt: string | null;
@@ -259,11 +334,19 @@ export type MerchantProfile = {
259
334
  id: string;
260
335
  name: string;
261
336
  logoUrl: string | null;
337
+ industryType: string | null;
338
+ industryOtherText: string | null;
339
+ integrationPath: MerchantIntegrationPathValue | null;
340
+ onboardingCompletedAt: string | null;
341
+ onboardingSkippedAt: string | null;
262
342
  apiKey: string;
263
343
  environment: MerchantEnvironmentType;
264
344
  sandboxMerchantId: string | null;
345
+ inPersonCheckoutEnabled: boolean;
265
346
  evmWalletAddress: string | null;
266
347
  solanaWalletAddress: string | null;
348
+ v1EvmWalletAddress: string | null;
349
+ v1SolanaWalletAddress: string | null;
267
350
  tier: 'FREE' | 'PRO';
268
351
  createdAt: string;
269
352
  updatedAt: string | null;
@@ -328,6 +411,8 @@ export type Merchant = {
328
411
  id: string;
329
412
  name: string;
330
413
  logoUrl?: string | null;
414
+ industryType?: string | null;
415
+ industryOtherText?: string | null;
331
416
  disableBranding?: boolean;
332
417
  apiKey: string;
333
418
  environment?: MerchantEnvironmentType;
@@ -475,6 +560,7 @@ type CreateSessionBaseRequest = {
475
560
  cancelUrl?: string;
476
561
  metadata?: Record<string, string>;
477
562
  enabledPaymentPlatforms?: PaymentPlatformType[];
563
+ dynamicOrdersEnabled?: boolean;
478
564
  };
479
565
  type CreateSessionExactTokenRequest = CreateSessionBaseRequest & {
480
566
  checkoutMode?: 'exact-token';
@@ -596,15 +682,48 @@ export interface OrderBridgeInfo {
596
682
  fallbackToOrigin?: boolean;
597
683
  failureMessage?: string | null;
598
684
  }
685
+ export declare const MerchantIntegrationPath: {
686
+ readonly CUSTOM_API: "CUSTOM_API";
687
+ readonly WOOCOMMERCE: "WOOCOMMERCE";
688
+ readonly IN_PERSON: "IN_PERSON";
689
+ readonly TELEGRAM: "TELEGRAM";
690
+ readonly SHOPIFY: "SHOPIFY";
691
+ };
692
+ export type MerchantIntegrationPathValue = typeof MerchantIntegrationPath[keyof typeof MerchantIntegrationPath];
693
+ export declare const OnboardingStepStatus: {
694
+ readonly DONE: "done";
695
+ readonly TODO: "todo";
696
+ };
697
+ export type OnboardingStepStatusValue = typeof OnboardingStepStatus[keyof typeof OnboardingStepStatus];
698
+ export declare const OnboardingStepVerifiedBy: {
699
+ readonly AUTO: "auto";
700
+ readonly MANUAL: "manual";
701
+ };
702
+ export type OnboardingStepVerifiedByValue = typeof OnboardingStepVerifiedBy[keyof typeof OnboardingStepVerifiedBy];
703
+ export type OnboardingStepState = {
704
+ id: string;
705
+ status: OnboardingStepStatusValue;
706
+ verifiedBy: OnboardingStepVerifiedByValue;
707
+ };
708
+ export type MerchantOnboardingResponse = {
709
+ path: MerchantIntegrationPathValue | null;
710
+ sandboxApiKey: string | null;
711
+ completedAt: string | null;
712
+ skippedAt: string | null;
713
+ steps: OnboardingStepState[];
714
+ };
599
715
  export declare const WebhookEventType: {
600
716
  readonly ORDER_CREATED: "ORDER_CREATED";
601
717
  readonly ORDER_FULFILLED: "ORDER_FULFILLED";
602
718
  readonly ORDER_CANCELLED: "ORDER_CANCELLED";
719
+ readonly ORDER_RESIZED: "ORDER_RESIZED";
603
720
  readonly PAYMENT_CREATED: "PAYMENT_CREATED";
604
721
  readonly PAYMENT_SETTLED: "PAYMENT_SETTLED";
605
722
  readonly PAYMENT_CANCELLED: "PAYMENT_CANCELLED";
606
723
  readonly PAYMENT_EXPIRED: "PAYMENT_EXPIRED";
607
724
  readonly PAYMENT_FAILED: "PAYMENT_FAILED";
725
+ readonly REFUND_PENDING: "REFUND_PENDING";
726
+ readonly REFUND_COMPLETED: "REFUND_COMPLETED";
608
727
  readonly PAYMENT_BRIDGE_PENDING: "PAYMENT_BRIDGE_PENDING";
609
728
  readonly PAYMENT_BRIDGE_SUBMITTED: "PAYMENT_BRIDGE_SUBMITTED";
610
729
  readonly PAYMENT_BRIDGE_COMPLETED: "PAYMENT_BRIDGE_COMPLETED";
@@ -631,9 +750,6 @@ export type Webhook = {
631
750
  createdAt: string;
632
751
  updatedAt: string;
633
752
  };
634
- export type WebhookWithSecret = Webhook & {
635
- secret: string;
636
- };
637
753
  export type WebhookDelivery = {
638
754
  id: string;
639
755
  webhookId: string;
@@ -653,7 +769,12 @@ export type WebhookPayload = {
653
769
  data: {
654
770
  order: CheckoutOrder | null;
655
771
  payment: CheckoutPayment | null;
772
+ refund: Record<string, unknown> | null;
656
773
  paymentBridge: Record<string, unknown> | null;
774
+ resize?: {
775
+ previousAmountUsdc: string;
776
+ newAmountUsdc: string;
777
+ };
657
778
  };
658
779
  };
659
780
  export type CreateWebhookRequest = {
@@ -661,7 +782,10 @@ export type CreateWebhookRequest = {
661
782
  events?: WebhookEventTypeValue[];
662
783
  customHeaders?: WebhookHeader[];
663
784
  };
664
- export type CreateWebhookResponse = WebhookWithSecret;
785
+ export type CreateWebhookResponse = {
786
+ webhook: Webhook;
787
+ secret: string;
788
+ };
665
789
  export type UpdateWebhookRequest = {
666
790
  url?: string;
667
791
  events?: WebhookEventTypeValue[];
package/dist/types.js CHANGED
@@ -10,6 +10,14 @@ export const PaymentPlatform = {
10
10
  N26: 'n26',
11
11
  CHIME: 'chime',
12
12
  };
13
+ const PAYMENT_PLATFORM_VALUES = new Set(Object.values(PaymentPlatform));
14
+ /**
15
+ * Type guard for PaymentPlatform values.
16
+ * Returns true if `value` is one of the known PaymentPlatform enum values.
17
+ */
18
+ export function isPaymentPlatform(value) {
19
+ return typeof value === 'string' && PAYMENT_PLATFORM_VALUES.has(value);
20
+ }
13
21
  // Supported chains for USDC destination
14
22
  // Re-exported from chains.ts for backward compatibility
15
23
  export const SupportedChains = SupportedChainsMap;
@@ -53,12 +61,23 @@ export const FeePayer = {
53
61
  MERCHANT: 'MERCHANT',
54
62
  PAYEE: 'PAYEE',
55
63
  };
64
+ export const MerchantPaymentFlowMode = {
65
+ EXCLUSIVE_SAR: 'EXCLUSIVE_SAR',
66
+ PREFER_SAR: 'PREFER_SAR',
67
+ PREFER_BUYER_TEE: 'PREFER_BUYER_TEE',
68
+ EXCLUSIVE_BUYER_TEE: 'EXCLUSIVE_BUYER_TEE',
69
+ };
56
70
  export const CheckoutOrderStatus = {
57
71
  CREATED: 'CREATED',
58
72
  PARTIALLY_FULFILLED: 'PARTIALLY_FULFILLED',
59
73
  FULFILLED: 'FULFILLED',
60
74
  CANCELLED: 'CANCELLED',
61
75
  };
76
+ export const CheckoutOrderRefundStatus = {
77
+ NONE: 'NONE',
78
+ PENDING: 'PENDING',
79
+ COMPLETED: 'COMPLETED',
80
+ };
62
81
  export const CheckoutPaymentStatus = {
63
82
  CREATED: 'CREATED',
64
83
  SETTLED: 'SETTLED',
@@ -66,6 +85,11 @@ export const CheckoutPaymentStatus = {
66
85
  EXPIRED: 'EXPIRED',
67
86
  FAILED: 'FAILED',
68
87
  };
88
+ export const CheckoutPaymentMemoPolicy = {
89
+ NONE: 'NONE',
90
+ REQUIRED: 'REQUIRED',
91
+ EMPTY: 'EMPTY',
92
+ };
69
93
  // Structured error codes for Order failures
70
94
  export const OrderErrorCode = {
71
95
  // Proof verification errors
@@ -97,16 +121,35 @@ export const TrancheCurrency = {
97
121
  USD: 'USD',
98
122
  USDC: 'USDC',
99
123
  };
124
+ // ============ Merchant Onboarding Types ============
125
+ export const MerchantIntegrationPath = {
126
+ CUSTOM_API: 'CUSTOM_API',
127
+ WOOCOMMERCE: 'WOOCOMMERCE',
128
+ IN_PERSON: 'IN_PERSON',
129
+ TELEGRAM: 'TELEGRAM',
130
+ SHOPIFY: 'SHOPIFY',
131
+ };
132
+ export const OnboardingStepStatus = {
133
+ DONE: 'done',
134
+ TODO: 'todo',
135
+ };
136
+ export const OnboardingStepVerifiedBy = {
137
+ AUTO: 'auto',
138
+ MANUAL: 'manual',
139
+ };
100
140
  // ============ Webhook Types ============
101
141
  export const WebhookEventType = {
102
142
  ORDER_CREATED: 'ORDER_CREATED',
103
143
  ORDER_FULFILLED: 'ORDER_FULFILLED',
104
144
  ORDER_CANCELLED: 'ORDER_CANCELLED',
145
+ ORDER_RESIZED: 'ORDER_RESIZED',
105
146
  PAYMENT_CREATED: 'PAYMENT_CREATED',
106
147
  PAYMENT_SETTLED: 'PAYMENT_SETTLED',
107
148
  PAYMENT_CANCELLED: 'PAYMENT_CANCELLED',
108
149
  PAYMENT_EXPIRED: 'PAYMENT_EXPIRED',
109
150
  PAYMENT_FAILED: 'PAYMENT_FAILED',
151
+ REFUND_PENDING: 'REFUND_PENDING',
152
+ REFUND_COMPLETED: 'REFUND_COMPLETED',
110
153
  PAYMENT_BRIDGE_PENDING: 'PAYMENT_BRIDGE_PENDING',
111
154
  PAYMENT_BRIDGE_SUBMITTED: 'PAYMENT_BRIDGE_SUBMITTED',
112
155
  PAYMENT_BRIDGE_COMPLETED: 'PAYMENT_BRIDGE_COMPLETED',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zkp2p/pay-shared",
3
- "version": "1.0.0",
3
+ "version": "3.0.0",
4
4
  "description": "Shared TypeScript types, enums, and chain utilities used by ZKP2P Pay API, SDK, and frontend apps.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -37,7 +37,11 @@
37
37
  "scripts": {
38
38
  "build": "rm -rf dist && tsc -p tsconfig.json",
39
39
  "lint": "eslint . --ext .ts,.tsx",
40
+ "test": "vitest run",
40
41
  "prepack": "npm run build",
41
42
  "prepublishOnly": "npm pack --dry-run"
43
+ },
44
+ "devDependencies": {
45
+ "vitest": "^1.6.1"
42
46
  }
43
47
  }