@things-factory/integration-sellercraft 4.0.7 → 4.0.12
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/dist-server/constants/index.js +14 -0
- package/dist-server/constants/index.js.map +1 -0
- package/dist-server/constants/platform.js +7 -0
- package/dist-server/constants/platform.js.map +1 -0
- package/dist-server/controllers/sellercraft-channel-integration/apis/echo.js +19 -0
- package/dist-server/controllers/sellercraft-channel-integration/apis/echo.js.map +1 -0
- package/dist-server/controllers/sellercraft-channel-integration/apis/index.js +19 -0
- package/dist-server/controllers/sellercraft-channel-integration/apis/index.js.map +1 -0
- package/dist-server/controllers/sellercraft-channel-integration/apis/ingest-channel-categories.js +40 -0
- package/dist-server/controllers/sellercraft-channel-integration/apis/ingest-channel-categories.js.map +1 -0
- package/dist-server/controllers/sellercraft-channel-integration/apis/ingest-channel-category-attributes.js +48 -0
- package/dist-server/controllers/sellercraft-channel-integration/apis/ingest-channel-category-attributes.js.map +1 -0
- package/dist-server/controllers/sellercraft-channel-integration/apis/ingest-channel-order-package.js +46 -0
- package/dist-server/controllers/sellercraft-channel-integration/apis/ingest-channel-order-package.js.map +1 -0
- package/dist-server/controllers/sellercraft-channel-integration/apis/ingest-channel-order.js +81 -0
- package/dist-server/controllers/sellercraft-channel-integration/apis/ingest-channel-order.js.map +1 -0
- package/dist-server/controllers/sellercraft-channel-integration/apis/ingest-channel-product.js +105 -0
- package/dist-server/controllers/sellercraft-channel-integration/apis/ingest-channel-product.js.map +1 -0
- package/dist-server/controllers/sellercraft-channel-integration/index.js +30 -0
- package/dist-server/controllers/sellercraft-channel-integration/index.js.map +1 -0
- package/dist-server/controllers/sellercraft-channel-integration/platform-action.js +33 -0
- package/dist-server/controllers/sellercraft-channel-integration/platform-action.js.map +1 -0
- package/dist-server/controllers/sellercraft-channel-integration/sellercraft-channel-integration.js +90 -0
- package/dist-server/controllers/sellercraft-channel-integration/sellercraft-channel-integration.js.map +1 -0
- package/dist-server/controllers/sellercraft-channel-integration-api/decorators.js +32 -0
- package/dist-server/controllers/sellercraft-channel-integration-api/decorators.js.map +1 -0
- package/dist-server/controllers/sellercraft-channel-integration-api/index.js +78 -0
- package/dist-server/controllers/sellercraft-channel-integration-api/index.js.map +1 -0
- package/dist-server/controllers/sellercraft-channel-integration-api/types.js +1 -0
- package/dist-server/controllers/sellercraft-channel-integration-api/types.js.map +1 -0
- package/dist-server/index.js +1 -0
- package/dist-server/index.js.map +1 -1
- package/dist-server/routers/sellercraft-router.js +174 -0
- package/dist-server/routers/sellercraft-router.js.map +1 -0
- package/dist-server/routes.js +4 -0
- package/dist-server/routes.js.map +1 -1
- package/package.json +15 -14
- package/server/constants/index.ts +1 -0
- package/server/constants/platform.ts +3 -0
- package/server/controllers/sellercraft-channel-integration/apis/echo.ts +14 -0
- package/server/controllers/sellercraft-channel-integration/apis/index.ts +6 -0
- package/server/controllers/sellercraft-channel-integration/apis/ingest-channel-categories.ts +38 -0
- package/server/controllers/sellercraft-channel-integration/apis/ingest-channel-category-attributes.ts +65 -0
- package/server/controllers/sellercraft-channel-integration/apis/ingest-channel-order-package.ts +58 -0
- package/server/controllers/sellercraft-channel-integration/apis/ingest-channel-order.ts +79 -0
- package/server/controllers/sellercraft-channel-integration/apis/ingest-channel-product.ts +110 -0
- package/server/controllers/sellercraft-channel-integration/index.ts +7 -0
- package/server/controllers/sellercraft-channel-integration/platform-action.ts +39 -0
- package/server/controllers/sellercraft-channel-integration/sellercraft-channel-integration.ts +106 -0
- package/server/controllers/sellercraft-channel-integration-api/decorators.ts +45 -0
- package/server/controllers/sellercraft-channel-integration-api/index.ts +45 -0
- package/server/controllers/sellercraft-channel-integration-api/types.ts +0 -0
- package/server/index.ts +1 -0
- package/server/routers/sellercraft-router.ts +202 -0
- package/server/routes.ts +4 -0
@@ -0,0 +1,110 @@
|
|
1
|
+
/* https://docs.sellercraft.co/docs/api-integrations/b3A6MTY4NjQxODU-initiate-order-shipment */
|
2
|
+
|
3
|
+
export function ingestChannelProduct() {
|
4
|
+
return {
|
5
|
+
method: 'post',
|
6
|
+
path: '/channel/ingest/product',
|
7
|
+
denormalize(req) {
|
8
|
+
const { products } = req
|
9
|
+
|
10
|
+
let newProducts = products.map(product => {
|
11
|
+
let productVariations: any[] = product.variations.map(variant => {
|
12
|
+
return {
|
13
|
+
seller_sku: variant.variationSku,
|
14
|
+
native_variant_id: variant.variationId,
|
15
|
+
label: variant.name,
|
16
|
+
is_enabled: variant.isEnabled,
|
17
|
+
is_sellable: variant.isSellable,
|
18
|
+
variant_attributes: variant?.attributes
|
19
|
+
? variant.attributes.map(attribute => {
|
20
|
+
return {
|
21
|
+
attribute_key: attribute.id,
|
22
|
+
values: []
|
23
|
+
}
|
24
|
+
})
|
25
|
+
: [],
|
26
|
+
stock_locked: variant?.stockLocked ? variant.stockLocked : 0,
|
27
|
+
native_stock_reported: variant?.stockReported ? variant.stockReported : 0,
|
28
|
+
price_full: variant.fullPrice,
|
29
|
+
price_discounted: variant.priceDiscounted,
|
30
|
+
price_discounts: variant?.product_discounts
|
31
|
+
? variant.product_discounts.map(discount => {
|
32
|
+
return {
|
33
|
+
price_discounted: discount.priceDiscounted,
|
34
|
+
native_discount_id: discount.id,
|
35
|
+
name: discount.name
|
36
|
+
}
|
37
|
+
})
|
38
|
+
: [],
|
39
|
+
inventory_products: variant?.inventoryProducts
|
40
|
+
? variant.inventoryProducts.map(inventoryProduct => {
|
41
|
+
return {
|
42
|
+
quantity: inventoryProduct.qty,
|
43
|
+
name: inventoryProduct.name,
|
44
|
+
inventory_sku: inventoryProduct.sku,
|
45
|
+
product_versions: inventoryProduct?.productVersions
|
46
|
+
? inventoryProduct.productVersions.map(productVersion => {
|
47
|
+
return {
|
48
|
+
label: productVersion.label,
|
49
|
+
package_content: productVersion.packageContent,
|
50
|
+
package_length_mm: productVersion?.packageLengthMM ? productVersion.packageLengthMM : 0,
|
51
|
+
package_width_mm: productVersion?.packageWidthMM ? productVersion.packageWidthMM : 0,
|
52
|
+
package_height_mm: productVersion?.packageHeightMM ? productVersion.packageHeightMM : 0,
|
53
|
+
package_weight_gram: productVersion?.packageWeightGram
|
54
|
+
? productVersion.packageWeightGram
|
55
|
+
: 0,
|
56
|
+
stock_available: productVersion.qty
|
57
|
+
}
|
58
|
+
})
|
59
|
+
: []
|
60
|
+
}
|
61
|
+
})
|
62
|
+
: []
|
63
|
+
}
|
64
|
+
})
|
65
|
+
|
66
|
+
return {
|
67
|
+
organisation_id: product.organisationId,
|
68
|
+
channel_shop_id: product.channelShopId,
|
69
|
+
channel_code: product.channelCode,
|
70
|
+
channel_country: product.channelCountry,
|
71
|
+
native_category_id: product.categoryId,
|
72
|
+
native_product_id: product.productId,
|
73
|
+
label: product.name,
|
74
|
+
brand: product.brand,
|
75
|
+
is_verified: product.isVerified,
|
76
|
+
images: product.images.map(image => {
|
77
|
+
return {
|
78
|
+
file_url: image.url
|
79
|
+
}
|
80
|
+
}),
|
81
|
+
product_attributes: product.attributes.map(attribute => {
|
82
|
+
return {
|
83
|
+
native_attribute_id: attribute.id,
|
84
|
+
values: []
|
85
|
+
}
|
86
|
+
})
|
87
|
+
}
|
88
|
+
})
|
89
|
+
|
90
|
+
return {
|
91
|
+
payload: {}
|
92
|
+
}
|
93
|
+
},
|
94
|
+
normalize(res) {
|
95
|
+
const {
|
96
|
+
handover_type: handOverType,
|
97
|
+
pickup_time: pickupTime,
|
98
|
+
pickup_address: pickupAddress,
|
99
|
+
dropoff_address: dropoffAddress
|
100
|
+
} = res.data
|
101
|
+
|
102
|
+
return {
|
103
|
+
handOverType,
|
104
|
+
pickupTime,
|
105
|
+
pickupAddress,
|
106
|
+
dropoffAddress
|
107
|
+
}
|
108
|
+
}
|
109
|
+
}
|
110
|
+
}
|
@@ -0,0 +1,7 @@
|
|
1
|
+
import { SellercraftChannelIntegrationAPI } from '../sellercraft-channel-integration-api'
|
2
|
+
import * as APIS from './apis'
|
3
|
+
import { action } from './platform-action'
|
4
|
+
|
5
|
+
export * from './sellercraft-channel-integration'
|
6
|
+
|
7
|
+
SellercraftChannelIntegrationAPI.registerPlatform('sellercraftChannelIntegration', action, APIS)
|
@@ -0,0 +1,39 @@
|
|
1
|
+
import { config } from '@things-factory/env'
|
2
|
+
|
3
|
+
import { SellercraftChannelIntegration } from './sellercraft-channel-integration'
|
4
|
+
|
5
|
+
const sellercraftConfig = config.get('sellercraftChannelIntegrationConfig', {})
|
6
|
+
const { apiKey } = sellercraftConfig
|
7
|
+
|
8
|
+
function substitute(path, obj) {
|
9
|
+
var props = []
|
10
|
+
var re = /{([^}]+)}/g
|
11
|
+
var text
|
12
|
+
|
13
|
+
while ((text = re.exec(path))) {
|
14
|
+
props.push(text[1])
|
15
|
+
}
|
16
|
+
|
17
|
+
var result = path
|
18
|
+
props.forEach(prop => {
|
19
|
+
let value = obj[prop.trim()]
|
20
|
+
result = result.replace(`{${prop}}`, value === undefined ? '' : value)
|
21
|
+
})
|
22
|
+
|
23
|
+
return result
|
24
|
+
}
|
25
|
+
|
26
|
+
export const action = async ({ method = 'get', path, request }) => {
|
27
|
+
const client = new SellercraftChannelIntegration({ apiKey })
|
28
|
+
|
29
|
+
const { resource = {}, payload = {} } = request
|
30
|
+
|
31
|
+
path = substitute(path, resource)
|
32
|
+
|
33
|
+
var response = await client[method](path, payload)
|
34
|
+
if (response.errors) {
|
35
|
+
throw response
|
36
|
+
}
|
37
|
+
|
38
|
+
return response
|
39
|
+
}
|
@@ -0,0 +1,106 @@
|
|
1
|
+
import fetch from 'node-fetch'
|
2
|
+
import uuid from 'uuid/v4'
|
3
|
+
|
4
|
+
const debug = require('debug')('things-factory:integration-sellercraft:sellercraft')
|
5
|
+
|
6
|
+
export type SellercraftConfig = {
|
7
|
+
apiKey: string
|
8
|
+
}
|
9
|
+
|
10
|
+
export class SellercraftChannelIntegration {
|
11
|
+
private config: SellercraftConfig
|
12
|
+
|
13
|
+
constructor(config: SellercraftConfig) {
|
14
|
+
this.config = {
|
15
|
+
...config
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
getBaseUrl() {
|
20
|
+
return `https://open.sellercraft.co/v1`
|
21
|
+
}
|
22
|
+
|
23
|
+
generateRequestId() {
|
24
|
+
return uuid()
|
25
|
+
}
|
26
|
+
|
27
|
+
async post(path: string, data: any = {}) {
|
28
|
+
const { apiKey } = this.config
|
29
|
+
|
30
|
+
debug('data', data)
|
31
|
+
|
32
|
+
const jsondata = JSON.stringify(data)
|
33
|
+
const requestId: string = this.generateRequestId()
|
34
|
+
const fullPath: string = `${this.getBaseUrl()}${path}`
|
35
|
+
|
36
|
+
const response: any = await fetch(fullPath, {
|
37
|
+
method: 'post',
|
38
|
+
headers: {
|
39
|
+
'Content-Type': 'application/json',
|
40
|
+
request_id: requestId,
|
41
|
+
'x-api-key': apiKey
|
42
|
+
},
|
43
|
+
body: jsondata
|
44
|
+
})
|
45
|
+
|
46
|
+
if (response.ok) {
|
47
|
+
return await response.json()
|
48
|
+
} else {
|
49
|
+
throw new Error(`response code - ${response.status}, ${response.statusText}`)
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
async put(path: string, data: any = {}) {
|
54
|
+
const { apiKey } = this.config
|
55
|
+
|
56
|
+
const jsondata = JSON.stringify(data)
|
57
|
+
const requestId: string = this.generateRequestId()
|
58
|
+
const fullPath: string = `${this.getBaseUrl()}${path}`
|
59
|
+
debug('data', data)
|
60
|
+
|
61
|
+
const response: any = await fetch(fullPath, {
|
62
|
+
method: 'put',
|
63
|
+
headers: {
|
64
|
+
'Content-Type': 'application/json',
|
65
|
+
request_id: requestId,
|
66
|
+
'x-api-key': apiKey
|
67
|
+
},
|
68
|
+
body: jsondata
|
69
|
+
})
|
70
|
+
|
71
|
+
if (response.ok) {
|
72
|
+
return await response.json()
|
73
|
+
} else {
|
74
|
+
throw new Error(`response code - ${response.status}, ${response.statusText}`)
|
75
|
+
}
|
76
|
+
}
|
77
|
+
|
78
|
+
async get(path: string, data: any = {}) {
|
79
|
+
const { apiKey } = this.config
|
80
|
+
|
81
|
+
const qs = Object.entries(data)
|
82
|
+
.map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`)
|
83
|
+
.join('&')
|
84
|
+
|
85
|
+
const fullPath: string = `${this.getBaseUrl()}${path}`
|
86
|
+
const endpoint = `${fullPath}${qs ? '?' + qs : ''}`
|
87
|
+
debug('endpoint', endpoint)
|
88
|
+
|
89
|
+
const requestId: string = this.generateRequestId()
|
90
|
+
|
91
|
+
const response: any = await fetch(endpoint, {
|
92
|
+
method: 'get',
|
93
|
+
headers: {
|
94
|
+
'Content-Type': 'application/json',
|
95
|
+
request_id: requestId,
|
96
|
+
'x-api-key': apiKey
|
97
|
+
}
|
98
|
+
})
|
99
|
+
|
100
|
+
if (response.ok) {
|
101
|
+
return await response.json()
|
102
|
+
} else {
|
103
|
+
throw new Error(`response code - ${response.status}, ${response.statusText}`)
|
104
|
+
}
|
105
|
+
}
|
106
|
+
}
|
@@ -0,0 +1,45 @@
|
|
1
|
+
import Debug from 'debug'
|
2
|
+
|
3
|
+
import { Sellercraft } from '../../service'
|
4
|
+
|
5
|
+
const debug = Debug('things-factory:integration-marketplace:store-api-decorator')
|
6
|
+
|
7
|
+
const NOOP = v => v
|
8
|
+
|
9
|
+
export const api = (target: Object, property: string, descriptor: TypedPropertyDescriptor<any>): any => {
|
10
|
+
const method = descriptor.value
|
11
|
+
|
12
|
+
descriptor.value = async function (store: Sellercraft, request) {
|
13
|
+
const SellercraftChannelIntegrationAPI = this
|
14
|
+
|
15
|
+
var { platform } = store
|
16
|
+
|
17
|
+
var { action: platformAction, apis } = SellercraftChannelIntegrationAPI.getPlatform(platform)
|
18
|
+
|
19
|
+
var m = apis[method.name]
|
20
|
+
if (!m) {
|
21
|
+
throw Error(`Sellercraft doesn't have API ${method.name}`)
|
22
|
+
}
|
23
|
+
|
24
|
+
var {
|
25
|
+
path,
|
26
|
+
method: httpMethod = 'post',
|
27
|
+
denormalize = NOOP,
|
28
|
+
normalize = NOOP,
|
29
|
+
action = platformAction
|
30
|
+
} = m.apply(this, [request])
|
31
|
+
|
32
|
+
var denormalized = await denormalize(request || {}, { store })
|
33
|
+
debug('request', denormalized)
|
34
|
+
|
35
|
+
var response = await action.apply(this, [
|
36
|
+
{ store, method: httpMethod, path, request: denormalized, platformAction }
|
37
|
+
])
|
38
|
+
|
39
|
+
debug('response', response)
|
40
|
+
|
41
|
+
return await normalize(response, { store })
|
42
|
+
}
|
43
|
+
|
44
|
+
return descriptor
|
45
|
+
}
|
@@ -0,0 +1,45 @@
|
|
1
|
+
import { getRepository } from 'typeorm'
|
2
|
+
|
3
|
+
import { Sellercraft } from '../../service'
|
4
|
+
import { api } from './decorators'
|
5
|
+
|
6
|
+
export class SellercraftChannelIntegrationAPI {
|
7
|
+
static platforms = {}
|
8
|
+
|
9
|
+
static registerPlatform(name, action, apis) {
|
10
|
+
SellercraftChannelIntegrationAPI.platforms[name] = {
|
11
|
+
action,
|
12
|
+
apis
|
13
|
+
}
|
14
|
+
}
|
15
|
+
|
16
|
+
static getPlatform(name) {
|
17
|
+
return SellercraftChannelIntegrationAPI.platforms[name]
|
18
|
+
}
|
19
|
+
|
20
|
+
static async getSellercraft(id) {
|
21
|
+
const repository = getRepository(Sellercraft)
|
22
|
+
return await repository.findOne({
|
23
|
+
where: { id },
|
24
|
+
relations: ['domain']
|
25
|
+
})
|
26
|
+
}
|
27
|
+
|
28
|
+
@api
|
29
|
+
static echo(sellercraft, req): any {}
|
30
|
+
|
31
|
+
@api
|
32
|
+
static ingestChannelCategories(sellercraft, req): any {}
|
33
|
+
|
34
|
+
@api
|
35
|
+
static ingestChannelCategoryAttributes(sellercraft, req): any {}
|
36
|
+
|
37
|
+
@api
|
38
|
+
static ingestChannelOrderPackage(sellercraft, req): any {}
|
39
|
+
|
40
|
+
@api
|
41
|
+
static ingestChannelOrder(sellercraft, req): any {}
|
42
|
+
|
43
|
+
@api
|
44
|
+
static ingestChannelProduct(sellercraft, req): any {}
|
45
|
+
}
|
File without changes
|
package/server/index.ts
CHANGED
@@ -0,0 +1,202 @@
|
|
1
|
+
import Router from 'koa-router'
|
2
|
+
|
3
|
+
import { config } from '@things-factory/env'
|
4
|
+
import { StoreAPI } from '@things-factory/integration-marketplace'
|
5
|
+
import { PLATFORM } from '../constants'
|
6
|
+
|
7
|
+
const debug = require('debug')('things-factory:integration-sellercraft:sellercraft-router')
|
8
|
+
|
9
|
+
export const sellercraftRouter = new Router()
|
10
|
+
|
11
|
+
sellercraftRouter.post('/sellercraft/store/update-product-price', async (context, next) => {
|
12
|
+
const sellercraftChannelIntegrationConfig = config.get('sellercraftChannelIntegrationConfig', {})
|
13
|
+
const { apiKey, tokenCraftUrl } = sellercraftChannelIntegrationConfig
|
14
|
+
|
15
|
+
const xApiKey = context.headers['x-api-key']
|
16
|
+
|
17
|
+
if (apiKey !== xApiKey) context.throw(400, 'api key validation failed')
|
18
|
+
|
19
|
+
const requestBody = context.request.body
|
20
|
+
|
21
|
+
for (var i = 0; i < requestBody.length; i++) {
|
22
|
+
var store: any = {} // get from tokencraft
|
23
|
+
var result
|
24
|
+
|
25
|
+
// https://staging-tokencraft.sellercraft.co/v1/get-shop?channel_id=4bfb3362-d57c-47f8-8781-007316d179bf&shop_id=dd9cf3b7-114f-4d74-a7e2-7b524ae086f2
|
26
|
+
var fullPath = tokenCraftUrl + '?channel_id=4bfb3362-d57c-47f8-8781-007316d179bf&shop_id=' + requestBody[i].shop_id
|
27
|
+
const response: any = await fetch(fullPath, {
|
28
|
+
method: 'get',
|
29
|
+
headers: {
|
30
|
+
'Content-Type': 'application/json',
|
31
|
+
'x-api-key': apiKey
|
32
|
+
}
|
33
|
+
})
|
34
|
+
if (response.ok) {
|
35
|
+
store = await response.json()
|
36
|
+
}
|
37
|
+
|
38
|
+
let mappedStore: any = {
|
39
|
+
accessKey: store.shop.credential.consumer_key,
|
40
|
+
accessSecret: store.shop.credential.consumer_secret,
|
41
|
+
storeURL: store.shop.credential.store_url,
|
42
|
+
platform: PLATFORM[`${store.shop.org_prefix}`]
|
43
|
+
}
|
44
|
+
|
45
|
+
if (requestBody[i].native_variant_id) {
|
46
|
+
const req = {
|
47
|
+
costPrice: requestBody[i].full_price,
|
48
|
+
sellPrice: requestBody[i].sale_price,
|
49
|
+
productId: requestBody[i].native_product_id,
|
50
|
+
variationId: requestBody[i].native_variant_id
|
51
|
+
}
|
52
|
+
result = await StoreAPI.updateStoreProductVariationPrice(mappedStore, req)
|
53
|
+
} else {
|
54
|
+
const req = {
|
55
|
+
costPrice: requestBody[i].full_price,
|
56
|
+
sellPrice: requestBody[i].sale_price,
|
57
|
+
productId: requestBody[i].native_product_id
|
58
|
+
}
|
59
|
+
result = await StoreAPI.updateStoreProductPrice(mappedStore, req)
|
60
|
+
}
|
61
|
+
|
62
|
+
debug(result)
|
63
|
+
}
|
64
|
+
|
65
|
+
context.status = 200
|
66
|
+
})
|
67
|
+
|
68
|
+
sellercraftRouter.post('/sellercraft/store/update-product-stock', async (context, next) => {
|
69
|
+
const sellercraftChannelIntegrationConfig = config.get('sellercraftChannelIntegrationConfig', {})
|
70
|
+
const { apiKey, tokenCraftUrl } = sellercraftChannelIntegrationConfig
|
71
|
+
|
72
|
+
const xApiKey = context.headers['x-api-key']
|
73
|
+
|
74
|
+
if (apiKey !== xApiKey) context.throw(400, 'api key validation failed')
|
75
|
+
|
76
|
+
const requestBody = context.request.body
|
77
|
+
for (var i = 0; i < requestBody.length; i++) {
|
78
|
+
var store: any = {} // get from tokencraft
|
79
|
+
var result
|
80
|
+
|
81
|
+
// https://staging-tokencraft.sellercraft.co/v1/get-shop?channel_id=4bfb3362-d57c-47f8-8781-007316d179bf&shop_id=dd9cf3b7-114f-4d74-a7e2-7b524ae086f2
|
82
|
+
var fullPath = tokenCraftUrl + '?channel_id=4bfb3362-d57c-47f8-8781-007316d179bf&shop_id=' + requestBody[i].shop_id
|
83
|
+
const response: any = await fetch(fullPath, {
|
84
|
+
method: 'get',
|
85
|
+
headers: {
|
86
|
+
'Content-Type': 'application/json',
|
87
|
+
'x-api-key': apiKey
|
88
|
+
}
|
89
|
+
})
|
90
|
+
if (response.ok) {
|
91
|
+
store = await response.json()
|
92
|
+
}
|
93
|
+
|
94
|
+
let mappedStore: any = {
|
95
|
+
accessKey: store.shop.credential.consumer_key,
|
96
|
+
accessSecret: store.shop.credential.consumer_secret,
|
97
|
+
storeURL: store.shop.credential.store_url,
|
98
|
+
platform: PLATFORM[`${store.shop.org_prefix}`]
|
99
|
+
}
|
100
|
+
|
101
|
+
if (requestBody[i].native_variant_id) {
|
102
|
+
const req = {
|
103
|
+
qty: requestBody[i].stock,
|
104
|
+
itemId: requestBody[i].native_product_id,
|
105
|
+
variationId: requestBody[i].native_variant_id
|
106
|
+
}
|
107
|
+
result = await StoreAPI.updateStoreProductVariationStock(mappedStore, req)
|
108
|
+
} else {
|
109
|
+
const req = {
|
110
|
+
qty: requestBody[i].stock,
|
111
|
+
itemId: requestBody[i].native_product_id
|
112
|
+
}
|
113
|
+
result = await StoreAPI.updateStoreProductStock(mappedStore, req)
|
114
|
+
}
|
115
|
+
|
116
|
+
debug(result)
|
117
|
+
}
|
118
|
+
context.status = 200
|
119
|
+
})
|
120
|
+
|
121
|
+
sellercraftRouter.post('/sellercraft/store/update-order-status', async (context, next) => {
|
122
|
+
const sellercraftChannelIntegrationConfig = config.get('sellercraftChannelIntegrationConfig', {})
|
123
|
+
const { apiKey, tokenCraftUrl } = sellercraftChannelIntegrationConfig
|
124
|
+
|
125
|
+
const xApiKey = context.headers['x-api-key']
|
126
|
+
|
127
|
+
if (apiKey !== xApiKey) context.throw(400, 'api key validation failed')
|
128
|
+
|
129
|
+
const requestBody = context.request.body
|
130
|
+
var result
|
131
|
+
var store: any = {}
|
132
|
+
|
133
|
+
// https://staging-tokencraft.sellercraft.co/v1/get-shop?channel_id=4bfb3362-d57c-47f8-8781-007316d179bf&shop_id=dd9cf3b7-114f-4d74-a7e2-7b524ae086f2
|
134
|
+
var fullPath = tokenCraftUrl + '?channel_id=4bfb3362-d57c-47f8-8781-007316d179bf&shop_id=' + requestBody.shop_id
|
135
|
+
const response: any = await fetch(fullPath, {
|
136
|
+
method: 'get',
|
137
|
+
headers: {
|
138
|
+
'Content-Type': 'application/json',
|
139
|
+
'x-api-key': apiKey
|
140
|
+
}
|
141
|
+
})
|
142
|
+
if (response.ok) {
|
143
|
+
store = await response.json()
|
144
|
+
}
|
145
|
+
|
146
|
+
let mappedStore: any = {
|
147
|
+
accessKey: store.shop.credential.consumer_key,
|
148
|
+
accessSecret: store.shop.credential.consumer_secret,
|
149
|
+
storeURL: store.shop.credential.store_url,
|
150
|
+
platform: PLATFORM[`${store.shop.org_prefix}`]
|
151
|
+
}
|
152
|
+
|
153
|
+
const reqBody = { orderId: requestBody.native_order_id, status: requestBody.order_status }
|
154
|
+
|
155
|
+
result = await StoreAPI.updateOrder(mappedStore, reqBody)
|
156
|
+
debug(result)
|
157
|
+
|
158
|
+
context.status = 200
|
159
|
+
})
|
160
|
+
|
161
|
+
sellercraftRouter.post('/sellercraft/store/update-product-attribute', async (context, next) => {
|
162
|
+
const sellercraftChannelIntegrationConfig = config.get('sellercraftChannelIntegrationConfig', {})
|
163
|
+
const { apiKey, tokenCraftUrl } = sellercraftChannelIntegrationConfig
|
164
|
+
|
165
|
+
const xApiKey = context.headers['x-api-key']
|
166
|
+
|
167
|
+
if (apiKey !== xApiKey) context.throw(400, 'api key validation failed')
|
168
|
+
|
169
|
+
const requestBody = context.request.body
|
170
|
+
var store: any = {}
|
171
|
+
const attributes: any[] = requestBody.attributes
|
172
|
+
|
173
|
+
// https://staging-tokencraft.sellercraft.co/v1/get-shop?channel_id=4bfb3362-d57c-47f8-8781-007316d179bf&shop_id=dd9cf3b7-114f-4d74-a7e2-7b524ae086f2
|
174
|
+
var fullPath = tokenCraftUrl + '?channel_id=4bfb3362-d57c-47f8-8781-007316d179bf&shop_id=' + requestBody.shop_id
|
175
|
+
const response: any = await fetch(fullPath, {
|
176
|
+
method: 'get',
|
177
|
+
headers: {
|
178
|
+
'Content-Type': 'application/json',
|
179
|
+
'x-api-key': apiKey
|
180
|
+
}
|
181
|
+
})
|
182
|
+
if (response.ok) {
|
183
|
+
store = await response.json()
|
184
|
+
}
|
185
|
+
|
186
|
+
let mappedStore: any = {
|
187
|
+
accessKey: store.shop.credential.consumer_key,
|
188
|
+
accessSecret: store.shop.credential.consumer_secret,
|
189
|
+
storeURL: store.shop.credential.store_url,
|
190
|
+
platform: PLATFORM[`${store.shop.org_prefix}`]
|
191
|
+
}
|
192
|
+
|
193
|
+
await Promise.all(
|
194
|
+
attributes.map(async attribute => {
|
195
|
+
const attributeReqBody = { attributeId: attribute.native_attribute_id, name: attribute.attribute_key }
|
196
|
+
|
197
|
+
await StoreAPI.updateProductAttribute(mappedStore, attributeReqBody)
|
198
|
+
})
|
199
|
+
)
|
200
|
+
|
201
|
+
context.status = 200
|
202
|
+
})
|
package/server/routes.ts
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
import { sellercraftRouter } from './routers/sellercraft-router'
|
2
|
+
|
1
3
|
const debug = require('debug')('things-factory:integration-sellercraft:routes')
|
2
4
|
|
3
5
|
process.on('bootstrap-module-global-public-route' as any, (app, globalPublicRouter) => {
|
@@ -7,6 +9,8 @@ process.on('bootstrap-module-global-public-route' as any, (app, globalPublicRout
|
|
7
9
|
* ex) routes.get('/path', async(context, next) => {})
|
8
10
|
* ex) routes.post('/path', async(context, next) => {})
|
9
11
|
*/
|
12
|
+
|
13
|
+
globalPublicRouter.use(sellercraftRouter.routes(), sellercraftRouter.allowedMethods())
|
10
14
|
})
|
11
15
|
|
12
16
|
process.on('bootstrap-module-global-private-route' as any, (app, globalPrivateRouter) => {
|