@skalpgg/sdk 1.7.0 → 1.8.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/README.md +15 -4
- package/dist/cjs/index.d.ts +10 -3
- package/dist/cjs/index.js +15 -6
- package/dist/cjs/types.d.ts +90 -9
- package/dist/esm/index.d.ts +10 -3
- package/dist/esm/index.js +15 -6
- package/dist/esm/types.d.ts +90 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -41,7 +41,8 @@ Create the key on the API keys page of your dashboard. Each key is bound to one
|
|
|
41
41
|
|
|
42
42
|
| Method | Scope |
|
|
43
43
|
| --- | --- |
|
|
44
|
-
| `
|
|
44
|
+
| `me()` | none |
|
|
45
|
+
| `checkout.create({ productId, quantity?, customerEmail?, metadata?, couponCode?, returnUrl?, customFields?, player? })` | `checkout:write` |
|
|
45
46
|
| `checkout.get(id)` | `checkout:read` |
|
|
46
47
|
| `orders.list({ status?, productId?, email?, identifier?, createdAfter?, createdBefore?, updatedSince?, limit?, offset? })` | `orders:read` |
|
|
47
48
|
| `orders.get(id)` | `orders:read` |
|
|
@@ -63,7 +64,7 @@ Create the key on the API keys page of your dashboard. Each key is bound to one
|
|
|
63
64
|
| `groups.list()` / `groups.get(id)` | `products:read` |
|
|
64
65
|
| `groups.create({ title, productIds, ... })` / `groups.update(id, { ... })` / `groups.delete(id)` | `products:write` |
|
|
65
66
|
| `coupons.list()` / `coupons.get(id)` | `coupons:read` |
|
|
66
|
-
| `coupons.create({ code, discountType?, discountPercent?, discountAmount?, validFrom?, validTo?, maxUses?, ... })` / `coupons.update(id, { ... })` / `coupons.delete(id)` | `coupons:write` |
|
|
67
|
+
| `coupons.create({ code, discountType?, discountPercent?, discountAmount?, validFrom?, validTo?, maxUses?, subscriptionDuration?, subscriptionMonths?, ... })` / `coupons.update(id, { ... })` / `coupons.delete(id)` | `coupons:write` |
|
|
67
68
|
| `customers.list({ search?, limit?, offset? })` / `customers.get(id)` | `customers:read` |
|
|
68
69
|
| `customers.create({ email, name?, note? })` / `customers.update(id, { name?, note? })` / `customers.delete(id)` | `customers:write` |
|
|
69
70
|
| `feedback.list({ productId?, rating?, limit?, offset? })` / `feedback.get(id)` | `feedback:read` |
|
|
@@ -86,6 +87,8 @@ Create the key on the API keys page of your dashboard. Each key is bound to one
|
|
|
86
87
|
| `licenses.resetDevices({ key, hardwareId? })` | `licenses:write` |
|
|
87
88
|
| `licenses.verify({ licenseKey, serverIp, serverKey, serverPort? })` | none |
|
|
88
89
|
| `licenses.heartbeat({ licenseKey, serverIp })` | none |
|
|
90
|
+
| `webhooks.list()` | `webhooks:read` |
|
|
91
|
+
| `webhooks.create({ url, events, productIds? })` / `webhooks.delete(id)` | `webhooks:write` |
|
|
89
92
|
| `webhooks.constructEvent(rawBody, headers)` | none |
|
|
90
93
|
| `webhooks.verify(rawBody, headers)` | none |
|
|
91
94
|
|
|
@@ -135,7 +138,9 @@ const { replacements } = await skalp.orders.replace(order.id, { reason: 'Key doe
|
|
|
135
138
|
|
|
136
139
|
`updatedSince` lists oldest change first, so you can page through it and keep the last `updatedAt` as your cursor; without it, newest orders come first. Amounts are in major units (`19.5`).
|
|
137
140
|
|
|
138
|
-
Coupons take `validFrom`, `validTo` as an ISO string or a `Date`; `coupons.update` accepts `null` to clear `validTo`, `maxUses`, `minPurchaseAmount` and `description`.
|
|
141
|
+
Coupons take `validFrom`, `validTo` as an ISO string or a `Date`; `coupons.update` accepts `null` to clear `validTo`, `maxUses`, `minPurchaseAmount`, `subscriptionMonths` and `description`. On a subscription, `subscriptionDuration` sets how long the discount lasts: `ONCE` (the default), `REPEATING` for `subscriptionMonths` (1 to 36) or `FOREVER`.
|
|
142
|
+
|
|
143
|
+
`me()` returns the store and the key you are using, with its scopes. `checkout.create` takes `player`, a `name` and game `ids` such as `steamid64` or `mc_name`, when your server already knows who gets the order. Orders carry `serviceFee`, the buyer fee included in `amount`, and customers carry `spent`, one total per currency.
|
|
139
144
|
|
|
140
145
|
## Support and access rules
|
|
141
146
|
|
|
@@ -180,9 +185,15 @@ export async function POST(request: Request) {
|
|
|
180
185
|
}
|
|
181
186
|
```
|
|
182
187
|
|
|
188
|
+
`webhooks.create` returns the endpoint's signing `secret` once, so store it then. `events` takes event names or `'*'` for all of them.
|
|
189
|
+
|
|
190
|
+
```ts
|
|
191
|
+
const { id, secret } = await skalp.webhooks.create({ url: 'https://example.com/skalp', events: ['order.paid', 'subscription.renewed'] })
|
|
192
|
+
```
|
|
193
|
+
|
|
183
194
|
A webhook with the default events receives every purchase as both `order.paid` and its legacy name `purchase.completed`. Handle `order.paid` and deduplicate on `data.idempotencyKey`.
|
|
184
195
|
|
|
185
|
-
`order.created`, `order.updated`, `order.canceled`, `order.replaced`, `query.created`, `query.replied`, `feedback.received` and the subscription events `subscription.
|
|
196
|
+
`order.created`, `order.updated`, `order.canceled`, `order.replaced`, `query.created`, `query.replied`, `feedback.received` and the subscription events `subscription.trial_started`, `subscription.trial_ended` and `subscription.upcoming` are not in the default list either: subscribe the webhook to them by name, and `event.type` narrows `event.data` to the right payload. `order.created`, `order.updated` and `order.canceled` carry the order as `orders.get` returns it, plus `previousStatus`; `order.replaced` adds `reason` and the new keys in `replacements[].key`. Every one of them, like `query.created`, `query.replied` and `feedback.received`, carries a `data.idempotencyKey` that stays the same on every retry of the same event, so deduplicate on it. `subscription.trial_started` follows `subscription.created` when a subscription starts with a trial, free or paid, `subscription.trial_ended` comes when the trial is over, and `subscription.upcoming` comes before a renewal is charged.
|
|
186
197
|
|
|
187
198
|
`product.created`, `product.updated` and `product.stock` are not in the default list: subscribe the webhook to them by name. `product.stock` carries `stock`, `previousStock` and `change` whenever the number of available keys changes.
|
|
188
199
|
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { AccessRule, AddAccessRuleParams, AddSerialsParams, AddSerialsResult, AppealFeedbackParams, ChangeSubscriptionPlanParams, CheckoutSession, CheckoutSessionStatus, CoinCheckout, CoinCheckoutStatus, Coupon, CreateCheckoutParams, CreateCoinCheckoutParams, CreateCouponParams, CreateCustomerParams, CreateProductGroupParams, CreateProductParams, CreateStoreCategoryParams, CreateSubscriptionCheckoutParams, CreateUsageChargeParams, Customer, CustomerDetails, CustomerList, Deleted, Feedback, FeedbackList, HeartbeatParams, Invoice, LicenseKeyInfo, LicenseValidation, LicenseVerification, ListAccessRulesParams, ListCustomersParams, ListFeedbackParams, ListOrdersParams, ListProductsParams, ListQueriesParams, ListSerialsParams, ListSubscriptionsParams, Order, OrderKeysReplaced, OrderList, Product, ProductGroup, ProductStock, ReplaceOrderKeysParams, ReplyParams, SerialList, SkalpEvent, StoreCategory, StoreCategoryWithCount, Subscription, SubscriptionCheckout, SubscriptionCheckoutStatus, SubscriptionList, SupportQueryDetails, SupportQueryList, ResetLicenseDevicesParams, UpdateCouponParams, UpdateCustomerParams, UpdateProductGroupParams, UpdateProductParams, UpdateStoreCategoryParams, UsageCharge, ValidateLicenseParams, VerifyLicenseParams } from './types.js';
|
|
1
|
+
import type { AccessRule, AddAccessRuleParams, AddSerialsParams, AddSerialsResult, AppealFeedbackParams, ChangeSubscriptionPlanParams, CheckoutSession, CheckoutSessionStatus, CoinCheckout, CoinCheckoutStatus, Coupon, CreateCheckoutParams, CreateCoinCheckoutParams, CreateCouponParams, CreateCustomerParams, CreateProductGroupParams, CreateProductParams, CreateStoreCategoryParams, CreateSubscriptionCheckoutParams, CreateUsageChargeParams, CreateWebhookParams, CreatedWebhookEndpoint, Customer, CustomerDetails, CustomerList, Deleted, Feedback, FeedbackList, HeartbeatParams, Invoice, LicenseKeyInfo, LicenseValidation, LicenseVerification, ListAccessRulesParams, ListCustomersParams, ListFeedbackParams, ListOrdersParams, ListProductsParams, ListQueriesParams, ListSerialsParams, ListSubscriptionsParams, Me, Order, OrderKeysReplaced, OrderList, Product, ProductGroup, ProductStock, ReplaceOrderKeysParams, ReplyParams, SerialList, SkalpEvent, StoreCategory, StoreCategoryWithCount, Subscription, SubscriptionCheckout, SubscriptionCheckoutStatus, SubscriptionList, SupportQueryDetails, SupportQueryList, ResetLicenseDevicesParams, UpdateCouponParams, UpdateCustomerParams, UpdateProductGroupParams, UpdateProductParams, UpdateStoreCategoryParams, UsageCharge, ValidateLicenseParams, VerifyLicenseParams, WebhookEndpoint } from './types.js';
|
|
2
2
|
export type * from './types.js';
|
|
3
|
-
export declare const VERSION = "1.
|
|
3
|
+
export declare const VERSION = "1.8.0";
|
|
4
4
|
export interface SkalpOptions {
|
|
5
5
|
apiKey?: string;
|
|
6
6
|
webhookSecret?: string;
|
|
@@ -31,8 +31,9 @@ export declare class SkalpSignatureError extends Error {
|
|
|
31
31
|
export declare class Skalp {
|
|
32
32
|
#private;
|
|
33
33
|
constructor(options?: string | SkalpOptions);
|
|
34
|
+
readonly me: () => Promise<Me>;
|
|
34
35
|
readonly checkout: {
|
|
35
|
-
create: ({ productId, quantity, customerEmail, metadata, couponCode, returnUrl, customFields }: CreateCheckoutParams) => Promise<CheckoutSession>;
|
|
36
|
+
create: ({ productId, quantity, customerEmail, metadata, couponCode, returnUrl, customFields, player }: CreateCheckoutParams) => Promise<CheckoutSession>;
|
|
36
37
|
get: (id: string) => Promise<CheckoutSessionStatus>;
|
|
37
38
|
};
|
|
38
39
|
readonly orders: {
|
|
@@ -129,6 +130,12 @@ export declare class Skalp {
|
|
|
129
130
|
}>;
|
|
130
131
|
};
|
|
131
132
|
readonly webhooks: {
|
|
133
|
+
list: () => Promise<WebhookEndpoint[]>;
|
|
134
|
+
create: ({ url, events, productIds }: CreateWebhookParams) => Promise<CreatedWebhookEndpoint>;
|
|
135
|
+
delete: (id: string) => Promise<{
|
|
136
|
+
id: string;
|
|
137
|
+
deleted: true;
|
|
138
|
+
}>;
|
|
132
139
|
verify: (payload: WebhookPayload, signature: SignatureSource, secret?: string) => Promise<boolean>;
|
|
133
140
|
constructEvent: (payload: WebhookPayload, signature: SignatureSource, secret?: string) => Promise<SkalpEvent>;
|
|
134
141
|
};
|
package/dist/cjs/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Skalp = exports.SkalpSignatureError = exports.SkalpConnectionError = exports.SkalpError = exports.VERSION = void 0;
|
|
4
|
-
exports.VERSION = '1.
|
|
4
|
+
exports.VERSION = '1.8.0';
|
|
5
5
|
const SIGNATURE_HEADER = 'skalp-signature';
|
|
6
6
|
const SIGNATURE_TOLERANCE_SECONDS = 300;
|
|
7
7
|
const PRODUCT_PAGE = 100;
|
|
@@ -82,6 +82,9 @@ const PRODUCT_FIELDS = [
|
|
|
82
82
|
'volumeDiscounts',
|
|
83
83
|
'upsells',
|
|
84
84
|
'prices',
|
|
85
|
+
'poolsEnabled',
|
|
86
|
+
'upgradeFrom',
|
|
87
|
+
'includes',
|
|
85
88
|
];
|
|
86
89
|
const COUPON_FIELDS = [
|
|
87
90
|
'discountType',
|
|
@@ -93,6 +96,8 @@ const COUPON_FIELDS = [
|
|
|
93
96
|
'maxUses',
|
|
94
97
|
'minPurchaseAmount',
|
|
95
98
|
'oneTimePerUser',
|
|
99
|
+
'subscriptionDuration',
|
|
100
|
+
'subscriptionMonths',
|
|
96
101
|
];
|
|
97
102
|
const GROUP_FIELDS = ['title', 'productIds', 'description', 'image', 'sortPriority', 'unlisted'];
|
|
98
103
|
function pick(source, keys) {
|
|
@@ -123,9 +128,10 @@ class Skalp {
|
|
|
123
128
|
throw new Error('Skalp: your API key is a secret and must never reach the browser. Call the SDK from server code, or pass dangerouslyAllowBrowser: true if you really know what you are doing.');
|
|
124
129
|
}
|
|
125
130
|
}
|
|
131
|
+
me = () => this.#request('GET', '/v1/me');
|
|
126
132
|
checkout = {
|
|
127
|
-
create: ({ productId, quantity, customerEmail, metadata, couponCode, returnUrl, customFields }) => this.#request('POST', '/v1/checkout/sessions', {
|
|
128
|
-
body: { items: [{ productId, quantity }], customerEmail, metadata, couponCode, returnUrl, customFields },
|
|
133
|
+
create: ({ productId, quantity, customerEmail, metadata, couponCode, returnUrl, customFields, player }) => this.#request('POST', '/v1/checkout/sessions', {
|
|
134
|
+
body: { items: [{ productId, quantity }], customerEmail, metadata, couponCode, returnUrl, customFields, player },
|
|
129
135
|
}),
|
|
130
136
|
get: (id) => this.#request('GET', `/v1/checkout/sessions/${segment(id)}`),
|
|
131
137
|
};
|
|
@@ -303,6 +309,9 @@ class Skalp {
|
|
|
303
309
|
}),
|
|
304
310
|
};
|
|
305
311
|
webhooks = {
|
|
312
|
+
list: () => this.#request('GET', '/v1/webhooks'),
|
|
313
|
+
create: ({ url, events, productIds }) => this.#request('POST', '/v1/webhooks', { body: { url, events, productIds } }),
|
|
314
|
+
delete: (id) => this.#request('DELETE', `/v1/webhooks/${segment(id)}`),
|
|
306
315
|
verify: async (payload, signature, secret) => (await this.#checkSignature(payload, signature, secret)) === undefined,
|
|
307
316
|
constructEvent: async (payload, signature, secret) => {
|
|
308
317
|
const failure = await this.#checkSignature(payload, signature, secret);
|
|
@@ -416,10 +425,10 @@ function parseSignature(header) {
|
|
|
416
425
|
function toBytes(payload, encoder) {
|
|
417
426
|
if (typeof payload === 'string')
|
|
418
427
|
return encoder.encode(payload);
|
|
419
|
-
if (payload
|
|
428
|
+
if (ArrayBuffer.isView(payload))
|
|
429
|
+
return new Uint8Array(payload.buffer, payload.byteOffset, payload.byteLength);
|
|
430
|
+
if (Object.prototype.toString.call(payload) === '[object ArrayBuffer]')
|
|
420
431
|
return new Uint8Array(payload);
|
|
421
|
-
if (payload instanceof Uint8Array)
|
|
422
|
-
return payload;
|
|
423
432
|
throw new TypeError('Skalp: webhook payload must be the raw request body (string, Buffer or ArrayBuffer). A parsed JSON object cannot be verified, because re-serializing it changes the bytes that were signed.');
|
|
424
433
|
}
|
|
425
434
|
function retryAfterSeconds(res, attempt) {
|
package/dist/cjs/types.d.ts
CHANGED
|
@@ -5,10 +5,19 @@ export type ProductType = 'ONE_TIME' | 'RECURRING' | 'COINS';
|
|
|
5
5
|
export type Game = 'fivem' | 'minecraft' | 'rust';
|
|
6
6
|
export type BillingInterval = 'WEEK' | 'MONTH' | 'QUARTER' | 'HALF_YEAR' | 'YEAR';
|
|
7
7
|
export type OrderStatus = 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'FAILED' | 'REFUNDED' | 'DISPUTED' | 'CANCELED';
|
|
8
|
-
export type PaymentProvider = 'STRIPE' | 'NOWPAYMENTS' | 'PAYPAL';
|
|
8
|
+
export type PaymentProvider = 'STRIPE' | 'NOWPAYMENTS' | 'PAYPAL' | 'PAYSSION';
|
|
9
9
|
export type DeliveryStatus = 'PENDING' | 'PROCESSING' | 'DELIVERED' | 'FAILED';
|
|
10
10
|
export type SubscriptionStatus = 'ACTIVE' | 'CANCELED' | 'PAST_DUE' | 'UNPAID' | 'INCOMPLETE' | 'INCOMPLETE_EXPIRED' | 'TRIALING' | 'PAUSED';
|
|
11
11
|
export type Metadata = Record<string, string>;
|
|
12
|
+
export type PlayerIdKey = 'fivem' | 'license2' | 'steam' | 'discord' | 'xbl' | 'live' | 'fivemId' | 'mc_uuid' | 'mc_name' | 'steamid64';
|
|
13
|
+
export interface PlayerInput {
|
|
14
|
+
name?: string;
|
|
15
|
+
ids?: Partial<Record<PlayerIdKey, string>>;
|
|
16
|
+
}
|
|
17
|
+
export interface Player {
|
|
18
|
+
name: string | null;
|
|
19
|
+
ids: Partial<Record<PlayerIdKey, string>>;
|
|
20
|
+
}
|
|
12
21
|
export interface CreateCheckoutParams {
|
|
13
22
|
productId: string;
|
|
14
23
|
/** Units to sell, within the product's minQuantity and maxQuantity. Defaults to minQuantity. */
|
|
@@ -19,6 +28,7 @@ export interface CreateCheckoutParams {
|
|
|
19
28
|
returnUrl?: string;
|
|
20
29
|
/** Answers you already have, by field key; the buyer adds the rest on the pay page. */
|
|
21
30
|
customFields?: Record<string, string>;
|
|
31
|
+
player?: PlayerInput;
|
|
22
32
|
}
|
|
23
33
|
export interface CheckoutSession {
|
|
24
34
|
id: string;
|
|
@@ -28,7 +38,7 @@ export interface CheckoutSession {
|
|
|
28
38
|
}
|
|
29
39
|
export interface CheckoutSessionStatus {
|
|
30
40
|
id: string;
|
|
31
|
-
status: 'pending' | 'completed' | 'failed';
|
|
41
|
+
status: 'pending' | 'completed' | 'failed' | 'canceled';
|
|
32
42
|
orderNumber: string;
|
|
33
43
|
amount: number;
|
|
34
44
|
currency: Currency;
|
|
@@ -45,23 +55,24 @@ export interface Order {
|
|
|
45
55
|
vatRate: number | null;
|
|
46
56
|
currency: Currency;
|
|
47
57
|
discountAmount: number;
|
|
58
|
+
serviceFee: number | null;
|
|
48
59
|
couponCode: string | null;
|
|
49
60
|
productId: string;
|
|
50
61
|
productName: string;
|
|
51
62
|
productSlug: string;
|
|
52
63
|
/** Units of productId. */
|
|
53
64
|
quantity: number;
|
|
54
|
-
fulfillmentType: FulfillmentType;
|
|
65
|
+
fulfillmentType: FulfillmentType | null;
|
|
55
66
|
bundleId: string | null;
|
|
56
67
|
buyerEmail: string;
|
|
57
68
|
buyerCountry: string | null;
|
|
58
69
|
paymentProvider: PaymentProvider | null;
|
|
59
70
|
isGift: boolean;
|
|
60
|
-
granted
|
|
71
|
+
granted: boolean;
|
|
61
72
|
deliveryStatus: DeliveryStatus | null;
|
|
62
73
|
serialsCount?: number;
|
|
63
74
|
serialsReplaced?: number;
|
|
64
|
-
/** Delivered and replaced keys by id, never their values.
|
|
75
|
+
/** Delivered and replaced keys by id, never their values. Filled in by orders.get, orders.cancel and orders.redeliver. */
|
|
65
76
|
serials?: Array<OrderSerial>;
|
|
66
77
|
createdAt: string;
|
|
67
78
|
updatedAt: string;
|
|
@@ -240,6 +251,9 @@ export interface Product {
|
|
|
240
251
|
volumeDiscounts: Array<VolumeDiscount>;
|
|
241
252
|
/** Products offered on this product's checkout page. */
|
|
242
253
|
upsells: Array<ProductUpsell>;
|
|
254
|
+
poolsEnabled: boolean | null;
|
|
255
|
+
upgradeFrom: Array<string>;
|
|
256
|
+
includes: Array<string>;
|
|
243
257
|
stock: number | null;
|
|
244
258
|
sale: ProductSale | null;
|
|
245
259
|
salesCount: number;
|
|
@@ -313,6 +327,9 @@ interface ProductFields {
|
|
|
313
327
|
upsells?: Array<ProductUpsellInput> | null;
|
|
314
328
|
/** Up to 3 currencies other than the store currency, not for coin packs; the list replaces the old one, [] or null removes them all. */
|
|
315
329
|
prices?: Array<ProductPrice> | null;
|
|
330
|
+
poolsEnabled?: boolean;
|
|
331
|
+
upgradeFrom?: Array<string>;
|
|
332
|
+
includes?: Array<string>;
|
|
316
333
|
}
|
|
317
334
|
export interface CreateProductParams extends ProductFields {
|
|
318
335
|
name: string;
|
|
@@ -370,6 +387,39 @@ export interface Deleted {
|
|
|
370
387
|
id: string;
|
|
371
388
|
deleted: true;
|
|
372
389
|
}
|
|
390
|
+
export interface Me {
|
|
391
|
+
store: {
|
|
392
|
+
id: string;
|
|
393
|
+
name: string;
|
|
394
|
+
slug: string;
|
|
395
|
+
currency: Currency;
|
|
396
|
+
url: string;
|
|
397
|
+
};
|
|
398
|
+
key: {
|
|
399
|
+
name: string;
|
|
400
|
+
scopes: Array<string>;
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
export type WebhookEventName = SkalpEventType | '*';
|
|
404
|
+
export interface WebhookEndpoint {
|
|
405
|
+
id: string;
|
|
406
|
+
url: string;
|
|
407
|
+
events: Array<WebhookEventName>;
|
|
408
|
+
format: 'skalp' | (string & {});
|
|
409
|
+
isActive: boolean;
|
|
410
|
+
createdAt: string;
|
|
411
|
+
}
|
|
412
|
+
export interface CreateWebhookParams {
|
|
413
|
+
url: string;
|
|
414
|
+
events: Array<WebhookEventName>;
|
|
415
|
+
productIds?: Array<string>;
|
|
416
|
+
}
|
|
417
|
+
export interface CreatedWebhookEndpoint {
|
|
418
|
+
id: string;
|
|
419
|
+
url: string;
|
|
420
|
+
events: Array<WebhookEventName>;
|
|
421
|
+
secret: string;
|
|
422
|
+
}
|
|
373
423
|
export interface StoreCategory {
|
|
374
424
|
id: string;
|
|
375
425
|
name: string;
|
|
@@ -423,6 +473,7 @@ export interface UpdateProductGroupParams {
|
|
|
423
473
|
unlisted?: boolean;
|
|
424
474
|
}
|
|
425
475
|
export type CouponDiscountType = 'PERCENT' | 'FIXED';
|
|
476
|
+
export type CouponDuration = 'ONCE' | 'REPEATING' | 'FOREVER';
|
|
426
477
|
export interface Coupon {
|
|
427
478
|
id: string;
|
|
428
479
|
code: string;
|
|
@@ -432,6 +483,8 @@ export interface Coupon {
|
|
|
432
483
|
discountAmount: number | null;
|
|
433
484
|
productIds: Array<string>;
|
|
434
485
|
disabledWithVolumeDiscounts: boolean;
|
|
486
|
+
subscriptionDuration: CouponDuration;
|
|
487
|
+
subscriptionMonths: number | null;
|
|
435
488
|
validFrom: string;
|
|
436
489
|
validTo: string | null;
|
|
437
490
|
maxUses: number | null;
|
|
@@ -455,6 +508,8 @@ export interface CreateCouponParams {
|
|
|
455
508
|
maxUses?: number;
|
|
456
509
|
minPurchaseAmount?: number;
|
|
457
510
|
oneTimePerUser?: boolean;
|
|
511
|
+
subscriptionDuration?: CouponDuration;
|
|
512
|
+
subscriptionMonths?: number;
|
|
458
513
|
}
|
|
459
514
|
export interface UpdateCouponParams {
|
|
460
515
|
discountType?: CouponDiscountType;
|
|
@@ -469,6 +524,8 @@ export interface UpdateCouponParams {
|
|
|
469
524
|
minPurchaseAmount?: number | null;
|
|
470
525
|
oneTimePerUser?: boolean;
|
|
471
526
|
isActive?: boolean;
|
|
527
|
+
subscriptionDuration?: CouponDuration;
|
|
528
|
+
subscriptionMonths?: number | null;
|
|
472
529
|
}
|
|
473
530
|
export interface Customer {
|
|
474
531
|
id: string;
|
|
@@ -479,6 +536,10 @@ export interface Customer {
|
|
|
479
536
|
ordersCount: number;
|
|
480
537
|
totalSpent: number;
|
|
481
538
|
currency: Currency;
|
|
539
|
+
spent: Array<{
|
|
540
|
+
currency: Currency;
|
|
541
|
+
amount: number;
|
|
542
|
+
}>;
|
|
482
543
|
firstOrderAt: string | null;
|
|
483
544
|
lastOrderAt: string | null;
|
|
484
545
|
createdAt: string;
|
|
@@ -486,6 +547,17 @@ export interface Customer {
|
|
|
486
547
|
}
|
|
487
548
|
export interface CustomerDetails extends Customer {
|
|
488
549
|
recentOrders: Array<Order>;
|
|
550
|
+
recentSubscriptionPayments: Array<SubscriptionPayment>;
|
|
551
|
+
}
|
|
552
|
+
export interface SubscriptionPayment {
|
|
553
|
+
id: string;
|
|
554
|
+
orderNumber: string | null;
|
|
555
|
+
status: 'COMPLETED' | 'REFUNDED';
|
|
556
|
+
amount: number;
|
|
557
|
+
currency: Currency;
|
|
558
|
+
productName: string;
|
|
559
|
+
subscriptionId: string;
|
|
560
|
+
createdAt: string;
|
|
489
561
|
}
|
|
490
562
|
export interface ListCustomersParams {
|
|
491
563
|
search?: string;
|
|
@@ -615,7 +687,7 @@ export interface CreateSubscriptionCheckoutParams {
|
|
|
615
687
|
customerEmail?: string;
|
|
616
688
|
externalRef?: string;
|
|
617
689
|
metadata?: Metadata;
|
|
618
|
-
currency?: 'EUR' | 'USD' | 'PLN';
|
|
690
|
+
currency?: 'EUR' | 'USD' | 'PLN' | 'BRL';
|
|
619
691
|
returnUrl?: string;
|
|
620
692
|
}
|
|
621
693
|
export interface SubscriptionCheckout {
|
|
@@ -692,7 +764,7 @@ export interface Invoice {
|
|
|
692
764
|
}
|
|
693
765
|
export interface CreateUsageChargeParams {
|
|
694
766
|
amount: number;
|
|
695
|
-
currency:
|
|
767
|
+
currency: Currency;
|
|
696
768
|
description: string;
|
|
697
769
|
idempotencyKey: string;
|
|
698
770
|
periodStart: string | Date;
|
|
@@ -824,6 +896,7 @@ export interface OrderPaidData {
|
|
|
824
896
|
customFields: Record<string, string>;
|
|
825
897
|
deliveryType?: string;
|
|
826
898
|
deliveryCommand?: string;
|
|
899
|
+
player?: Player;
|
|
827
900
|
}
|
|
828
901
|
export interface OrderRefundedData {
|
|
829
902
|
orderId: string;
|
|
@@ -839,6 +912,8 @@ export interface OrderRefundedData {
|
|
|
839
912
|
fullRefund: boolean;
|
|
840
913
|
licenses: Array<WebhookLicense>;
|
|
841
914
|
revocations: Array<Revocation>;
|
|
915
|
+
upgradedTo?: string;
|
|
916
|
+
player?: Player;
|
|
842
917
|
}
|
|
843
918
|
export interface Revocation {
|
|
844
919
|
productId: string;
|
|
@@ -891,6 +966,9 @@ export interface SubscriptionEventData {
|
|
|
891
966
|
licenseKey: string | null;
|
|
892
967
|
licenseStatus: string | null;
|
|
893
968
|
licenseExpiresAt: string | null;
|
|
969
|
+
deliveryType?: string;
|
|
970
|
+
deliveryCommand?: string;
|
|
971
|
+
player?: Player;
|
|
894
972
|
}
|
|
895
973
|
export interface ProductEventData {
|
|
896
974
|
productId: string;
|
|
@@ -953,7 +1031,10 @@ export interface FeedbackReceivedData {
|
|
|
953
1031
|
customerName: string | null;
|
|
954
1032
|
createdAt: string;
|
|
955
1033
|
}
|
|
956
|
-
export type SkalpEvent = Envelope<'order.created' | 'order.updated' | 'order.canceled', OrderEventData> | Envelope<'order.replaced', OrderReplacedData> | Envelope<'order.paid' | 'purchase.completed', OrderPaidData> | Envelope<'order.refunded', OrderRefundedData> | Envelope<'order.disputed' | 'account.suspend', OrderDisputedData> | Envelope<'account.restore', AccountRestoreData> | Envelope<'subscription.created' | 'subscription.updated' | 'subscription.trial_started' | 'subscription.trial_ended'
|
|
1034
|
+
export type SkalpEvent = Envelope<'order.created' | 'order.updated' | 'order.canceled', OrderEventData> | Envelope<'order.replaced', OrderReplacedData> | Envelope<'order.paid' | 'purchase.completed', OrderPaidData> | Envelope<'order.refunded', OrderRefundedData> | Envelope<'order.disputed' | 'account.suspend', OrderDisputedData> | Envelope<'account.restore', AccountRestoreData> | Envelope<'subscription.created' | 'subscription.updated' | 'subscription.trial_started' | 'subscription.trial_ended', SubscriptionEventData> | Envelope<'subscription.upcoming', SubscriptionEventData & {
|
|
1035
|
+
amountDue: number;
|
|
1036
|
+
nextPaymentAttempt: string | null;
|
|
1037
|
+
}> | Envelope<'subscription.renewed', SubscriptionEventData & {
|
|
957
1038
|
invoiceId: string;
|
|
958
1039
|
amountPaid: number;
|
|
959
1040
|
periodExtendedTo: string;
|
|
@@ -963,7 +1044,7 @@ export type SkalpEvent = Envelope<'order.created' | 'order.updated' | 'order.can
|
|
|
963
1044
|
nextPaymentAttempt: string | null;
|
|
964
1045
|
}> | Envelope<'subscription.canceled', SubscriptionEventData & {
|
|
965
1046
|
endedAt: string | null;
|
|
966
|
-
cancelReason: 'requested' | 'payment_failure' | 'dispute' | 'stripe';
|
|
1047
|
+
cancelReason: 'requested' | 'payment_failure' | 'dispute' | 'stripe' | 'expired';
|
|
967
1048
|
revokeCommand?: string;
|
|
968
1049
|
}> | Envelope<'subscription.refunded', SubscriptionEventData & {
|
|
969
1050
|
invoiceId: string;
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { AccessRule, AddAccessRuleParams, AddSerialsParams, AddSerialsResult, AppealFeedbackParams, ChangeSubscriptionPlanParams, CheckoutSession, CheckoutSessionStatus, CoinCheckout, CoinCheckoutStatus, Coupon, CreateCheckoutParams, CreateCoinCheckoutParams, CreateCouponParams, CreateCustomerParams, CreateProductGroupParams, CreateProductParams, CreateStoreCategoryParams, CreateSubscriptionCheckoutParams, CreateUsageChargeParams, Customer, CustomerDetails, CustomerList, Deleted, Feedback, FeedbackList, HeartbeatParams, Invoice, LicenseKeyInfo, LicenseValidation, LicenseVerification, ListAccessRulesParams, ListCustomersParams, ListFeedbackParams, ListOrdersParams, ListProductsParams, ListQueriesParams, ListSerialsParams, ListSubscriptionsParams, Order, OrderKeysReplaced, OrderList, Product, ProductGroup, ProductStock, ReplaceOrderKeysParams, ReplyParams, SerialList, SkalpEvent, StoreCategory, StoreCategoryWithCount, Subscription, SubscriptionCheckout, SubscriptionCheckoutStatus, SubscriptionList, SupportQueryDetails, SupportQueryList, ResetLicenseDevicesParams, UpdateCouponParams, UpdateCustomerParams, UpdateProductGroupParams, UpdateProductParams, UpdateStoreCategoryParams, UsageCharge, ValidateLicenseParams, VerifyLicenseParams } from './types.js';
|
|
1
|
+
import type { AccessRule, AddAccessRuleParams, AddSerialsParams, AddSerialsResult, AppealFeedbackParams, ChangeSubscriptionPlanParams, CheckoutSession, CheckoutSessionStatus, CoinCheckout, CoinCheckoutStatus, Coupon, CreateCheckoutParams, CreateCoinCheckoutParams, CreateCouponParams, CreateCustomerParams, CreateProductGroupParams, CreateProductParams, CreateStoreCategoryParams, CreateSubscriptionCheckoutParams, CreateUsageChargeParams, CreateWebhookParams, CreatedWebhookEndpoint, Customer, CustomerDetails, CustomerList, Deleted, Feedback, FeedbackList, HeartbeatParams, Invoice, LicenseKeyInfo, LicenseValidation, LicenseVerification, ListAccessRulesParams, ListCustomersParams, ListFeedbackParams, ListOrdersParams, ListProductsParams, ListQueriesParams, ListSerialsParams, ListSubscriptionsParams, Me, Order, OrderKeysReplaced, OrderList, Product, ProductGroup, ProductStock, ReplaceOrderKeysParams, ReplyParams, SerialList, SkalpEvent, StoreCategory, StoreCategoryWithCount, Subscription, SubscriptionCheckout, SubscriptionCheckoutStatus, SubscriptionList, SupportQueryDetails, SupportQueryList, ResetLicenseDevicesParams, UpdateCouponParams, UpdateCustomerParams, UpdateProductGroupParams, UpdateProductParams, UpdateStoreCategoryParams, UsageCharge, ValidateLicenseParams, VerifyLicenseParams, WebhookEndpoint } from './types.js';
|
|
2
2
|
export type * from './types.js';
|
|
3
|
-
export declare const VERSION = "1.
|
|
3
|
+
export declare const VERSION = "1.8.0";
|
|
4
4
|
export interface SkalpOptions {
|
|
5
5
|
apiKey?: string;
|
|
6
6
|
webhookSecret?: string;
|
|
@@ -31,8 +31,9 @@ export declare class SkalpSignatureError extends Error {
|
|
|
31
31
|
export declare class Skalp {
|
|
32
32
|
#private;
|
|
33
33
|
constructor(options?: string | SkalpOptions);
|
|
34
|
+
readonly me: () => Promise<Me>;
|
|
34
35
|
readonly checkout: {
|
|
35
|
-
create: ({ productId, quantity, customerEmail, metadata, couponCode, returnUrl, customFields }: CreateCheckoutParams) => Promise<CheckoutSession>;
|
|
36
|
+
create: ({ productId, quantity, customerEmail, metadata, couponCode, returnUrl, customFields, player }: CreateCheckoutParams) => Promise<CheckoutSession>;
|
|
36
37
|
get: (id: string) => Promise<CheckoutSessionStatus>;
|
|
37
38
|
};
|
|
38
39
|
readonly orders: {
|
|
@@ -129,6 +130,12 @@ export declare class Skalp {
|
|
|
129
130
|
}>;
|
|
130
131
|
};
|
|
131
132
|
readonly webhooks: {
|
|
133
|
+
list: () => Promise<WebhookEndpoint[]>;
|
|
134
|
+
create: ({ url, events, productIds }: CreateWebhookParams) => Promise<CreatedWebhookEndpoint>;
|
|
135
|
+
delete: (id: string) => Promise<{
|
|
136
|
+
id: string;
|
|
137
|
+
deleted: true;
|
|
138
|
+
}>;
|
|
132
139
|
verify: (payload: WebhookPayload, signature: SignatureSource, secret?: string) => Promise<boolean>;
|
|
133
140
|
constructEvent: (payload: WebhookPayload, signature: SignatureSource, secret?: string) => Promise<SkalpEvent>;
|
|
134
141
|
};
|
package/dist/esm/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const VERSION = '1.
|
|
1
|
+
export const VERSION = '1.8.0';
|
|
2
2
|
const SIGNATURE_HEADER = 'skalp-signature';
|
|
3
3
|
const SIGNATURE_TOLERANCE_SECONDS = 300;
|
|
4
4
|
const PRODUCT_PAGE = 100;
|
|
@@ -76,6 +76,9 @@ const PRODUCT_FIELDS = [
|
|
|
76
76
|
'volumeDiscounts',
|
|
77
77
|
'upsells',
|
|
78
78
|
'prices',
|
|
79
|
+
'poolsEnabled',
|
|
80
|
+
'upgradeFrom',
|
|
81
|
+
'includes',
|
|
79
82
|
];
|
|
80
83
|
const COUPON_FIELDS = [
|
|
81
84
|
'discountType',
|
|
@@ -87,6 +90,8 @@ const COUPON_FIELDS = [
|
|
|
87
90
|
'maxUses',
|
|
88
91
|
'minPurchaseAmount',
|
|
89
92
|
'oneTimePerUser',
|
|
93
|
+
'subscriptionDuration',
|
|
94
|
+
'subscriptionMonths',
|
|
90
95
|
];
|
|
91
96
|
const GROUP_FIELDS = ['title', 'productIds', 'description', 'image', 'sortPriority', 'unlisted'];
|
|
92
97
|
function pick(source, keys) {
|
|
@@ -117,9 +122,10 @@ export class Skalp {
|
|
|
117
122
|
throw new Error('Skalp: your API key is a secret and must never reach the browser. Call the SDK from server code, or pass dangerouslyAllowBrowser: true if you really know what you are doing.');
|
|
118
123
|
}
|
|
119
124
|
}
|
|
125
|
+
me = () => this.#request('GET', '/v1/me');
|
|
120
126
|
checkout = {
|
|
121
|
-
create: ({ productId, quantity, customerEmail, metadata, couponCode, returnUrl, customFields }) => this.#request('POST', '/v1/checkout/sessions', {
|
|
122
|
-
body: { items: [{ productId, quantity }], customerEmail, metadata, couponCode, returnUrl, customFields },
|
|
127
|
+
create: ({ productId, quantity, customerEmail, metadata, couponCode, returnUrl, customFields, player }) => this.#request('POST', '/v1/checkout/sessions', {
|
|
128
|
+
body: { items: [{ productId, quantity }], customerEmail, metadata, couponCode, returnUrl, customFields, player },
|
|
123
129
|
}),
|
|
124
130
|
get: (id) => this.#request('GET', `/v1/checkout/sessions/${segment(id)}`),
|
|
125
131
|
};
|
|
@@ -297,6 +303,9 @@ export class Skalp {
|
|
|
297
303
|
}),
|
|
298
304
|
};
|
|
299
305
|
webhooks = {
|
|
306
|
+
list: () => this.#request('GET', '/v1/webhooks'),
|
|
307
|
+
create: ({ url, events, productIds }) => this.#request('POST', '/v1/webhooks', { body: { url, events, productIds } }),
|
|
308
|
+
delete: (id) => this.#request('DELETE', `/v1/webhooks/${segment(id)}`),
|
|
300
309
|
verify: async (payload, signature, secret) => (await this.#checkSignature(payload, signature, secret)) === undefined,
|
|
301
310
|
constructEvent: async (payload, signature, secret) => {
|
|
302
311
|
const failure = await this.#checkSignature(payload, signature, secret);
|
|
@@ -409,10 +418,10 @@ function parseSignature(header) {
|
|
|
409
418
|
function toBytes(payload, encoder) {
|
|
410
419
|
if (typeof payload === 'string')
|
|
411
420
|
return encoder.encode(payload);
|
|
412
|
-
if (payload
|
|
421
|
+
if (ArrayBuffer.isView(payload))
|
|
422
|
+
return new Uint8Array(payload.buffer, payload.byteOffset, payload.byteLength);
|
|
423
|
+
if (Object.prototype.toString.call(payload) === '[object ArrayBuffer]')
|
|
413
424
|
return new Uint8Array(payload);
|
|
414
|
-
if (payload instanceof Uint8Array)
|
|
415
|
-
return payload;
|
|
416
425
|
throw new TypeError('Skalp: webhook payload must be the raw request body (string, Buffer or ArrayBuffer). A parsed JSON object cannot be verified, because re-serializing it changes the bytes that were signed.');
|
|
417
426
|
}
|
|
418
427
|
function retryAfterSeconds(res, attempt) {
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -5,10 +5,19 @@ export type ProductType = 'ONE_TIME' | 'RECURRING' | 'COINS';
|
|
|
5
5
|
export type Game = 'fivem' | 'minecraft' | 'rust';
|
|
6
6
|
export type BillingInterval = 'WEEK' | 'MONTH' | 'QUARTER' | 'HALF_YEAR' | 'YEAR';
|
|
7
7
|
export type OrderStatus = 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'FAILED' | 'REFUNDED' | 'DISPUTED' | 'CANCELED';
|
|
8
|
-
export type PaymentProvider = 'STRIPE' | 'NOWPAYMENTS' | 'PAYPAL';
|
|
8
|
+
export type PaymentProvider = 'STRIPE' | 'NOWPAYMENTS' | 'PAYPAL' | 'PAYSSION';
|
|
9
9
|
export type DeliveryStatus = 'PENDING' | 'PROCESSING' | 'DELIVERED' | 'FAILED';
|
|
10
10
|
export type SubscriptionStatus = 'ACTIVE' | 'CANCELED' | 'PAST_DUE' | 'UNPAID' | 'INCOMPLETE' | 'INCOMPLETE_EXPIRED' | 'TRIALING' | 'PAUSED';
|
|
11
11
|
export type Metadata = Record<string, string>;
|
|
12
|
+
export type PlayerIdKey = 'fivem' | 'license2' | 'steam' | 'discord' | 'xbl' | 'live' | 'fivemId' | 'mc_uuid' | 'mc_name' | 'steamid64';
|
|
13
|
+
export interface PlayerInput {
|
|
14
|
+
name?: string;
|
|
15
|
+
ids?: Partial<Record<PlayerIdKey, string>>;
|
|
16
|
+
}
|
|
17
|
+
export interface Player {
|
|
18
|
+
name: string | null;
|
|
19
|
+
ids: Partial<Record<PlayerIdKey, string>>;
|
|
20
|
+
}
|
|
12
21
|
export interface CreateCheckoutParams {
|
|
13
22
|
productId: string;
|
|
14
23
|
/** Units to sell, within the product's minQuantity and maxQuantity. Defaults to minQuantity. */
|
|
@@ -19,6 +28,7 @@ export interface CreateCheckoutParams {
|
|
|
19
28
|
returnUrl?: string;
|
|
20
29
|
/** Answers you already have, by field key; the buyer adds the rest on the pay page. */
|
|
21
30
|
customFields?: Record<string, string>;
|
|
31
|
+
player?: PlayerInput;
|
|
22
32
|
}
|
|
23
33
|
export interface CheckoutSession {
|
|
24
34
|
id: string;
|
|
@@ -28,7 +38,7 @@ export interface CheckoutSession {
|
|
|
28
38
|
}
|
|
29
39
|
export interface CheckoutSessionStatus {
|
|
30
40
|
id: string;
|
|
31
|
-
status: 'pending' | 'completed' | 'failed';
|
|
41
|
+
status: 'pending' | 'completed' | 'failed' | 'canceled';
|
|
32
42
|
orderNumber: string;
|
|
33
43
|
amount: number;
|
|
34
44
|
currency: Currency;
|
|
@@ -45,23 +55,24 @@ export interface Order {
|
|
|
45
55
|
vatRate: number | null;
|
|
46
56
|
currency: Currency;
|
|
47
57
|
discountAmount: number;
|
|
58
|
+
serviceFee: number | null;
|
|
48
59
|
couponCode: string | null;
|
|
49
60
|
productId: string;
|
|
50
61
|
productName: string;
|
|
51
62
|
productSlug: string;
|
|
52
63
|
/** Units of productId. */
|
|
53
64
|
quantity: number;
|
|
54
|
-
fulfillmentType: FulfillmentType;
|
|
65
|
+
fulfillmentType: FulfillmentType | null;
|
|
55
66
|
bundleId: string | null;
|
|
56
67
|
buyerEmail: string;
|
|
57
68
|
buyerCountry: string | null;
|
|
58
69
|
paymentProvider: PaymentProvider | null;
|
|
59
70
|
isGift: boolean;
|
|
60
|
-
granted
|
|
71
|
+
granted: boolean;
|
|
61
72
|
deliveryStatus: DeliveryStatus | null;
|
|
62
73
|
serialsCount?: number;
|
|
63
74
|
serialsReplaced?: number;
|
|
64
|
-
/** Delivered and replaced keys by id, never their values.
|
|
75
|
+
/** Delivered and replaced keys by id, never their values. Filled in by orders.get, orders.cancel and orders.redeliver. */
|
|
65
76
|
serials?: Array<OrderSerial>;
|
|
66
77
|
createdAt: string;
|
|
67
78
|
updatedAt: string;
|
|
@@ -240,6 +251,9 @@ export interface Product {
|
|
|
240
251
|
volumeDiscounts: Array<VolumeDiscount>;
|
|
241
252
|
/** Products offered on this product's checkout page. */
|
|
242
253
|
upsells: Array<ProductUpsell>;
|
|
254
|
+
poolsEnabled: boolean | null;
|
|
255
|
+
upgradeFrom: Array<string>;
|
|
256
|
+
includes: Array<string>;
|
|
243
257
|
stock: number | null;
|
|
244
258
|
sale: ProductSale | null;
|
|
245
259
|
salesCount: number;
|
|
@@ -313,6 +327,9 @@ interface ProductFields {
|
|
|
313
327
|
upsells?: Array<ProductUpsellInput> | null;
|
|
314
328
|
/** Up to 3 currencies other than the store currency, not for coin packs; the list replaces the old one, [] or null removes them all. */
|
|
315
329
|
prices?: Array<ProductPrice> | null;
|
|
330
|
+
poolsEnabled?: boolean;
|
|
331
|
+
upgradeFrom?: Array<string>;
|
|
332
|
+
includes?: Array<string>;
|
|
316
333
|
}
|
|
317
334
|
export interface CreateProductParams extends ProductFields {
|
|
318
335
|
name: string;
|
|
@@ -370,6 +387,39 @@ export interface Deleted {
|
|
|
370
387
|
id: string;
|
|
371
388
|
deleted: true;
|
|
372
389
|
}
|
|
390
|
+
export interface Me {
|
|
391
|
+
store: {
|
|
392
|
+
id: string;
|
|
393
|
+
name: string;
|
|
394
|
+
slug: string;
|
|
395
|
+
currency: Currency;
|
|
396
|
+
url: string;
|
|
397
|
+
};
|
|
398
|
+
key: {
|
|
399
|
+
name: string;
|
|
400
|
+
scopes: Array<string>;
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
export type WebhookEventName = SkalpEventType | '*';
|
|
404
|
+
export interface WebhookEndpoint {
|
|
405
|
+
id: string;
|
|
406
|
+
url: string;
|
|
407
|
+
events: Array<WebhookEventName>;
|
|
408
|
+
format: 'skalp' | (string & {});
|
|
409
|
+
isActive: boolean;
|
|
410
|
+
createdAt: string;
|
|
411
|
+
}
|
|
412
|
+
export interface CreateWebhookParams {
|
|
413
|
+
url: string;
|
|
414
|
+
events: Array<WebhookEventName>;
|
|
415
|
+
productIds?: Array<string>;
|
|
416
|
+
}
|
|
417
|
+
export interface CreatedWebhookEndpoint {
|
|
418
|
+
id: string;
|
|
419
|
+
url: string;
|
|
420
|
+
events: Array<WebhookEventName>;
|
|
421
|
+
secret: string;
|
|
422
|
+
}
|
|
373
423
|
export interface StoreCategory {
|
|
374
424
|
id: string;
|
|
375
425
|
name: string;
|
|
@@ -423,6 +473,7 @@ export interface UpdateProductGroupParams {
|
|
|
423
473
|
unlisted?: boolean;
|
|
424
474
|
}
|
|
425
475
|
export type CouponDiscountType = 'PERCENT' | 'FIXED';
|
|
476
|
+
export type CouponDuration = 'ONCE' | 'REPEATING' | 'FOREVER';
|
|
426
477
|
export interface Coupon {
|
|
427
478
|
id: string;
|
|
428
479
|
code: string;
|
|
@@ -432,6 +483,8 @@ export interface Coupon {
|
|
|
432
483
|
discountAmount: number | null;
|
|
433
484
|
productIds: Array<string>;
|
|
434
485
|
disabledWithVolumeDiscounts: boolean;
|
|
486
|
+
subscriptionDuration: CouponDuration;
|
|
487
|
+
subscriptionMonths: number | null;
|
|
435
488
|
validFrom: string;
|
|
436
489
|
validTo: string | null;
|
|
437
490
|
maxUses: number | null;
|
|
@@ -455,6 +508,8 @@ export interface CreateCouponParams {
|
|
|
455
508
|
maxUses?: number;
|
|
456
509
|
minPurchaseAmount?: number;
|
|
457
510
|
oneTimePerUser?: boolean;
|
|
511
|
+
subscriptionDuration?: CouponDuration;
|
|
512
|
+
subscriptionMonths?: number;
|
|
458
513
|
}
|
|
459
514
|
export interface UpdateCouponParams {
|
|
460
515
|
discountType?: CouponDiscountType;
|
|
@@ -469,6 +524,8 @@ export interface UpdateCouponParams {
|
|
|
469
524
|
minPurchaseAmount?: number | null;
|
|
470
525
|
oneTimePerUser?: boolean;
|
|
471
526
|
isActive?: boolean;
|
|
527
|
+
subscriptionDuration?: CouponDuration;
|
|
528
|
+
subscriptionMonths?: number | null;
|
|
472
529
|
}
|
|
473
530
|
export interface Customer {
|
|
474
531
|
id: string;
|
|
@@ -479,6 +536,10 @@ export interface Customer {
|
|
|
479
536
|
ordersCount: number;
|
|
480
537
|
totalSpent: number;
|
|
481
538
|
currency: Currency;
|
|
539
|
+
spent: Array<{
|
|
540
|
+
currency: Currency;
|
|
541
|
+
amount: number;
|
|
542
|
+
}>;
|
|
482
543
|
firstOrderAt: string | null;
|
|
483
544
|
lastOrderAt: string | null;
|
|
484
545
|
createdAt: string;
|
|
@@ -486,6 +547,17 @@ export interface Customer {
|
|
|
486
547
|
}
|
|
487
548
|
export interface CustomerDetails extends Customer {
|
|
488
549
|
recentOrders: Array<Order>;
|
|
550
|
+
recentSubscriptionPayments: Array<SubscriptionPayment>;
|
|
551
|
+
}
|
|
552
|
+
export interface SubscriptionPayment {
|
|
553
|
+
id: string;
|
|
554
|
+
orderNumber: string | null;
|
|
555
|
+
status: 'COMPLETED' | 'REFUNDED';
|
|
556
|
+
amount: number;
|
|
557
|
+
currency: Currency;
|
|
558
|
+
productName: string;
|
|
559
|
+
subscriptionId: string;
|
|
560
|
+
createdAt: string;
|
|
489
561
|
}
|
|
490
562
|
export interface ListCustomersParams {
|
|
491
563
|
search?: string;
|
|
@@ -615,7 +687,7 @@ export interface CreateSubscriptionCheckoutParams {
|
|
|
615
687
|
customerEmail?: string;
|
|
616
688
|
externalRef?: string;
|
|
617
689
|
metadata?: Metadata;
|
|
618
|
-
currency?: 'EUR' | 'USD' | 'PLN';
|
|
690
|
+
currency?: 'EUR' | 'USD' | 'PLN' | 'BRL';
|
|
619
691
|
returnUrl?: string;
|
|
620
692
|
}
|
|
621
693
|
export interface SubscriptionCheckout {
|
|
@@ -692,7 +764,7 @@ export interface Invoice {
|
|
|
692
764
|
}
|
|
693
765
|
export interface CreateUsageChargeParams {
|
|
694
766
|
amount: number;
|
|
695
|
-
currency:
|
|
767
|
+
currency: Currency;
|
|
696
768
|
description: string;
|
|
697
769
|
idempotencyKey: string;
|
|
698
770
|
periodStart: string | Date;
|
|
@@ -824,6 +896,7 @@ export interface OrderPaidData {
|
|
|
824
896
|
customFields: Record<string, string>;
|
|
825
897
|
deliveryType?: string;
|
|
826
898
|
deliveryCommand?: string;
|
|
899
|
+
player?: Player;
|
|
827
900
|
}
|
|
828
901
|
export interface OrderRefundedData {
|
|
829
902
|
orderId: string;
|
|
@@ -839,6 +912,8 @@ export interface OrderRefundedData {
|
|
|
839
912
|
fullRefund: boolean;
|
|
840
913
|
licenses: Array<WebhookLicense>;
|
|
841
914
|
revocations: Array<Revocation>;
|
|
915
|
+
upgradedTo?: string;
|
|
916
|
+
player?: Player;
|
|
842
917
|
}
|
|
843
918
|
export interface Revocation {
|
|
844
919
|
productId: string;
|
|
@@ -891,6 +966,9 @@ export interface SubscriptionEventData {
|
|
|
891
966
|
licenseKey: string | null;
|
|
892
967
|
licenseStatus: string | null;
|
|
893
968
|
licenseExpiresAt: string | null;
|
|
969
|
+
deliveryType?: string;
|
|
970
|
+
deliveryCommand?: string;
|
|
971
|
+
player?: Player;
|
|
894
972
|
}
|
|
895
973
|
export interface ProductEventData {
|
|
896
974
|
productId: string;
|
|
@@ -953,7 +1031,10 @@ export interface FeedbackReceivedData {
|
|
|
953
1031
|
customerName: string | null;
|
|
954
1032
|
createdAt: string;
|
|
955
1033
|
}
|
|
956
|
-
export type SkalpEvent = Envelope<'order.created' | 'order.updated' | 'order.canceled', OrderEventData> | Envelope<'order.replaced', OrderReplacedData> | Envelope<'order.paid' | 'purchase.completed', OrderPaidData> | Envelope<'order.refunded', OrderRefundedData> | Envelope<'order.disputed' | 'account.suspend', OrderDisputedData> | Envelope<'account.restore', AccountRestoreData> | Envelope<'subscription.created' | 'subscription.updated' | 'subscription.trial_started' | 'subscription.trial_ended'
|
|
1034
|
+
export type SkalpEvent = Envelope<'order.created' | 'order.updated' | 'order.canceled', OrderEventData> | Envelope<'order.replaced', OrderReplacedData> | Envelope<'order.paid' | 'purchase.completed', OrderPaidData> | Envelope<'order.refunded', OrderRefundedData> | Envelope<'order.disputed' | 'account.suspend', OrderDisputedData> | Envelope<'account.restore', AccountRestoreData> | Envelope<'subscription.created' | 'subscription.updated' | 'subscription.trial_started' | 'subscription.trial_ended', SubscriptionEventData> | Envelope<'subscription.upcoming', SubscriptionEventData & {
|
|
1035
|
+
amountDue: number;
|
|
1036
|
+
nextPaymentAttempt: string | null;
|
|
1037
|
+
}> | Envelope<'subscription.renewed', SubscriptionEventData & {
|
|
957
1038
|
invoiceId: string;
|
|
958
1039
|
amountPaid: number;
|
|
959
1040
|
periodExtendedTo: string;
|
|
@@ -963,7 +1044,7 @@ export type SkalpEvent = Envelope<'order.created' | 'order.updated' | 'order.can
|
|
|
963
1044
|
nextPaymentAttempt: string | null;
|
|
964
1045
|
}> | Envelope<'subscription.canceled', SubscriptionEventData & {
|
|
965
1046
|
endedAt: string | null;
|
|
966
|
-
cancelReason: 'requested' | 'payment_failure' | 'dispute' | 'stripe';
|
|
1047
|
+
cancelReason: 'requested' | 'payment_failure' | 'dispute' | 'stripe' | 'expired';
|
|
967
1048
|
revokeCommand?: string;
|
|
968
1049
|
}> | Envelope<'subscription.refunded', SubscriptionEventData & {
|
|
969
1050
|
invoiceId: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skalpgg/sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "Official Skalp SDK for Node.js and edge runtimes: checkout, subscriptions, catalog and key stock, webhooks and license verification.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://skalp.gg/docs/sdk",
|