@skalpgg/sdk 1.5.0 → 1.7.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 +14 -3
- package/dist/cjs/index.d.ts +3 -2
- package/dist/cjs/index.js +28 -3
- package/dist/cjs/types.d.ts +16 -1
- package/dist/esm/index.d.ts +3 -2
- package/dist/esm/index.js +28 -3
- package/dist/esm/types.d.ts +16 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -43,9 +43,10 @@ Create the key on the API keys page of your dashboard. Each key is bound to one
|
|
|
43
43
|
| --- | --- |
|
|
44
44
|
| `checkout.create({ productId, quantity?, customerEmail?, metadata?, couponCode?, returnUrl?, customFields? })` | `checkout:write` |
|
|
45
45
|
| `checkout.get(id)` | `checkout:read` |
|
|
46
|
-
| `orders.list({ status?, productId?, email?, createdAfter?, createdBefore?, updatedSince?, limit?, offset? })` | `orders:read` |
|
|
46
|
+
| `orders.list({ status?, productId?, email?, identifier?, createdAfter?, createdBefore?, updatedSince?, limit?, offset? })` | `orders:read` |
|
|
47
47
|
| `orders.get(id)` | `orders:read` |
|
|
48
48
|
| `orders.cancel(id)` | `orders:write` |
|
|
49
|
+
| `orders.redeliver(id)` | `orders:write` |
|
|
49
50
|
| `orders.replace(id, { serialIds?, values?, reason? })` | `orders:write` |
|
|
50
51
|
| `products.list({ status?, limit?, offset? })` | `products:read` |
|
|
51
52
|
| `products.get(idOrSlug)` | `products:read` |
|
|
@@ -106,7 +107,9 @@ const { added, skipped, stock } = await skalp.products.addSerials(product.id, {
|
|
|
106
107
|
await skalp.products.submit(product.id)
|
|
107
108
|
```
|
|
108
109
|
|
|
109
|
-
A product starts as a `DRAFT`. `submit` sends it to review, and the review sets `ACTIVE` or `REJECTED`; read the product to see which. `update` accepts only `DRAFT` and `ARCHIVED` as a `status`, and `archive` takes a product off sale without deleting anything. Pass `null` to `update` to clear `comparePrice`, `storeCategoryId`, `dynamicUrl` or `
|
|
110
|
+
A product starts as a `DRAFT`. `submit` sends it to review, and the review sets `ACTIVE` or `REJECTED`; read the product to see which. `update` accepts only `DRAFT` and `ARCHIVED` as a `status`, and `archive` takes a product off sale without deleting anything. Pass `null` to `update` to clear `comparePrice`, `storeCategoryId`, `dynamicUrl`, `licenseDurationDays` or `trialPrice`. `trialPrice` is what the buyer pays for the trial of a recurring product in a digital store, in the store currency before VAT, and `null` makes the trial free.
|
|
111
|
+
|
|
112
|
+
`price` is in your store currency, and buyers in Poland, the euro area, the US and Brazil pay it converted at the day's rate. To charge a round local price instead, pass `prices: [{ currency: 'PLN', price: 79 }]`: up to three currencies other than the store one, from 5 to 999999 each, not on coin packs. The list replaces the old one, and `[]` removes them.
|
|
110
113
|
|
|
111
114
|
`addSerials` splits `text` on new lines unless you pass `delimiter` (`'comma'`, `'semicolon'` or any other string). A key the product already has is counted in `skipped` and not added again. `listSerials` returns the plain key values, which is why it needs `products:write`.
|
|
112
115
|
|
|
@@ -117,11 +120,19 @@ const { data: orders } = await skalp.orders.list({ status: 'COMPLETED', updatedS
|
|
|
117
120
|
|
|
118
121
|
await skalp.orders.cancel(order.id)
|
|
119
122
|
|
|
123
|
+
const { data: mine } = await skalp.orders.list({ identifier: ['steam:110000112345679', 'discord:123456789012345678'] })
|
|
124
|
+
|
|
125
|
+
await skalp.orders.redeliver(order.id)
|
|
126
|
+
|
|
120
127
|
const { replacements } = await skalp.orders.replace(order.id, { reason: 'Key does not activate' })
|
|
121
128
|
```
|
|
122
129
|
|
|
123
130
|
`cancel` works only on a `PENDING` order and returns it as `CANCELED`. `replace` swaps the delivered keys of a completed order: with no `serialIds` it replaces every key, and with no `values` it draws the new ones from stock (`values` is required for keys that come from your server). The replacement keys come back in `replacements[].value`. `orders.get` also returns `serialsReplaced`, the `replacements` history and `serials`: the id, status, `deliveredAt` and `replacedById` of every delivered or replaced key (never its value), which are the ids `serialIds` expects.
|
|
124
131
|
|
|
132
|
+
`identifier` keeps the orders of one player (up to 10 values of up to 200 characters; a longer list or value is a 400). A value is a game identity: `steam:<hex>`, a SteamID64, any `kind:value` such as `discord:123456789012345678` or `license:abc...`, or a bare value. It matches orders whose buyer or gift recipient signed in with that Steam account, or where a checkout custom field answer equals the value (case and a leading `kind:` prefix on either side are ignored). It combines with the other filters.
|
|
133
|
+
|
|
134
|
+
`redeliver` takes the order's id or its number (`SKP-XXXX-XXXX-XXXX`) and sends a completed order that was not delivered again: a `FAILED` delivery goes back to `PENDING` and the `order.paid` and `purchase.completed` webhooks are sent again to the store's game server, which delivers it as a normal purchase. It returns the order as `orders.get` does. It answers 400 when the order is not `COMPLETED`, is already `DELIVERED`, is a gift nobody has claimed yet, or never had a licence issued, and 404 when the order is not in the key's store.
|
|
135
|
+
|
|
125
136
|
`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`).
|
|
126
137
|
|
|
127
138
|
Coupons take `validFrom`, `validTo` as an ISO string or a `Date`; `coupons.update` accepts `null` to clear `validTo`, `maxUses`, `minPurchaseAmount` and `description`.
|
|
@@ -171,7 +182,7 @@ export async function POST(request: Request) {
|
|
|
171
182
|
|
|
172
183
|
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`.
|
|
173
184
|
|
|
174
|
-
`order.created`, `order.updated`, `order.canceled`, `order.replaced`, `query.created`, `query.replied`, `feedback.received` and the subscription events `subscription.updated`, `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.
|
|
185
|
+
`order.created`, `order.updated`, `order.canceled`, `order.replaced`, `query.created`, `query.replied`, `feedback.received` and the subscription events `subscription.updated`, `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.
|
|
175
186
|
|
|
176
187
|
`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.
|
|
177
188
|
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
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';
|
|
2
2
|
export type * from './types.js';
|
|
3
|
-
export declare const VERSION = "1.
|
|
3
|
+
export declare const VERSION = "1.7.0";
|
|
4
4
|
export interface SkalpOptions {
|
|
5
5
|
apiKey?: string;
|
|
6
6
|
webhookSecret?: string;
|
|
@@ -36,9 +36,10 @@ export declare class Skalp {
|
|
|
36
36
|
get: (id: string) => Promise<CheckoutSessionStatus>;
|
|
37
37
|
};
|
|
38
38
|
readonly orders: {
|
|
39
|
-
list: ({ status, productId, email, createdAfter, createdBefore, updatedSince, limit, offset }?: ListOrdersParams) => Promise<OrderList>;
|
|
39
|
+
list: ({ status, productId, email, identifier, createdAfter, createdBefore, updatedSince, limit, offset }?: ListOrdersParams) => Promise<OrderList>;
|
|
40
40
|
get: (id: string) => Promise<Order>;
|
|
41
41
|
cancel: (id: string) => Promise<Order>;
|
|
42
|
+
redeliver: (id: string) => Promise<Order>;
|
|
42
43
|
replace: (id: string, { serialIds, values, reason }?: ReplaceOrderKeysParams) => Promise<OrderKeysReplaced>;
|
|
43
44
|
};
|
|
44
45
|
readonly products: {
|
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.7.0';
|
|
5
5
|
const SIGNATURE_HEADER = 'skalp-signature';
|
|
6
6
|
const SIGNATURE_TOLERANCE_SECONDS = 300;
|
|
7
7
|
const PRODUCT_PAGE = 100;
|
|
@@ -52,6 +52,7 @@ const PRODUCT_FIELDS = [
|
|
|
52
52
|
'comparePrice',
|
|
53
53
|
'category',
|
|
54
54
|
'categoryId',
|
|
55
|
+
'game',
|
|
55
56
|
'storeCategoryId',
|
|
56
57
|
'tags',
|
|
57
58
|
'images',
|
|
@@ -59,9 +60,28 @@ const PRODUCT_FIELDS = [
|
|
|
59
60
|
'fulfillmentType',
|
|
60
61
|
'billingInterval',
|
|
61
62
|
'trialPeriodDays',
|
|
63
|
+
'trialPrice',
|
|
62
64
|
'dynamicUrl',
|
|
63
65
|
'licenseDeviceLimit',
|
|
64
66
|
'licenseDurationDays',
|
|
67
|
+
'deliveryType',
|
|
68
|
+
'deliveryPayload',
|
|
69
|
+
'revokePayload',
|
|
70
|
+
'coinConfig',
|
|
71
|
+
'visibility',
|
|
72
|
+
'sortPriority',
|
|
73
|
+
'deliveryNote',
|
|
74
|
+
'termsOfService',
|
|
75
|
+
'warrantyDays',
|
|
76
|
+
'warrantyText',
|
|
77
|
+
'blockVpn',
|
|
78
|
+
'maxRiskScore',
|
|
79
|
+
'customFields',
|
|
80
|
+
'minQuantity',
|
|
81
|
+
'maxQuantity',
|
|
82
|
+
'volumeDiscounts',
|
|
83
|
+
'upsells',
|
|
84
|
+
'prices',
|
|
65
85
|
];
|
|
66
86
|
const COUPON_FIELDS = [
|
|
67
87
|
'discountType',
|
|
@@ -110,11 +130,12 @@ class Skalp {
|
|
|
110
130
|
get: (id) => this.#request('GET', `/v1/checkout/sessions/${segment(id)}`),
|
|
111
131
|
};
|
|
112
132
|
orders = {
|
|
113
|
-
list: ({ status, productId, email, createdAfter, createdBefore, updatedSince, limit, offset } = {}) => this.#request('GET', '/v1/orders', {
|
|
133
|
+
list: ({ status, productId, email, identifier, createdAfter, createdBefore, updatedSince, limit, offset } = {}) => this.#request('GET', '/v1/orders', {
|
|
114
134
|
query: {
|
|
115
135
|
status,
|
|
116
136
|
productId,
|
|
117
137
|
email,
|
|
138
|
+
identifier,
|
|
118
139
|
createdAfter: optionalDate(createdAfter),
|
|
119
140
|
createdBefore: optionalDate(createdBefore),
|
|
120
141
|
updatedSince: optionalDate(updatedSince),
|
|
@@ -124,6 +145,7 @@ class Skalp {
|
|
|
124
145
|
}),
|
|
125
146
|
get: (id) => this.#request('GET', `/v1/orders/${segment(id)}`),
|
|
126
147
|
cancel: (id) => this.#request('POST', `/v1/orders/${segment(id)}/cancel`),
|
|
148
|
+
redeliver: (id) => this.#request('POST', `/v1/orders/${segment(id)}/redeliver`),
|
|
127
149
|
replace: (id, { serialIds, values, reason } = {}) => this.#request('POST', `/v1/orders/${segment(id)}/replacement`, {
|
|
128
150
|
body: { serialIds, values, reason },
|
|
129
151
|
}),
|
|
@@ -318,7 +340,10 @@ class Skalp {
|
|
|
318
340
|
}
|
|
319
341
|
const url = new URL(this.#baseUrl + path);
|
|
320
342
|
for (const [name, value] of Object.entries(query ?? {})) {
|
|
321
|
-
if (value
|
|
343
|
+
if (Array.isArray(value))
|
|
344
|
+
for (const item of value)
|
|
345
|
+
url.searchParams.append(name, String(item));
|
|
346
|
+
else if (value !== undefined && value !== null)
|
|
322
347
|
url.searchParams.set(name, String(value));
|
|
323
348
|
}
|
|
324
349
|
const headers = { accept: 'application/json', 'user-agent': USER_AGENT };
|
package/dist/cjs/types.d.ts
CHANGED
|
@@ -2,7 +2,8 @@ export type Currency = 'EUR' | 'USD' | 'PLN' | (string & {});
|
|
|
2
2
|
export type FulfillmentType = 'FILE' | 'SERIAL' | 'GAME' | 'SERVICE' | 'DYNAMIC' | 'LICENSE';
|
|
3
3
|
export type ProductStatus = 'DRAFT' | 'PENDING_REVIEW' | 'PROCESSING' | 'PROCESSING_FAILED' | 'ACTIVE' | 'REJECTED' | 'ARCHIVED';
|
|
4
4
|
export type ProductType = 'ONE_TIME' | 'RECURRING' | 'COINS';
|
|
5
|
-
export type
|
|
5
|
+
export type Game = 'fivem' | 'minecraft' | 'rust';
|
|
6
|
+
export type BillingInterval = 'WEEK' | 'MONTH' | 'QUARTER' | 'HALF_YEAR' | 'YEAR';
|
|
6
7
|
export type OrderStatus = 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'FAILED' | 'REFUNDED' | 'DISPUTED' | 'CANCELED';
|
|
7
8
|
export type PaymentProvider = 'STRIPE' | 'NOWPAYMENTS' | 'PAYPAL';
|
|
8
9
|
export type DeliveryStatus = 'PENDING' | 'PROCESSING' | 'DELIVERED' | 'FAILED';
|
|
@@ -91,6 +92,7 @@ export interface ListOrdersParams {
|
|
|
91
92
|
status?: OrderStatus;
|
|
92
93
|
productId?: string;
|
|
93
94
|
email?: string;
|
|
95
|
+
identifier?: string | Array<string>;
|
|
94
96
|
createdAfter?: string | Date;
|
|
95
97
|
createdBefore?: string | Date;
|
|
96
98
|
updatedSince?: string | Date;
|
|
@@ -176,6 +178,10 @@ export type DeliveryType = 'COMMAND' | 'SQL';
|
|
|
176
178
|
* ON_HOLD is listed but not buyable, PRIVATE sells only through the API.
|
|
177
179
|
*/
|
|
178
180
|
export type ProductVisibility = 'PUBLIC' | 'UNLISTED' | 'ON_HOLD' | 'PRIVATE';
|
|
181
|
+
export interface ProductPrice {
|
|
182
|
+
currency: Currency;
|
|
183
|
+
price: number;
|
|
184
|
+
}
|
|
179
185
|
export interface Product {
|
|
180
186
|
id: string;
|
|
181
187
|
storeId: string;
|
|
@@ -186,12 +192,16 @@ export interface Product {
|
|
|
186
192
|
price: number;
|
|
187
193
|
comparePrice: number | null;
|
|
188
194
|
currency: Currency;
|
|
195
|
+
/** Round prices the seller set in other currencies. A buyer whose local currency is listed pays it exactly. */
|
|
196
|
+
prices: Array<ProductPrice>;
|
|
189
197
|
status: ProductStatus;
|
|
190
198
|
rejectionReason: string | null;
|
|
191
199
|
productType: ProductType;
|
|
192
200
|
billingInterval: BillingInterval | null;
|
|
193
201
|
trialPeriodDays: number;
|
|
202
|
+
trialPrice: number | null;
|
|
194
203
|
fulfillmentType: FulfillmentType | null;
|
|
204
|
+
game: Game | null;
|
|
195
205
|
category: string;
|
|
196
206
|
categoryId: string | null;
|
|
197
207
|
storeCategoryId: string | null;
|
|
@@ -264,6 +274,7 @@ interface ProductFields {
|
|
|
264
274
|
shortDescription?: string;
|
|
265
275
|
category?: string;
|
|
266
276
|
categoryId?: string;
|
|
277
|
+
game?: Game | null;
|
|
267
278
|
storeCategoryId?: string | null;
|
|
268
279
|
tags?: Array<string>;
|
|
269
280
|
images?: Array<string>;
|
|
@@ -271,6 +282,7 @@ interface ProductFields {
|
|
|
271
282
|
fulfillmentType?: FulfillmentType;
|
|
272
283
|
billingInterval?: BillingInterval;
|
|
273
284
|
trialPeriodDays?: number;
|
|
285
|
+
trialPrice?: number | null;
|
|
274
286
|
dynamicUrl?: string | null;
|
|
275
287
|
licenseDeviceLimit?: number;
|
|
276
288
|
licenseDurationDays?: number | null;
|
|
@@ -299,6 +311,8 @@ interface ProductFields {
|
|
|
299
311
|
volumeDiscounts?: Array<VolumeDiscount> | null;
|
|
300
312
|
/** Up to 3 one-time products of the store; the list replaces the old one, [] or null removes them all. */
|
|
301
313
|
upsells?: Array<ProductUpsellInput> | null;
|
|
314
|
+
/** 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
|
+
prices?: Array<ProductPrice> | null;
|
|
302
316
|
}
|
|
303
317
|
export interface CreateProductParams extends ProductFields {
|
|
304
318
|
name: string;
|
|
@@ -886,6 +900,7 @@ export interface ProductEventData {
|
|
|
886
900
|
price: number;
|
|
887
901
|
fulfillmentType: FulfillmentType | null;
|
|
888
902
|
productType: ProductType;
|
|
903
|
+
game: Game | null;
|
|
889
904
|
}
|
|
890
905
|
export interface ProductStockData {
|
|
891
906
|
productId: string;
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
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';
|
|
2
2
|
export type * from './types.js';
|
|
3
|
-
export declare const VERSION = "1.
|
|
3
|
+
export declare const VERSION = "1.7.0";
|
|
4
4
|
export interface SkalpOptions {
|
|
5
5
|
apiKey?: string;
|
|
6
6
|
webhookSecret?: string;
|
|
@@ -36,9 +36,10 @@ export declare class Skalp {
|
|
|
36
36
|
get: (id: string) => Promise<CheckoutSessionStatus>;
|
|
37
37
|
};
|
|
38
38
|
readonly orders: {
|
|
39
|
-
list: ({ status, productId, email, createdAfter, createdBefore, updatedSince, limit, offset }?: ListOrdersParams) => Promise<OrderList>;
|
|
39
|
+
list: ({ status, productId, email, identifier, createdAfter, createdBefore, updatedSince, limit, offset }?: ListOrdersParams) => Promise<OrderList>;
|
|
40
40
|
get: (id: string) => Promise<Order>;
|
|
41
41
|
cancel: (id: string) => Promise<Order>;
|
|
42
|
+
redeliver: (id: string) => Promise<Order>;
|
|
42
43
|
replace: (id: string, { serialIds, values, reason }?: ReplaceOrderKeysParams) => Promise<OrderKeysReplaced>;
|
|
43
44
|
};
|
|
44
45
|
readonly products: {
|
package/dist/esm/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const VERSION = '1.
|
|
1
|
+
export const VERSION = '1.7.0';
|
|
2
2
|
const SIGNATURE_HEADER = 'skalp-signature';
|
|
3
3
|
const SIGNATURE_TOLERANCE_SECONDS = 300;
|
|
4
4
|
const PRODUCT_PAGE = 100;
|
|
@@ -46,6 +46,7 @@ const PRODUCT_FIELDS = [
|
|
|
46
46
|
'comparePrice',
|
|
47
47
|
'category',
|
|
48
48
|
'categoryId',
|
|
49
|
+
'game',
|
|
49
50
|
'storeCategoryId',
|
|
50
51
|
'tags',
|
|
51
52
|
'images',
|
|
@@ -53,9 +54,28 @@ const PRODUCT_FIELDS = [
|
|
|
53
54
|
'fulfillmentType',
|
|
54
55
|
'billingInterval',
|
|
55
56
|
'trialPeriodDays',
|
|
57
|
+
'trialPrice',
|
|
56
58
|
'dynamicUrl',
|
|
57
59
|
'licenseDeviceLimit',
|
|
58
60
|
'licenseDurationDays',
|
|
61
|
+
'deliveryType',
|
|
62
|
+
'deliveryPayload',
|
|
63
|
+
'revokePayload',
|
|
64
|
+
'coinConfig',
|
|
65
|
+
'visibility',
|
|
66
|
+
'sortPriority',
|
|
67
|
+
'deliveryNote',
|
|
68
|
+
'termsOfService',
|
|
69
|
+
'warrantyDays',
|
|
70
|
+
'warrantyText',
|
|
71
|
+
'blockVpn',
|
|
72
|
+
'maxRiskScore',
|
|
73
|
+
'customFields',
|
|
74
|
+
'minQuantity',
|
|
75
|
+
'maxQuantity',
|
|
76
|
+
'volumeDiscounts',
|
|
77
|
+
'upsells',
|
|
78
|
+
'prices',
|
|
59
79
|
];
|
|
60
80
|
const COUPON_FIELDS = [
|
|
61
81
|
'discountType',
|
|
@@ -104,11 +124,12 @@ export class Skalp {
|
|
|
104
124
|
get: (id) => this.#request('GET', `/v1/checkout/sessions/${segment(id)}`),
|
|
105
125
|
};
|
|
106
126
|
orders = {
|
|
107
|
-
list: ({ status, productId, email, createdAfter, createdBefore, updatedSince, limit, offset } = {}) => this.#request('GET', '/v1/orders', {
|
|
127
|
+
list: ({ status, productId, email, identifier, createdAfter, createdBefore, updatedSince, limit, offset } = {}) => this.#request('GET', '/v1/orders', {
|
|
108
128
|
query: {
|
|
109
129
|
status,
|
|
110
130
|
productId,
|
|
111
131
|
email,
|
|
132
|
+
identifier,
|
|
112
133
|
createdAfter: optionalDate(createdAfter),
|
|
113
134
|
createdBefore: optionalDate(createdBefore),
|
|
114
135
|
updatedSince: optionalDate(updatedSince),
|
|
@@ -118,6 +139,7 @@ export class Skalp {
|
|
|
118
139
|
}),
|
|
119
140
|
get: (id) => this.#request('GET', `/v1/orders/${segment(id)}`),
|
|
120
141
|
cancel: (id) => this.#request('POST', `/v1/orders/${segment(id)}/cancel`),
|
|
142
|
+
redeliver: (id) => this.#request('POST', `/v1/orders/${segment(id)}/redeliver`),
|
|
121
143
|
replace: (id, { serialIds, values, reason } = {}) => this.#request('POST', `/v1/orders/${segment(id)}/replacement`, {
|
|
122
144
|
body: { serialIds, values, reason },
|
|
123
145
|
}),
|
|
@@ -312,7 +334,10 @@ export class Skalp {
|
|
|
312
334
|
}
|
|
313
335
|
const url = new URL(this.#baseUrl + path);
|
|
314
336
|
for (const [name, value] of Object.entries(query ?? {})) {
|
|
315
|
-
if (value
|
|
337
|
+
if (Array.isArray(value))
|
|
338
|
+
for (const item of value)
|
|
339
|
+
url.searchParams.append(name, String(item));
|
|
340
|
+
else if (value !== undefined && value !== null)
|
|
316
341
|
url.searchParams.set(name, String(value));
|
|
317
342
|
}
|
|
318
343
|
const headers = { accept: 'application/json', 'user-agent': USER_AGENT };
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -2,7 +2,8 @@ export type Currency = 'EUR' | 'USD' | 'PLN' | (string & {});
|
|
|
2
2
|
export type FulfillmentType = 'FILE' | 'SERIAL' | 'GAME' | 'SERVICE' | 'DYNAMIC' | 'LICENSE';
|
|
3
3
|
export type ProductStatus = 'DRAFT' | 'PENDING_REVIEW' | 'PROCESSING' | 'PROCESSING_FAILED' | 'ACTIVE' | 'REJECTED' | 'ARCHIVED';
|
|
4
4
|
export type ProductType = 'ONE_TIME' | 'RECURRING' | 'COINS';
|
|
5
|
-
export type
|
|
5
|
+
export type Game = 'fivem' | 'minecraft' | 'rust';
|
|
6
|
+
export type BillingInterval = 'WEEK' | 'MONTH' | 'QUARTER' | 'HALF_YEAR' | 'YEAR';
|
|
6
7
|
export type OrderStatus = 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'FAILED' | 'REFUNDED' | 'DISPUTED' | 'CANCELED';
|
|
7
8
|
export type PaymentProvider = 'STRIPE' | 'NOWPAYMENTS' | 'PAYPAL';
|
|
8
9
|
export type DeliveryStatus = 'PENDING' | 'PROCESSING' | 'DELIVERED' | 'FAILED';
|
|
@@ -91,6 +92,7 @@ export interface ListOrdersParams {
|
|
|
91
92
|
status?: OrderStatus;
|
|
92
93
|
productId?: string;
|
|
93
94
|
email?: string;
|
|
95
|
+
identifier?: string | Array<string>;
|
|
94
96
|
createdAfter?: string | Date;
|
|
95
97
|
createdBefore?: string | Date;
|
|
96
98
|
updatedSince?: string | Date;
|
|
@@ -176,6 +178,10 @@ export type DeliveryType = 'COMMAND' | 'SQL';
|
|
|
176
178
|
* ON_HOLD is listed but not buyable, PRIVATE sells only through the API.
|
|
177
179
|
*/
|
|
178
180
|
export type ProductVisibility = 'PUBLIC' | 'UNLISTED' | 'ON_HOLD' | 'PRIVATE';
|
|
181
|
+
export interface ProductPrice {
|
|
182
|
+
currency: Currency;
|
|
183
|
+
price: number;
|
|
184
|
+
}
|
|
179
185
|
export interface Product {
|
|
180
186
|
id: string;
|
|
181
187
|
storeId: string;
|
|
@@ -186,12 +192,16 @@ export interface Product {
|
|
|
186
192
|
price: number;
|
|
187
193
|
comparePrice: number | null;
|
|
188
194
|
currency: Currency;
|
|
195
|
+
/** Round prices the seller set in other currencies. A buyer whose local currency is listed pays it exactly. */
|
|
196
|
+
prices: Array<ProductPrice>;
|
|
189
197
|
status: ProductStatus;
|
|
190
198
|
rejectionReason: string | null;
|
|
191
199
|
productType: ProductType;
|
|
192
200
|
billingInterval: BillingInterval | null;
|
|
193
201
|
trialPeriodDays: number;
|
|
202
|
+
trialPrice: number | null;
|
|
194
203
|
fulfillmentType: FulfillmentType | null;
|
|
204
|
+
game: Game | null;
|
|
195
205
|
category: string;
|
|
196
206
|
categoryId: string | null;
|
|
197
207
|
storeCategoryId: string | null;
|
|
@@ -264,6 +274,7 @@ interface ProductFields {
|
|
|
264
274
|
shortDescription?: string;
|
|
265
275
|
category?: string;
|
|
266
276
|
categoryId?: string;
|
|
277
|
+
game?: Game | null;
|
|
267
278
|
storeCategoryId?: string | null;
|
|
268
279
|
tags?: Array<string>;
|
|
269
280
|
images?: Array<string>;
|
|
@@ -271,6 +282,7 @@ interface ProductFields {
|
|
|
271
282
|
fulfillmentType?: FulfillmentType;
|
|
272
283
|
billingInterval?: BillingInterval;
|
|
273
284
|
trialPeriodDays?: number;
|
|
285
|
+
trialPrice?: number | null;
|
|
274
286
|
dynamicUrl?: string | null;
|
|
275
287
|
licenseDeviceLimit?: number;
|
|
276
288
|
licenseDurationDays?: number | null;
|
|
@@ -299,6 +311,8 @@ interface ProductFields {
|
|
|
299
311
|
volumeDiscounts?: Array<VolumeDiscount> | null;
|
|
300
312
|
/** Up to 3 one-time products of the store; the list replaces the old one, [] or null removes them all. */
|
|
301
313
|
upsells?: Array<ProductUpsellInput> | null;
|
|
314
|
+
/** 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
|
+
prices?: Array<ProductPrice> | null;
|
|
302
316
|
}
|
|
303
317
|
export interface CreateProductParams extends ProductFields {
|
|
304
318
|
name: string;
|
|
@@ -886,6 +900,7 @@ export interface ProductEventData {
|
|
|
886
900
|
price: number;
|
|
887
901
|
fulfillmentType: FulfillmentType | null;
|
|
888
902
|
productType: ProductType;
|
|
903
|
+
game: Game | null;
|
|
889
904
|
}
|
|
890
905
|
export interface ProductStockData {
|
|
891
906
|
productId: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skalpgg/sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.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",
|