vantuz 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,239 @@
1
+ /**
2
+ * 🟑 AMAZON SP-API Entegrasyonu
3
+ * developer-docs.amazon.com/sp-api
4
+ */
5
+
6
+ import axios from 'axios';
7
+ import crypto from 'crypto';
8
+
9
+ const REGIONS = {
10
+ eu: {
11
+ endpoint: 'https://sellingpartnerapi-eu.amazon.com',
12
+ marketplace: 'A1PA6795UKMFR9' // DE
13
+ },
14
+ na: {
15
+ endpoint: 'https://sellingpartnerapi-na.amazon.com',
16
+ marketplace: 'ATVPDKIKX0DER' // US
17
+ },
18
+ tr: {
19
+ endpoint: 'https://sellingpartnerapi-eu.amazon.com',
20
+ marketplace: 'A33AVAJ2PDY3EV' // TR
21
+ }
22
+ };
23
+
24
+ export class AmazonAPI {
25
+ constructor(config) {
26
+ this.region = config.region || 'eu';
27
+ this.sellerId = config.sellerId;
28
+ this.clientId = config.clientId;
29
+ this.clientSecret = config.clientSecret;
30
+ this.refreshToken = config.refreshToken;
31
+
32
+ this.regionConfig = REGIONS[this.region];
33
+ this.accessToken = null;
34
+ this.tokenExpiry = null;
35
+ }
36
+
37
+ async _getAccessToken() {
38
+ if (this.accessToken && this.tokenExpiry > Date.now()) {
39
+ return this.accessToken;
40
+ }
41
+
42
+ try {
43
+ const response = await axios.post('https://api.amazon.com/auth/o2/token', {
44
+ grant_type: 'refresh_token',
45
+ refresh_token: this.refreshToken,
46
+ client_id: this.clientId,
47
+ client_secret: this.clientSecret
48
+ });
49
+
50
+ this.accessToken = response.data.access_token;
51
+ this.tokenExpiry = Date.now() + (response.data.expires_in * 1000) - 60000;
52
+ return this.accessToken;
53
+ } catch (error) {
54
+ throw new Error('Token alΔ±namadΔ±: ' + error.message);
55
+ }
56
+ }
57
+
58
+ async _request(method, path, data = null, params = null) {
59
+ try {
60
+ const token = await this._getAccessToken();
61
+ const response = await axios({
62
+ method,
63
+ url: `${this.regionConfig.endpoint}${path}`,
64
+ headers: {
65
+ 'x-amz-access-token': token,
66
+ 'Content-Type': 'application/json'
67
+ },
68
+ data,
69
+ params: {
70
+ ...params,
71
+ MarketplaceIds: this.regionConfig.marketplace
72
+ }
73
+ });
74
+ return { success: true, data: response.data };
75
+ } catch (error) {
76
+ return {
77
+ success: false,
78
+ error: error.response?.data?.errors || error.message
79
+ };
80
+ }
81
+ }
82
+
83
+ // ═══════════════════════════════════════════════════════════════════════════
84
+ // ÜRÜN İŞLEMLERİ
85
+ // ═══════════════════════════════════════════════════════════════════════════
86
+
87
+ async getInventory(params = {}) {
88
+ const { nextToken, skus } = params;
89
+ return await this._request('GET', '/fba/inventory/v1/summaries', null, {
90
+ details: true,
91
+ granularityType: 'Marketplace',
92
+ granularityId: this.regionConfig.marketplace,
93
+ sellerSkus: skus?.join(','),
94
+ nextToken
95
+ });
96
+ }
97
+
98
+ async getCatalogItem(asin) {
99
+ return await this._request('GET', `/catalog/2022-04-01/items/${asin}`, null, {
100
+ includedData: 'summaries,attributes,images,productTypes,salesRanks'
101
+ });
102
+ }
103
+
104
+ async searchCatalog(keywords) {
105
+ return await this._request('GET', '/catalog/2022-04-01/items', null, {
106
+ keywords,
107
+ includedData: 'summaries,images'
108
+ });
109
+ }
110
+
111
+ async createListing(sku, productType, attributes) {
112
+ return await this._request('PUT', `/listings/2021-08-01/items/${this.sellerId}/${sku}`, {
113
+ productType,
114
+ attributes,
115
+ requirements: 'LISTING'
116
+ });
117
+ }
118
+
119
+ // ═══════════════════════════════════════════════════════════════════════════
120
+ // FΔ°YAT
121
+ // ═══════════════════════════════════════════════════════════════════════════
122
+
123
+ async getPricing(skus) {
124
+ return await this._request('GET', '/products/pricing/v0/price', null, {
125
+ ItemType: 'Sku',
126
+ Skus: skus.join(',')
127
+ });
128
+ }
129
+
130
+ async getCompetitivePricing(asins) {
131
+ return await this._request('GET', '/products/pricing/v0/competitivePrice', null, {
132
+ ItemType: 'Asin',
133
+ Asins: asins.join(',')
134
+ });
135
+ }
136
+
137
+ async updatePrice(sku, price, currency = 'EUR') {
138
+ // SP-API için feed sistemi gerekir - basitleştirilmiş ârnek
139
+ const feed = {
140
+ header: { sellerId: this.sellerId, version: '2.0' },
141
+ messages: [{
142
+ messageId: 1,
143
+ sku,
144
+ operationType: 'PARTIAL_UPDATE',
145
+ productType: 'PRODUCT',
146
+ attributes: {
147
+ purchasable_offer: [{
148
+ our_price: [{ schedule: [{ value_with_tax: price }] }],
149
+ currency
150
+ }]
151
+ }
152
+ }]
153
+ };
154
+ return await this._request('POST', '/feeds/2021-06-30/feeds', {
155
+ feedType: 'JSON_LISTINGS_FEED',
156
+ marketplaceIds: [this.regionConfig.marketplace]
157
+ });
158
+ }
159
+
160
+ // ═══════════════════════════════════════════════════════════════════════════
161
+ // SİPARİŞ
162
+ // ═══════════════════════════════════════════════════════════════════════════
163
+
164
+ async getOrders(params = {}) {
165
+ const { createdAfter, orderStatuses, nextToken } = params;
166
+ return await this._request('GET', '/orders/v0/orders', null, {
167
+ CreatedAfter: createdAfter || new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString(),
168
+ OrderStatuses: orderStatuses?.join(','),
169
+ NextToken: nextToken
170
+ });
171
+ }
172
+
173
+ async getOrderItems(orderId) {
174
+ return await this._request('GET', `/orders/v0/orders/${orderId}/orderItems`);
175
+ }
176
+
177
+ async confirmShipment(orderId, items) {
178
+ return await this._request('POST', `/orders/v0/orders/${orderId}/shipmentConfirmation`, {
179
+ packageDetail: {
180
+ packageReferenceId: `pkg-${Date.now()}`,
181
+ carrierCode: 'OTHER',
182
+ shippingMethod: 'Standard',
183
+ trackingNumber: items.trackingNumber,
184
+ shipFromSupplySourceId: this.sellerId
185
+ },
186
+ codCollectionMethod: 'DirectPayment',
187
+ marketplaceId: this.regionConfig.marketplace
188
+ });
189
+ }
190
+
191
+ // ═══════════════════════════════════════════════════════════════════════════
192
+ // FBA
193
+ // ═══════════════════════════════════════════════════════════════════════════
194
+
195
+ async getFbaInventory(params = {}) {
196
+ return await this._request('GET', '/fba/inventory/v1/summaries', null, {
197
+ details: true,
198
+ granularityType: 'Marketplace',
199
+ granularityId: this.regionConfig.marketplace,
200
+ ...params
201
+ });
202
+ }
203
+
204
+ async getInboundShipments(params = {}) {
205
+ return await this._request('GET', '/fba/inbound/v0/shipments', null, params);
206
+ }
207
+
208
+ // ═══════════════════════════════════════════════════════════════════════════
209
+ // HELPER
210
+ // ═══════════════════════════════════════════════════════════════════════════
211
+
212
+ async testConnection() {
213
+ try {
214
+ await this._getAccessToken();
215
+ return true;
216
+ } catch {
217
+ return false;
218
+ }
219
+ }
220
+
221
+ isConnected() {
222
+ return !!(this.sellerId && this.clientId && this.refreshToken);
223
+ }
224
+ }
225
+
226
+ let instances = {};
227
+
228
+ export const amazonApi = {
229
+ init(config, region = 'eu') {
230
+ instances[region] = new AmazonAPI({ ...config, region });
231
+ return instances[region];
232
+ },
233
+ getInstance(region = 'eu') { return instances[region]; },
234
+ isConnected(region = 'eu') { return instances[region]?.isConnected() || false; },
235
+
236
+ async getProducts(params, region) { return instances[region]?.getInventory(params); },
237
+ async updatePrice(sku, price, region) { return instances[region]?.updatePrice(sku, price); },
238
+ async getOrders(params, region) { return instances[region]?.getOrders(params); }
239
+ };
@@ -0,0 +1,175 @@
1
+ /**
2
+ * 🌸 Γ‡Δ°Γ‡EKSEPETΔ° API Entegrasyonu
3
+ * bayi.ciceksepeti.com
4
+ */
5
+
6
+ import axios from 'axios';
7
+
8
+ const BASE_URL = 'https://apis.ciceksepeti.com/api/v1';
9
+
10
+ export class CiceksepetiAPI {
11
+ constructor(config) {
12
+ this.apiKey = config.apiKey;
13
+ this.supplierId = config.supplierId;
14
+ }
15
+
16
+ _headers() {
17
+ return {
18
+ 'x-api-key': this.apiKey,
19
+ 'Content-Type': 'application/json'
20
+ };
21
+ }
22
+
23
+ async _request(method, endpoint, data = null, params = null) {
24
+ try {
25
+ const response = await axios({
26
+ method,
27
+ url: `${BASE_URL}${endpoint}`,
28
+ headers: this._headers(),
29
+ data,
30
+ params
31
+ });
32
+ return { success: true, data: response.data };
33
+ } catch (error) {
34
+ return {
35
+ success: false,
36
+ error: error.response?.data || error.message
37
+ };
38
+ }
39
+ }
40
+
41
+ // ═══════════════════════════════════════════════════════════════════════════
42
+ // ÜRÜN İŞLEMLERİ
43
+ // ═══════════════════════════════════════════════════════════════════════════
44
+
45
+ async getProducts(params = {}) {
46
+ const { page = 1, pageSize = 100, stockCode } = params;
47
+ return await this._request('GET', '/products', null, {
48
+ page, pageSize, stockCode
49
+ });
50
+ }
51
+
52
+ async getProductByStockCode(stockCode) {
53
+ const result = await this.getProducts({ stockCode });
54
+ if (result.success && result.data.products?.length > 0) {
55
+ return { success: true, data: result.data.products[0] };
56
+ }
57
+ return { success: false, error: 'Ürün bulunamadı' };
58
+ }
59
+
60
+ async updateProduct(product) {
61
+ return await this._request('PUT', '/products', {
62
+ items: [product]
63
+ });
64
+ }
65
+
66
+ async updatePrice(stockCode, salesPrice, listPrice = null) {
67
+ return await this._request('PUT', '/products/price-and-stock', {
68
+ items: [{
69
+ stockCode,
70
+ salesPrice,
71
+ listPrice: listPrice || salesPrice
72
+ }]
73
+ });
74
+ }
75
+
76
+ async updateStock(stockCode, stockQuantity) {
77
+ return await this._request('PUT', '/products/price-and-stock', {
78
+ items: [{
79
+ stockCode,
80
+ stockQuantity
81
+ }]
82
+ });
83
+ }
84
+
85
+ async bulkUpdate(items) {
86
+ // items: [{ stockCode, salesPrice?, stockQuantity? }]
87
+ return await this._request('PUT', '/products/price-and-stock', { items });
88
+ }
89
+
90
+ // ═══════════════════════════════════════════════════════════════════════════
91
+ // SİPARİŞ İŞLEMLERİ
92
+ // ═══════════════════════════════════════════════════════════════════════════
93
+
94
+ async getOrders(params = {}) {
95
+ const {
96
+ startDate,
97
+ endDate,
98
+ page = 1,
99
+ pageSize = 100,
100
+ orderStatus // 1: Yeni, 2: HazΔ±rlanΔ±yor, 3: Kargoda, 4: Teslim
101
+ } = params;
102
+
103
+ return await this._request('GET', '/orders', null, {
104
+ startDate, endDate, page, pageSize, orderStatus
105
+ });
106
+ }
107
+
108
+ async getOrderDetail(orderId) {
109
+ return await this._request('GET', `/orders/${orderId}`);
110
+ }
111
+
112
+ async updateOrderStatus(orderId, status, trackingNumber = null) {
113
+ const data = { orderStatus: status };
114
+ if (trackingNumber) {
115
+ data.cargoTrackingNumber = trackingNumber;
116
+ }
117
+ return await this._request('PUT', `/orders/${orderId}`, data);
118
+ }
119
+
120
+ async shipOrder(orderId, trackingNumber, cargoCompanyId = 1) {
121
+ return await this._request('PUT', `/orders/${orderId}/ship`, {
122
+ cargoCompanyId,
123
+ cargoTrackingNumber: trackingNumber
124
+ });
125
+ }
126
+
127
+ // ═══════════════════════════════════════════════════════════════════════════
128
+ // KATEGORΔ°
129
+ // ═══════════════════════════════════════════════════════════════════════════
130
+
131
+ async getCategories() {
132
+ return await this._request('GET', '/categories');
133
+ }
134
+
135
+ async getCategoryAttributes(categoryId) {
136
+ return await this._request('GET', `/categories/${categoryId}/attributes`);
137
+ }
138
+
139
+ // ═══════════════════════════════════════════════════════════════════════════
140
+ // KARGO
141
+ // ═══════════════════════════════════════════════════════════════════════════
142
+
143
+ async getCargoCompanies() {
144
+ return await this._request('GET', '/cargo-companies');
145
+ }
146
+
147
+ // ═══════════════════════════════════════════════════════════════════════════
148
+ // HELPER
149
+ // ═══════════════════════════════════════════════════════════════════════════
150
+
151
+ async testConnection() {
152
+ const result = await this.getProducts({ page: 1, pageSize: 1 });
153
+ return result.success;
154
+ }
155
+
156
+ isConnected() {
157
+ return !!(this.apiKey);
158
+ }
159
+ }
160
+
161
+ let instance = null;
162
+
163
+ export const ciceksepetiApi = {
164
+ init(config) {
165
+ instance = new CiceksepetiAPI(config);
166
+ return instance;
167
+ },
168
+ getInstance() { return instance; },
169
+ isConnected() { return instance?.isConnected() || false; },
170
+
171
+ async getProducts(params) { return instance?.getProducts(params); },
172
+ async updatePrice(code, price) { return instance?.updatePrice(code, price); },
173
+ async updateStock(code, qty) { return instance?.updateStock(code, qty); },
174
+ async getOrders(params) { return instance?.getOrders(params); }
175
+ };
@@ -0,0 +1,189 @@
1
+ /**
2
+ * 🟣 HEPSİBURADA API Entegrasyonu
3
+ * developer.hepsiburada.com
4
+ */
5
+
6
+ import axios from 'axios';
7
+
8
+ const BASE_URL = 'https://mpop-sit.hepsiburada.com'; // Production: mpop.hepsiburada.com
9
+ const LISTING_URL = 'https://listing-external.hepsiburada.com';
10
+
11
+ export class HepsiburadaAPI {
12
+ constructor(config) {
13
+ this.merchantId = config.merchantId;
14
+ this.username = config.username;
15
+ this.password = config.password;
16
+
17
+ this.auth = Buffer.from(`${this.username}:${this.password}`).toString('base64');
18
+ }
19
+
20
+ _headers() {
21
+ return {
22
+ 'Authorization': `Basic ${this.auth}`,
23
+ 'Content-Type': 'application/json',
24
+ 'Accept': 'application/json'
25
+ };
26
+ }
27
+
28
+ async _request(method, url, data = null, params = null) {
29
+ try {
30
+ const response = await axios({
31
+ method,
32
+ url,
33
+ headers: this._headers(),
34
+ data,
35
+ params
36
+ });
37
+ return { success: true, data: response.data };
38
+ } catch (error) {
39
+ return {
40
+ success: false,
41
+ error: error.response?.data || error.message
42
+ };
43
+ }
44
+ }
45
+
46
+ // ═══════════════════════════════════════════════════════════════════════════
47
+ // ÜRÜN İŞLEMLERİ
48
+ // ═══════════════════════════════════════════════════════════════════════════
49
+
50
+ async getProducts(params = {}) {
51
+ const { page = 0, size = 100, sku } = params;
52
+ return await this._request('GET',
53
+ `${LISTING_URL}/Listings/merchantid/${this.merchantId}`,
54
+ null, { page, size, merchantSku: sku }
55
+ );
56
+ }
57
+
58
+ async createProduct(product) {
59
+ // product: { merchantSku, hepsiburadaSku, price, availableStock, ... }
60
+ return await this._request('POST',
61
+ `${LISTING_URL}/Listings/merchantid/${this.merchantId}/sku/${product.hepsiburadaSku}`,
62
+ product
63
+ );
64
+ }
65
+
66
+ async updatePrice(merchantSku, price) {
67
+ return await this._request('POST',
68
+ `${LISTING_URL}/Listings/merchantid/${this.merchantId}`,
69
+ {
70
+ listings: [{
71
+ merchantSku,
72
+ price,
73
+ currency: 'TRY'
74
+ }]
75
+ }
76
+ );
77
+ }
78
+
79
+ async updateStock(merchantSku, stock) {
80
+ return await this._request('POST',
81
+ `${LISTING_URL}/Listings/merchantid/${this.merchantId}`,
82
+ {
83
+ listings: [{
84
+ merchantSku,
85
+ availableStock: stock
86
+ }]
87
+ }
88
+ );
89
+ }
90
+
91
+ async bulkUpdate(listings) {
92
+ // listings: [{ merchantSku, price?, availableStock? }]
93
+ return await this._request('POST',
94
+ `${LISTING_URL}/Listings/merchantid/${this.merchantId}`,
95
+ { listings }
96
+ );
97
+ }
98
+
99
+ // ═══════════════════════════════════════════════════════════════════════════
100
+ // SİPARİŞ İŞLEMLERİ
101
+ // ═══════════════════════════════════════════════════════════════════════════
102
+
103
+ async getOrders(params = {}) {
104
+ const {
105
+ status, // Open, Shipped, Delivered, Cancelled
106
+ startDate,
107
+ endDate,
108
+ page = 0,
109
+ size = 50
110
+ } = params;
111
+
112
+ return await this._request('GET',
113
+ `${BASE_URL}/orders/merchantid/${this.merchantId}`,
114
+ null, { status, startDate, endDate, page, size }
115
+ );
116
+ }
117
+
118
+ async getOrderDetail(orderId) {
119
+ return await this._request('GET',
120
+ `${BASE_URL}/orders/merchantid/${this.merchantId}/id/${orderId}`
121
+ );
122
+ }
123
+
124
+ async confirmOrder(orderId) {
125
+ return await this._request('PUT',
126
+ `${BASE_URL}/orders/merchantid/${this.merchantId}/id/${orderId}/confirm`
127
+ );
128
+ }
129
+
130
+ async shipOrder(orderId, trackingNumber, cargoCompany) {
131
+ return await this._request('PUT',
132
+ `${BASE_URL}/orders/merchantid/${this.merchantId}/id/${orderId}/ship`,
133
+ {
134
+ trackingNumber,
135
+ cargoCompany
136
+ }
137
+ );
138
+ }
139
+
140
+ async cancelOrder(orderId, reason) {
141
+ return await this._request('PUT',
142
+ `${BASE_URL}/orders/merchantid/${this.merchantId}/id/${orderId}/cancel`,
143
+ { reason }
144
+ );
145
+ }
146
+
147
+ // ═══════════════════════════════════════════════════════════════════════════
148
+ // KATEGORΔ°
149
+ // ═══════════════════════════════════════════════════════════════════════════
150
+
151
+ async getCategories() {
152
+ return await this._request('GET', `${LISTING_URL}/categories/get-all-categories`);
153
+ }
154
+
155
+ async getCategoryAttributes(categoryId) {
156
+ return await this._request('GET',
157
+ `${LISTING_URL}/product-attributes/category/${categoryId}`
158
+ );
159
+ }
160
+
161
+ // ═══════════════════════════════════════════════════════════════════════════
162
+ // HELPER
163
+ // ═══════════════════════════════════════════════════════════════════════════
164
+
165
+ async testConnection() {
166
+ const result = await this.getProducts({ page: 0, size: 1 });
167
+ return result.success;
168
+ }
169
+
170
+ isConnected() {
171
+ return !!(this.merchantId && this.username && this.password);
172
+ }
173
+ }
174
+
175
+ let instance = null;
176
+
177
+ export const hepsiburadaApi = {
178
+ init(config) {
179
+ instance = new HepsiburadaAPI(config);
180
+ return instance;
181
+ },
182
+ getInstance() { return instance; },
183
+ isConnected() { return instance?.isConnected() || false; },
184
+
185
+ async getProducts(params) { return instance?.getProducts(params); },
186
+ async updatePrice(sku, price) { return instance?.updatePrice(sku, price); },
187
+ async updateStock(sku, qty) { return instance?.updateStock(sku, qty); },
188
+ async getOrders(params) { return instance?.getOrders(params); }
189
+ };