สรุปเนื้อหา
Etsy API ช่วยให้นักพัฒนาสามารถสร้างแอปพลิเคชันที่โต้ตอบกับตลาดกลางของ Etsy ได้ โดยใช้ OAuth 2.0, รองรับ RESTful endpoint สำหรับร้านค้า, รายการสินค้า, คำสั่งซื้อ และการจัดการคลังสินค้า มีข้อจำกัดอัตราการเรียกใช้ 10 ครั้ง/วินาที/แอป คู่มือนี้สอนตั้งค่าการรับรองความถูกต้อง, ใช้ endpoint หลัก, รวม Webhook และแนวทางการใช้งานใน production
💡 Apidog ช่วยให้การทดสอบการผสานรวม API ง่ายขึ้น ทดสอบ endpoint Etsy, ตรวจสอบโฟลว์ OAuth, ตรวจสอบ payload Webhook และแก้ไขข้อผิดพลาดการรับรองความถูกต้องได้ในที่เดียว นำเข้า API spec, จำลอง response และแชร์ test case กับทีม
Etsy API คืออะไร?
Etsy มี RESTful API สำหรับเข้าถึงข้อมูล marketplace และการดำเนินการฝั่งผู้ขาย เช่น:
- ดึงข้อมูลร้านค้าและโปรไฟล์
- สร้าง/อัปเดต/จัดการรายการสินค้า
- ประมวลผลคำสั่งซื้อและติดตามการจัดส่ง
- ดึงข้อมูลลูกค้าและธุรกรรม
- โปรไฟล์การจัดส่งและภาษี
- อัปโหลดรูปภาพและสื่อ
คุณสมบัติหลัก
| คุณสมบัติ | คำอธิบาย |
|---|---|
| RESTful | ใช้ HTTP มาตรฐาน, JSON response |
| OAuth 2.0 | รับรองความถูกต้องปลอดภัย, refresh token |
| Webhooks | แจ้งเหตุการณ์แบบ real-time (order, listing, ฯลฯ) |
| Rate Limiting | 10 requests/วินาที/แอป (มี burst allowance) |
| Sandbox | ทดสอบ API โดยไม่มีข้อมูลจริง |
ภาพรวมสถาปัตยกรรม API
API base path:
https://openapi.etsy.com/v3/application/
ปัจจุบันใช้ v3 (OAuth 2.0, โครงสร้าง endpoint ที่ง่ายกว่า v2)
เปรียบเทียบเวอร์ชัน API
| เวอร์ชัน | สถานะ | การรับรองความถูกต้อง | กรณีใช้งาน |
|---|---|---|---|
| V3 | ปัจจุบัน | OAuth 2.0 | สำหรับ integration ใหม่ |
| V2 | เลิกใช้ | OAuth 1.0a | ใช้งานกับแอปเก่าเท่านั้น |
| V1 | เลิกถาวร | N/A | ห้ามใช้ |
ข้อควรทราบ: รีบอัปเกรด V2 → V3 ภายในปี 2026
เริ่มต้นใช้งาน: การตั้งค่าการรับรองความถูกต้อง
ขั้นตอนที่ 1: สร้างบัญชีนักพัฒนา Etsy
- ไปที่ Etsy Developer Portal
- ล็อกอิน (หรือสมัครใหม่)
- ไปที่เมนู Your Apps
- คลิก Create a new app
ขั้นตอนที่ 2: ลงทะเบียนแอปพลิเคชัน
- App Name: ตั้งชื่อสื่อความหมาย
- App Description: อธิบายจุดประสงค์
- Redirect URI: URL สำหรับ callback (ต้องใช้ HTTPS)
- Production/Development: เริ่มด้วยโหมด development
หลังลงทะเบียน จะได้
- Key String (client_id)
- Shared Secret (client_secret)
เก็บ credential ใน environment variable:
# .env file
ETSY_KEY_STRING="your_key_string_here"
ETSY_SHARED_SECRET="your_shared_secret_here"
ETSY_ACCESS_TOKEN="generated_via_oauth"
ETSY_REFRESH_TOKEN="generated_via_oauth"
ขั้นตอนที่ 3: ทำความเข้าใจโฟลว์ OAuth 2.0
1. ผู้ใช้คลิก "Connect with Etsy"
2. Redirect ไปหน้า authorize ของ Etsy
3. ผู้ใช้ login และ authorize
4. Etsy redirect กลับมาพร้อม auth code
5. แอปแลก code เป็น access token
6. ใช้ access token เรียก API
7. refresh token เมื่อ access token หมดอายุ (1 ชม.)
ขั้นตอนที่ 4: ใช้การอนุญาต OAuth
const generateAuthUrl = (clientId, redirectUri, state) => {
const baseUrl = 'https://www.etsy.com/oauth/connect';
const params = new URLSearchParams({
client_id: clientId,
redirect_uri: redirectUri,
scope: 'listings_r listings_w orders_r orders_w shops_r',
state: state, // random string
response_type: 'code'
});
return `${baseUrl}?${params.toString()}`;
};
// ตัวอย่างการใช้งาน
const authUrl = generateAuthUrl(
process.env.ETSY_KEY_STRING,
'https://your-app.com/callback',
crypto.randomBytes(16).toString('hex')
);
console.log(`Redirect user to: ${authUrl}`);
ขอบเขตที่จำเป็น (Required Scopes)
| Scope | คำอธิบาย | ใช้สำหรับ |
|---|---|---|
listings_r |
อ่านสินค้า | แสดง/ซิงค์ stock |
listings_w |
เขียนสินค้า | สร้าง/อัปเดตสินค้า |
orders_r |
อ่านคำสั่งซื้อ | จัดการ order/จัดส่ง |
orders_w |
เขียนคำสั่งซื้อ | อัปเดตสถานะ/เพิ่ม tracking |
shops_r |
อ่านร้านค้า | แสดงโปรไฟล์/วิเคราะห์ |
transactions_r |
อ่านธุรกรรม | รายงานการเงิน |
email |
อ่านอีเมลผู้ซื้อ | ติดต่อเกี่ยวกับ order |
ขั้นตอนที่ 5: แลกเปลี่ยนรหัสเพื่อรับโทเค็นการเข้าถึง
const exchangeCodeForToken = async (code, redirectUri) => {
const response = await fetch('https://api.etsy.com/v3/public/oauth/token', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
grant_type: 'authorization_code',
client_id: process.env.ETSY_KEY_STRING,
client_secret: process.env.ETSY_SHARED_SECRET,
redirect_uri: redirectUri,
code: code
})
});
const data = await response.json();
return {
access_token: data.access_token,
refresh_token: data.refresh_token,
expires_in: data.expires_in,
user_id: data.user_id,
scope: data.scope
};
};
// handle callback route
app.get('/callback', async (req, res) => {
const { code, state } = req.query;
if (state !== req.session.oauthState) {
return res.status(400).send('Invalid state parameter');
}
try {
const tokens = await exchangeCodeForToken(code, 'https://your-app.com/callback');
await db.users.update(req.session.userId, {
etsy_access_token: tokens.access_token,
etsy_refresh_token: tokens.refresh_token,
etsy_token_expires: Date.now() + (tokens.expires_in * 1000),
etsy_user_id: tokens.user_id
});
res.redirect('/dashboard');
} catch (error) {
console.error('Token exchange failed:', error);
res.status(500).send('Authentication failed');
}
});
ขั้นตอนที่ 6: ใช้การรีเฟรชโทเค็น
const refreshAccessToken = async (refreshToken) => {
const response = await fetch('https://api.etsy.com/v3/public/oauth/token', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
grant_type: 'refresh_token',
client_id: process.env.ETSY_KEY_STRING,
client_secret: process.env.ETSY_SHARED_SECRET,
refresh_token: refreshToken
})
});
const data = await response.json();
return {
access_token: data.access_token,
refresh_token: data.refresh_token,
expires_in: data.expires_in
};
};
// Middleware to ensure valid token
const ensureValidToken = async (userId) => {
const user = await db.users.findById(userId);
if (user.etsy_token_expires < Date.now() + 300000) {
const newTokens = await refreshAccessToken(user.etsy_refresh_token);
await db.users.update(userId, {
etsy_access_token: newTokens.access_token,
etsy_refresh_token: newTokens.refresh_token,
etsy_token_expires: Date.now() + (newTokens.expires_in * 1000)
});
return newTokens.access_token;
}
return user.etsy_access_token;
};
ขั้นตอนที่ 7: เรียกใช้ API ที่ต้องการรับรองความถูกต้อง
const makeEtsyRequest = async (endpoint, options = {}) => {
const accessToken = await ensureValidToken(options.userId);
const response = await fetch(`https://openapi.etsy.com/v3/application${endpoint}`, {
...options,
headers: {
'Authorization': `Bearer ${accessToken}`,
'x-api-key': process.env.ETSY_KEY_STRING,
'Accept': 'application/json',
'Content-Type': 'application/json',
...options.headers
}
});
if (!response.ok) {
const error = await response.json();
throw new Error(`Etsy API Error: ${error.message}`);
}
return response.json();
};
เอนด์พอยต์การจัดการร้านค้า
การดึงข้อมูลร้านค้า
const getShopInfo = async (shopId) => {
const response = await makeEtsyRequest(`/shops/${shopId}`, {
method: 'GET'
});
return response;
};
// ตัวอย่าง
const shop = await getShopInfo(12345678);
console.log(`Shop: ${shop.title}`);
console.log(`Currency: ${shop.currency_code}`);
console.log(`Listings count: ${shop.num_listings_active}`);
โครงสร้างข้อมูลร้านค้าตัวอย่าง
{
"shop_id": 12345678,
"shop_name": "MyHandmadeShop",
"title": "Handmade Jewelry & Accessories",
"announcement": "Welcome! Free shipping on orders over $50",
"currency_code": "USD",
"num_listings_active": 127,
...
}
การดึงส่วนร้านค้า (Shop Sections)
const getShopSections = async (shopId) => {
const response = await makeEtsyRequest(`/shops/${shopId}/sections`, {
method: 'GET'
});
return response;
};
การจัดการรายการสินค้า
การสร้างรายการสินค้าใหม่
const createListing = async (shopId, listingData) => {
const payload = {
title: listingData.title,
description: listingData.description,
price: listingData.price.toString(),
quantity: listingData.quantity,
sku: listingData.sku || [],
tags: listingData.tags.slice(0, 13),
category_id: listingData.categoryId,
shop_section_id: listingData.sectionId,
state: listingData.state || 'active',
who_made: listingData.whoMade,
when_made: listingData.whenMade,
is_supply: listingData.isSupply,
item_weight: listingData.weight || null,
item_weight_unit: listingData.weightUnit || 'g',
item_length: listingData.length || null,
item_width: listingData.width || null,
item_height: listingData.height || null,
item_dimensions_unit: listingData.dimensionsUnit || 'mm',
is_private: listingData.isPrivate || false,
recipient: listingData.recipient || null,
occasion: listingData.occasion || null,
style: listingData.style || []
};
const response = await makeEtsyRequest(`/shops/${shopId}/listings`, {
method: 'POST',
body: JSON.stringify(payload)
});
return response;
};
// ตัวอย่าง
const listing = await createListing(12345678, {
title: 'Sterling Silver Moon Phase Necklace',
description: 'Handcrafted sterling silver necklace featuring moon phases...',
price: 89.99,
quantity: 15,
sku: ['MOON-NECKLACE-001'],
tags: ['moon necklace', 'sterling silver'],
categoryId: 10623,
sectionId: 12345,
state: 'active',
whoMade: 'i_did',
whenMade: 'made_to_order',
isSupply: false,
weight: 25,
weightUnit: 'g'
});
การอัปโหลดรูปภาพรายการสินค้า
const uploadListingImage = async (listingId, imagePath, imagePosition = 1) => {
const fs = require('fs');
const imageBuffer = fs.readFileSync(imagePath);
const base64Image = imageBuffer.toString('base64');
const payload = {
image: base64Image,
position: imagePosition,
is_watermarked: false,
alt_text: 'Handcrafted sterling silver moon phase necklace'
};
const response = await makeEtsyRequest(`/listings/${listingId}/images`, {
method: 'POST',
body: JSON.stringify(payload)
});
return response;
};
การอัปเดตสต็อกสินค้า
const updateListingInventory = async (shopId, listingId, inventory) => {
const payload = {
products: inventory.products.map(product => ({
sku: product.sku,
quantity: product.quantity
})),
is_over_selling: inventory.isOverSelling || false,
on_property: inventory.onProperty || []
};
const response = await makeEtsyRequest(
`/shops/${shopId}/listings/${listingId}/inventory`,
{
method: 'PUT',
body: JSON.stringify(payload)
}
);
return response;
};
// ตัวอย่าง
await updateListingInventory(12345678, 987654321, {
products: [
{ sku: 'MOON-NECKLACE-001', quantity: 10 },
{ sku: 'MOON-NECKLACE-002', quantity: 5 }
],
isOverSelling: false
});
การดึง / ลบรายการสินค้า
const getListings = async (shopId, options = {}) => {
const params = new URLSearchParams({
limit: options.limit || 25,
offset: options.offset || 0
});
if (options.state) {
params.append('state', options.state);
}
const response = await makeEtsyRequest(
`/shops/${shopId}/listings?${params.toString()}`,
{ method: 'GET' }
);
return response;
};
const deleteListing = async (listingId) => {
return await makeEtsyRequest(`/listings/${listingId}`, {
method: 'DELETE'
});
};
การจัดการคำสั่งซื้อ
การดึงคำสั่งซื้อ
const getOrders = async (shopId, options = {}) => {
const params = new URLSearchParams({
limit: options.limit || 25,
offset: options.offset || 0
});
if (options.status) {
params.append('status', options.status);
}
if (options.minLastModified) {
params.append('min_last_modified', options.minLastModified);
}
const response = await makeEtsyRequest(
`/shops/${shopId}/orders?${params.toString()}`,
{ method: 'GET' }
);
return response;
};
การอัปเดตสถานะคำสั่งซื้อ
const updateOrderStatus = async (shopId, orderId, trackingData) => {
const payload = {
carrier_id: trackingData.carrierId,
tracking_code: trackingData.trackingCode,
should_send_bcc_to_buyer: trackingData.notifyBuyer || true
};
return await makeEtsyRequest(
`/shops/${shopId}/orders/${orderId}/shipping`,
{
method: 'POST',
body: JSON.stringify(payload)
}
);
};
รหัสผู้ให้บริการขนส่งที่ใช้บ่อย
| ผู้ให้บริการ | รหัส |
|---|---|
| USPS | usps |
| FedEx | fedex |
| UPS | ups |
| DHL | dhl_express |
| Canada Post | canada_post |
| Royal Mail | royal_mail |
| Australia Post | australia_post |
การจำกัดอัตราและโควต้า
- 10 คำขอ/วินาที/แอป
- Burst: สูงสุด 50 คำขอใน 1 วินาที (ช่วงสั้น)
- Quota: 10,000 calls/ชั่วโมง/แอป
หากเกินจะได้รับ HTTP 429
เทคนิคการจัดการ
const makeRateLimitedRequest = async (endpoint, options = {}, maxRetries = 3) => {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const response = await makeEtsyRequest(endpoint, options);
// เช็ค header quota
const remaining = response.headers.get('x-etsy-quota-remaining');
const resetTime = response.headers.get('x-etsy-quota-reset');
if (remaining < 100) {
console.warn(`Low quota remaining: ${remaining}, resets at ${resetTime}`);
}
return response;
} catch (error) {
if (error.message.includes('429') && attempt < maxRetries) {
const delay = Math.pow(2, attempt) * 1000;
console.log(`Rate limited. Retrying in ${delay}ms...`);
await new Promise(resolve => setTimeout(resolve, delay));
} else {
throw error;
}
}
}
};
Rate Limit Headers
| Header | คำอธิบาย |
|---|---|
x-etsy-quota-remaining |
จำนวน quota/h ที่เหลือ |
x-etsy-quota-reset |
Unix timestamp quota รีเซ็ต |
x-etsy-limit-remaining |
เหลือกี่ request ในวินาทีนี้ |
x-etsy-limit-reset |
Unix timestamp limit รีเซ็ต |
การผสานรวม Webhook
การกำหนดค่า Webhook
- ที่แดชบอร์ด Your Apps
- เลือกแอป → Add Webhook
- ระบุ HTTPS endpoint
- เลือก event ที่ต้องการ subscribe
Webhook events ที่รองรับ
| Event | Trigger | กรณีใช้งาน |
|---|---|---|
v3/shops/{shop_id}/orders/create |
คำสั่งซื้อใหม่ | แจ้งเตือน, sync stock |
v3/shops/{shop_id}/orders/update |
สถานะ order เปลี่ยน | sync การจัดการ order |
v3/shops/{shop_id}/listings/create |
รายการสินค้าใหม่ | sync กับระบบภายนอก |
v3/shops/{shop_id}/listings/update |
แก้ไขสินค้า | sync ข้อมูลสินค้า |
v3/shops/{shop_id}/listings/delete |
ลบสินค้า | sync ลบออกระบบอื่น |
ตัวอย่าง Webhook handler
const express = require('express');
const crypto = require('crypto');
const app = express();
app.post('/webhooks/etsy', express.raw({ type: 'application/json' }), async (req, res) => {
const signature = req.headers['x-etsy-signature'];
const payload = req.body;
// Verify webhook signature
const isValid = verifyWebhookSignature(payload, signature, process.env.ETSY_WEBHOOK_SECRET);
if (!isValid) {
return res.status(401).send('Unauthorized');
}
const event = JSON.parse(payload.toString());
switch (event.type) {
case 'v3/shops/*/orders/create':
await handleNewOrder(event.data);
break;
// ... เพิ่มเติมตาม event
default:
console.log('Unhandled event type:', event.type);
}
res.status(200).send('OK');
});
function verifyWebhookSignature(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature, 'hex'),
Buffer.from(expectedSignature, 'hex')
);
}
Best practice:
- ตรวจสอบลายเซ็น
- ตอบ 200 OK ทันที (<5 วิ)
- ประมวลผล event แบบ async
- ใช้ idempotency
- บันทึก event log
การแก้ไขปัญหาที่พบบ่อย
การแลกเปลี่ยนโทเค็น OAuth ล้มเหลว
- เช็คว่า redirect URI, client_id/secret ถูกต้อง
- รหัส authorization หมดอายุหรือถูกใช้แล้ว
- แอปต้องอยู่โหมด production หากใช้กับร้านค้าจริง
เกินขีดจำกัดอัตราการใช้งาน
- ตั้ง queue + rate limiter
- ใช้ exponential backoff
- รวม request หลายอันถ้าเป็นไปได้
class RateLimiter {
constructor(requestsPerSecond = 9) {
this.queue = [];
this.interval = 1000 / requestsPerSecond;
this.processing = false;
}
async add(requestFn) {
return new Promise((resolve, reject) => {
this.queue.push({ requestFn, resolve, reject });
this.process();
});
}
async process() {
if (this.processing || this.queue.length === 0) return;
this.processing = true;
while (this.queue.length > 0) {
const { requestFn, resolve, reject } = this.queue.shift();
try {
const result = await requestFn();
resolve(result);
} catch (error) {
reject(error);
}
if (this.queue.length > 0) {
await new Promise(r => setTimeout(r, this.interval));
}
}
this.processing = false;
}
}
สินค้าสร้างไม่ผ่าน - validation error
-
category_idไม่ถูกต้อง → ใช้ API categories ของ Etsy - price ต้องเป็น string
- tags สูงสุด 13
- ฟิลด์บังคับ: title, description, price, quantity, who_made, when_made
Webhook ไม่ถึงปลายทาง
- เช็ค log การส่งที่แดชบอร์ด
- endpoint ต้องคืน 200 OK ภายใน 5 วินาที
- ใช้ HTTPS, เปิด firewall, ตรวจสอบ SSL
รูปภาพอัปโหลดล้มเหลว
- รูปต้องเป็น JPEG, PNG, GIF
- ขนาดไม่เกิน 20MB/รูป
- base64 encode ถูกต้อง
- รูปภาพต้องอัปโหลดแบบลำดับ (ไม่ parallel)
รายการตรวจสอบก่อน deploy production
- [ ] เปลี่ยนแอปเป็น production
- [ ] Redirect URI เป็น production URL
- [ ] เก็บ token ใน database ที่เข้ารหัส
- [ ] ใช้โค้ดรีเฟรช token อัตโนมัติ
- [ ] ตั้ง queue/rate limit
- [ ] webhook endpoint ต้องเป็น HTTPS
- [ ] error handling ครบถ้วน
- [ ] log API calls
- [ ] monitor quota
- [ ] คู่มือแก้ไขปัญหาทั่วไป
- [ ] ทดสอบกับหลายบัญชีร้านค้า
- [ ] document โฟลว์ OAuth สำหรับ user onboarding
การตรวจสอบและการแจ้งเตือน
const metrics = {
apiCalls: { total: 0, successful: 0, failed: 0, rateLimited: 0 },
quotaUsage: { current: 0, limit: 10000, resetTime: null },
oauthTokens: { active: 0, expiring_soon: 0, refresh_failures: 0 },
webhooks: { received: 0, processed: 0, failed: 0 }
};
const failureRate = metrics.apiCalls.failed / metrics.apiCalls.total;
if (failureRate > 0.05) {
sendAlert('Etsy API failure rate above 5%');
}
if (metrics.quotaUsage.current < 500) {
sendAlert('Etsy API quota below 500 calls remaining');
}
กรณีการใช้งานจริง
การซิงค์สต็อกสินค้าหลายช่องทาง
ตัวอย่าง workflow:
- Webhook Etsy trigger เมื่อมี order ใหม่
- ระบบกลางหักสต็อก
- เรียก API อัปเดต stock Shopify/Amazon
- บันทึก log
การจัดการคำสั่งซื้ออัตโนมัติ (POD)
- ใช้ webhook event
orders/create - ส่งรายละเอียด order ไปยัง API ฝั่ง production
- รับ tracking code กลับมาอัปเดตผ่าน Etsy API
- ลูกค้าได้รับแจ้งเตือนอัตโนมัติ
แดชบอร์ดวิเคราะห์
- ดึงข้อมูลหลายร้านด้วย OAuth
- สร้าง dashboard รวมยอดขาย, การเข้าชม, conversion rate
บทสรุป
- OAuth 2.0 ต้องจัดการ token/refresh อย่างดี
- ต้อง monitor rate limit และ queue request
- Webhook ช่วยซิงค์ stock/order real-time
- Error handling และ retry สำคัญสำหรับระบบ production
- Apidog ช่วยให้ dev ทดสอบและ debug integration ได้ง่ายขึ้น
ส่วนคำถามที่พบบ่อย (FAQ)
Etsy API ใช้สำหรับอะไร?
สำหรับสร้างแอปที่เชื่อมต่อกับ marketplace Etsy เช่น ระบบซิงค์สต็อก, ออโต้ order, dashboard วิเคราะห์, สร้างสินค้า, CRM
ฉันจะรับ Etsy API key ได้อย่างไร?
สร้างผ่าน Etsy Developer Portal → Your Apps → Create a new app จะได้ Key String และ Shared Secret
Etsy API ใช้งานฟรีหรือไม่?
ใช้ฟรี มี rate limit: 10 requests/วินาที, 10,000/ชั่วโมง ถ้าเกินต้องขออนุมัติ
Etsy API ใช้การรับรองความถูกต้องแบบใด?
OAuth 2.0 ผู้ใช้ authorize แอปผ่านหน้า Etsy รับ access token อายุ 1 ชม. และ refresh token
ฉันจะจัดการการจำกัดอัตราของ Etsy API ได้อย่างไร?
ใช้ request queue, ตรวจสอบ header quota (x-etsy-quota-remaining), ใช้ exponential backoff เมื่อโดน HTTP 429
ฉันสามารถทดสอบ Etsy API โดยไม่มีร้านค้าจริงได้หรือไม่?
ได้ ใช้โหมด development เชื่อมกับร้านค้าทดสอบ
Webhooks ทำงานอย่างไรกับ Etsy API?
Etsy POST ไปยัง HTTPS endpoint ของคุณเมื่อมี event กำหนด/จัดการใน dashboard, ตรวจสอบลายเซ็น, ต้องตอบ 200 OK <5 วินาที
จะเกิดอะไรขึ้นเมื่อโทเค็น OAuth ของ Etsy หมดอายุ?
หมดอายุใน 1 ชม. ใช้ refresh token ขอโทเค็นใหม่ ควร refresh อัตโนมัติใน middleware
ฉันสามารถอัปโหลดรูปภาพรายการสินค้าผ่าน API ได้หรือไม่?
ได้ อัปโหลด base64, JPEG/PNG/GIF, สูงสุด 20MB/รูป
ฉันจะย้ายจาก Etsy API V2 ไปยัง V3 ได้อย่างไร?
V3 ใช้ OAuth 2.0, endpoint เปลี่ยน /v2/ → /v3/application/, อัปเดตโค้ดและทดสอบก่อน V2 ปิดถาวรปี 2026
Top comments (0)