@zkp2p/pay-shared 3.1.0 → 4.0.1
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/README.md +5 -2
- package/dist/attribution.d.ts +4 -0
- package/dist/attribution.js +5 -0
- package/dist/chains.d.ts +3 -2
- package/dist/chains.js +18 -2
- package/dist/crypto.d.ts +1 -2
- package/dist/crypto.js +2 -8
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/llmIntegration.d.ts +111 -0
- package/dist/llmIntegration.js +28 -0
- package/dist/onboarding.d.ts +18 -0
- package/dist/onboarding.js +73 -15
- package/dist/tiers.d.ts +66 -0
- package/dist/tiers.js +65 -0
- package/dist/types.d.ts +68 -4
- package/dist/types.js +29 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ Shared TypeScript types, enums, and chain utilities used by ZKP2P Pay API, SDK,
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
npm install @zkp2p/pay-shared@
|
|
12
|
+
npm install @zkp2p/pay-shared@4.0.1
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
## Published artifacts
|
|
@@ -58,6 +58,7 @@ console.log(CheckoutOrderStatus.CREATED); // "CREATED"
|
|
|
58
58
|
```ts
|
|
59
59
|
import {
|
|
60
60
|
BASE_CHAIN_ID,
|
|
61
|
+
TRON_CHAIN_ID,
|
|
61
62
|
getSupportedChainIds,
|
|
62
63
|
parseSupportedChainSelection,
|
|
63
64
|
resolveDestinationTokenAddress,
|
|
@@ -67,8 +68,9 @@ import {
|
|
|
67
68
|
const chainId = parseSupportedChainSelection('polygon'); // 137
|
|
68
69
|
const usdc = resolveDestinationTokenAddress('USDC', 137); // Chain-specific USDC address
|
|
69
70
|
const supportedAliases = getSupportedDestinationTokenAliasesForChain(BASE_CHAIN_ID); // ["USDC", "USDT"]
|
|
71
|
+
const tronAliases = getSupportedDestinationTokenAliasesForChain(TRON_CHAIN_ID); // ["USDT"]
|
|
70
72
|
|
|
71
|
-
console.log(getSupportedChainIds(), chainId, usdc, supportedAliases);
|
|
73
|
+
console.log(getSupportedChainIds(), chainId, usdc, supportedAliases, tronAliases);
|
|
72
74
|
```
|
|
73
75
|
|
|
74
76
|
## Key Exports
|
|
@@ -100,6 +102,7 @@ Chain constants and helpers:
|
|
|
100
102
|
- `BASE_CHAIN_ID`
|
|
101
103
|
- `HYPEREVM_CHAIN_ID`
|
|
102
104
|
- `SOLANA_CHAIN_ID`
|
|
105
|
+
- `TRON_CHAIN_ID`
|
|
103
106
|
- `SUPPORTED_DESTINATION_TOKEN_ALIASES`
|
|
104
107
|
- `parseSupportedChainSelection(...)`
|
|
105
108
|
- `resolveDestinationTokenAddress(...)`
|
package/dist/chains.d.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Centralized chain configuration for ZKP2P Pay.
|
|
3
3
|
*
|
|
4
|
-
* All supported chains and their
|
|
4
|
+
* All supported payout chains and their destination token addresses are defined here.
|
|
5
5
|
* Import this module instead of duplicating chain configs in each app.
|
|
6
6
|
*/
|
|
7
7
|
export declare const BASE_CHAIN_ID = 8453;
|
|
8
8
|
export declare const ETHEREUM_CHAIN_ID = 1;
|
|
9
9
|
export declare const HYPEREVM_CHAIN_ID = 999;
|
|
10
10
|
export declare const SOLANA_CHAIN_ID = 792703809;
|
|
11
|
+
export declare const TRON_CHAIN_ID = 728126428;
|
|
11
12
|
export declare const SUPPORTED_DESTINATION_TOKEN_ALIASES: readonly ["USDC", "USDT"];
|
|
12
13
|
export type DestinationTokenAlias = (typeof SUPPORTED_DESTINATION_TOKEN_ALIASES)[number];
|
|
13
14
|
export declare const DEFAULT_DESTINATION_TOKEN_ALIAS: DestinationTokenAlias;
|
|
@@ -20,7 +21,7 @@ export interface ChainConfig {
|
|
|
20
21
|
chainId: number;
|
|
21
22
|
name: string;
|
|
22
23
|
shortName: string;
|
|
23
|
-
usdcAddress: string;
|
|
24
|
+
usdcAddress: string | null;
|
|
24
25
|
isOriginChain: boolean;
|
|
25
26
|
isEvm: boolean;
|
|
26
27
|
explorerUrl?: string;
|
package/dist/chains.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Centralized chain configuration for ZKP2P Pay.
|
|
3
3
|
*
|
|
4
|
-
* All supported chains and their
|
|
4
|
+
* All supported payout chains and their destination token addresses are defined here.
|
|
5
5
|
* Import this module instead of duplicating chain configs in each app.
|
|
6
6
|
*/
|
|
7
7
|
// Chain IDs
|
|
@@ -9,6 +9,7 @@ export const BASE_CHAIN_ID = 8453;
|
|
|
9
9
|
export const ETHEREUM_CHAIN_ID = 1;
|
|
10
10
|
export const HYPEREVM_CHAIN_ID = 999;
|
|
11
11
|
export const SOLANA_CHAIN_ID = 792703809;
|
|
12
|
+
export const TRON_CHAIN_ID = 728126428;
|
|
12
13
|
export const SUPPORTED_DESTINATION_TOKEN_ALIASES = ['USDC', 'USDT'];
|
|
13
14
|
export const DEFAULT_DESTINATION_TOKEN_ALIAS = 'USDC';
|
|
14
15
|
// Mainnet chain configurations
|
|
@@ -97,6 +98,15 @@ export const MAINNET_CHAINS = {
|
|
|
97
98
|
isEvm: false,
|
|
98
99
|
explorerUrl: 'https://solscan.io',
|
|
99
100
|
},
|
|
101
|
+
[TRON_CHAIN_ID]: {
|
|
102
|
+
chainId: TRON_CHAIN_ID,
|
|
103
|
+
name: 'Tron',
|
|
104
|
+
shortName: 'TRON',
|
|
105
|
+
usdcAddress: null,
|
|
106
|
+
isOriginChain: false,
|
|
107
|
+
isEvm: false,
|
|
108
|
+
explorerUrl: 'https://tronscan.org/#',
|
|
109
|
+
},
|
|
100
110
|
};
|
|
101
111
|
function normalizeChainSelectionKey(value) {
|
|
102
112
|
return value.trim().toLowerCase().replace(/[^a-z0-9]/g, '');
|
|
@@ -123,6 +133,8 @@ const CHAIN_SELECTION_ALIASES = {
|
|
|
123
133
|
hl: 999,
|
|
124
134
|
solana: 792703809,
|
|
125
135
|
sol: 792703809,
|
|
136
|
+
tron: TRON_CHAIN_ID,
|
|
137
|
+
trx: TRON_CHAIN_ID,
|
|
126
138
|
};
|
|
127
139
|
for (const chainId of SUPPORTED_CHAIN_IDS) {
|
|
128
140
|
const chainConfig = MAINNET_CHAINS[chainId];
|
|
@@ -164,6 +176,10 @@ const DESTINATION_TOKEN_ADDRESSES = {
|
|
|
164
176
|
999: {
|
|
165
177
|
usdt: '0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb',
|
|
166
178
|
},
|
|
179
|
+
// Tron
|
|
180
|
+
[TRON_CHAIN_ID]: {
|
|
181
|
+
usdt: 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t',
|
|
182
|
+
},
|
|
167
183
|
};
|
|
168
184
|
function isKnownDestinationTokenAlias(value) {
|
|
169
185
|
return SUPPORTED_DESTINATION_TOKEN_ALIASES.includes(value);
|
|
@@ -245,7 +261,7 @@ export function getOriginChainId() {
|
|
|
245
261
|
* Get USDC address for a chain.
|
|
246
262
|
*/
|
|
247
263
|
export function getUsdcAddress(chainId) {
|
|
248
|
-
return getChainConfig(chainId)?.usdcAddress;
|
|
264
|
+
return getChainConfig(chainId)?.usdcAddress ?? undefined;
|
|
249
265
|
}
|
|
250
266
|
/**
|
|
251
267
|
* Resolve destination token alias to chain-specific token address.
|
package/dist/crypto.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export declare const BITCOIN_CHAIN_ID = 8253038;
|
|
2
|
-
export declare const TRON_CHAIN_ID = 728126428;
|
|
3
2
|
export declare const PAY_CRYPTO_TOKEN_SYMBOLS: readonly ["BTC", "USDC", "USDT", "ETH", "PYUSD", "SOL", "BNB", "HYPE", "WBTC", "USDH"];
|
|
4
3
|
export type PayCryptoTokenSymbol = (typeof PAY_CRYPTO_TOKEN_SYMBOLS)[number];
|
|
5
4
|
export declare const DEFAULT_ENABLED_PAY_CRYPTO_TOKENS: PayCryptoTokenSymbol[];
|
|
@@ -45,7 +44,7 @@ export declare function getSupportedPayCryptoChainIdsForToken(symbol: PayCryptoT
|
|
|
45
44
|
/**
|
|
46
45
|
* Returns the display name for a chain used by the "Pay with crypto"
|
|
47
46
|
* flow. Resolves through PAY_CRYPTO_CHAIN_CONFIGS first so Bitcoin
|
|
48
|
-
*
|
|
47
|
+
* gets the correct label.
|
|
49
48
|
* Falls back to getChainName for chains not registered here.
|
|
50
49
|
*/
|
|
51
50
|
export declare function getPayCryptoChainName(chainId: number): string;
|
package/dist/crypto.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { MAINNET_CHAINS, BASE_CHAIN_ID, ETHEREUM_CHAIN_ID, SOLANA_CHAIN_ID, getChainName, } from './chains.js';
|
|
1
|
+
import { MAINNET_CHAINS, BASE_CHAIN_ID, ETHEREUM_CHAIN_ID, SOLANA_CHAIN_ID, TRON_CHAIN_ID, getChainName, } from './chains.js';
|
|
2
2
|
export const BITCOIN_CHAIN_ID = 8253038;
|
|
3
|
-
export const TRON_CHAIN_ID = 728126428;
|
|
4
3
|
export const PAY_CRYPTO_TOKEN_SYMBOLS = [
|
|
5
4
|
'BTC', // Kept in symbols for DB compatibility with existing sessions
|
|
6
5
|
'USDC',
|
|
@@ -56,11 +55,6 @@ const PAY_CRYPTO_CHAIN_CONFIGS = {
|
|
|
56
55
|
name: 'Bitcoin',
|
|
57
56
|
shortName: 'BTC',
|
|
58
57
|
},
|
|
59
|
-
[TRON_CHAIN_ID]: {
|
|
60
|
-
chainId: TRON_CHAIN_ID,
|
|
61
|
-
name: 'Tron',
|
|
62
|
-
shortName: 'TRON',
|
|
63
|
-
},
|
|
64
58
|
};
|
|
65
59
|
const CHAIN_TOKEN_CONFIGS = {
|
|
66
60
|
[BITCOIN_CHAIN_ID]: {
|
|
@@ -219,7 +213,7 @@ export function getSupportedPayCryptoChainIdsForToken(symbol, enabledChainIds) {
|
|
|
219
213
|
/**
|
|
220
214
|
* Returns the display name for a chain used by the "Pay with crypto"
|
|
221
215
|
* flow. Resolves through PAY_CRYPTO_CHAIN_CONFIGS first so Bitcoin
|
|
222
|
-
*
|
|
216
|
+
* gets the correct label.
|
|
223
217
|
* Falls back to getChainName for chains not registered here.
|
|
224
218
|
*/
|
|
225
219
|
export function getPayCryptoChainName(chainId) {
|
package/dist/index.d.ts
CHANGED
|
@@ -6,8 +6,12 @@ export * from './rails.js';
|
|
|
6
6
|
export * from './buyerTee.js';
|
|
7
7
|
export * from './bitcoin.js';
|
|
8
8
|
export * from './addressValidators.js';
|
|
9
|
+
export { doubleSha256, encodeBase58 } from './addressEncoding.js';
|
|
9
10
|
export * from './fiatAmount.js';
|
|
10
11
|
export * from './paypalSarPhase.js';
|
|
11
12
|
export * from './paypalSarVerify.js';
|
|
12
13
|
export * from './payeeFeeCap.js';
|
|
13
14
|
export * from './onboarding.js';
|
|
15
|
+
export * from './llmIntegration.js';
|
|
16
|
+
export * from './tiers.js';
|
|
17
|
+
export * from './attribution.js';
|
package/dist/index.js
CHANGED
|
@@ -6,8 +6,12 @@ export * from './rails.js';
|
|
|
6
6
|
export * from './buyerTee.js';
|
|
7
7
|
export * from './bitcoin.js';
|
|
8
8
|
export * from './addressValidators.js';
|
|
9
|
+
export { doubleSha256, encodeBase58 } from './addressEncoding.js';
|
|
9
10
|
export * from './fiatAmount.js';
|
|
10
11
|
export * from './paypalSarPhase.js';
|
|
11
12
|
export * from './paypalSarVerify.js';
|
|
12
13
|
export * from './payeeFeeCap.js';
|
|
13
14
|
export * from './onboarding.js';
|
|
15
|
+
export * from './llmIntegration.js';
|
|
16
|
+
export * from './tiers.js';
|
|
17
|
+
export * from './attribution.js';
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import type { OnboardingStepIdValue } from './onboarding.js';
|
|
2
|
+
import type { MerchantEnvironmentType, MerchantIntegrationPathValue, OnboardingStepStatusValue } from './types.js';
|
|
3
|
+
export declare const IntegrationStepActor: {
|
|
4
|
+
readonly AGENT: "AGENT";
|
|
5
|
+
readonly MERCHANT: "MERCHANT";
|
|
6
|
+
};
|
|
7
|
+
export type IntegrationStepActorValue = typeof IntegrationStepActor[keyof typeof IntegrationStepActor];
|
|
8
|
+
/**
|
|
9
|
+
* Which party can satisfy each onboarding step when a coding agent drives the
|
|
10
|
+
* integration. AGENT steps are reachable with an API key alone; MERCHANT steps
|
|
11
|
+
* need a Privy-authenticated dashboard session (tier selection), a human decision
|
|
12
|
+
* (industry, path), or physical action. An agent that retries a MERCHANT step
|
|
13
|
+
* gets 403 with no way to learn the wall is structural, so it is told up front.
|
|
14
|
+
*/
|
|
15
|
+
export declare const INTEGRATION_STEP_ACTORS: Readonly<Record<OnboardingStepIdValue, IntegrationStepActorValue>>;
|
|
16
|
+
export type IntegrationDeliveryEvidence = {
|
|
17
|
+
/** WebhookDeliveryStatus. PENDING means queued but not yet attempted. */
|
|
18
|
+
readonly deliveryStatus: string;
|
|
19
|
+
readonly attempts: number;
|
|
20
|
+
readonly responseCode: number | null;
|
|
21
|
+
/**
|
|
22
|
+
* Locally generated transport failure reason — SSRF block, DNS timeout, fetch
|
|
23
|
+
* error. `null` whenever ANY HTTP response was received, including 401 and 500:
|
|
24
|
+
* webhook.service.ts records `responseBody: null` on every received response and
|
|
25
|
+
* never stores receiver body content. Diagnose received responses from
|
|
26
|
+
* `responseCode`; use this field only to explain why nothing was received.
|
|
27
|
+
*/
|
|
28
|
+
readonly error: string | null;
|
|
29
|
+
readonly attemptedAt: string | null;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Webhooks are scoped per merchant row, and sandbox is its own row. An agent needs
|
|
33
|
+
* both: the sandbox registration is what a test order actually delivers to, and the
|
|
34
|
+
* live registration is what real payments deliver to (and what the onboarding step
|
|
35
|
+
* reads). Reporting only one hides half the integration.
|
|
36
|
+
*/
|
|
37
|
+
export type IntegrationWebhookEvidence = {
|
|
38
|
+
readonly webhookId: string | null;
|
|
39
|
+
readonly webhookUrl: string | null;
|
|
40
|
+
readonly subscribedEvents: readonly string[];
|
|
41
|
+
readonly lastDelivery: IntegrationDeliveryEvidence | null;
|
|
42
|
+
};
|
|
43
|
+
export type IntegrationStepEvidence = {
|
|
44
|
+
readonly sandboxOrderId?: string | null;
|
|
45
|
+
readonly sandboxOrderStatus?: string | null;
|
|
46
|
+
readonly liveOrderId?: string | null;
|
|
47
|
+
readonly canCreateLiveOrders?: boolean;
|
|
48
|
+
readonly sandboxWebhook?: IntegrationWebhookEvidence | null;
|
|
49
|
+
readonly liveWebhook?: IntegrationWebhookEvidence | null;
|
|
50
|
+
readonly tier?: string | null;
|
|
51
|
+
readonly missingFields?: readonly string[];
|
|
52
|
+
};
|
|
53
|
+
export type IntegrationStatusStep = {
|
|
54
|
+
readonly id: OnboardingStepIdValue;
|
|
55
|
+
readonly status: OnboardingStepStatusValue;
|
|
56
|
+
readonly actor: IntegrationStepActorValue;
|
|
57
|
+
readonly evidence: IntegrationStepEvidence;
|
|
58
|
+
};
|
|
59
|
+
export type IntegrationNextAction = {
|
|
60
|
+
readonly stepId: OnboardingStepIdValue;
|
|
61
|
+
readonly actor: IntegrationStepActorValue;
|
|
62
|
+
readonly instruction: string;
|
|
63
|
+
readonly docs: string;
|
|
64
|
+
};
|
|
65
|
+
export type IntegrationStatusResponse = {
|
|
66
|
+
readonly merchant: {
|
|
67
|
+
readonly id: string;
|
|
68
|
+
readonly name: string;
|
|
69
|
+
readonly integrationPath: MerchantIntegrationPathValue | null;
|
|
70
|
+
};
|
|
71
|
+
readonly environmentOfKey: MerchantEnvironmentType;
|
|
72
|
+
/** Onboarding checklist completion. See `verified` before trusting this. */
|
|
73
|
+
readonly complete: boolean;
|
|
74
|
+
/**
|
|
75
|
+
* True only when a sandbox ORDER_FULFILLED delivery has actually been accepted
|
|
76
|
+
* by the merchant's handler.
|
|
77
|
+
*
|
|
78
|
+
* Deliberately independent of `complete`. `GO_LIVE` carries
|
|
79
|
+
* `impliesPrevious: true`, so a single live order forces every earlier step —
|
|
80
|
+
* including `webhook` — to DONE, and `complete` would report a verified
|
|
81
|
+
* integration for a handler that has never successfully received anything.
|
|
82
|
+
* `verified` is the field the agent must gate on.
|
|
83
|
+
*/
|
|
84
|
+
readonly verified: boolean;
|
|
85
|
+
/**
|
|
86
|
+
* True when the live merchant row has an active webhook subscribed to
|
|
87
|
+
* ORDER_FULFILLED. This is independent of the broader onboarding webhook step.
|
|
88
|
+
*/
|
|
89
|
+
readonly liveWebhookReady: boolean;
|
|
90
|
+
readonly steps: readonly IntegrationStatusStep[];
|
|
91
|
+
readonly nextAction: IntegrationNextAction | null;
|
|
92
|
+
/**
|
|
93
|
+
* Missing agent work in dependency order: sandbox webhook, accepted sandbox
|
|
94
|
+
* delivery, then live webhook plus live order. Independent of registry order.
|
|
95
|
+
*/
|
|
96
|
+
readonly nextAgentAction: IntegrationNextAction | null;
|
|
97
|
+
};
|
|
98
|
+
export type SandboxTestOrderRequest = {
|
|
99
|
+
readonly orderId?: string;
|
|
100
|
+
readonly requestedUsdcAmount?: string;
|
|
101
|
+
readonly rail?: string;
|
|
102
|
+
};
|
|
103
|
+
export type SandboxTestOrderResponse = {
|
|
104
|
+
readonly orderId: string;
|
|
105
|
+
readonly status: string;
|
|
106
|
+
readonly paymentId: string;
|
|
107
|
+
};
|
|
108
|
+
export type LlmIntegrationPromptResponse = {
|
|
109
|
+
readonly prompt: string;
|
|
110
|
+
readonly filename: string;
|
|
111
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { OnboardingStepId } from './onboarding.js';
|
|
2
|
+
export const IntegrationStepActor = {
|
|
3
|
+
AGENT: 'AGENT',
|
|
4
|
+
MERCHANT: 'MERCHANT',
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Which party can satisfy each onboarding step when a coding agent drives the
|
|
8
|
+
* integration. AGENT steps are reachable with an API key alone; MERCHANT steps
|
|
9
|
+
* need a Privy-authenticated dashboard session (tier selection), a human decision
|
|
10
|
+
* (industry, path), or physical action. An agent that retries a MERCHANT step
|
|
11
|
+
* gets 403 with no way to learn the wall is structural, so it is told up front.
|
|
12
|
+
*/
|
|
13
|
+
export const INTEGRATION_STEP_ACTORS = {
|
|
14
|
+
[OnboardingStepId.PROFILE]: IntegrationStepActor.MERCHANT,
|
|
15
|
+
[OnboardingStepId.INDUSTRY]: IntegrationStepActor.MERCHANT,
|
|
16
|
+
[OnboardingStepId.PLAN]: IntegrationStepActor.MERCHANT,
|
|
17
|
+
[OnboardingStepId.PATH]: IntegrationStepActor.MERCHANT,
|
|
18
|
+
[OnboardingStepId.RAILS]: IntegrationStepActor.MERCHANT,
|
|
19
|
+
[OnboardingStepId.INTEGRATION]: IntegrationStepActor.AGENT,
|
|
20
|
+
[OnboardingStepId.WEBHOOK]: IntegrationStepActor.AGENT,
|
|
21
|
+
[OnboardingStepId.GO_LIVE]: IntegrationStepActor.AGENT,
|
|
22
|
+
[OnboardingStepId.DOWNLOAD_PLUGIN]: IntegrationStepActor.MERCHANT,
|
|
23
|
+
[OnboardingStepId.PLUGIN_API_KEY]: IntegrationStepActor.MERCHANT,
|
|
24
|
+
[OnboardingStepId.TEST_ORDER]: IntegrationStepActor.MERCHANT,
|
|
25
|
+
[OnboardingStepId.FIRST_QR]: IntegrationStepActor.MERCHANT,
|
|
26
|
+
[OnboardingStepId.LINK_BOT]: IntegrationStepActor.MERCHANT,
|
|
27
|
+
[OnboardingStepId.REQUEST_SETUP]: IntegrationStepActor.MERCHANT,
|
|
28
|
+
};
|
package/dist/onboarding.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { MerchantIntegrationPathValue, OnboardingStepState, OnboardingStepVerifiedByValue } from './types.js';
|
|
2
|
+
import type { MerchantTierName } from './tiers.js';
|
|
2
3
|
export type OnboardingFacts = {
|
|
3
4
|
hasName: boolean;
|
|
4
5
|
hasLogo: boolean;
|
|
5
6
|
hasIndustry: boolean;
|
|
7
|
+
hasSelectedTier: boolean;
|
|
6
8
|
hasIntegrationPath: boolean;
|
|
7
9
|
hasWebhook: boolean;
|
|
8
10
|
hasSandboxOrder: boolean;
|
|
@@ -14,6 +16,7 @@ export type OnboardingFacts = {
|
|
|
14
16
|
export declare const OnboardingStepId: {
|
|
15
17
|
readonly PROFILE: "profile";
|
|
16
18
|
readonly INDUSTRY: "industry";
|
|
19
|
+
readonly PLAN: "plan";
|
|
17
20
|
readonly PATH: "path";
|
|
18
21
|
readonly RAILS: "rails";
|
|
19
22
|
readonly INTEGRATION: "integration";
|
|
@@ -34,6 +37,21 @@ export type OnboardingStepRegistryEntry = {
|
|
|
34
37
|
readonly inChecklist: boolean;
|
|
35
38
|
readonly impliesPrevious: boolean;
|
|
36
39
|
};
|
|
40
|
+
export declare const TierCardAction: {
|
|
41
|
+
readonly SELECT: "select";
|
|
42
|
+
readonly REQUEST: "request";
|
|
43
|
+
};
|
|
44
|
+
export type TierCardActionValue = typeof TierCardAction[keyof typeof TierCardAction];
|
|
45
|
+
export type SelfServeMerchantTier = Exclude<MerchantTierName, 'CONCIERGE'>;
|
|
46
|
+
export type TierCopy = {
|
|
47
|
+
readonly displayLabel: string;
|
|
48
|
+
readonly kicker: string;
|
|
49
|
+
readonly price: string;
|
|
50
|
+
readonly features: readonly string[];
|
|
51
|
+
readonly cardAction: TierCardActionValue;
|
|
52
|
+
};
|
|
53
|
+
/** Shared copy and card behavior for every displayable merchant tier. */
|
|
54
|
+
export declare const TIER_COPY: Readonly<Record<MerchantTierName, TierCopy>>;
|
|
37
55
|
export declare const ONBOARDING_STEP_REGISTRY: readonly OnboardingStepRegistryEntry[];
|
|
38
56
|
export declare function resolveOnboardingSteps(facts: OnboardingFacts, path: MerchantIntegrationPathValue | null): OnboardingStepState[];
|
|
39
57
|
export declare function isOnboardingComplete(steps: readonly OnboardingStepState[]): boolean;
|
package/dist/onboarding.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { MerchantIntegrationPath, OnboardingStepStatus, OnboardingStepVerifiedBy, } from './types.js';
|
|
2
|
+
import { TIER_DEFINITIONS, formatTierMonthlyLimitsCopy } from './tiers.js';
|
|
2
3
|
export const OnboardingStepId = {
|
|
3
4
|
PROFILE: 'profile',
|
|
4
5
|
INDUSTRY: 'industry',
|
|
6
|
+
PLAN: 'plan',
|
|
5
7
|
PATH: 'path',
|
|
6
8
|
RAILS: 'rails',
|
|
7
9
|
INTEGRATION: 'integration',
|
|
@@ -14,6 +16,54 @@ export const OnboardingStepId = {
|
|
|
14
16
|
LINK_BOT: 'linkBot',
|
|
15
17
|
REQUEST_SETUP: 'requestSetup',
|
|
16
18
|
};
|
|
19
|
+
export const TierCardAction = {
|
|
20
|
+
SELECT: 'select',
|
|
21
|
+
REQUEST: 'request',
|
|
22
|
+
};
|
|
23
|
+
/** Shared copy and card behavior for every displayable merchant tier. */
|
|
24
|
+
export const TIER_COPY = {
|
|
25
|
+
// features[0] is the plan's monthly cap, formatted from TIER_DEFINITIONS so
|
|
26
|
+
// copy always matches the enforced limits. Every surface leads with it (the
|
|
27
|
+
// landing's rate rows, the onboarding tier cards, billing).
|
|
28
|
+
BASE: {
|
|
29
|
+
displayLabel: 'Base',
|
|
30
|
+
kicker: 'Self-serve',
|
|
31
|
+
price: '2.95% fiat / 1% crypto per successful payment',
|
|
32
|
+
features: [
|
|
33
|
+
formatTierMonthlyLimitsCopy(TIER_DEFINITIONS.BASE.monthlyLimits),
|
|
34
|
+
'Every platform included; Venmo and PayPal require staking',
|
|
35
|
+
'Verify payments with the Peer app or extension',
|
|
36
|
+
'Instant settlement, merchant-funded refunds',
|
|
37
|
+
],
|
|
38
|
+
cardAction: TierCardAction.SELECT,
|
|
39
|
+
},
|
|
40
|
+
PRO: {
|
|
41
|
+
displayLabel: 'Pro',
|
|
42
|
+
kicker: 'Self-serve',
|
|
43
|
+
price: '4.95% fiat / 1% crypto per successful payment',
|
|
44
|
+
features: [
|
|
45
|
+
formatTierMonthlyLimitsCopy(TIER_DEFINITIONS.PRO.monthlyLimits),
|
|
46
|
+
'Everything in Base',
|
|
47
|
+
'Seller Autopilot: customers pay with no Peer app or extension',
|
|
48
|
+
'Checkout branding and priority support',
|
|
49
|
+
],
|
|
50
|
+
cardAction: TierCardAction.SELECT,
|
|
51
|
+
},
|
|
52
|
+
CONCIERGE: {
|
|
53
|
+
displayLabel: 'Concierge',
|
|
54
|
+
kicker: 'With our team',
|
|
55
|
+
price: 'Custom pricing',
|
|
56
|
+
features: [
|
|
57
|
+
formatTierMonthlyLimitsCopy(TIER_DEFINITIONS.CONCIERGE.monthlyLimits),
|
|
58
|
+
'No staking and no lockups',
|
|
59
|
+
'Negotiated rate or flat-fee invoicing',
|
|
60
|
+
'Full integration support',
|
|
61
|
+
'Named support in a dedicated group',
|
|
62
|
+
'Custom embedded checkout and integrations',
|
|
63
|
+
],
|
|
64
|
+
cardAction: TierCardAction.REQUEST,
|
|
65
|
+
},
|
|
66
|
+
};
|
|
17
67
|
export const ONBOARDING_STEP_REGISTRY = [
|
|
18
68
|
{ id: OnboardingStepId.PROFILE, paths: 'ALL', verifiedBy: OnboardingStepVerifiedBy.AUTO, inChecklist: true, impliesPrevious: true },
|
|
19
69
|
{ id: OnboardingStepId.INDUSTRY, paths: 'ALL', verifiedBy: OnboardingStepVerifiedBy.AUTO, inChecklist: true, impliesPrevious: true },
|
|
@@ -48,13 +98,6 @@ export const ONBOARDING_STEP_REGISTRY = [
|
|
|
48
98
|
inChecklist: true,
|
|
49
99
|
impliesPrevious: true,
|
|
50
100
|
},
|
|
51
|
-
{
|
|
52
|
-
id: OnboardingStepId.GO_LIVE,
|
|
53
|
-
paths: [MerchantIntegrationPath.CUSTOM_API, MerchantIntegrationPath.TELEGRAM],
|
|
54
|
-
verifiedBy: OnboardingStepVerifiedBy.AUTO,
|
|
55
|
-
inChecklist: true,
|
|
56
|
-
impliesPrevious: true,
|
|
57
|
-
},
|
|
58
101
|
{
|
|
59
102
|
id: OnboardingStepId.DOWNLOAD_PLUGIN,
|
|
60
103
|
paths: [MerchantIntegrationPath.WOOCOMMERCE],
|
|
@@ -76,13 +119,6 @@ export const ONBOARDING_STEP_REGISTRY = [
|
|
|
76
119
|
inChecklist: true,
|
|
77
120
|
impliesPrevious: true,
|
|
78
121
|
},
|
|
79
|
-
{
|
|
80
|
-
id: OnboardingStepId.GO_LIVE,
|
|
81
|
-
paths: [MerchantIntegrationPath.WOOCOMMERCE],
|
|
82
|
-
verifiedBy: OnboardingStepVerifiedBy.AUTO,
|
|
83
|
-
inChecklist: true,
|
|
84
|
-
impliesPrevious: true,
|
|
85
|
-
},
|
|
86
122
|
{
|
|
87
123
|
id: OnboardingStepId.FIRST_QR,
|
|
88
124
|
paths: [MerchantIntegrationPath.IN_PERSON],
|
|
@@ -99,17 +135,39 @@ export const ONBOARDING_STEP_REGISTRY = [
|
|
|
99
135
|
inChecklist: true,
|
|
100
136
|
impliesPrevious: true,
|
|
101
137
|
},
|
|
138
|
+
{
|
|
139
|
+
id: OnboardingStepId.PLAN,
|
|
140
|
+
paths: 'ALL',
|
|
141
|
+
verifiedBy: OnboardingStepVerifiedBy.AUTO,
|
|
142
|
+
inChecklist: true,
|
|
143
|
+
// Deliberately the last ask before go-live: a tier is only required for LIVE
|
|
144
|
+
// orders, and it can also be selected out-of-band (billing page, admin), so a
|
|
145
|
+
// done plan step must not imply the integration steps that now precede it.
|
|
146
|
+
impliesPrevious: false,
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
id: OnboardingStepId.GO_LIVE,
|
|
150
|
+
paths: [
|
|
151
|
+
MerchantIntegrationPath.CUSTOM_API,
|
|
152
|
+
MerchantIntegrationPath.TELEGRAM,
|
|
153
|
+
MerchantIntegrationPath.WOOCOMMERCE,
|
|
154
|
+
],
|
|
155
|
+
verifiedBy: OnboardingStepVerifiedBy.AUTO,
|
|
156
|
+
inChecklist: true,
|
|
157
|
+
impliesPrevious: true,
|
|
158
|
+
},
|
|
102
159
|
];
|
|
103
160
|
const autoStepPredicates = {
|
|
104
161
|
[OnboardingStepId.PROFILE]: (facts) => facts.hasName && facts.hasLogo,
|
|
105
162
|
[OnboardingStepId.INDUSTRY]: (facts) => facts.hasIndustry,
|
|
163
|
+
[OnboardingStepId.PLAN]: (facts) => facts.hasSelectedTier,
|
|
106
164
|
[OnboardingStepId.PATH]: (facts) => facts.hasIntegrationPath,
|
|
107
165
|
[OnboardingStepId.RAILS]: () => true,
|
|
108
166
|
[OnboardingStepId.INTEGRATION]: (facts) => facts.hasSandboxFulfilledOrder,
|
|
109
167
|
[OnboardingStepId.WEBHOOK]: (facts) => facts.hasWebhook,
|
|
110
168
|
[OnboardingStepId.TEST_ORDER]: (facts) => facts.hasSandboxFulfilledOrder,
|
|
111
169
|
[OnboardingStepId.LINK_BOT]: (facts) => facts.hasSandboxFulfilledOrder,
|
|
112
|
-
[OnboardingStepId.GO_LIVE]: (facts) => facts.
|
|
170
|
+
[OnboardingStepId.GO_LIVE]: (facts) => facts.hasLiveOrder,
|
|
113
171
|
[OnboardingStepId.FIRST_QR]: (facts) => facts.hasSandboxOrder,
|
|
114
172
|
};
|
|
115
173
|
export function resolveOnboardingSteps(facts, path) {
|
package/dist/tiers.d.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { type FeeTranche, type MerchantEnvironmentType, type MerchantPaymentFlowModeType, type MerchantTierName } from './types.js';
|
|
2
|
+
export type { MerchantTierName } from './types.js';
|
|
3
|
+
export declare const TierChangeSource: {
|
|
4
|
+
readonly SELF_SERVE: "SELF_SERVE";
|
|
5
|
+
readonly ADMIN: "ADMIN";
|
|
6
|
+
readonly MIGRATION: "MIGRATION";
|
|
7
|
+
};
|
|
8
|
+
export type TierChangeSourceType = typeof TierChangeSource[keyof typeof TierChangeSource];
|
|
9
|
+
/**
|
|
10
|
+
* A fee config resolved to concrete numbers. `mode: 'default'` is deliberately
|
|
11
|
+
* unrepresentable — it would resolve against a mutable global at read time.
|
|
12
|
+
*
|
|
13
|
+
* `tranches` IS included: it is frozen data, just amount-parameterised. The bracket
|
|
14
|
+
* is chosen from the order amount at resolution time by `feeService`, so it cannot be
|
|
15
|
+
* flattened to a single `valueBps` at snapshot time.
|
|
16
|
+
*/
|
|
17
|
+
export type MaterializedFeeConfig = {
|
|
18
|
+
readonly mode: 'exempt';
|
|
19
|
+
} | {
|
|
20
|
+
readonly mode: 'flat';
|
|
21
|
+
readonly currency: 'USDC';
|
|
22
|
+
readonly valueBps: number;
|
|
23
|
+
} | {
|
|
24
|
+
readonly mode: 'tranches';
|
|
25
|
+
readonly currency: 'USDC';
|
|
26
|
+
readonly tranches: readonly FeeTranche[];
|
|
27
|
+
};
|
|
28
|
+
/** Monthly caps for a self-serve tier. `volumeUsdc` is a decimal string in whole USDC. */
|
|
29
|
+
export type TierMonthlyLimits = {
|
|
30
|
+
readonly volumeUsdc: string;
|
|
31
|
+
readonly orderCount: number;
|
|
32
|
+
};
|
|
33
|
+
type TierFeeDefinition = {
|
|
34
|
+
readonly fiatFeeConfig: MaterializedFeeConfig;
|
|
35
|
+
readonly cryptoFeeConfig: MaterializedFeeConfig;
|
|
36
|
+
} | {
|
|
37
|
+
/** Paired nulls mean commercial terms are admin-configured and must never be overwritten. */
|
|
38
|
+
readonly fiatFeeConfig: null;
|
|
39
|
+
readonly cryptoFeeConfig: null;
|
|
40
|
+
};
|
|
41
|
+
export type TierDefinition = TierFeeDefinition & {
|
|
42
|
+
readonly quotePreference: MerchantPaymentFlowModeType | null;
|
|
43
|
+
/** Policy-role name in the support dashboard. A string literal — SupportPolicyRole is a type alias, not a runtime enum. */
|
|
44
|
+
readonly supportPolicyRole: string;
|
|
45
|
+
/** Monthly order-volume / order-count caps enforced at order creation. null = unlimited. */
|
|
46
|
+
readonly monthlyLimits: TierMonthlyLimits | null;
|
|
47
|
+
/** Marketing/display copy only — render verbatim, never parse or branch on entries. */
|
|
48
|
+
readonly features: readonly string[];
|
|
49
|
+
};
|
|
50
|
+
export declare const TIER_DEFINITIONS: Readonly<Record<MerchantTierName, TierDefinition>>;
|
|
51
|
+
/** Server-side allowlist for self-serve tier selection — the only authority; `features` copy gates nothing. */
|
|
52
|
+
export declare const SELF_SERVE_TIERS: readonly MerchantTierName[];
|
|
53
|
+
/**
|
|
54
|
+
* Scan to Pay depends on seller automated release, which is available to Pro and Concierge merchants.
|
|
55
|
+
* Sandbox stays available so merchants can complete the no-value onboarding demo
|
|
56
|
+
* before choosing a live plan.
|
|
57
|
+
*/
|
|
58
|
+
export declare function canUseScanToPay(input: {
|
|
59
|
+
readonly tier: MerchantTierName | null | undefined;
|
|
60
|
+
readonly environment: MerchantEnvironmentType;
|
|
61
|
+
}): boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Formats a tier's monthly caps for display. `volumeUsdc` is a whole-USDC decimal string;
|
|
64
|
+
* exact thousands render as `$10K`, anything else as `$2,500`.
|
|
65
|
+
*/
|
|
66
|
+
export declare function formatTierMonthlyLimitsCopy(limits: TierMonthlyLimits | null): string;
|
package/dist/tiers.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { MerchantPaymentFlowMode, } from './types.js';
|
|
2
|
+
export const TierChangeSource = {
|
|
3
|
+
SELF_SERVE: 'SELF_SERVE',
|
|
4
|
+
ADMIN: 'ADMIN',
|
|
5
|
+
MIGRATION: 'MIGRATION',
|
|
6
|
+
};
|
|
7
|
+
export const TIER_DEFINITIONS = {
|
|
8
|
+
BASE: {
|
|
9
|
+
fiatFeeConfig: { mode: 'flat', currency: 'USDC', valueBps: 295 },
|
|
10
|
+
cryptoFeeConfig: { mode: 'flat', currency: 'USDC', valueBps: 100 },
|
|
11
|
+
quotePreference: MerchantPaymentFlowMode.PREFER_BUYER_TEE,
|
|
12
|
+
supportPolicyRole: 'BASIC_MERCHANT',
|
|
13
|
+
monthlyLimits: { volumeUsdc: '10000', orderCount: 50 },
|
|
14
|
+
features: [
|
|
15
|
+
'2.95% fiat / 1% crypto platform fees',
|
|
16
|
+
'Staking required before transacting on chargebackable rails',
|
|
17
|
+
],
|
|
18
|
+
},
|
|
19
|
+
PRO: {
|
|
20
|
+
fiatFeeConfig: { mode: 'flat', currency: 'USDC', valueBps: 495 },
|
|
21
|
+
cryptoFeeConfig: { mode: 'flat', currency: 'USDC', valueBps: 100 },
|
|
22
|
+
quotePreference: MerchantPaymentFlowMode.PREFER_SAR,
|
|
23
|
+
supportPolicyRole: 'PRO_MERCHANT',
|
|
24
|
+
monthlyLimits: { volumeUsdc: '30000', orderCount: 100 },
|
|
25
|
+
features: [
|
|
26
|
+
'4.95% fiat / 1% crypto platform fees',
|
|
27
|
+
'Staking required before transacting on chargebackable rails',
|
|
28
|
+
],
|
|
29
|
+
},
|
|
30
|
+
CONCIERGE: {
|
|
31
|
+
fiatFeeConfig: null,
|
|
32
|
+
cryptoFeeConfig: null,
|
|
33
|
+
quotePreference: null,
|
|
34
|
+
supportPolicyRole: 'CONCIERGE_MERCHANT',
|
|
35
|
+
monthlyLimits: null,
|
|
36
|
+
features: [
|
|
37
|
+
'Custom commercial terms',
|
|
38
|
+
'Flat-fee pricing available (admin-configured per merchant)',
|
|
39
|
+
],
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
/** Server-side allowlist for self-serve tier selection — the only authority; `features` copy gates nothing. */
|
|
43
|
+
export const SELF_SERVE_TIERS = ['BASE', 'PRO'];
|
|
44
|
+
/**
|
|
45
|
+
* Scan to Pay depends on seller automated release, which is available to Pro and Concierge merchants.
|
|
46
|
+
* Sandbox stays available so merchants can complete the no-value onboarding demo
|
|
47
|
+
* before choosing a live plan.
|
|
48
|
+
*/
|
|
49
|
+
export function canUseScanToPay(input) {
|
|
50
|
+
return input.environment === 'SANDBOX' || input.tier === 'PRO' || input.tier === 'CONCIERGE';
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Formats a tier's monthly caps for display. `volumeUsdc` is a whole-USDC decimal string;
|
|
54
|
+
* exact thousands render as `$10K`, anything else as `$2,500`.
|
|
55
|
+
*/
|
|
56
|
+
export function formatTierMonthlyLimitsCopy(limits) {
|
|
57
|
+
if (limits === null) {
|
|
58
|
+
return 'Unlimited volume and orders';
|
|
59
|
+
}
|
|
60
|
+
const whole = limits.volumeUsdc.split('.')[0] ?? '0';
|
|
61
|
+
const volume = whole.length > 3 && /^\d+000$/.test(whole)
|
|
62
|
+
? `$${whole.slice(0, -3)}K`
|
|
63
|
+
: `$${whole.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}`;
|
|
64
|
+
return `Up to ${volume} volume and ${limits.orderCount} orders per month`;
|
|
65
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { PayCryptoTokenSymbol } from './crypto.js';
|
|
2
2
|
import type { ProofMode } from './buyerTee.js';
|
|
3
|
+
import type { OnboardingStepIdValue } from './onboarding.js';
|
|
3
4
|
export declare const PaymentPlatform: {
|
|
4
5
|
readonly VENMO: "venmo";
|
|
5
6
|
readonly CASHAPP: "cashapp";
|
|
@@ -91,6 +92,46 @@ export declare const CheckoutPaymentStatus: {
|
|
|
91
92
|
readonly FAILED: "FAILED";
|
|
92
93
|
};
|
|
93
94
|
export type CheckoutPaymentStatusType = typeof CheckoutPaymentStatus[keyof typeof CheckoutPaymentStatus];
|
|
95
|
+
export declare const PaymentChargebackStatus: {
|
|
96
|
+
readonly NONE: "NONE";
|
|
97
|
+
readonly CHARGEBACKED: "CHARGEBACKED";
|
|
98
|
+
};
|
|
99
|
+
export type PaymentChargebackStatusType = typeof PaymentChargebackStatus[keyof typeof PaymentChargebackStatus];
|
|
100
|
+
export declare const OrderChargebackStatus: {
|
|
101
|
+
readonly NONE: "NONE";
|
|
102
|
+
readonly PARTIALLY_CHARGEBACKED: "PARTIALLY_CHARGEBACKED";
|
|
103
|
+
readonly CHARGEBACKED: "CHARGEBACKED";
|
|
104
|
+
};
|
|
105
|
+
export type OrderChargebackStatusType = typeof OrderChargebackStatus[keyof typeof OrderChargebackStatus];
|
|
106
|
+
export declare const ChargebackRefundOverlap: {
|
|
107
|
+
readonly NONE: "NONE";
|
|
108
|
+
readonly PENDING_HALTED: "PENDING_HALTED";
|
|
109
|
+
readonly SUBMITTING_OR_UNKNOWN: "SUBMITTING_OR_UNKNOWN";
|
|
110
|
+
readonly ALREADY_SUBMITTED: "ALREADY_SUBMITTED";
|
|
111
|
+
readonly ALREADY_REFUNDED: "ALREADY_REFUNDED";
|
|
112
|
+
};
|
|
113
|
+
export type ChargebackRefundOverlapType = typeof ChargebackRefundOverlap[keyof typeof ChargebackRefundOverlap];
|
|
114
|
+
export declare const PaymentBridgeStatus: {
|
|
115
|
+
readonly PENDING: "PENDING";
|
|
116
|
+
readonly SUBMITTED: "SUBMITTED";
|
|
117
|
+
readonly COMPLETED: "COMPLETED";
|
|
118
|
+
readonly FAILED: "FAILED";
|
|
119
|
+
};
|
|
120
|
+
export type PaymentBridgeStatusType = typeof PaymentBridgeStatus[keyof typeof PaymentBridgeStatus];
|
|
121
|
+
export type PaymentChargebackFact = {
|
|
122
|
+
paymentId: string;
|
|
123
|
+
intentHash: string;
|
|
124
|
+
disputeId: string;
|
|
125
|
+
status: typeof PaymentChargebackStatus.CHARGEBACKED;
|
|
126
|
+
compensatedUsdcAmount: string;
|
|
127
|
+
disputedAt: string;
|
|
128
|
+
disputeTxHash: string;
|
|
129
|
+
refundOverlap: ChargebackRefundOverlapType;
|
|
130
|
+
bridgeOrSweepOverlap: null | {
|
|
131
|
+
paymentBridgeId: string;
|
|
132
|
+
status: PaymentBridgeStatusType;
|
|
133
|
+
};
|
|
134
|
+
};
|
|
94
135
|
export declare const CheckoutPaymentMemoPolicy: {
|
|
95
136
|
readonly NONE: "NONE";
|
|
96
137
|
readonly REQUIRED: "REQUIRED";
|
|
@@ -159,6 +200,8 @@ export type CheckoutOrder = {
|
|
|
159
200
|
id: string;
|
|
160
201
|
merchantId: string;
|
|
161
202
|
status: CheckoutOrderStatusType;
|
|
203
|
+
chargebackStatus: OrderChargebackStatusType;
|
|
204
|
+
chargebacks: PaymentChargebackFact[];
|
|
162
205
|
refundStatus: CheckoutOrderRefundStatusType;
|
|
163
206
|
refundAmountUsdc: string | null;
|
|
164
207
|
refundDepositId: string | null;
|
|
@@ -232,6 +275,8 @@ export type CheckoutNearbySuggestions = {
|
|
|
232
275
|
export type QuoteAvailabilityRequest = {
|
|
233
276
|
amount: string;
|
|
234
277
|
quoteMode: CheckoutModeType;
|
|
278
|
+
/** Match the checkout's enabledRails override. Defaults to merchant rails; any matching rail suffices. */
|
|
279
|
+
enabledRails?: string[];
|
|
235
280
|
fiatCurrency?: string;
|
|
236
281
|
destinationChainId: string | number;
|
|
237
282
|
destinationToken: string;
|
|
@@ -268,6 +313,8 @@ export type CheckoutPayment = {
|
|
|
268
313
|
id: string;
|
|
269
314
|
orderId: string;
|
|
270
315
|
status: CheckoutPaymentStatusType;
|
|
316
|
+
chargebackStatus: PaymentChargebackStatusType;
|
|
317
|
+
chargeback: PaymentChargebackFact | null;
|
|
271
318
|
rail: string;
|
|
272
319
|
paymentMethodId: string | null;
|
|
273
320
|
proofMode: ProofMode;
|
|
@@ -319,6 +366,7 @@ export type CreatePaymentRequest = {
|
|
|
319
366
|
};
|
|
320
367
|
export type CheckoutPaymentCreationResponse = CheckoutPayment & {
|
|
321
368
|
relayerTransactionId?: string;
|
|
369
|
+
recipientRecovery?: 'matched' | 'missed' | 'not_applicable';
|
|
322
370
|
};
|
|
323
371
|
export type PaymentDeeplinkResponse = {
|
|
324
372
|
paymentId: string;
|
|
@@ -339,7 +387,6 @@ export type MerchantConfig = {
|
|
|
339
387
|
destinationChainId: string;
|
|
340
388
|
destinationToken: string;
|
|
341
389
|
sweepEnabled: boolean;
|
|
342
|
-
recipientOverrideEnabled: boolean;
|
|
343
390
|
disableBranding: boolean;
|
|
344
391
|
dynamicOrdersEnabled: boolean;
|
|
345
392
|
merchantCheckoutTheme: MerchantCheckoutTheme;
|
|
@@ -359,6 +406,7 @@ export type MerchantUser = {
|
|
|
359
406
|
createdAt: string;
|
|
360
407
|
updatedAt: string | null;
|
|
361
408
|
};
|
|
409
|
+
export type MerchantTierName = 'BASE' | 'PRO' | 'CONCIERGE';
|
|
362
410
|
export type MerchantProfile = {
|
|
363
411
|
id: string;
|
|
364
412
|
name: string;
|
|
@@ -376,7 +424,7 @@ export type MerchantProfile = {
|
|
|
376
424
|
solanaWalletAddress: string | null;
|
|
377
425
|
v1EvmWalletAddress: string | null;
|
|
378
426
|
v1SolanaWalletAddress: string | null;
|
|
379
|
-
tier:
|
|
427
|
+
tier: MerchantTierName | null;
|
|
380
428
|
createdAt: string;
|
|
381
429
|
updatedAt: string | null;
|
|
382
430
|
merchantConfig: MerchantConfig | null;
|
|
@@ -399,6 +447,12 @@ export declare const OrderErrorCode: {
|
|
|
399
447
|
readonly UNKNOWN_ERROR: "UNKNOWN_ERROR";
|
|
400
448
|
};
|
|
401
449
|
export type OrderErrorCodeType = typeof OrderErrorCode[keyof typeof OrderErrorCode];
|
|
450
|
+
export type PaymentSigningErrorCode = 'MERCHANT_WALLET_NOT_DELEGATED' | 'MERCHANT_SIGNER_WALLET_MISSING' | 'MERCHANT_SIGNING_UNAVAILABLE';
|
|
451
|
+
export declare const SubmissionChannel: {
|
|
452
|
+
readonly OZ_RELAYER: "OZ_RELAYER";
|
|
453
|
+
readonly MERCHANT_PRIVY: "MERCHANT_PRIVY";
|
|
454
|
+
};
|
|
455
|
+
export type SubmissionChannelType = (typeof SubmissionChannel)[keyof typeof SubmissionChannel];
|
|
402
456
|
export declare const MerchantEnvironment: {
|
|
403
457
|
readonly LIVE: "LIVE";
|
|
404
458
|
readonly SANDBOX: "SANDBOX";
|
|
@@ -701,7 +755,7 @@ export interface BridgeStatusResponse {
|
|
|
701
755
|
failureMessage?: string;
|
|
702
756
|
}
|
|
703
757
|
export interface OrderBridgeInfo {
|
|
704
|
-
status:
|
|
758
|
+
status: PaymentBridgeStatusType;
|
|
705
759
|
destinationChainId: string;
|
|
706
760
|
outputAmount?: string;
|
|
707
761
|
estimatedOutputAmount?: string;
|
|
@@ -730,7 +784,7 @@ export declare const OnboardingStepVerifiedBy: {
|
|
|
730
784
|
};
|
|
731
785
|
export type OnboardingStepVerifiedByValue = typeof OnboardingStepVerifiedBy[keyof typeof OnboardingStepVerifiedBy];
|
|
732
786
|
export type OnboardingStepState = {
|
|
733
|
-
id:
|
|
787
|
+
id: OnboardingStepIdValue;
|
|
734
788
|
status: OnboardingStepStatusValue;
|
|
735
789
|
verifiedBy: OnboardingStepVerifiedByValue;
|
|
736
790
|
};
|
|
@@ -757,6 +811,9 @@ export declare const WebhookEventType: {
|
|
|
757
811
|
readonly PAYMENT_BRIDGE_SUBMITTED: "PAYMENT_BRIDGE_SUBMITTED";
|
|
758
812
|
readonly PAYMENT_BRIDGE_COMPLETED: "PAYMENT_BRIDGE_COMPLETED";
|
|
759
813
|
readonly PAYMENT_BRIDGE_FAILED: "PAYMENT_BRIDGE_FAILED";
|
|
814
|
+
readonly PAYMENT_CHARGEBACKED: "PAYMENT_CHARGEBACKED";
|
|
815
|
+
readonly ORDER_PARTIALLY_CHARGEBACKED: "ORDER_PARTIALLY_CHARGEBACKED";
|
|
816
|
+
readonly ORDER_CHARGEBACKED: "ORDER_CHARGEBACKED";
|
|
760
817
|
};
|
|
761
818
|
export type WebhookEventTypeValue = typeof WebhookEventType[keyof typeof WebhookEventType];
|
|
762
819
|
export declare const WebhookDeliveryStatus: {
|
|
@@ -800,6 +857,13 @@ export type WebhookPayload = {
|
|
|
800
857
|
payment: CheckoutPayment | null;
|
|
801
858
|
refund: Record<string, unknown> | null;
|
|
802
859
|
paymentBridge: Record<string, unknown> | null;
|
|
860
|
+
trigger?: {
|
|
861
|
+
type: 'CHARGEBACK_APPLIED';
|
|
862
|
+
chargeback: PaymentChargebackFact;
|
|
863
|
+
} | {
|
|
864
|
+
type: 'PAYMENT_SETTLED';
|
|
865
|
+
paymentId: string;
|
|
866
|
+
};
|
|
803
867
|
resize?: {
|
|
804
868
|
previousAmountUsdc: string;
|
|
805
869
|
newAmountUsdc: string;
|
package/dist/types.js
CHANGED
|
@@ -85,6 +85,28 @@ export const CheckoutPaymentStatus = {
|
|
|
85
85
|
EXPIRED: 'EXPIRED',
|
|
86
86
|
FAILED: 'FAILED',
|
|
87
87
|
};
|
|
88
|
+
export const PaymentChargebackStatus = {
|
|
89
|
+
NONE: 'NONE',
|
|
90
|
+
CHARGEBACKED: 'CHARGEBACKED',
|
|
91
|
+
};
|
|
92
|
+
export const OrderChargebackStatus = {
|
|
93
|
+
NONE: 'NONE',
|
|
94
|
+
PARTIALLY_CHARGEBACKED: 'PARTIALLY_CHARGEBACKED',
|
|
95
|
+
CHARGEBACKED: 'CHARGEBACKED',
|
|
96
|
+
};
|
|
97
|
+
export const ChargebackRefundOverlap = {
|
|
98
|
+
NONE: 'NONE',
|
|
99
|
+
PENDING_HALTED: 'PENDING_HALTED',
|
|
100
|
+
SUBMITTING_OR_UNKNOWN: 'SUBMITTING_OR_UNKNOWN',
|
|
101
|
+
ALREADY_SUBMITTED: 'ALREADY_SUBMITTED',
|
|
102
|
+
ALREADY_REFUNDED: 'ALREADY_REFUNDED',
|
|
103
|
+
};
|
|
104
|
+
export const PaymentBridgeStatus = {
|
|
105
|
+
PENDING: 'PENDING',
|
|
106
|
+
SUBMITTED: 'SUBMITTED',
|
|
107
|
+
COMPLETED: 'COMPLETED',
|
|
108
|
+
FAILED: 'FAILED',
|
|
109
|
+
};
|
|
88
110
|
export const CheckoutPaymentMemoPolicy = {
|
|
89
111
|
NONE: 'NONE',
|
|
90
112
|
REQUIRED: 'REQUIRED',
|
|
@@ -113,6 +135,10 @@ export const OrderErrorCode = {
|
|
|
113
135
|
SDK_ERROR: 'SDK_ERROR', // Unknown SDK error
|
|
114
136
|
UNKNOWN_ERROR: 'UNKNOWN_ERROR', // Uncategorized error
|
|
115
137
|
};
|
|
138
|
+
export const SubmissionChannel = {
|
|
139
|
+
OZ_RELAYER: 'OZ_RELAYER',
|
|
140
|
+
MERCHANT_PRIVY: 'MERCHANT_PRIVY',
|
|
141
|
+
};
|
|
116
142
|
export const MerchantEnvironment = {
|
|
117
143
|
LIVE: 'LIVE',
|
|
118
144
|
SANDBOX: 'SANDBOX',
|
|
@@ -154,6 +180,9 @@ export const WebhookEventType = {
|
|
|
154
180
|
PAYMENT_BRIDGE_SUBMITTED: 'PAYMENT_BRIDGE_SUBMITTED',
|
|
155
181
|
PAYMENT_BRIDGE_COMPLETED: 'PAYMENT_BRIDGE_COMPLETED',
|
|
156
182
|
PAYMENT_BRIDGE_FAILED: 'PAYMENT_BRIDGE_FAILED',
|
|
183
|
+
PAYMENT_CHARGEBACKED: 'PAYMENT_CHARGEBACKED',
|
|
184
|
+
ORDER_PARTIALLY_CHARGEBACKED: 'ORDER_PARTIALLY_CHARGEBACKED',
|
|
185
|
+
ORDER_CHARGEBACKED: 'ORDER_CHARGEBACKED',
|
|
157
186
|
};
|
|
158
187
|
export const WebhookDeliveryStatus = {
|
|
159
188
|
PENDING: 'PENDING',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zkp2p/pay-shared",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.1",
|
|
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",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"lint": "eslint . --ext .ts,.tsx",
|
|
40
40
|
"test": "vitest run",
|
|
41
41
|
"prepack": "npm run build",
|
|
42
|
-
"prepublishOnly": "npm
|
|
42
|
+
"prepublishOnly": "npm run lint"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"vitest": "^1.6.1"
|