@youidian/pay-sdk 1.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/index.mjs ADDED
@@ -0,0 +1,314 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+
5
+ // src/client.ts
6
+ var PaymentUI = class {
7
+ constructor() {
8
+ __publicField(this, "iframe", null);
9
+ __publicField(this, "modal", null);
10
+ __publicField(this, "messageHandler", null);
11
+ }
12
+ /**
13
+ * Opens the payment checkout page in an iframe modal.
14
+ * @param checkoutUrl - The checkout page URL
15
+ * @param options - UI options
16
+ */
17
+ openPayment(checkoutUrl, options) {
18
+ if (typeof document === "undefined") return;
19
+ if (this.modal) return;
20
+ let finalUrl = checkoutUrl;
21
+ if (options?.locale) {
22
+ try {
23
+ const url = new URL(checkoutUrl);
24
+ if (!url.pathname.startsWith(`/${options.locale}/`)) {
25
+ url.pathname = `/${options.locale}${url.pathname}`;
26
+ finalUrl = url.toString();
27
+ }
28
+ } catch (_e) {
29
+ if (!checkoutUrl.startsWith(`/${options.locale}/`)) {
30
+ finalUrl = `/${options.locale}${checkoutUrl.startsWith("/") ? "" : "/"}${checkoutUrl}`;
31
+ }
32
+ }
33
+ }
34
+ this.modal = document.createElement("div");
35
+ Object.assign(this.modal.style, {
36
+ position: "fixed",
37
+ top: "0",
38
+ left: "0",
39
+ width: "100%",
40
+ height: "100%",
41
+ backgroundColor: "rgba(0,0,0,0.5)",
42
+ display: "flex",
43
+ alignItems: "center",
44
+ justifyContent: "center",
45
+ zIndex: "9999",
46
+ transition: "opacity 0.3s ease"
47
+ });
48
+ const container = document.createElement("div");
49
+ Object.assign(container.style, {
50
+ width: "450px",
51
+ height: "min(600px, 90vh)",
52
+ backgroundColor: "#fff",
53
+ borderRadius: "20px",
54
+ overflow: "hidden",
55
+ position: "relative",
56
+ boxShadow: "0 25px 50px -12px rgba(0,0,0,0.25)"
57
+ });
58
+ const closeBtn = document.createElement("button");
59
+ closeBtn.innerHTML = "\xD7";
60
+ Object.assign(closeBtn.style, {
61
+ position: "absolute",
62
+ right: "15px",
63
+ top: "10px",
64
+ fontSize: "24px",
65
+ border: "none",
66
+ background: "none",
67
+ cursor: "pointer",
68
+ color: "#999",
69
+ zIndex: "1"
70
+ });
71
+ closeBtn.onclick = () => {
72
+ this.close();
73
+ options?.onCancel?.();
74
+ };
75
+ this.iframe = document.createElement("iframe");
76
+ this.iframe.src = finalUrl;
77
+ Object.assign(this.iframe.style, {
78
+ width: "100%",
79
+ height: "100%",
80
+ border: "none"
81
+ });
82
+ container.appendChild(closeBtn);
83
+ container.appendChild(this.iframe);
84
+ this.modal.appendChild(container);
85
+ document.body.appendChild(this.modal);
86
+ this.messageHandler = (event) => {
87
+ if (options?.allowedOrigin && options.allowedOrigin !== "*") {
88
+ if (event.origin !== options.allowedOrigin) {
89
+ return;
90
+ }
91
+ }
92
+ const data = event.data;
93
+ if (!data || typeof data !== "object" || !data.type) {
94
+ return;
95
+ }
96
+ switch (data.type) {
97
+ case "PAYMENT_SUCCESS":
98
+ options?.onSuccess?.(data.orderId);
99
+ setTimeout(() => this.close(), 2e3);
100
+ break;
101
+ case "PAYMENT_CANCELLED":
102
+ options?.onCancel?.(data.orderId);
103
+ break;
104
+ case "PAYMENT_RESIZE":
105
+ if (data.height && container) {
106
+ const maxHeight = window.innerHeight * 0.9;
107
+ const newHeight = Math.min(data.height, maxHeight);
108
+ container.style.height = `${newHeight}px`;
109
+ }
110
+ break;
111
+ case "PAYMENT_CLOSE":
112
+ this.close();
113
+ options?.onClose?.();
114
+ break;
115
+ }
116
+ };
117
+ window.addEventListener("message", this.messageHandler);
118
+ }
119
+ /**
120
+ * Close the payment modal
121
+ */
122
+ close() {
123
+ if (typeof window === "undefined") return;
124
+ if (this.messageHandler) {
125
+ window.removeEventListener("message", this.messageHandler);
126
+ this.messageHandler = null;
127
+ }
128
+ if (this.modal && this.modal.parentNode) {
129
+ this.modal.parentNode.removeChild(this.modal);
130
+ }
131
+ this.modal = null;
132
+ this.iframe = null;
133
+ }
134
+ /**
135
+ * Poll order status from integrator's API endpoint
136
+ * @param statusUrl - The integrator's API endpoint to check order status
137
+ * @param options - Polling options
138
+ * @returns Promise that resolves when order is paid or rejects on timeout/failure
139
+ */
140
+ async pollOrderStatus(statusUrl, options) {
141
+ const interval = options?.interval || 3e3;
142
+ const timeout = options?.timeout || 3e5;
143
+ const startTime = Date.now();
144
+ return new Promise((resolve, reject) => {
145
+ const poll = async () => {
146
+ try {
147
+ const response = await fetch(statusUrl);
148
+ if (!response.ok) {
149
+ throw new Error(`Status check failed: ${response.status}`);
150
+ }
151
+ const status = await response.json();
152
+ options?.onStatusChange?.(status);
153
+ if (status.status === "PAID") {
154
+ resolve(status);
155
+ return;
156
+ }
157
+ if (status.status === "CANCELLED" || status.status === "FAILED") {
158
+ reject(new Error(`Order ${status.status.toLowerCase()}`));
159
+ return;
160
+ }
161
+ if (Date.now() - startTime > timeout) {
162
+ reject(new Error("Polling timeout"));
163
+ return;
164
+ }
165
+ setTimeout(poll, interval);
166
+ } catch (error) {
167
+ if (Date.now() - startTime > timeout) {
168
+ reject(error);
169
+ return;
170
+ }
171
+ setTimeout(poll, interval);
172
+ }
173
+ };
174
+ poll();
175
+ });
176
+ }
177
+ };
178
+ function createPaymentUI() {
179
+ return new PaymentUI();
180
+ }
181
+
182
+ // src/server.ts
183
+ import crypto from "crypto";
184
+ var PaymentClient = class {
185
+ constructor(options) {
186
+ __publicField(this, "appId");
187
+ __publicField(this, "appSecret");
188
+ __publicField(this, "baseUrl");
189
+ if (!options.appId) throw new Error("appId is required");
190
+ if (!options.appSecret) throw new Error("appSecret is required");
191
+ if (!options.baseUrl) throw new Error("baseUrl is required");
192
+ this.appId = options.appId;
193
+ this.appSecret = options.appSecret;
194
+ this.baseUrl = options.baseUrl.replace(/\/$/, "");
195
+ }
196
+ /**
197
+ * Generate SHA256 signature for the request
198
+ * Logic: SHA256(appId + appSecret + timestamp)
199
+ */
200
+ generateSignature(timestamp) {
201
+ const str = `${this.appId}${this.appSecret}${timestamp}`;
202
+ return crypto.createHash("sha256").update(str).digest("hex");
203
+ }
204
+ /**
205
+ * Internal request helper for Gateway API
206
+ */
207
+ async request(method, path, body) {
208
+ const timestamp = Date.now();
209
+ const signature = this.generateSignature(timestamp);
210
+ const url = `${this.baseUrl}/api/v1/gateway/${this.appId}${path}`;
211
+ const headers = {
212
+ "Content-Type": "application/json",
213
+ "X-Pay-Timestamp": timestamp.toString(),
214
+ "X-Pay-Sign": signature
215
+ };
216
+ const options = {
217
+ method,
218
+ headers,
219
+ body: body ? JSON.stringify(body) : void 0
220
+ };
221
+ const response = await fetch(url, options);
222
+ if (!response.ok) {
223
+ const errorText = await response.text();
224
+ throw new Error(`Payment SDK Error (${response.status}): ${errorText}`);
225
+ }
226
+ const json = await response.json();
227
+ if (json.error) {
228
+ throw new Error(`Payment API Error: ${json.error}`);
229
+ }
230
+ return json.data;
231
+ }
232
+ /**
233
+ * Decrypts the callback notification payload using AES-256-GCM.
234
+ * @param notification - The encrypted notification from payment webhook
235
+ * @returns Decrypted payment callback data
236
+ */
237
+ decryptCallback(notification) {
238
+ try {
239
+ const { iv, encryptedData, authTag } = notification;
240
+ const key = crypto.createHash("sha256").update(this.appSecret).digest();
241
+ const decipher = crypto.createDecipheriv(
242
+ "aes-256-gcm",
243
+ key,
244
+ Buffer.from(iv, "hex")
245
+ );
246
+ decipher.setAuthTag(Buffer.from(authTag, "hex"));
247
+ let decrypted = decipher.update(encryptedData, "hex", "utf8");
248
+ decrypted += decipher.final("utf8");
249
+ return JSON.parse(decrypted);
250
+ } catch (error) {
251
+ throw new Error("Failed to decrypt payment callback: Invalid secret or tampered data.");
252
+ }
253
+ }
254
+ /**
255
+ * Fetch products for the configured app.
256
+ */
257
+ async getProducts(options) {
258
+ const params = new URLSearchParams();
259
+ params.append("appId", this.appId);
260
+ if (options?.locale) params.append("locale", options.locale);
261
+ if (options?.currency) params.append("currency", options.currency);
262
+ const url = `${this.baseUrl}/api/v1/pay/products?${params.toString()}`;
263
+ const res = await fetch(url, {
264
+ method: "GET",
265
+ headers: {
266
+ "Content-Type": "application/json",
267
+ "Accept": "application/json"
268
+ }
269
+ });
270
+ if (!res.ok) {
271
+ throw new Error(`Failed to fetch products: ${res.status} ${res.statusText}`);
272
+ }
273
+ const json = await res.json();
274
+ return json.data?.products || [];
275
+ }
276
+ /**
277
+ * Create a new order
278
+ * @param params - Order creation parameters
279
+ * @returns Order details with payment parameters
280
+ */
281
+ async createOrder(params) {
282
+ return this.request("POST", "/orders", params);
283
+ }
284
+ /**
285
+ * Pay for an existing order
286
+ * @param orderId - The order ID to pay
287
+ * @param params - Payment parameters including channel
288
+ */
289
+ async payOrder(orderId, params) {
290
+ return this.request("POST", `/orders/${orderId}/pay`, params);
291
+ }
292
+ /**
293
+ * Query order status
294
+ * @param orderId - The order ID to query
295
+ */
296
+ async getOrderStatus(orderId) {
297
+ return this.request("GET", `/orders/${orderId}`);
298
+ }
299
+ /**
300
+ * Generate checkout URL for client-side payment
301
+ * @param productId - Product ID
302
+ * @param priceId - Price ID
303
+ * @returns Checkout page URL
304
+ */
305
+ getCheckoutUrl(productId, priceId) {
306
+ return `${this.baseUrl}/checkout/${this.appId}/${productId}/${priceId}`;
307
+ }
308
+ };
309
+ export {
310
+ PaymentClient,
311
+ PaymentUI,
312
+ createPaymentUI
313
+ };
314
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/client.ts","../src/server.ts"],"sourcesContent":["/**\n * Youidian Payment SDK - Client Module\n * 用于浏览器端集成,包含支付弹窗、状态轮询等功能\n * 不依赖 Node.js crypto 模块\n */\n\n/**\n * Payment event types from checkout pages\n */\nexport type PaymentEventType = 'PAYMENT_SUCCESS' | 'PAYMENT_CANCELLED' | 'PAYMENT_CLOSE' | 'PAYMENT_RESIZE';\n\n/**\n * Payment event data from postMessage\n */\nexport interface PaymentEventData {\n type: PaymentEventType;\n orderId?: string;\n height?: number;\n}\n\n/**\n * Order status response\n */\nexport interface OrderStatus {\n orderId: string;\n status: 'PENDING' | 'PAID' | 'CANCELLED' | 'REFUNDED' | 'FAILED';\n paidAt?: string;\n channelTransactionId?: string;\n}\n\n/**\n * Payment UI Options\n */\nexport interface PaymentUIOptions {\n locale?: string;\n onSuccess?: (orderId?: string) => void;\n onCancel?: (orderId?: string) => void;\n onClose?: () => void;\n /** Origin to validate postMessage (defaults to '*', set for security) */\n allowedOrigin?: string;\n}\n\n/**\n * Poll Options\n */\nexport interface PollOptions {\n /** Polling interval in ms (default: 3000) */\n interval?: number;\n /** Timeout in ms (default: 300000 = 5 minutes) */\n timeout?: number;\n /** Callback on each status check */\n onStatusChange?: (status: OrderStatus) => void;\n}\n\n/**\n * Client-side Payment UI Helper\n * 浏览器端支付 UI 辅助类,用于弹出支付窗口和轮询订单状态\n */\nexport class PaymentUI {\n private iframe: HTMLIFrameElement | null = null;\n private modal: HTMLDivElement | null = null;\n private messageHandler: ((event: MessageEvent) => void) | null = null;\n\n /**\n * Opens the payment checkout page in an iframe modal.\n * @param checkoutUrl - The checkout page URL\n * @param options - UI options\n */\n openPayment(checkoutUrl: string, options?: PaymentUIOptions) {\n if (typeof document === 'undefined') return; // Server-side guard\n if (this.modal) return; // Prevent multiple modals\n\n let finalUrl = checkoutUrl;\n if (options?.locale) {\n try {\n const url = new URL(checkoutUrl);\n if (!url.pathname.startsWith(`/${options.locale}/`)) {\n url.pathname = `/${options.locale}${url.pathname}`;\n finalUrl = url.toString();\n }\n } catch (_e) {\n // Fallback if URL is relative or invalid\n if (!checkoutUrl.startsWith(`/${options.locale}/`)) {\n finalUrl = `/${options.locale}${checkoutUrl.startsWith('/') ? '' : '/'}${checkoutUrl}`;\n }\n }\n }\n\n // Create Modal Overlay\n this.modal = document.createElement('div');\n Object.assign(this.modal.style, {\n position: 'fixed',\n top: '0',\n left: '0',\n width: '100%',\n height: '100%',\n backgroundColor: 'rgba(0,0,0,0.5)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: '9999',\n transition: 'opacity 0.3s ease'\n });\n\n // Create Container\n const container = document.createElement('div');\n Object.assign(container.style, {\n width: '450px',\n height: 'min(600px, 90vh)',\n backgroundColor: '#fff',\n borderRadius: '20px',\n overflow: 'hidden',\n position: 'relative',\n boxShadow: '0 25px 50px -12px rgba(0,0,0,0.25)'\n });\n\n // Create Close Button\n const closeBtn = document.createElement('button');\n closeBtn.innerHTML = '×';\n Object.assign(closeBtn.style, {\n position: 'absolute',\n right: '15px',\n top: '10px',\n fontSize: '24px',\n border: 'none',\n background: 'none',\n cursor: 'pointer',\n color: '#999',\n zIndex: '1'\n });\n closeBtn.onclick = () => {\n this.close();\n options?.onCancel?.();\n };\n\n // Create Iframe\n this.iframe = document.createElement('iframe');\n this.iframe.src = finalUrl;\n Object.assign(this.iframe.style, {\n width: '100%',\n height: '100%',\n border: 'none'\n });\n\n container.appendChild(closeBtn);\n container.appendChild(this.iframe);\n this.modal.appendChild(container);\n document.body.appendChild(this.modal);\n\n // Listen for messages from checkout page\n this.messageHandler = (event: MessageEvent) => {\n // Validate origin if specified\n if (options?.allowedOrigin && options.allowedOrigin !== '*') {\n if (event.origin !== options.allowedOrigin) {\n return;\n }\n }\n\n const data = event.data as PaymentEventData;\n\n if (!data || typeof data !== 'object' || !data.type) {\n return;\n }\n\n switch (data.type) {\n case 'PAYMENT_SUCCESS':\n options?.onSuccess?.(data.orderId);\n // Auto-close after success callback\n setTimeout(() => this.close(), 2000);\n break;\n case 'PAYMENT_CANCELLED':\n options?.onCancel?.(data.orderId);\n break;\n case 'PAYMENT_RESIZE':\n if (data.height && container) {\n // Limit max height to 90% of viewport\n const maxHeight = window.innerHeight * 0.9;\n const newHeight = Math.min(data.height, maxHeight);\n container.style.height = `${newHeight}px`;\n }\n break;\n case 'PAYMENT_CLOSE':\n this.close();\n options?.onClose?.();\n break;\n }\n };\n window.addEventListener('message', this.messageHandler);\n }\n\n /**\n * Close the payment modal\n */\n close() {\n if (typeof window === 'undefined') return;\n\n if (this.messageHandler) {\n window.removeEventListener('message', this.messageHandler);\n this.messageHandler = null;\n }\n if (this.modal && this.modal.parentNode) {\n this.modal.parentNode.removeChild(this.modal);\n }\n this.modal = null;\n this.iframe = null;\n }\n\n /**\n * Poll order status from integrator's API endpoint\n * @param statusUrl - The integrator's API endpoint to check order status\n * @param options - Polling options\n * @returns Promise that resolves when order is paid or rejects on timeout/failure\n */\n async pollOrderStatus(statusUrl: string, options?: PollOptions): Promise<OrderStatus> {\n const interval = options?.interval || 3000;\n const timeout = options?.timeout || 300000;\n const startTime = Date.now();\n\n return new Promise((resolve, reject) => {\n const poll = async () => {\n try {\n const response = await fetch(statusUrl);\n if (!response.ok) {\n throw new Error(`Status check failed: ${response.status}`);\n }\n\n const status: OrderStatus = await response.json();\n options?.onStatusChange?.(status);\n\n if (status.status === 'PAID') {\n resolve(status);\n return;\n }\n\n if (status.status === 'CANCELLED' || status.status === 'FAILED') {\n reject(new Error(`Order ${status.status.toLowerCase()}`));\n return;\n }\n\n // Check timeout\n if (Date.now() - startTime > timeout) {\n reject(new Error('Polling timeout'));\n return;\n }\n\n // Continue polling\n setTimeout(poll, interval);\n } catch (error) {\n // On network error, continue polling unless timeout\n if (Date.now() - startTime > timeout) {\n reject(error);\n return;\n }\n setTimeout(poll, interval);\n }\n };\n\n poll();\n });\n }\n}\n\n/**\n * Convenience function to create a PaymentUI instance\n */\nexport function createPaymentUI(): PaymentUI {\n return new PaymentUI();\n}\n","/**\n * Youidian Payment SDK - Server Module\n * 用于服务端集成,包含签名、订单创建、回调解密等功能\n */\n\nimport crypto from \"crypto\";\n\n/**\n * Order status response\n */\nexport interface OrderStatus {\n orderId: string;\n status: 'PENDING' | 'PAID' | 'CANCELLED' | 'REFUNDED' | 'FAILED';\n paidAt?: string;\n channelTransactionId?: string;\n}\n\n/**\n * Product Entitlements\n */\nexport interface ProductEntitlements {\n [key: string]: any;\n}\n\n/**\n * Product Price\n */\nexport interface ProductPrice {\n id: string;\n currency: string;\n amount: number;\n displayAmount: string;\n locale: string | null;\n isDefault: boolean;\n}\n\n/**\n * Product Data\n */\nexport interface Product {\n id: string;\n code: string;\n type: string;\n name: string;\n description?: string;\n entitlements: ProductEntitlements;\n prices: ProductPrice[];\n}\n\n/**\n * SDK Client Options\n */\nexport interface PaymentClientOptions {\n /** Application ID (Required) */\n appId: string;\n /** Application Secret (Required for server-side operations) */\n appSecret: string;\n /** API Base URL (e.g. https://pay.youidian.com) */\n baseUrl: string;\n}\n\n/**\n * Create Order Parameters\n */\nexport interface CreateOrderParams {\n productId?: string;\n priceId?: string;\n channel?: string;\n userId: string;\n returnUrl?: string;\n metadata?: Record<string, any>;\n merchantOrderId?: string;\n openid?: string;\n}\n\n/**\n * Create Order Response\n */\nexport interface CreateOrderResponse {\n orderId: string;\n internalId: string;\n amount: number;\n currency: string;\n payParams: any;\n}\n\n/**\n * Payment Callback Notification\n */\nexport interface PaymentNotification {\n iv: string;\n encryptedData: string;\n authTag: string;\n}\n\n/**\n * Decrypted Payment Callback Data\n */\nexport interface PaymentCallbackData {\n orderId: string;\n merchantOrderId?: string;\n status: 'PAID' | 'CANCELLED' | 'REFUNDED' | 'FAILED';\n amount: number;\n currency: string;\n paidAt: string;\n channelTransactionId?: string;\n metadata?: Record<string, any>;\n}\n\n/**\n * Server-side Payment Client\n * 服务端支付客户端,用于创建订单、查询状态、解密回调\n */\nexport class PaymentClient {\n private appId: string;\n private appSecret: string;\n private baseUrl: string;\n\n constructor(options: PaymentClientOptions) {\n if (!options.appId) throw new Error(\"appId is required\");\n if (!options.appSecret) throw new Error(\"appSecret is required\");\n if (!options.baseUrl) throw new Error(\"baseUrl is required\");\n\n this.appId = options.appId;\n this.appSecret = options.appSecret;\n this.baseUrl = options.baseUrl.replace(/\\/$/, ''); // Remove trailing slash\n }\n\n /**\n * Generate SHA256 signature for the request\n * Logic: SHA256(appId + appSecret + timestamp)\n */\n private generateSignature(timestamp: number): string {\n const str = `${this.appId}${this.appSecret}${timestamp}`;\n return crypto.createHash(\"sha256\").update(str).digest(\"hex\");\n }\n\n /**\n * Internal request helper for Gateway API\n */\n private async request<T>(method: string, path: string, body?: any): Promise<T> {\n const timestamp = Date.now();\n const signature = this.generateSignature(timestamp);\n\n const url = `${this.baseUrl}/api/v1/gateway/${this.appId}${path}`;\n\n const headers: HeadersInit = {\n \"Content-Type\": \"application/json\",\n \"X-Pay-Timestamp\": timestamp.toString(),\n \"X-Pay-Sign\": signature,\n };\n\n const options: RequestInit = {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n };\n\n const response = await fetch(url, options);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Payment SDK Error (${response.status}): ${errorText}`);\n }\n\n const json = await response.json();\n if (json.error) {\n throw new Error(`Payment API Error: ${json.error}`);\n }\n\n return json.data as T;\n }\n\n /**\n * Decrypts the callback notification payload using AES-256-GCM.\n * @param notification - The encrypted notification from payment webhook\n * @returns Decrypted payment callback data\n */\n decryptCallback(notification: PaymentNotification): PaymentCallbackData {\n try {\n const { iv, encryptedData, authTag } = notification;\n const key = crypto.createHash('sha256').update(this.appSecret).digest();\n const decipher = crypto.createDecipheriv(\n 'aes-256-gcm',\n key,\n Buffer.from(iv, 'hex')\n );\n\n decipher.setAuthTag(Buffer.from(authTag, 'hex'));\n\n let decrypted = decipher.update(encryptedData, 'hex', 'utf8');\n decrypted += decipher.final('utf8');\n\n return JSON.parse(decrypted);\n } catch (error) {\n throw new Error(\"Failed to decrypt payment callback: Invalid secret or tampered data.\");\n }\n }\n\n /**\n * Fetch products for the configured app.\n */\n async getProducts(options?: {\n locale?: string;\n currency?: string;\n }): Promise<Product[]> {\n const params = new URLSearchParams();\n params.append('appId', this.appId);\n if (options?.locale) params.append('locale', options.locale);\n if (options?.currency) params.append('currency', options.currency);\n\n const url = `${this.baseUrl}/api/v1/pay/products?${params.toString()}`;\n\n const res = await fetch(url, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json'\n }\n });\n\n if (!res.ok) {\n throw new Error(`Failed to fetch products: ${res.status} ${res.statusText}`);\n }\n\n const json = await res.json();\n return json.data?.products || [];\n }\n\n /**\n * Create a new order\n * @param params - Order creation parameters\n * @returns Order details with payment parameters\n */\n async createOrder(params: CreateOrderParams): Promise<CreateOrderResponse> {\n return this.request(\"POST\", \"/orders\", params);\n }\n\n /**\n * Pay for an existing order\n * @param orderId - The order ID to pay\n * @param params - Payment parameters including channel\n */\n async payOrder(orderId: string, params: {\n channel: string;\n returnUrl?: string;\n openid?: string;\n [key: string]: any;\n }): Promise<CreateOrderResponse> {\n return this.request(\"POST\", `/orders/${orderId}/pay`, params);\n }\n\n /**\n * Query order status\n * @param orderId - The order ID to query\n */\n async getOrderStatus(orderId: string): Promise<OrderStatus> {\n return this.request(\"GET\", `/orders/${orderId}`);\n }\n\n /**\n * Generate checkout URL for client-side payment\n * @param productId - Product ID\n * @param priceId - Price ID\n * @returns Checkout page URL\n */\n getCheckoutUrl(productId: string, priceId: string): string {\n return `${this.baseUrl}/checkout/${this.appId}/${productId}/${priceId}`;\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,160 @@
1
+ /**
2
+ * Youidian Payment SDK - Server Module
3
+ * 用于服务端集成,包含签名、订单创建、回调解密等功能
4
+ */
5
+ /**
6
+ * Order status response
7
+ */
8
+ interface OrderStatus {
9
+ orderId: string;
10
+ status: 'PENDING' | 'PAID' | 'CANCELLED' | 'REFUNDED' | 'FAILED';
11
+ paidAt?: string;
12
+ channelTransactionId?: string;
13
+ }
14
+ /**
15
+ * Product Entitlements
16
+ */
17
+ interface ProductEntitlements {
18
+ [key: string]: any;
19
+ }
20
+ /**
21
+ * Product Price
22
+ */
23
+ interface ProductPrice {
24
+ id: string;
25
+ currency: string;
26
+ amount: number;
27
+ displayAmount: string;
28
+ locale: string | null;
29
+ isDefault: boolean;
30
+ }
31
+ /**
32
+ * Product Data
33
+ */
34
+ interface Product {
35
+ id: string;
36
+ code: string;
37
+ type: string;
38
+ name: string;
39
+ description?: string;
40
+ entitlements: ProductEntitlements;
41
+ prices: ProductPrice[];
42
+ }
43
+ /**
44
+ * SDK Client Options
45
+ */
46
+ interface PaymentClientOptions {
47
+ /** Application ID (Required) */
48
+ appId: string;
49
+ /** Application Secret (Required for server-side operations) */
50
+ appSecret: string;
51
+ /** API Base URL (e.g. https://pay.youidian.com) */
52
+ baseUrl: string;
53
+ }
54
+ /**
55
+ * Create Order Parameters
56
+ */
57
+ interface CreateOrderParams {
58
+ productId?: string;
59
+ priceId?: string;
60
+ channel?: string;
61
+ userId: string;
62
+ returnUrl?: string;
63
+ metadata?: Record<string, any>;
64
+ merchantOrderId?: string;
65
+ openid?: string;
66
+ }
67
+ /**
68
+ * Create Order Response
69
+ */
70
+ interface CreateOrderResponse {
71
+ orderId: string;
72
+ internalId: string;
73
+ amount: number;
74
+ currency: string;
75
+ payParams: any;
76
+ }
77
+ /**
78
+ * Payment Callback Notification
79
+ */
80
+ interface PaymentNotification {
81
+ iv: string;
82
+ encryptedData: string;
83
+ authTag: string;
84
+ }
85
+ /**
86
+ * Decrypted Payment Callback Data
87
+ */
88
+ interface PaymentCallbackData {
89
+ orderId: string;
90
+ merchantOrderId?: string;
91
+ status: 'PAID' | 'CANCELLED' | 'REFUNDED' | 'FAILED';
92
+ amount: number;
93
+ currency: string;
94
+ paidAt: string;
95
+ channelTransactionId?: string;
96
+ metadata?: Record<string, any>;
97
+ }
98
+ /**
99
+ * Server-side Payment Client
100
+ * 服务端支付客户端,用于创建订单、查询状态、解密回调
101
+ */
102
+ declare class PaymentClient {
103
+ private appId;
104
+ private appSecret;
105
+ private baseUrl;
106
+ constructor(options: PaymentClientOptions);
107
+ /**
108
+ * Generate SHA256 signature for the request
109
+ * Logic: SHA256(appId + appSecret + timestamp)
110
+ */
111
+ private generateSignature;
112
+ /**
113
+ * Internal request helper for Gateway API
114
+ */
115
+ private request;
116
+ /**
117
+ * Decrypts the callback notification payload using AES-256-GCM.
118
+ * @param notification - The encrypted notification from payment webhook
119
+ * @returns Decrypted payment callback data
120
+ */
121
+ decryptCallback(notification: PaymentNotification): PaymentCallbackData;
122
+ /**
123
+ * Fetch products for the configured app.
124
+ */
125
+ getProducts(options?: {
126
+ locale?: string;
127
+ currency?: string;
128
+ }): Promise<Product[]>;
129
+ /**
130
+ * Create a new order
131
+ * @param params - Order creation parameters
132
+ * @returns Order details with payment parameters
133
+ */
134
+ createOrder(params: CreateOrderParams): Promise<CreateOrderResponse>;
135
+ /**
136
+ * Pay for an existing order
137
+ * @param orderId - The order ID to pay
138
+ * @param params - Payment parameters including channel
139
+ */
140
+ payOrder(orderId: string, params: {
141
+ channel: string;
142
+ returnUrl?: string;
143
+ openid?: string;
144
+ [key: string]: any;
145
+ }): Promise<CreateOrderResponse>;
146
+ /**
147
+ * Query order status
148
+ * @param orderId - The order ID to query
149
+ */
150
+ getOrderStatus(orderId: string): Promise<OrderStatus>;
151
+ /**
152
+ * Generate checkout URL for client-side payment
153
+ * @param productId - Product ID
154
+ * @param priceId - Price ID
155
+ * @returns Checkout page URL
156
+ */
157
+ getCheckoutUrl(productId: string, priceId: string): string;
158
+ }
159
+
160
+ export { type CreateOrderParams, type CreateOrderResponse, type OrderStatus, type PaymentCallbackData, PaymentClient, type PaymentClientOptions, type PaymentNotification, type Product, type ProductEntitlements, type ProductPrice };
@@ -0,0 +1,160 @@
1
+ /**
2
+ * Youidian Payment SDK - Server Module
3
+ * 用于服务端集成,包含签名、订单创建、回调解密等功能
4
+ */
5
+ /**
6
+ * Order status response
7
+ */
8
+ interface OrderStatus {
9
+ orderId: string;
10
+ status: 'PENDING' | 'PAID' | 'CANCELLED' | 'REFUNDED' | 'FAILED';
11
+ paidAt?: string;
12
+ channelTransactionId?: string;
13
+ }
14
+ /**
15
+ * Product Entitlements
16
+ */
17
+ interface ProductEntitlements {
18
+ [key: string]: any;
19
+ }
20
+ /**
21
+ * Product Price
22
+ */
23
+ interface ProductPrice {
24
+ id: string;
25
+ currency: string;
26
+ amount: number;
27
+ displayAmount: string;
28
+ locale: string | null;
29
+ isDefault: boolean;
30
+ }
31
+ /**
32
+ * Product Data
33
+ */
34
+ interface Product {
35
+ id: string;
36
+ code: string;
37
+ type: string;
38
+ name: string;
39
+ description?: string;
40
+ entitlements: ProductEntitlements;
41
+ prices: ProductPrice[];
42
+ }
43
+ /**
44
+ * SDK Client Options
45
+ */
46
+ interface PaymentClientOptions {
47
+ /** Application ID (Required) */
48
+ appId: string;
49
+ /** Application Secret (Required for server-side operations) */
50
+ appSecret: string;
51
+ /** API Base URL (e.g. https://pay.youidian.com) */
52
+ baseUrl: string;
53
+ }
54
+ /**
55
+ * Create Order Parameters
56
+ */
57
+ interface CreateOrderParams {
58
+ productId?: string;
59
+ priceId?: string;
60
+ channel?: string;
61
+ userId: string;
62
+ returnUrl?: string;
63
+ metadata?: Record<string, any>;
64
+ merchantOrderId?: string;
65
+ openid?: string;
66
+ }
67
+ /**
68
+ * Create Order Response
69
+ */
70
+ interface CreateOrderResponse {
71
+ orderId: string;
72
+ internalId: string;
73
+ amount: number;
74
+ currency: string;
75
+ payParams: any;
76
+ }
77
+ /**
78
+ * Payment Callback Notification
79
+ */
80
+ interface PaymentNotification {
81
+ iv: string;
82
+ encryptedData: string;
83
+ authTag: string;
84
+ }
85
+ /**
86
+ * Decrypted Payment Callback Data
87
+ */
88
+ interface PaymentCallbackData {
89
+ orderId: string;
90
+ merchantOrderId?: string;
91
+ status: 'PAID' | 'CANCELLED' | 'REFUNDED' | 'FAILED';
92
+ amount: number;
93
+ currency: string;
94
+ paidAt: string;
95
+ channelTransactionId?: string;
96
+ metadata?: Record<string, any>;
97
+ }
98
+ /**
99
+ * Server-side Payment Client
100
+ * 服务端支付客户端,用于创建订单、查询状态、解密回调
101
+ */
102
+ declare class PaymentClient {
103
+ private appId;
104
+ private appSecret;
105
+ private baseUrl;
106
+ constructor(options: PaymentClientOptions);
107
+ /**
108
+ * Generate SHA256 signature for the request
109
+ * Logic: SHA256(appId + appSecret + timestamp)
110
+ */
111
+ private generateSignature;
112
+ /**
113
+ * Internal request helper for Gateway API
114
+ */
115
+ private request;
116
+ /**
117
+ * Decrypts the callback notification payload using AES-256-GCM.
118
+ * @param notification - The encrypted notification from payment webhook
119
+ * @returns Decrypted payment callback data
120
+ */
121
+ decryptCallback(notification: PaymentNotification): PaymentCallbackData;
122
+ /**
123
+ * Fetch products for the configured app.
124
+ */
125
+ getProducts(options?: {
126
+ locale?: string;
127
+ currency?: string;
128
+ }): Promise<Product[]>;
129
+ /**
130
+ * Create a new order
131
+ * @param params - Order creation parameters
132
+ * @returns Order details with payment parameters
133
+ */
134
+ createOrder(params: CreateOrderParams): Promise<CreateOrderResponse>;
135
+ /**
136
+ * Pay for an existing order
137
+ * @param orderId - The order ID to pay
138
+ * @param params - Payment parameters including channel
139
+ */
140
+ payOrder(orderId: string, params: {
141
+ channel: string;
142
+ returnUrl?: string;
143
+ openid?: string;
144
+ [key: string]: any;
145
+ }): Promise<CreateOrderResponse>;
146
+ /**
147
+ * Query order status
148
+ * @param orderId - The order ID to query
149
+ */
150
+ getOrderStatus(orderId: string): Promise<OrderStatus>;
151
+ /**
152
+ * Generate checkout URL for client-side payment
153
+ * @param productId - Product ID
154
+ * @param priceId - Price ID
155
+ * @returns Checkout page URL
156
+ */
157
+ getCheckoutUrl(productId: string, priceId: string): string;
158
+ }
159
+
160
+ export { type CreateOrderParams, type CreateOrderResponse, type OrderStatus, type PaymentCallbackData, PaymentClient, type PaymentClientOptions, type PaymentNotification, type Product, type ProductEntitlements, type ProductPrice };