@bitpal/checkout 0.3.0 → 0.5.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/LICENSE +21 -0
- package/README.md +221 -392
- package/dist/index.cjs +374 -0
- package/dist/index.d.cts +566 -0
- package/dist/index.d.ts +266 -411
- package/dist/index.js +118 -201
- package/package.json +33 -17
- package/MIGRATION_v0.2.md +0 -135
package/dist/index.d.ts
CHANGED
|
@@ -3,13 +3,17 @@
|
|
|
3
3
|
*/
|
|
4
4
|
interface BitPalConfig {
|
|
5
5
|
/**
|
|
6
|
-
* API
|
|
6
|
+
* API 키(서버 전용, secret). prefix 가 mode 를 결정합니다:
|
|
7
7
|
* - `bp_test_...` → TEST mode (testnet 또는 local anvil)
|
|
8
8
|
* - `bp_live_...` → LIVE mode (mainnet)
|
|
9
9
|
*
|
|
10
10
|
* BitPal 콘솔 → Developers → API Keys 에서 발급.
|
|
11
|
+
*
|
|
12
|
+
* **선택**: createSession/listSessions/products 등 서버 메서드는 필수. 그러나 buyer-facing 공개 메서드
|
|
13
|
+
* (getPublicSession/getStatus/issueDepositAddress)는 인증 불요(session_token 기반)이므로 브라우저에서
|
|
14
|
+
* apiKey 없이 쓸 수 있다 — 절대 secret 키를 브라우저에 노출하지 말 것.
|
|
11
15
|
*/
|
|
12
|
-
apiKey
|
|
16
|
+
apiKey?: string;
|
|
13
17
|
/**
|
|
14
18
|
* BitPal API 기본 URL. 환경별로 다릅니다:
|
|
15
19
|
* - production: `https://api.bitpal.io` (기본값) — 실제 testnet/mainnet 컨트랙트
|
|
@@ -32,12 +36,24 @@ interface LineItem {
|
|
|
32
36
|
currency: string;
|
|
33
37
|
quantity?: number;
|
|
34
38
|
}
|
|
39
|
+
interface PriceLineItem {
|
|
40
|
+
/** price_... — bitpal.checkout.prices.create()로 만든 가격 */
|
|
41
|
+
price_id: string;
|
|
42
|
+
quantity?: number;
|
|
43
|
+
}
|
|
44
|
+
type CheckoutLineItemInput = LineItem | PriceLineItem;
|
|
35
45
|
interface CreateSessionParams {
|
|
36
|
-
line_items:
|
|
46
|
+
line_items: CheckoutLineItemInput[];
|
|
37
47
|
/** 고객 지갑 주소 (선택) */
|
|
38
48
|
payer_wallet?: string;
|
|
39
|
-
/** 결제 체인 (예: eip155:8453) */
|
|
49
|
+
/** 결제 체인 (예: eip155:8453). 단일 고정 — allowed_pay_chains와 상호 배타. */
|
|
40
50
|
pay_chain?: string;
|
|
51
|
+
/**
|
|
52
|
+
* 허용 결제 체인 목록 (CAIP-2). 구매자가 이 중에서 선택하며, 하나뿐이면 자동 선택된다.
|
|
53
|
+
* pay_chain(단일 고정)과 **상호 배타** — 동시 지정 시 SDK가 에러를 throw한다.
|
|
54
|
+
* 예: ['eip155:84532', 'eip155:11155420', 'eip155:80002', 'eip155:421614']
|
|
55
|
+
*/
|
|
56
|
+
allowed_pay_chains?: string[];
|
|
41
57
|
/** 결제 자산 (예: USDC) */
|
|
42
58
|
pay_asset?: string;
|
|
43
59
|
/** 허용 오차 (%, 기본값: 2.00) */
|
|
@@ -67,12 +83,8 @@ interface CheckoutSession {
|
|
|
67
83
|
settled_at: string | null;
|
|
68
84
|
tx_hash: string | null;
|
|
69
85
|
created_at: string;
|
|
70
|
-
/** 'hosted'
|
|
86
|
+
/** 'hosted' — 결제 경로. hosted deposit-address 단일 경로. */
|
|
71
87
|
payment_source?: string;
|
|
72
|
-
/** External on-chain 결제 검증 기록 목록 */
|
|
73
|
-
payment_observations?: PaymentObservation[];
|
|
74
|
-
/** External/gasless checkout payment config supplied by BitPal API. */
|
|
75
|
-
external_payment_config?: ExternalPaymentConfig;
|
|
76
88
|
/** 호스티드 결제 페이지 URL (token 쿼리 포함). backend 응답 그대로 사용 — buyer를 이 URL로 redirect. */
|
|
77
89
|
checkout_url?: string;
|
|
78
90
|
/** 1회용 session token. `checkout_url`에 이미 query로 박혀 있어 별도 사용 불필요. */
|
|
@@ -80,119 +92,89 @@ interface CheckoutSession {
|
|
|
80
92
|
/** `checkout_url`의 별칭 (backwards compat). buyer redirect 시 이 필드 또는 `checkout_url` 사용. */
|
|
81
93
|
url: string;
|
|
82
94
|
}
|
|
83
|
-
interface ExternalPaymentConfig {
|
|
84
|
-
chain: string;
|
|
85
|
-
chain_id: string;
|
|
86
|
-
payment_id: string;
|
|
87
|
-
escrow_contract_address: string | null;
|
|
88
|
-
token_address: string | null;
|
|
89
|
-
merchant_wallet: string;
|
|
90
|
-
amount: string;
|
|
91
|
-
fee_amount: string;
|
|
92
|
-
reserve_amount: string;
|
|
93
|
-
asset: string;
|
|
94
|
-
decimals: number;
|
|
95
|
-
supported_methods: Array<'authorization_relay'>;
|
|
96
|
-
}
|
|
97
95
|
/**
|
|
98
|
-
*
|
|
99
|
-
* `
|
|
96
|
+
* 결제 옵션(chain×token). `/public` 이 서버 권위로 내려주며, buyer 가 하나를 골라
|
|
97
|
+
* `issueDepositAddress({ chain, token })` 로 입금주소를 발급받는다. 단일-자산 세션은 1개.
|
|
100
98
|
*/
|
|
101
|
-
interface
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
chain_id:
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
/** Atomic μUSDC 정수 문자열 */
|
|
108
|
-
amount: string;
|
|
109
|
-
/** 'pending' | 'valid' | 'invalid' | 'duplicate' | 'underpaid' | 'overpaid' */
|
|
110
|
-
validation_status: string;
|
|
111
|
-
/** 'detected' | 'soft_confirmed' | 'final_confirmed' | 'reorg_revoked' */
|
|
112
|
-
finality_status: string;
|
|
113
|
-
validation_error: string | null;
|
|
114
|
-
block_number: number | null;
|
|
115
|
-
confirmations: number;
|
|
116
|
-
created_at: string;
|
|
99
|
+
interface PaymentOption {
|
|
100
|
+
/** CAIP-2 (예: eip155:8453) */
|
|
101
|
+
caip2: string;
|
|
102
|
+
chain_id: number;
|
|
103
|
+
token_symbol: string;
|
|
104
|
+
token_address: string;
|
|
117
105
|
}
|
|
118
106
|
/**
|
|
119
|
-
* `
|
|
120
|
-
*
|
|
107
|
+
* `getPublicSession()` (`GET /v1/checkout/sessions/:id/public`) 응답 — 인증 불요(공개).
|
|
108
|
+
* buyer-facing 결제 페이지가 표시/폴링에 쓰는 서버 권위 뷰.
|
|
121
109
|
*/
|
|
122
|
-
interface
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
110
|
+
interface PublicSession {
|
|
111
|
+
id: string;
|
|
112
|
+
/** created | awaiting_deposit | deposit_detected | paid_confirmed | swept | unresolved_* | wrong_token | expired ... */
|
|
113
|
+
status: string;
|
|
114
|
+
mode: string | null;
|
|
115
|
+
currency: string;
|
|
116
|
+
/** Atomic 정수 문자열(토큰 decimals 기준). */
|
|
117
|
+
amount_total: string;
|
|
118
|
+
amount_received?: string | null;
|
|
119
|
+
pay_chain: string | null;
|
|
120
|
+
pay_asset: string | null;
|
|
121
|
+
/** 발급된 주문별 forwarder 입금주소(미발급이면 null). */
|
|
122
|
+
deposit_address?: string | null;
|
|
123
|
+
/** 구매자 선택 가능한 결제 옵션(서버 권위). 단일-자산이면 1개. */
|
|
124
|
+
payment_options: PaymentOption[];
|
|
125
|
+
chain_id: number | null;
|
|
126
|
+
token_address: string | null;
|
|
127
|
+
tx_hash: string | null;
|
|
128
|
+
release_tx_hash?: string | null;
|
|
129
|
+
expires_at: string | null;
|
|
130
|
+
success_url: string | null;
|
|
131
|
+
cancel_url: string | null;
|
|
132
|
+
fee_amount: string | null;
|
|
133
|
+
net_amount: string | null;
|
|
134
|
+
seller_wallet: string;
|
|
135
|
+
paid_at: string | null;
|
|
136
|
+
settled_at: string | null;
|
|
137
|
+
created_at: string;
|
|
138
|
+
line_items: LineItem[];
|
|
129
139
|
}
|
|
130
140
|
/**
|
|
131
|
-
* `
|
|
141
|
+
* `issueDepositAddress()` 요청 파라미터.
|
|
142
|
+
* chain/token 은 멀티옵션 세션에서만 필요(단일-자산 세션은 생략). refundAddress 는 필수 —
|
|
143
|
+
* 금액부족/잘못된토큰/만료 시 이 주소로 환불되며, 입금주소에 커밋되어 발급 후 변경 불가.
|
|
132
144
|
*/
|
|
133
|
-
interface
|
|
134
|
-
|
|
135
|
-
/** 'valid' | 'invalid' | 'underpaid' | 'overpaid' | 'duplicate' */
|
|
136
|
-
validation_status: string;
|
|
137
|
-
/** 검증 후 세션 상태 */
|
|
138
|
-
session_status: string;
|
|
139
|
-
/** 입금한 지갑 주소 (on-chain 이벤트에서 도출) */
|
|
140
|
-
from_address: string | null;
|
|
141
|
-
/** Atomic μUSDC 정수 문자열 */
|
|
142
|
-
amount: string;
|
|
143
|
-
message: string;
|
|
144
|
-
}
|
|
145
|
-
interface PayWithAuthorizationParams {
|
|
146
|
-
chain?: string;
|
|
145
|
+
interface IssueDepositAddressParams {
|
|
146
|
+
/** 결제 페이지 접근 증명(HMAC). createSession 응답의 session_token. */
|
|
147
147
|
session_token: string;
|
|
148
|
-
/**
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
v: number;
|
|
155
|
-
r: string;
|
|
156
|
-
s: string;
|
|
157
|
-
};
|
|
158
|
-
/**
|
|
159
|
-
* Q5 C-01 옵션 2 (SDK v0.2.0): PaymentAuthorization typed-data sig.
|
|
160
|
-
* Buyer 가 결제 의도 전체 (paymentId, merchant, amount, fee, reserve, duration) 에 서명.
|
|
161
|
-
* gateway 키 탈취 시에도 buyer 의도 밖 결제 생성 차단.
|
|
162
|
-
*
|
|
163
|
-
* 서명 생성: `buildPaymentAuthTypedData()` helper 또는 viem `signTypedData` 직접 호출.
|
|
164
|
-
* Required for SDK v0.2.x+ — gasless lane 모든 호출에 필수. v0.1.x 는 미지원.
|
|
165
|
-
*/
|
|
166
|
-
payment_auth: {
|
|
167
|
-
deadline: string;
|
|
168
|
-
duration: string;
|
|
169
|
-
v: number;
|
|
170
|
-
r: string;
|
|
171
|
-
s: string;
|
|
172
|
-
};
|
|
148
|
+
/** 환불 주소(0x EVM). 필수. */
|
|
149
|
+
refundAddress: string;
|
|
150
|
+
/** 선택 자산의 chain(CAIP-2 또는 short-name). 멀티옵션 세션 필수. */
|
|
151
|
+
chain?: string;
|
|
152
|
+
/** 선택 자산의 token symbol(예: USDC). 멀티옵션 세션 필수. */
|
|
153
|
+
token?: string;
|
|
173
154
|
}
|
|
174
155
|
/**
|
|
175
|
-
*
|
|
176
|
-
* `buildPaymentAuthTypedData()` 가 이를 받아 viem 호환 객체를 반환.
|
|
156
|
+
* `issueDepositAddress()` 응답 — 이 주소로 정확 금액을 송금하면 watcher 가 감지, keeper 가 정산한다.
|
|
177
157
|
*/
|
|
178
|
-
interface
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
158
|
+
interface DepositAddress {
|
|
159
|
+
sessionId: string;
|
|
160
|
+
chain: string;
|
|
161
|
+
/** 주문별 CREATE2 forwarder 입금주소. */
|
|
162
|
+
depositAddress: string;
|
|
163
|
+
expectedToken: string;
|
|
164
|
+
/** Atomic 정수 문자열. */
|
|
165
|
+
expectedAmount: string;
|
|
186
166
|
feeAmount: string;
|
|
187
|
-
|
|
188
|
-
|
|
167
|
+
refundAddress: string;
|
|
168
|
+
/** Unix seconds — on-chain deadline. */
|
|
189
169
|
deadline: string;
|
|
190
|
-
|
|
170
|
+
expiresAt: string | null;
|
|
191
171
|
}
|
|
192
|
-
|
|
172
|
+
/**
|
|
173
|
+
* `getStatus()` (`GET /v1/checkout/sessions/:id/status`) 응답 — 경량 폴링용(인증 불요).
|
|
174
|
+
*/
|
|
175
|
+
interface SessionStatus {
|
|
193
176
|
status: string;
|
|
194
|
-
|
|
195
|
-
message?: string;
|
|
177
|
+
paid_at: string | null;
|
|
196
178
|
}
|
|
197
179
|
/**
|
|
198
180
|
* 수수료 미리보기 응답.
|
|
@@ -206,65 +188,16 @@ interface FeePreview {
|
|
|
206
188
|
net_amount: string;
|
|
207
189
|
}
|
|
208
190
|
/**
|
|
209
|
-
*
|
|
210
|
-
*
|
|
211
|
-
*
|
|
212
|
-
* `amount` 미지정 시 backend가 잔액 전액(full refund)을 시도. 명시 시 atomic μUSDC.
|
|
213
|
-
*/
|
|
214
|
-
interface RefundSessionParams {
|
|
215
|
-
/** Atomic μUSDC 정수 문자열. 미지정 시 전액. */
|
|
216
|
-
amount?: string;
|
|
217
|
-
/** 환불 사유 코드 (선택, 머천트 대시보드/audit log 분류용) */
|
|
218
|
-
reason?: string;
|
|
219
|
-
/** 환불 사유 상세 (선택, 자유 텍스트) */
|
|
220
|
-
reason_detail?: string;
|
|
221
|
-
}
|
|
222
|
-
interface RefundSessionResult {
|
|
223
|
-
refunded: boolean;
|
|
224
|
-
refundId: string;
|
|
225
|
-
/** Atomic μUSDC 정수 문자열 */
|
|
226
|
-
amount: string;
|
|
227
|
-
type: 'full' | 'partial';
|
|
228
|
-
/** on-chain transaction hash. simulation/escrow 미배포 환경에서는 sim_xxx */
|
|
229
|
-
txHash: string | null;
|
|
230
|
-
}
|
|
231
|
-
/**
|
|
232
|
-
* Record refund 파라미터 — `status='settled'` 후 머천트가 외부 지갑에서 직접 송금하고
|
|
233
|
-
* tx_hash를 입력해 환불을 DB-only로 기록한다. 컨트랙트 호출 없음.
|
|
191
|
+
* 환불은 온체인 자동 경로 — SDK 에 수동 환불 API 는 없다.
|
|
192
|
+
* 금액부족/잘못된토큰/만료 시 issueDepositAddress 에 지정한 refundAddress 로 자동 환불되고,
|
|
193
|
+
* 세션 status(expired/unresolved) + webhook 으로 통지된다.
|
|
234
194
|
*/
|
|
235
|
-
interface RecordRefundParams {
|
|
236
|
-
/** Atomic μUSDC 정수 문자열 (필수) */
|
|
237
|
-
refund_amount: string;
|
|
238
|
-
/** 외부 송금 transaction hash (필수, 형식 검증 안 함) */
|
|
239
|
-
tx_hash: string;
|
|
240
|
-
/** 환불 사유 (선택) */
|
|
241
|
-
reason?: string;
|
|
242
|
-
}
|
|
243
195
|
/**
|
|
244
196
|
* 멱등성 키 — 동일 키로 재시도 시 backend가 같은 결과 반환.
|
|
245
|
-
* Phase 1 SDK는 사용자가 명시적으로 전달 (UUID 권장).
|
|
246
197
|
*/
|
|
247
198
|
interface IdempotencyOptions {
|
|
248
199
|
idempotencyKey?: string;
|
|
249
200
|
}
|
|
250
|
-
/**
|
|
251
|
-
* `GET /v1/checkout/sessions/:id/refunds` 응답 row.
|
|
252
|
-
* 필드는 backend `listSessionRefunds` 반환과 동일 — Phase 1에서는 통합 타입 미고정 (스냅샷 시점에 따라 컬럼 변동).
|
|
253
|
-
*/
|
|
254
|
-
interface RefundEntry {
|
|
255
|
-
id: string;
|
|
256
|
-
session_id: string;
|
|
257
|
-
/** 'auto' | 'record' (escrow refund vs DB-only manual) */
|
|
258
|
-
refund_mode?: string;
|
|
259
|
-
amount: string;
|
|
260
|
-
/** 'pending' | 'completed' | 'failed' 등 */
|
|
261
|
-
status?: string;
|
|
262
|
-
tx_hash: string | null;
|
|
263
|
-
reason?: string | null;
|
|
264
|
-
reason_detail?: string | null;
|
|
265
|
-
created_at: string;
|
|
266
|
-
[key: string]: unknown;
|
|
267
|
-
}
|
|
268
201
|
interface ApiResponse<T> {
|
|
269
202
|
data: T;
|
|
270
203
|
error?: string;
|
|
@@ -273,6 +206,125 @@ interface ListResponse<T> {
|
|
|
273
206
|
data: T[];
|
|
274
207
|
total?: number;
|
|
275
208
|
}
|
|
209
|
+
interface CheckoutProduct {
|
|
210
|
+
/** prod_... */
|
|
211
|
+
id: string;
|
|
212
|
+
name: string;
|
|
213
|
+
description: string | null;
|
|
214
|
+
image_url: string | null;
|
|
215
|
+
/** 'active' | 'inactive' */
|
|
216
|
+
status: string;
|
|
217
|
+
metadata: Record<string, unknown>;
|
|
218
|
+
mode: string;
|
|
219
|
+
created_at: string;
|
|
220
|
+
updated_at: string;
|
|
221
|
+
}
|
|
222
|
+
interface CheckoutPrice {
|
|
223
|
+
/** price_... */
|
|
224
|
+
id: string;
|
|
225
|
+
/** prod_... */
|
|
226
|
+
product_id: string;
|
|
227
|
+
/** 원자 단위 정수 문자열 ($1 = "1000000") — 불변 */
|
|
228
|
+
amount_atomic: string;
|
|
229
|
+
currency: string;
|
|
230
|
+
token_symbol: string;
|
|
231
|
+
/** v1: 'one_time' */
|
|
232
|
+
billing_type: string;
|
|
233
|
+
nickname: string | null;
|
|
234
|
+
lookup_key: string | null;
|
|
235
|
+
mode: string;
|
|
236
|
+
created_at: string;
|
|
237
|
+
}
|
|
238
|
+
interface CreateProductParams {
|
|
239
|
+
name: string;
|
|
240
|
+
description?: string;
|
|
241
|
+
image_url?: string;
|
|
242
|
+
metadata?: Record<string, unknown>;
|
|
243
|
+
}
|
|
244
|
+
interface UpdateProductParams {
|
|
245
|
+
name?: string;
|
|
246
|
+
description?: string | null;
|
|
247
|
+
image_url?: string | null;
|
|
248
|
+
metadata?: Record<string, unknown>;
|
|
249
|
+
status?: 'active' | 'inactive';
|
|
250
|
+
}
|
|
251
|
+
interface CreatePriceParams {
|
|
252
|
+
/** 원자 단위 정수 문자열 ($1 = "1000000"). `toAtomicUSDC('1.00')` 헬퍼 사용 권장 */
|
|
253
|
+
amount_atomic: string;
|
|
254
|
+
currency?: string;
|
|
255
|
+
token_symbol?: string;
|
|
256
|
+
billing_type?: 'one_time';
|
|
257
|
+
nickname?: string;
|
|
258
|
+
lookup_key?: string;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Price는 lifecycle 없는 immutable record — 변경 가능한 것은 nickname(표시 메타)뿐.
|
|
262
|
+
* 금액류 필드(amount_atomic 등)는 immutable, "그만 팔기"는 Price 가 아니라 그 Price 를 쓰는
|
|
263
|
+
* Payment Link 를 inactive 로 한다.
|
|
264
|
+
*/
|
|
265
|
+
interface UpdatePriceParams {
|
|
266
|
+
nickname?: string | null;
|
|
267
|
+
}
|
|
268
|
+
interface ListProductsParams {
|
|
269
|
+
status?: 'active' | 'inactive';
|
|
270
|
+
limit?: number;
|
|
271
|
+
offset?: number;
|
|
272
|
+
}
|
|
273
|
+
interface ListPricesParams {
|
|
274
|
+
limit?: number;
|
|
275
|
+
offset?: number;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* catalog.ts — Product / immutable Price 관리 리소스 (PROD-LINK-3a-SDK)
|
|
280
|
+
*
|
|
281
|
+
* server-side SDK 전용 (secret API key). 브라우저에서 사용 금지.
|
|
282
|
+
*
|
|
283
|
+
* 사용 예:
|
|
284
|
+
* ```ts
|
|
285
|
+
* const bitpal = new BitPal({ apiKey: 'bp_test_...' });
|
|
286
|
+
* const { data: product } = await bitpal.checkout.products.create({ name: 'Pro Plan' });
|
|
287
|
+
* const { data: price } = await bitpal.checkout.prices.create(product.id, {
|
|
288
|
+
* amount_atomic: toAtomicUSDC('29.00'),
|
|
289
|
+
* });
|
|
290
|
+
* ```
|
|
291
|
+
*
|
|
292
|
+
* Price immutable 원칙: 가격 변경은 update가 아니라 "새 price 생성"이다.
|
|
293
|
+
* `prices.update`는 nickname(표시 메타)만 받는다 — 금액류 필드 변경 helper는 의도적으로 없다.
|
|
294
|
+
* "그만 팔기"는 Price 를 끄는 게 아니라 그 Price 를 쓰는 Payment Link 를 inactive 로 한다.
|
|
295
|
+
*/
|
|
296
|
+
|
|
297
|
+
/** client.ts의 private request를 리소스에 주입하기 위한 시그니처 */
|
|
298
|
+
type CatalogRequester = <T>(method: string, path: string, body?: unknown) => Promise<T>;
|
|
299
|
+
declare class ProductsResource {
|
|
300
|
+
private readonly request;
|
|
301
|
+
constructor(request: CatalogRequester);
|
|
302
|
+
/** POST /v1/checkout/products */
|
|
303
|
+
create(params: CreateProductParams): Promise<ApiResponse<CheckoutProduct>>;
|
|
304
|
+
/** GET /v1/checkout/products */
|
|
305
|
+
list(params?: ListProductsParams): Promise<ListResponse<CheckoutProduct>>;
|
|
306
|
+
/** GET /v1/checkout/products/:id */
|
|
307
|
+
retrieve(productId: string): Promise<ApiResponse<CheckoutProduct>>;
|
|
308
|
+
/** PATCH /v1/checkout/products/:id */
|
|
309
|
+
update(productId: string, params: UpdateProductParams): Promise<ApiResponse<CheckoutProduct>>;
|
|
310
|
+
}
|
|
311
|
+
declare class PricesResource {
|
|
312
|
+
private readonly request;
|
|
313
|
+
constructor(request: CatalogRequester);
|
|
314
|
+
/** POST /v1/checkout/products/:id/prices */
|
|
315
|
+
create(productId: string, params: CreatePriceParams): Promise<ApiResponse<CheckoutPrice>>;
|
|
316
|
+
/** GET /v1/checkout/products/:id/prices */
|
|
317
|
+
list(productId: string, params?: ListPricesParams): Promise<ListResponse<CheckoutPrice>>;
|
|
318
|
+
/** GET /v1/checkout/prices/:id */
|
|
319
|
+
retrieve(priceId: string): Promise<ApiResponse<CheckoutPrice>>;
|
|
320
|
+
/**
|
|
321
|
+
* PATCH /v1/checkout/prices/:id — nickname(표시 메타)만.
|
|
322
|
+
* 금액류 필드(amount_atomic 등)는 immutable — 서버가 PRICE_IMMUTABLE_FIELD로 거부한다.
|
|
323
|
+
* 가격 변경은 `prices.create()`로 새 price를 만들 것. "그만 팔기"는 해당 Price 를 쓰는
|
|
324
|
+
* Payment Link 를 inactive 로 한다(Price 자체에는 active/inactive 개념이 없다).
|
|
325
|
+
*/
|
|
326
|
+
update(priceId: string, params: UpdatePriceParams): Promise<ApiResponse<CheckoutPrice>>;
|
|
327
|
+
}
|
|
276
328
|
|
|
277
329
|
/**
|
|
278
330
|
* @bitpal/checkout SDK — 클라이언트
|
|
@@ -282,9 +334,14 @@ interface ListResponse<T> {
|
|
|
282
334
|
*/
|
|
283
335
|
|
|
284
336
|
declare class BitPalCheckoutClient {
|
|
337
|
+
/** 서버 메서드용 secret 키. 공개(buyer-facing) 메서드는 없이도 동작. */
|
|
285
338
|
private readonly apiKey;
|
|
286
339
|
private readonly baseUrl;
|
|
287
340
|
private readonly timeout;
|
|
341
|
+
/** PROD-LINK-3a-SDK: Product 카탈로그 관리 (server-side 전용) */
|
|
342
|
+
readonly products: ProductsResource;
|
|
343
|
+
/** PROD-LINK-3a-SDK: immutable Price 관리 — 가격 변경은 비활성화 + 새 price 생성 */
|
|
344
|
+
readonly prices: PricesResource;
|
|
288
345
|
constructor(config: BitPalConfig);
|
|
289
346
|
private request;
|
|
290
347
|
/**
|
|
@@ -300,6 +357,13 @@ declare class BitPalCheckoutClient {
|
|
|
300
357
|
* line_items: [{ name: 'Pro', amount: toAtomicUSDC('29.00'), currency: 'USDC' }],
|
|
301
358
|
* });
|
|
302
359
|
* console.log(data.url); // → buyer를 redirect할 결제 페이지
|
|
360
|
+
*
|
|
361
|
+
* // 멀티체인 허용 — 구매자가 Base/Optimism 중 선택(하나뿐이면 자동 선택):
|
|
362
|
+
* await bp.checkout.createSession({
|
|
363
|
+
* line_items: [{ name: 'Pro', amount: toAtomicUSDC('29.00'), currency: 'USDC' }],
|
|
364
|
+
* allowed_pay_chains: ['eip155:84532', 'eip155:11155420'],
|
|
365
|
+
* });
|
|
366
|
+
* // 단일 체인 고정은 pay_chain 사용(둘은 상호 배타).
|
|
303
367
|
*/
|
|
304
368
|
createSession(params: CreateSessionParams): Promise<ApiResponse<CheckoutSession>>;
|
|
305
369
|
/** 세션 조회 */
|
|
@@ -311,109 +375,40 @@ declare class BitPalCheckoutClient {
|
|
|
311
375
|
offset?: number;
|
|
312
376
|
}): Promise<ListResponse<CheckoutSession>>;
|
|
313
377
|
/**
|
|
314
|
-
*
|
|
315
|
-
*
|
|
316
|
-
* `params.amount` 미지정 시 backend가 잔액 전액(`type: 'full'`). 명시 시 `type: 'partial'`.
|
|
317
|
-
* **Idempotency-Key 권장** — 같은 키로 재시도 시 backend가 같은 결과 반환.
|
|
318
|
-
*
|
|
319
|
-
* 머천트가 `frozen` 상태면 환불은 허용되지만, `suspended` 상태에서는 차단된다.
|
|
320
|
-
*
|
|
321
|
-
* @example
|
|
322
|
-
* ```ts
|
|
323
|
-
* import { randomUUID } from 'node:crypto';
|
|
324
|
-
* const { data } = await bitpal.checkout.refundSession(
|
|
325
|
-
* sessionId,
|
|
326
|
-
* { amount: toAtomicUSDC('5.00'), reason: 'customer_requested' },
|
|
327
|
-
* { idempotencyKey: randomUUID() },
|
|
328
|
-
* );
|
|
329
|
-
* console.log(data.txHash); // on-chain tx hash (또는 simulation 환경에서 sim_xxx)
|
|
330
|
-
* ```
|
|
331
|
-
*/
|
|
332
|
-
refundSession(sessionId: string, params?: RefundSessionParams, opts?: IdempotencyOptions): Promise<ApiResponse<RefundSessionResult>>;
|
|
333
|
-
/**
|
|
334
|
-
* Record refund — `status='settled'` 후 머천트가 외부 지갑에서 직접 송금하고 tx_hash를 입력.
|
|
335
|
-
* 컨트랙트 호출 없음 (DB-only).
|
|
336
|
-
*
|
|
337
|
-
* **Idempotency-Key 권장**.
|
|
378
|
+
* 공개 세션 조회 (`GET /v1/checkout/sessions/:id/public`) — 인증 불요.
|
|
338
379
|
*
|
|
339
|
-
*
|
|
340
|
-
*
|
|
341
|
-
* await bitpal.checkout.recordRefund(
|
|
342
|
-
* sessionId,
|
|
343
|
-
* {
|
|
344
|
-
* refund_amount: toAtomicUSDC('5.00'),
|
|
345
|
-
* tx_hash: '0xabc...',
|
|
346
|
-
* reason: 'manual_offchain_refund',
|
|
347
|
-
* },
|
|
348
|
-
* { idempotencyKey: randomUUID() },
|
|
349
|
-
* );
|
|
350
|
-
* ```
|
|
380
|
+
* buyer-facing 결제 페이지가 표시/자산선택에 쓰는 서버 권위 뷰. `payment_options` 로
|
|
381
|
+
* 구매자 선택 가능한 chain×token 을 얻고, 발급 후에는 `deposit_address` 가 채워진다.
|
|
351
382
|
*/
|
|
352
|
-
|
|
353
|
-
/** 세션별 환불 내역 (auto + record 통합) */
|
|
354
|
-
listRefunds(sessionId: string): Promise<ListResponse<RefundEntry>>;
|
|
383
|
+
getPublicSession(sessionId: string): Promise<ApiResponse<PublicSession>>;
|
|
355
384
|
/**
|
|
356
|
-
*
|
|
385
|
+
* 주문별 비수탁 입금주소 발급 (`POST /v1/checkout/sessions/:id/deposit-address`).
|
|
357
386
|
*
|
|
358
|
-
*
|
|
359
|
-
*
|
|
360
|
-
*
|
|
387
|
+
* 비수탁 결제 진입점. 구매자가 자산(멀티옵션이면 chain/token)과 환불 주소를 확정하면 서버가
|
|
388
|
+
* 그 주문 전용 CREATE2 forwarder 주소를 돌려준다. 구매자는 아무 지갑/거래소에서 **정확한 금액**을
|
|
389
|
+
* 그 주소로 일반 송금하면 된다(서명·연결 불필요). watcher 가 감지 → keeper 가 정산.
|
|
361
390
|
*
|
|
362
|
-
*
|
|
363
|
-
* - Merchant server (API key): `Authorization: Bearer bp_test_*` 헤더 자동 첨부
|
|
364
|
-
* - Buyer 측 (session_token): `params.session_token` 전달
|
|
391
|
+
* refundAddress 는 입금주소에 커밋되어 발급 후 변경 불가. session_token 은 createSession 응답값.
|
|
365
392
|
*
|
|
366
393
|
* @example
|
|
367
394
|
* ```ts
|
|
368
|
-
*
|
|
369
|
-
*
|
|
370
|
-
*
|
|
371
|
-
* chain: '
|
|
395
|
+
* const { data } = await bitpal.checkout.issueDepositAddress(sessionId, {
|
|
396
|
+
* session_token: session.session_token!,
|
|
397
|
+
* refundAddress: '0xBuyerWallet...',
|
|
398
|
+
* chain: 'eip155:8453', // 멀티옵션 세션만 필요
|
|
399
|
+
* token: 'USDC',
|
|
372
400
|
* });
|
|
373
|
-
* console.log(data.
|
|
374
|
-
* console.log(data.session_status); // 'paid' | 'unresolved_underpaid' | ...
|
|
401
|
+
* console.log(data.depositAddress, data.expectedAmount); // 이 주소로 정확 금액 송금
|
|
375
402
|
* ```
|
|
376
403
|
*/
|
|
377
|
-
|
|
404
|
+
issueDepositAddress(sessionId: string, params: IssueDepositAddressParams): Promise<ApiResponse<DepositAddress>>;
|
|
378
405
|
/**
|
|
379
|
-
*
|
|
380
|
-
*
|
|
381
|
-
* The buyer signs **two** EIP-712 typed-data structures and the API calls
|
|
382
|
-
* `CheckoutEscrow.depositWithAuthorization()` with the platform relayer:
|
|
383
|
-
*
|
|
384
|
-
* 1. **EIP-3009 USDC TransferWithAuthorization** (`params.authorization`) —
|
|
385
|
-
* authorizes USDC transfer from buyer to escrow.
|
|
386
|
-
* 2. **PaymentAuthorization** (`params.payment_auth`, since SDK v0.2.0) —
|
|
387
|
-
* binds the entire payment intent (paymentId, merchant, amount, fee,
|
|
388
|
-
* reserve, duration) to the buyer's signature. Without this, a compromised
|
|
389
|
-
* gateway key could redirect funds to an attacker-controlled merchant.
|
|
390
|
-
*
|
|
391
|
-
* Build the PaymentAuthorization typed-data with `buildPaymentAuthTypedData()`.
|
|
392
|
-
* The PaymentAuthorization nonce comes from `CheckoutEscrow.paymentAuthNonce(payer)`.
|
|
393
|
-
*
|
|
394
|
-
* Use the returned session/order state only as immediate UX feedback; the
|
|
395
|
-
* merchant backend should finalize fulfillment from signed webhooks.
|
|
406
|
+
* 경량 상태 폴링 (`GET /v1/checkout/sessions/:id/status`) — 인증 불요.
|
|
396
407
|
*
|
|
397
|
-
*
|
|
398
|
-
*
|
|
408
|
+
* status: awaiting_deposit → deposit_detected → paid_confirmed/swept. 확정/정산은 webhook 으로도
|
|
409
|
+
* 통지되므로, 서버 사이드 확정은 webhook 을 신뢰(폴링은 buyer UX 용).
|
|
399
410
|
*/
|
|
400
|
-
|
|
401
|
-
/**
|
|
402
|
-
* 세션의 external on-chain 결제 검증 기록 목록 조회.
|
|
403
|
-
*
|
|
404
|
-
* `getSession()`의 `payment_observations` 필드와 동일한 데이터를 반환하지만
|
|
405
|
-
* 검증 기록만 명시적으로 조회할 때 사용한다.
|
|
406
|
-
*
|
|
407
|
-
* @example
|
|
408
|
-
* ```ts
|
|
409
|
-
* const { data } = await bitpal.checkout.getExternalPaymentStatus(sessionId);
|
|
410
|
-
* const latest = data[0];
|
|
411
|
-
* if (latest?.finality_status === 'final_confirmed') {
|
|
412
|
-
* // 12 confirmations 완료 — 결제 확정
|
|
413
|
-
* }
|
|
414
|
-
* ```
|
|
415
|
-
*/
|
|
416
|
-
getExternalPaymentStatus(sessionId: string): Promise<ApiResponse<PaymentObservation[]>>;
|
|
411
|
+
getStatus(sessionId: string): Promise<ApiResponse<SessionStatus>>;
|
|
417
412
|
/** 수수료 미리보기 — `/v1/checkout/fee-preview` (Phase 1 credit system 폐기 후 canonical path) */
|
|
418
413
|
previewFee(amount: string): Promise<ApiResponse<FeePreview>>;
|
|
419
414
|
}
|
|
@@ -425,18 +420,12 @@ declare class BitPalError extends Error {
|
|
|
425
420
|
/**
|
|
426
421
|
* @bitpal/checkout — Webhook 서명 검증 + 이벤트 타입
|
|
427
422
|
*
|
|
428
|
-
* BitPal
|
|
429
|
-
* apps/api/src/services/webhook-canonical-delivery.ts
|
|
430
|
-
* apps/api/src/__tests__/webhook-canonical-delivery.test.ts
|
|
431
|
-
*
|
|
432
|
-
* 이벤트 명/서명 형식이 backend와 drift하면 머천트 검증이 깨진다.
|
|
423
|
+
* BitPal 이 보내는 canonical webhook contract(envelope/서명/헤더)와 1:1 정합한다.
|
|
433
424
|
*/
|
|
434
425
|
/**
|
|
435
|
-
*
|
|
436
|
-
* Backend `services/checkout-webhook.ts:CHECKOUT_WEBHOOK_EVENTS`와 동일 — drift 시
|
|
437
|
-
* 머천트 코드의 분기 매칭이 실패한다.
|
|
426
|
+
* BitPal 이 발송하는 webhook 이벤트 타입 전체 목록.
|
|
438
427
|
*/
|
|
439
|
-
declare const CHECKOUT_WEBHOOK_EVENTS: readonly ["checkout.session.created", "checkout.session.
|
|
428
|
+
declare const CHECKOUT_WEBHOOK_EVENTS: readonly ["checkout.session.created", "checkout.session.deposit_detected", "checkout.session.paid", "checkout.session.settled", "checkout.session.expired", "checkout.session.unresolved", "checkout.refund.recorded"];
|
|
440
429
|
type CheckoutWebhookEvent = (typeof CHECKOUT_WEBHOOK_EVENTS)[number];
|
|
441
430
|
/**
|
|
442
431
|
* Canonical envelope (HTTP body).
|
|
@@ -482,16 +471,29 @@ declare const WEBHOOK_HEADERS: {
|
|
|
482
471
|
* import { verifyWebhookSignature, parseWebhookEvent, WEBHOOK_HEADERS } from '@bitpal/checkout';
|
|
483
472
|
*
|
|
484
473
|
* app.post('/webhook', express.raw({ type: 'application/json' }), async (req, res) => {
|
|
485
|
-
* const
|
|
486
|
-
* const ok = await verifyWebhookSignature(
|
|
474
|
+
* const raw = req.body.toString('utf8'); // raw body — parse/re-serialize 하면 서명 깨짐
|
|
475
|
+
* const ok = await verifyWebhookSignature(
|
|
476
|
+
* raw,
|
|
477
|
+
* req.header(WEBHOOK_HEADERS.signature) ?? '',
|
|
478
|
+
* process.env.BITPAL_WEBHOOK_SECRET!,
|
|
479
|
+
* { timestamp: req.header(WEBHOOK_HEADERS.timestamp) ?? '' }, // replay 방어 — 필수
|
|
480
|
+
* );
|
|
487
481
|
* if (!ok) return res.status(400).send('invalid signature');
|
|
488
|
-
* const event = parseWebhookEvent(
|
|
482
|
+
* const event = parseWebhookEvent(raw);
|
|
483
|
+
* // dedup 은 서명된 body 의 event.id 로 (헤더 X-Webhook-Id 는 미서명)
|
|
484
|
+
* if (await alreadyProcessed(event.id)) return res.status(200).send('dup');
|
|
489
485
|
* if (event.event === 'checkout.session.paid') { ... }
|
|
490
486
|
* res.status(200).send('ok');
|
|
491
487
|
* });
|
|
492
488
|
* ```
|
|
493
489
|
*/
|
|
494
|
-
|
|
490
|
+
interface VerifyWebhookOptions {
|
|
491
|
+
/** `X-Webhook-Timestamp` 헤더 값(ISO UTC). 서명 대상에 포함되며 freshness 검사에 쓰인다. 필수. */
|
|
492
|
+
timestamp: string;
|
|
493
|
+
/** freshness 허용 오차(초). 기본 300(5분). |now - timestamp| 초과 시 replay 로 간주해 거부. */
|
|
494
|
+
toleranceSec?: number;
|
|
495
|
+
}
|
|
496
|
+
declare function verifyWebhookSignature(payload: string, signature: string, secret: string, opts?: VerifyWebhookOptions): Promise<boolean>;
|
|
495
497
|
/**
|
|
496
498
|
* Webhook envelope 파싱.
|
|
497
499
|
* 형식 검증 후 `WebhookPayload` 타입으로 캐스팅.
|
|
@@ -533,154 +535,6 @@ declare function toAtomicUSDC(decimal: string): string;
|
|
|
533
535
|
*/
|
|
534
536
|
declare function fromAtomicUSDC(atomic: string): string;
|
|
535
537
|
|
|
536
|
-
/**
|
|
537
|
-
* typed-data.ts — Q5 C-01 옵션 2 (SDK v0.2.0).
|
|
538
|
-
*
|
|
539
|
-
* BitPal Checkout 의 EIP-712 typed-data helper. SDK 가 모든 typed-data 작업을 직접
|
|
540
|
-
* 수행하지 않고 (서명은 머천트의 wallet provider 가) **typed-data 객체만 생성** 한다.
|
|
541
|
-
*
|
|
542
|
-
* 사용 예 (viem):
|
|
543
|
-
*
|
|
544
|
-
* ```ts
|
|
545
|
-
* import { buildPaymentAuthTypedData } from '@bitpal/checkout';
|
|
546
|
-
* import { signTypedData } from 'viem/accounts';
|
|
547
|
-
*
|
|
548
|
-
* const td = buildPaymentAuthTypedData({
|
|
549
|
-
* escrowAddress: '0x...',
|
|
550
|
-
* chainId: 8453,
|
|
551
|
-
* paymentId: '0x...', // = toBytes32(sessionId)
|
|
552
|
-
* payer: buyer.address,
|
|
553
|
-
* merchant: session.seller_wallet,
|
|
554
|
-
* token: session.token_address,
|
|
555
|
-
* amount: session.amount_total,
|
|
556
|
-
* feeAmount: '0',
|
|
557
|
-
* reserveAmount: '0',
|
|
558
|
-
* duration: '0',
|
|
559
|
-
* deadline: String(Math.floor(Date.now()/1000) + 3600),
|
|
560
|
-
* nonce: String(await escrow.read.paymentAuthNonce(buyer.address)),
|
|
561
|
-
* });
|
|
562
|
-
* const sig = await walletClient.signTypedData(td);
|
|
563
|
-
* ```
|
|
564
|
-
*
|
|
565
|
-
* 사용 예 (wagmi `useSignTypedData`):
|
|
566
|
-
*
|
|
567
|
-
* ```tsx
|
|
568
|
-
* const { signTypedDataAsync } = useSignTypedData();
|
|
569
|
-
* const td = buildPaymentAuthTypedData({ ... });
|
|
570
|
-
* const sig = await signTypedDataAsync(td);
|
|
571
|
-
* ```
|
|
572
|
-
*/
|
|
573
|
-
|
|
574
|
-
/**
|
|
575
|
-
* Build EIP-712 typed-data object for PaymentAuthorization signing.
|
|
576
|
-
* Returns a viem-compatible structure (also compatible with wagmi/ethers v6 signTypedData).
|
|
577
|
-
*/
|
|
578
|
-
declare function buildPaymentAuthTypedData(args: PaymentAuthTypedDataArgs): {
|
|
579
|
-
readonly domain: {
|
|
580
|
-
readonly name: "CheckoutEscrow";
|
|
581
|
-
readonly version: "1";
|
|
582
|
-
readonly chainId: number;
|
|
583
|
-
readonly verifyingContract: `0x${string}`;
|
|
584
|
-
};
|
|
585
|
-
readonly types: {
|
|
586
|
-
readonly PaymentAuthorization: readonly [{
|
|
587
|
-
readonly name: "paymentId";
|
|
588
|
-
readonly type: "bytes32";
|
|
589
|
-
}, {
|
|
590
|
-
readonly name: "payer";
|
|
591
|
-
readonly type: "address";
|
|
592
|
-
}, {
|
|
593
|
-
readonly name: "merchant";
|
|
594
|
-
readonly type: "address";
|
|
595
|
-
}, {
|
|
596
|
-
readonly name: "token";
|
|
597
|
-
readonly type: "address";
|
|
598
|
-
}, {
|
|
599
|
-
readonly name: "amount";
|
|
600
|
-
readonly type: "uint256";
|
|
601
|
-
}, {
|
|
602
|
-
readonly name: "feeAmount";
|
|
603
|
-
readonly type: "uint256";
|
|
604
|
-
}, {
|
|
605
|
-
readonly name: "reserveAmount";
|
|
606
|
-
readonly type: "uint256";
|
|
607
|
-
}, {
|
|
608
|
-
readonly name: "duration";
|
|
609
|
-
readonly type: "uint256";
|
|
610
|
-
}, {
|
|
611
|
-
readonly name: "deadline";
|
|
612
|
-
readonly type: "uint256";
|
|
613
|
-
}, {
|
|
614
|
-
readonly name: "nonce";
|
|
615
|
-
readonly type: "uint256";
|
|
616
|
-
}];
|
|
617
|
-
};
|
|
618
|
-
readonly primaryType: "PaymentAuthorization";
|
|
619
|
-
readonly message: {
|
|
620
|
-
readonly paymentId: `0x${string}`;
|
|
621
|
-
readonly payer: `0x${string}`;
|
|
622
|
-
readonly merchant: `0x${string}`;
|
|
623
|
-
readonly token: `0x${string}`;
|
|
624
|
-
readonly amount: bigint;
|
|
625
|
-
readonly feeAmount: bigint;
|
|
626
|
-
readonly reserveAmount: bigint;
|
|
627
|
-
readonly duration: bigint;
|
|
628
|
-
readonly deadline: bigint;
|
|
629
|
-
readonly nonce: bigint;
|
|
630
|
-
};
|
|
631
|
-
};
|
|
632
|
-
/**
|
|
633
|
-
* Args for the EIP-712 ConfirmReceipt typed-data.
|
|
634
|
-
* Used when buyer signs an off-chain receipt confirmation that BitPal gateway relays
|
|
635
|
-
* on-chain via `confirmReceiptWithSignature` (Q4 H-01).
|
|
636
|
-
*/
|
|
637
|
-
interface ConfirmReceiptTypedDataArgs {
|
|
638
|
-
escrowAddress: string;
|
|
639
|
-
chainId: number;
|
|
640
|
-
paymentId: string;
|
|
641
|
-
payer: string;
|
|
642
|
-
deadline: string;
|
|
643
|
-
nonce: string;
|
|
644
|
-
}
|
|
645
|
-
/**
|
|
646
|
-
* Build EIP-712 typed-data object for ConfirmReceipt signing (Q4 H-01).
|
|
647
|
-
*/
|
|
648
|
-
declare function buildConfirmReceiptTypedData(args: ConfirmReceiptTypedDataArgs): {
|
|
649
|
-
readonly domain: {
|
|
650
|
-
readonly name: "CheckoutEscrow";
|
|
651
|
-
readonly version: "1";
|
|
652
|
-
readonly chainId: number;
|
|
653
|
-
readonly verifyingContract: `0x${string}`;
|
|
654
|
-
};
|
|
655
|
-
readonly types: {
|
|
656
|
-
readonly ConfirmReceipt: readonly [{
|
|
657
|
-
readonly name: "paymentId";
|
|
658
|
-
readonly type: "bytes32";
|
|
659
|
-
}, {
|
|
660
|
-
readonly name: "payer";
|
|
661
|
-
readonly type: "address";
|
|
662
|
-
}, {
|
|
663
|
-
readonly name: "deadline";
|
|
664
|
-
readonly type: "uint256";
|
|
665
|
-
}, {
|
|
666
|
-
readonly name: "nonce";
|
|
667
|
-
readonly type: "uint256";
|
|
668
|
-
}];
|
|
669
|
-
};
|
|
670
|
-
readonly primaryType: "ConfirmReceipt";
|
|
671
|
-
readonly message: {
|
|
672
|
-
readonly paymentId: `0x${string}`;
|
|
673
|
-
readonly payer: `0x${string}`;
|
|
674
|
-
readonly deadline: bigint;
|
|
675
|
-
readonly nonce: bigint;
|
|
676
|
-
};
|
|
677
|
-
};
|
|
678
|
-
/**
|
|
679
|
-
* Convert a session ID string into a 32-byte hex (`paymentId`) suitable for typed-data signing.
|
|
680
|
-
* Mirrors the backend `toBytes32(sessionId)` helper.
|
|
681
|
-
*/
|
|
682
|
-
declare function sessionIdToPaymentId(sessionId: string): `0x${string}`;
|
|
683
|
-
|
|
684
538
|
/**
|
|
685
539
|
* @bitpal/checkout — BitPal Checkout SDK
|
|
686
540
|
*
|
|
@@ -693,10 +547,11 @@ declare function sessionIdToPaymentId(sessionId: string): `0x${string}`;
|
|
|
693
547
|
* const bitpal = new BitPal({ apiKey: 'bp_test_...' });
|
|
694
548
|
*
|
|
695
549
|
* const { data: session } = await bitpal.checkout.createSession({
|
|
696
|
-
*
|
|
550
|
+
* // amount 는 원자 단위 μUSDC 문자열(6 decimals). $29.00 → '29000000'. toAtomicUSDC 사용 권장.
|
|
551
|
+
* line_items: [{ name: 'Pro Plan', amount: toAtomicUSDC('29.00'), currency: 'USDC' }],
|
|
697
552
|
* });
|
|
698
553
|
*
|
|
699
|
-
* console.log(session.url); // 호스티드 결제 페이지 URL
|
|
554
|
+
* console.log(session.url); // 호스티드 결제 페이지 URL (checkout_url 별칭)
|
|
700
555
|
* ```
|
|
701
556
|
*/
|
|
702
557
|
|
|
@@ -708,4 +563,4 @@ declare class BitPal {
|
|
|
708
563
|
constructor(config: BitPalConfig | string);
|
|
709
564
|
}
|
|
710
565
|
|
|
711
|
-
export { type ApiResponse, BitPal, BitPalCheckoutClient, type BitPalConfig, BitPalError, CHECKOUT_WEBHOOK_EVENTS, type
|
|
566
|
+
export { type ApiResponse, BitPal, BitPalCheckoutClient, type BitPalConfig, BitPalError, CHECKOUT_WEBHOOK_EVENTS, type CheckoutLineItemInput, type CheckoutPrice, type CheckoutProduct, type CheckoutSession, type CheckoutWebhookEvent, type CreatePriceParams, type CreateProductParams, type CreateSessionParams, type DepositAddress, type FeePreview, type IdempotencyOptions, type IssueDepositAddressParams, type LineItem, type ListPricesParams, type ListProductsParams, type ListResponse, type PaymentOption, type PriceLineItem, PricesResource, ProductsResource, type PublicSession, type SessionStatus, type UpdatePriceParams, type UpdateProductParams, WEBHOOK_HEADERS, type WebhookPayload, fromAtomicUSDC, parseWebhookEvent, toAtomicUSDC, verifyWebhookSignature };
|