使用API自动创建和更新目录
注:
如果使用PlayFab、App Store或Google Play等外部系统,请按照相关说明从这些系统导入数据。
您可以通过Shop Builder API调用自动创建和更新目录。通过自动化,您可以轻松保持目录最新,无需投入大量时间。
这能显著减少以下内容和事项的维护和更新时间:
- 包含大量商品的目录
- 本地价格
注意
为保持用户参与度,创建商品目录后在艾克索拉侧及时更新目录十分重要。建议在己侧发生更新时(如添加了商品或更改了价格)同步更新艾克索拉侧的目录。
您可以:
通过API调用来创建及更新商品和促销活动时使用基本认证。请传入Authorization:Basic <your_authorization_basic_key>,其中<your_authorization_basic_key>是按照Base64标准加密的商户ID: API密钥对。请前往发布商帐户找到以下参数:
- 商户ID在以下位置显示:
- 在公司设置 > 公司部分。
- 在发布商帐户任意页面的浏览器地址栏的URL中。URL的格式如下:
https://publisher.xsolla.com/<merchant_id>/。
- API密钥仅在创建它时在发布商帐户中显示一次,必须存储在己侧。您可以在以下部分中创建新的密钥:
创建和更新商品
艾克索拉支持以下游戏内商品类型:
- 虚拟物品
- 虚拟货币
- 虚拟货币套餐
- 捆绑包
为简化集成(例如在手机游戏中),您可以使用虚拟物品⸺它是一种通用类型,能够实现任何游戏内购买逻辑。这样可以统一数据处理流程,避免目录架构冗余。
如要创建大量商品,可创建一个脚本以所需次数来调用相应商品类型的API方法。
注意
要向目录添加商品,请使用以下API调用:
要更新目录:
通过API自动创建商品的脚本
如需根据自己系统的数据创建大量商品,可使用API自动化该过程。
您需要:
如果需要使用商品组,请提前在发布商帐户中创建。
如果需要使用多种类型的商品,请按以下顺序创建:
- 在发布商帐户中创建商品组。
- 虚拟货币。
- 虚拟物品。
- 虚拟货币套餐。
- 捆绑包。
以下是重复调用创建虚拟物品方法来批量创建虚拟物品的脚本示例。
该脚本使用JavaScript和JavaScript运行时引擎 — Node.js开发。
- 导入
“node-fetch”模块的fetch函数以向艾克索拉服务器发送HTTP请求。
Copy
- javascript
1import fetch from "node-fetch";
- 设置请求授权所需的常量。不要插入
<your project_id from PA>和<your api key from PA>,而应插入项目ID和API密钥的值,它们将使用Base64编码以便后续在API请求中使用。
Copy
- javascript
1const projectId = <your project_id from PA>;
2
3const apiKey = <your api key from PA>;
4
5const buff = new Buffer(`${projectId}:${apiKey}`);
6
7const basicAuth = buff.toString('base64')
- 发送请求时应实施延迟机制,避免超出API速率限制。您可以:
- 使用
sleep辅助函数设置请求间的固定延迟。 - 使用
delay辅助函数实现指数退避。此方式下,每次遇到429 Too Many Requests错误后,重复请求间的等待时间会递增,并添加随机值(抖动)以分散负载。
- 使用
Copy
- javascript
1function sleep(ms) {
2
3 return new Promise(resolve => setTimeout(resolve, ms));
4
5}
指数退避方案:
Copy
- javascript
1/** Pause for the specified number of milliseconds */
2function delay(ms) {
3 return new Promise((resolve) => setTimeout(resolve, ms));
4}
5
6/**
7 * A fetch wrapper that handles HTTP 429 responses:
8 * - pure exponential backoff with jitter (ignores Retry-After);
9 * - limited number of retry attempts.
10 */
11async function fetchWithRateLimit(
12 url,
13 options = {},
14 {
15 maxAttempts = 4, // 1 initial attempt + 3 retries (balanced approach)
16 baseDelayMs = 1000, // 1 second base delay (15x the 67ms interval for 15 RPS)
17 factor = 1.5, // gentler backoff multiplier (1s → 1.5s → 2.25s → 3.4s)
18 maxDelayMs = 4000, // 4 seconds max delay (prevents excessive waiting)
19 jitterMs = 300 // 300ms random jitter (spreads retries without long delays)
20 } = {}
21) {
22 let attempt = 0;
23
24 while (true) {
25 attempt += 1;
26 const res = await fetch(url, options);
27
28 if (res.status !== 429) return res;
29
30 // 429: calculate pause (exponential backoff + jitter)
31 const backoff = Math.min(
32 Math.floor(baseDelayMs * Math.pow(factor, attempt - 1)),
33 maxDelayMs
34 );
35 const jitter = Math.floor(Math.random() * (jitterMs + 1)); // 0..jitterMs
36 const waitMs = backoff + jitter;
37
38 if (attempt >= maxAttempts) {
39 // retry limit reached — return the last response
40 return res;
41 }
42
43 await delay(waitMs);
44 }
45}
- 实现您系统专用的
getItems函数从您的系统获取商品数据。
Copy
- javascript
1async function getItems() {
2
3 // receive items from the original system or read from a pre-prepared file
4
5 return items;
6
7}
- 实现您系统专用的
prepareData函数以根据创建虚拟物品API调用中的数据格式来格式化商品数据。
Copy
- javascript
1function prepareData(items) {
2
3 // format items in accordance with API requirements
4
5 return formattedItems;
6
7}
- 添加
createItem函数,它向艾克索拉API发送POST请求来创建虚拟物品
Copy
- javascript
1async function createItem(item) {
2
3 const url = `https://store.xsolla.com/api/v2/project/${projectId}/admin/items/virtual_items`;
4
5
6
7 return await fetch(url, {
8
9 method: "POST",
10
11 headers: {
12
13 Authorization: `Basic ${basicAuth}`,
14
15 "Content-Type": "application/json"
16
17 },
18
19 body: JSON.stringify(item),
20
21 });
22
23}
- 添加
checkItemExist函数,用于检查指定SKU的虚拟物品是否存在。该函数向艾克索拉API发送GET请求:- 如果收到
404HTTP代码响应,表示未找到指定SKU的虚拟物品,需要创建。 - 如果收到
200HTTP代码响应,表示已找到指定SKU的虚拟物品,无需创建。
- 如果收到
Copy
- javascript
1async function checkItemExist(sku) {
2
3 const url = `https://store.xsolla.com/api/v2/project/${projectId}/admin/items/virtual_items/sku/${sku}`;
4
5 const response = await fetch(url, {
6
7 method: "GET",
8
9 headers: {
10
11 Authorization: `Basic ${basicAuth}`
12
13 }
14
15 });
16
17 return response.status !== 404;
18
19}
- 添加
createItems函数,它检查商品列表以查找艾克索拉侧是否存在您系统中SKU指定的商品。如没有该SKU的商品,则该函数创建该商品。进度信息在控制台中显示。
Copy
- javascript
1async function createItems(items) {
2
3 let success = 0;
4
5 let alreadyCreated = 0;
6
7 for (let i = 0; i < items.length; i++) {
8
9 const item = items[i];
10
11 if (item['sku'] === undefined) {
12
13 console.log(`${i} Field "sku" not specified`);
14
15 continue;
16
17 }
18
19 const sku = item['sku'];
20
21 if (await checkItemExist(sku)) {
22
23 console.log(`${i} Item with sku "${sku}" already created`);
24
25 alreadyCreated++;
26
27 continue;
28
29 }
30
31 const response = await createItem(item);
32
33 if (response.status === 201) {
34
35 console.log(`${i} Item with sku "${sku}" successfully created`)
36
37 success++;
38
39 } else {
40
41 const jsonData = await response.json();
42
43 console.log(`${i} An error occurred while creating the items with sku "${sku}"`);
44
45 console.log(jsonData);
46
47 }
48
49 // add a delay so as not to run into rate limits
50
51 await sleep(500);
52
53 }
54
55 console.log(`${success} items out of ${items.length} created. ${alreadyCreated} items already existed`);
56
57}
- 添加
run函数,以正确的顺序调用上述所有函数。
Copy
- javascript
1async function run() {
2
3 const items = await getItems();
4
5 const formattedItems = prepareData(items);
6
7 await createItems(formattedItems);
8
9}
完整代码:
本文对您的有帮助吗?
感谢您的反馈!
我们会查看您的留言并运用它改进用户体验。发现了错别字或其他内容错误? 请选择文本,然后按Ctrl+Enter。