@things-factory/integration-marketplace 4.3.57 → 4.3.61

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.
Files changed (85) hide show
  1. package/dist-server/controllers/shopee/apis2/create-shipping-document.js +28 -0
  2. package/dist-server/controllers/shopee/apis2/create-shipping-document.js.map +1 -0
  3. package/dist-server/controllers/shopee/apis2/echo.js +19 -0
  4. package/dist-server/controllers/shopee/apis2/echo.js.map +1 -0
  5. package/dist-server/controllers/shopee/apis2/get-logistics-param.js +51 -0
  6. package/dist-server/controllers/shopee/apis2/get-logistics-param.js.map +1 -0
  7. package/dist-server/controllers/shopee/apis2/get-shipping-document-result.js +26 -0
  8. package/dist-server/controllers/shopee/apis2/get-shipping-document-result.js.map +1 -0
  9. package/dist-server/controllers/shopee/apis2/get-store-logistics.js +25 -0
  10. package/dist-server/controllers/shopee/apis2/get-store-logistics.js.map +1 -0
  11. package/dist-server/controllers/shopee/apis2/get-store-order-by-batch.js +80 -0
  12. package/dist-server/controllers/shopee/apis2/get-store-order-by-batch.js.map +1 -0
  13. package/dist-server/controllers/shopee/apis2/get-store-order-document.js +41 -0
  14. package/dist-server/controllers/shopee/apis2/get-store-order-document.js.map +1 -0
  15. package/dist-server/controllers/shopee/apis2/get-store-order-payout-dates.js +36 -0
  16. package/dist-server/controllers/shopee/apis2/get-store-order-payout-dates.js.map +1 -0
  17. package/dist-server/controllers/shopee/apis2/get-store-order-transaction-details.js +31 -0
  18. package/dist-server/controllers/shopee/apis2/get-store-order-transaction-details.js.map +1 -0
  19. package/dist-server/controllers/shopee/apis2/get-store-order.js +77 -0
  20. package/dist-server/controllers/shopee/apis2/get-store-order.js.map +1 -0
  21. package/dist-server/controllers/shopee/apis2/get-store-orders.js +37 -0
  22. package/dist-server/controllers/shopee/apis2/get-store-orders.js.map +1 -0
  23. package/dist-server/controllers/shopee/apis2/get-store-product-variations.js +21 -0
  24. package/dist-server/controllers/shopee/apis2/get-store-product-variations.js.map +1 -0
  25. package/dist-server/controllers/shopee/apis2/get-store-product.js +101 -0
  26. package/dist-server/controllers/shopee/apis2/get-store-product.js.map +1 -0
  27. package/dist-server/controllers/shopee/apis2/get-store-products.js +29 -0
  28. package/dist-server/controllers/shopee/apis2/get-store-products.js.map +1 -0
  29. package/dist-server/controllers/shopee/apis2/get-store-refund-order-details.js +40 -0
  30. package/dist-server/controllers/shopee/apis2/get-store-refund-order-details.js.map +1 -0
  31. package/dist-server/controllers/shopee/apis2/get-store-refund-orders.js +36 -0
  32. package/dist-server/controllers/shopee/apis2/get-store-refund-orders.js.map +1 -0
  33. package/dist-server/controllers/shopee/apis2/get-tracking-number.js +21 -0
  34. package/dist-server/controllers/shopee/apis2/get-tracking-number.js.map +1 -0
  35. package/dist-server/controllers/shopee/apis2/index.js +33 -0
  36. package/dist-server/controllers/shopee/apis2/index.js.map +1 -0
  37. package/dist-server/controllers/shopee/apis2/init-logistics.js +39 -0
  38. package/dist-server/controllers/shopee/apis2/init-logistics.js.map +1 -0
  39. package/dist-server/controllers/shopee/apis2/update-store-product-stock.js +30 -0
  40. package/dist-server/controllers/shopee/apis2/update-store-product-stock.js.map +1 -0
  41. package/dist-server/controllers/shopee/apis2/update-store-product-variation-stock.js +31 -0
  42. package/dist-server/controllers/shopee/apis2/update-store-product-variation-stock.js.map +1 -0
  43. package/dist-server/controllers/shopee/index.js +10 -1
  44. package/dist-server/controllers/shopee/index.js.map +1 -1
  45. package/dist-server/controllers/shopee/platform-action.js +33 -1
  46. package/dist-server/controllers/shopee/platform-action.js.map +1 -1
  47. package/dist-server/controllers/shopee/refresh-access-token.js +67 -0
  48. package/dist-server/controllers/shopee/refresh-access-token.js.map +1 -0
  49. package/dist-server/controllers/shopee/shopee.js +81 -0
  50. package/dist-server/controllers/shopee/shopee.js.map +1 -1
  51. package/dist-server/controllers/store-api/index.js +28 -0
  52. package/dist-server/controllers/store-api/index.js.map +1 -1
  53. package/dist-server/controllers/tiktok/apis/get-store-order.js +1 -1
  54. package/dist-server/controllers/tiktok/apis/get-store-order.js.map +1 -1
  55. package/dist-server/controllers/tiktok/apis/update-order-status.js +4 -4
  56. package/dist-server/controllers/tiktok/apis/update-order-status.js.map +1 -1
  57. package/package.json +4 -4
  58. package/server/controllers/shopee/apis2/create-shipping-document.ts +27 -0
  59. package/server/controllers/shopee/apis2/echo.ts +14 -0
  60. package/server/controllers/shopee/apis2/get-logistics-param.ts +66 -0
  61. package/server/controllers/shopee/apis2/get-shipping-document-result.ts +21 -0
  62. package/server/controllers/shopee/apis2/get-store-logistics.ts +23 -0
  63. package/server/controllers/shopee/apis2/get-store-order-by-batch.ts +97 -0
  64. package/server/controllers/shopee/apis2/get-store-order-document.ts +39 -0
  65. package/server/controllers/shopee/apis2/get-store-order-payout-dates.ts +33 -0
  66. package/server/controllers/shopee/apis2/get-store-order-transaction-details.ts +28 -0
  67. package/server/controllers/shopee/apis2/get-store-order.ts +93 -0
  68. package/server/controllers/shopee/apis2/get-store-orders.ts +40 -0
  69. package/server/controllers/shopee/apis2/get-store-product-variations.ts +17 -0
  70. package/server/controllers/shopee/apis2/get-store-product.ts +105 -0
  71. package/server/controllers/shopee/apis2/get-store-products.ts +28 -0
  72. package/server/controllers/shopee/apis2/get-store-refund-order-details.ts +39 -0
  73. package/server/controllers/shopee/apis2/get-store-refund-orders.ts +37 -0
  74. package/server/controllers/shopee/apis2/get-tracking-number.ts +17 -0
  75. package/server/controllers/shopee/apis2/index.ts +20 -0
  76. package/server/controllers/shopee/apis2/init-logistics.ts +39 -0
  77. package/server/controllers/shopee/apis2/update-store-product-stock.ts +26 -0
  78. package/server/controllers/shopee/apis2/update-store-product-variation-stock.ts +28 -0
  79. package/server/controllers/shopee/index.ts +11 -2
  80. package/server/controllers/shopee/platform-action.ts +36 -0
  81. package/server/controllers/shopee/refresh-access-token.ts +75 -0
  82. package/server/controllers/shopee/shopee.ts +95 -0
  83. package/server/controllers/store-api/index.ts +12 -0
  84. package/server/controllers/tiktok/apis/get-store-order.ts +5 -4
  85. package/server/controllers/tiktok/apis/update-order-status.ts +4 -4
@@ -0,0 +1,93 @@
1
+ /* https://open.shopee.com/documents/v2/v2.order.get_order_detail?module=94&type=1 */
2
+
3
+ import { StoreAPI } from '../../store-api'
4
+
5
+ export function getStoreOrder() {
6
+ return {
7
+ path: '/order/get_order_detail',
8
+ method: 'getV2',
9
+ denormalize(req) {
10
+ const { orderNo } = req
11
+
12
+ return {
13
+ order_sn_list: [orderNo],
14
+ response_optional_fields: [
15
+ 'recipient_address',
16
+ 'item_list',
17
+ 'total_amount',
18
+ 'shipping_carrier',
19
+ 'estimated_shipping_fee',
20
+ 'buyer_username',
21
+ 'actual_shipping_fee',
22
+ 'pay_time',
23
+ 'cancel_by',
24
+ 'cancel_reason',
25
+ 'actual_shipping_fee_confirmed'
26
+ ]
27
+ }
28
+ },
29
+ async normalize(res, { store }) {
30
+ let order = res.order_list[0]
31
+ let recipientAddress = order?.recipient_address
32
+ let escrowDetails: any = {}
33
+ let trackingNo = null
34
+ try {
35
+ escrowDetails = await StoreAPI.getStoreOrderTransactionDetails(store, { orderNo: order.order_sn })
36
+ } catch (e) {}
37
+ try {
38
+ trackingNo = await StoreAPI.getTrackingNumber(store, { orderNo: order.order_sn })
39
+ } catch (e) {}
40
+ const result = {
41
+ name: order.order_sn,
42
+ orderNo: order.order_sn,
43
+ docRefNo: order.order_sn,
44
+ status: order.order_status.toLowerCase(),
45
+ orderCreatedAt: new Date(order.create_time * 1000),
46
+ orderUpdatedAt: new Date(order.update_time * 1000),
47
+ totalAmount: order.total_amount,
48
+ cancelBy: order?.cancel_by,
49
+ reason: order?.cancel_reason,
50
+ recipientAddress: recipientAddress ? JSON.stringify(recipientAddress) : null,
51
+ shippingProvider: order.shipping_carrier,
52
+ itemCount: order.item_list.length,
53
+ buyerUsername: order.buyer_username,
54
+ payTime: order?.pay_time ? new Date(order.pay_time * 1000) : null,
55
+ orderItems: order.item_list.map(item => {
56
+ return {
57
+ name: item.item_id,
58
+ variationId: item.model_id == 0 ? item.item_id : item.model_id,
59
+ qty: item.model_quantity_purchased,
60
+ paidPrice: item.model_discounted_price * item.model_quantity_purchased,
61
+ orderNo: order.order_sn,
62
+ promotionType: item?.promotion_type,
63
+ promotionId: item?.promotion_id,
64
+ isWholesale: item.wholesale,
65
+ docRefNo: order.order_sn,
66
+ originalPrice: item.model_quantity_purchased * item.model_original_price,
67
+ discount:
68
+ item.model_quantity_purchased * item.model_original_price -
69
+ item.model_quantity_purchased * item.model_discounted_price
70
+ }
71
+ }),
72
+ orderShipping: {
73
+ address1: recipientAddress?.full_address,
74
+ phone1: recipientAddress?.phone,
75
+ postCode: recipientAddress?.zipcode,
76
+ city: recipientAddress?.city,
77
+ state: recipientAddress?.state,
78
+ country: recipientAddress?.region == 'MY' ? 'Malaysia' : recipientAddress?.region,
79
+ attentionTo: recipientAddress?.name,
80
+ transporter: order?.shipping_carrier,
81
+ shippingFee: parseFloat(order?.estimated_shipping_fee) || null,
82
+ actualShippingFee: order.actual_shipping_fee_confirmed
83
+ ? parseFloat(order?.actual_shipping_fee)
84
+ : parseFloat(order?.estimated_shipping_fee) || null,
85
+ trackingNo
86
+ },
87
+ trackingNo,
88
+ ...escrowDetails
89
+ }
90
+ return result
91
+ }
92
+ }
93
+ }
@@ -0,0 +1,40 @@
1
+ /* https://open.shopee.com/documents/v2/v2.order.get_order_list?module=94&type=1 */
2
+
3
+ import { StoreAPI } from '../../store-api'
4
+
5
+ export function getStoreOrders() {
6
+ return {
7
+ path: '/order/get_order_list',
8
+ method: 'getV2',
9
+ denormalize(req) {
10
+ var { pagination, fromCreatedDate, toCreatedDate, nextCursor } = req || {}
11
+ var { limit = 100 } = pagination || {}
12
+
13
+ var time_from = Math.floor(new Date(fromCreatedDate).getTime() / 1000)
14
+ var time_to = Math.floor(new Date(toCreatedDate).getTime() / 1000)
15
+ var time_range_field = 'create_time' // Available values: create_time, update_time
16
+
17
+ let payload: any = { time_from, time_to, time_range_field, page_size: limit }
18
+
19
+ if (nextCursor) {
20
+ payload.cursor = nextCursor
21
+ }
22
+
23
+ return {
24
+ ...payload
25
+ }
26
+ },
27
+ async normalize(res, { store }) {
28
+ let results = []
29
+ const orderIdList = res.order_list.map(order => {
30
+ return order.order_sn
31
+ })
32
+ while (orderIdList.length > 0) {
33
+ let splicedList = orderIdList.splice(0, orderIdList.length >= 50 ? 50 : orderIdList.length)
34
+ let result = await StoreAPI.getStoreOrderByBatch(store, { orderIdList: splicedList })
35
+ results.push(...result)
36
+ }
37
+ return { results, more: res.more, cursor: res.next_cursor }
38
+ }
39
+ }
40
+ }
@@ -0,0 +1,17 @@
1
+ /* https://open.shopee.com/documents/v2/v2.product.get_model_list?module=89&type=1 */
2
+
3
+ export function getStoreProductVariations() {
4
+ return {
5
+ path: '/product/get_model_list',
6
+ method: 'getV2',
7
+ denormalize(req) {
8
+ const { itemId } = req
9
+ return {
10
+ item_id: itemId
11
+ }
12
+ },
13
+ normalize(res) {
14
+ return res
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,105 @@
1
+ /* https://open.shopee.com/documents/v2/v2.product.get_item_base_info?module=89&type=1 */
2
+
3
+ import { StoreAPI } from '../../store-api'
4
+
5
+ export function getStoreProduct() {
6
+ return {
7
+ path: '/product/get_item_base_info',
8
+ method: 'getV2',
9
+ denormalize(req) {
10
+ return {
11
+ item_id_list: req.itemIds
12
+ }
13
+ },
14
+ async normalize(res, { store }) {
15
+ let items = res.item_list
16
+ let results = []
17
+ for (let i = 0; i < items.length; i++) {
18
+ const item = items[i]
19
+ let variations
20
+ if (item.has_model) {
21
+ variations = await StoreAPI.getStoreProductVariations(store, { itemId: item.item_id })
22
+ }
23
+ const result = {
24
+ itemId: item.item_id,
25
+ isku: item?.item_sku,
26
+ weight: item.weight,
27
+ categoryId: item.category_id,
28
+ condition: item.condition,
29
+ marketplaceStatus: item.item_status,
30
+ name: item.item_name,
31
+ description: item.description_info?.extended_description?.field_list?.find(f => f.field_type == 'text')?.text,
32
+ currency: item?.price_info ? item?.price_info[0]?.currency : undefined,
33
+ costPrice: item?.price_info ? item?.price_info[0]?.original_price : undefined,
34
+ sellPrice: item?.price_info ? item?.price_info[0]?.current_price : undefined,
35
+ qty: item?.stock_info_v2?.summary_info?.total_available_stock,
36
+ bufferQty: item?.stock_info_v2?.summary_info?.total_reserved_stock,
37
+ packageLength: item.dimension.package_length,
38
+ packageWidth: item.dimension.package_width,
39
+ packageHeight: item.dimension.package_height,
40
+ daysToShip: item.pre_order.days_to_ship,
41
+ discountId: item.promotion_id,
42
+ isPreOrder: item.pre_order.is_pre_order,
43
+ hasVariation: item.has_model,
44
+ attributes: item?.attribute_list?.map(attribute => {
45
+ return {
46
+ attributeId: attribute.attribute_id,
47
+ name: attribute.original_attribute_name,
48
+ isMandatory: attribute.is_mandatory,
49
+ originalValue: JSON.stringify(
50
+ attribute?.attribute_value_list?.map(v => {
51
+ return v.original_value_name
52
+ })
53
+ ) || ''
54
+ }
55
+ }) || [],
56
+ variations: item.has_model
57
+ ? variations.model.map(variation => {
58
+ return {
59
+ variationId: variation.model_id,
60
+ variationSku: variation.model_sku,
61
+ channelSku: variation.model_sku,
62
+ name: `${item.item_name} - ${
63
+ variations.tier_variation[0].option_list[variation.tier_index[0]].option
64
+ }${
65
+ variations.tier_variation[1]
66
+ ? ' - ' + variations.tier_variation[1].option_list[variation.tier_index[1]].option
67
+ : ''
68
+ }`,
69
+ description: item.description_info?.extended_description?.field_list?.find(
70
+ f => f.field_type == 'text'
71
+ )?.text,
72
+ qty: variation.stock_info_v2.summary_info.total_available_stock,
73
+ bufferQty: variation.stock_info_v2.summary_info.total_reserved_stock,
74
+ costPrice: variation.price_info[0].original_price,
75
+ sellPrice: variation.price_info[0].current_price,
76
+ discountId: variation.promotion_id,
77
+ marketplaceStatus: item.item_status,
78
+ primaryUnitValue: item.weight
79
+ }
80
+ })
81
+ : [
82
+ {
83
+ variationId: item.item_id,
84
+ variationSku: item.item_sku,
85
+ channelSku: item.item_sku,
86
+ name: item.item_name,
87
+ description: item.description_info?.extended_description?.field_list?.find(
88
+ f => f.field_type == 'text'
89
+ )?.text,
90
+ qty: item.stock_info_v2.summary_info.total_available_stock,
91
+ bufferQty: item.stock_info_v2.summary_info.total_reserved_stock,
92
+ costPrice: item.price_info[0].original_price,
93
+ sellPrice: item.price_info[0].current_price,
94
+ discountId: item.promotion_id,
95
+ marketplaceStatus: item.item_status,
96
+ primaryUnitValue: item.weight
97
+ }
98
+ ]
99
+ }
100
+ results.push(result)
101
+ }
102
+ return results
103
+ }
104
+ }
105
+ }
@@ -0,0 +1,28 @@
1
+ /* https://open.shopee.com/documents/v2/v2.product.get_item_list?module=89&type=1 */
2
+
3
+ import { StoreAPI } from '../../store-api'
4
+
5
+ export function getStoreProducts() {
6
+ return {
7
+ path: '/product/get_item_list',
8
+ method: 'getV2',
9
+ denormalize(req) {
10
+ var { pagination } = req || {}
11
+ var { page = 0, limit = 100 } = pagination || {}
12
+
13
+ return {
14
+ offset: page * limit,
15
+ page_size: limit,
16
+ item_status: ['NORMAL']
17
+ }
18
+ },
19
+ async normalize(res, { store }) {
20
+ const itemIds = res.item.map(product => {
21
+ return product.item_id
22
+ })
23
+
24
+ const results = await StoreAPI.getStoreProduct(store, { itemIds })
25
+ return { results, total: res.total_count }
26
+ }
27
+ }
28
+ }
@@ -0,0 +1,39 @@
1
+ /* https://open.shopee.com/documents/v2/v2.returns.get_return_detail?module=102&type=1 */
2
+
3
+ export function getStoreRefundOrderDetails() {
4
+ return {
5
+ path: '/returns/get_return_detail',
6
+ method: 'getV2',
7
+ denormalize(req) {
8
+ var { refundOrderNo } = req
9
+
10
+ return {
11
+ return_sn: refundOrderNo
12
+ }
13
+ },
14
+ async normalize(res) {
15
+ let refundItems = res.items.map(item => {
16
+ let { item_id: name, item_id: orderItemId, item_price: price, amount: qty, variation_id: variationId } = item
17
+ name = name.toString()
18
+ orderItemId = orderItemId.toString()
19
+ return {
20
+ name,
21
+ orderItemId,
22
+ price,
23
+ qty,
24
+ variationId
25
+ }
26
+ })
27
+
28
+ let results = {
29
+ name: res.return_sn.toString(),
30
+ orderNo: res.return_sn.toString(),
31
+ amount: res.refund_amount,
32
+ status: res.status,
33
+ items: refundItems
34
+ }
35
+
36
+ return results
37
+ }
38
+ }
39
+ }
@@ -0,0 +1,37 @@
1
+ /* https://open.shopee.com/documents/v2/v2.returns.get_return_list?module=102&type=1 */
2
+
3
+ import { StoreAPI } from '../../store-api'
4
+
5
+ export function getStoreRefundOrders() {
6
+ return {
7
+ path: '/returns/get_return_list',
8
+ method: 'getV2',
9
+ denormalize(req) {
10
+ var { pagination, fromDate, toDate } = req || {}
11
+ var { page = 0, limit = 100 } = pagination || {}
12
+
13
+ var create_time_from = Math.floor(new Date(fromDate).getTime() / 1000)
14
+ var create_time_to = Math.floor(new Date(toDate).getTime() / 1000)
15
+
16
+ return {
17
+ page_size: limit,
18
+ page_no: page * limit,
19
+ create_time_from,
20
+ create_time_to
21
+ }
22
+ },
23
+ async normalize(res, { store }) {
24
+ let results: any[] = []
25
+
26
+ for (var i = 0; i < res.return?.length; i++) {
27
+ const refundOrder = res.return[i]
28
+ const refundOrderNo = refundOrder.return_sn
29
+
30
+ const result = await StoreAPI.getStoreRefundOrderDetails(store, { refundOrderNo })
31
+
32
+ results.push({ ...result, originalOrderNo: refundOrder.order_sn })
33
+ }
34
+ return { results, more: res.more }
35
+ }
36
+ }
37
+ }
@@ -0,0 +1,17 @@
1
+ /* https://open.shopee.com/documents/v2/v2.logistics.get_tracking_number?module=95&type=1 */
2
+
3
+ export function getTrackingNumber() {
4
+ return {
5
+ path: '/logistics/get_tracking_number',
6
+ method: 'getV2',
7
+ denormalize(req) {
8
+ const { orderNo } = req
9
+ return {
10
+ order_sn: orderNo
11
+ }
12
+ },
13
+ normalize(res) {
14
+ return res?.tracking_number || null
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,20 @@
1
+ export * from './echo'
2
+ export * from './get-store-products'
3
+ export * from './get-store-product'
4
+ export * from './get-store-product-variations'
5
+ export * from './get-store-orders'
6
+ export * from './get-store-order'
7
+ export * from './get-store-order-by-batch'
8
+ export * from './get-store-order-transaction-details'
9
+ export * from './update-store-product-stock'
10
+ export * from './update-store-product-variation-stock'
11
+ export * from './get-store-order-payout-dates'
12
+ export * from './get-store-refund-orders'
13
+ export * from './get-store-refund-order-details'
14
+ export * from './get-store-logistics'
15
+ export * from './get-logistics-param'
16
+ export * from './get-tracking-number'
17
+ export * from './init-logistics'
18
+ export * from './create-shipping-document'
19
+ export * from './get-shipping-document-result'
20
+ export * from './get-store-order-document'
@@ -0,0 +1,39 @@
1
+ /* https://open.shopee.com/documents?module=3&type=1&id=389 */
2
+
3
+ export function initLogistics() {
4
+ return {
5
+ path: '/logistics/ship_order',
6
+ method: 'postV2',
7
+ denormalize(req) {
8
+ var { orderNo: order_sn, deliveryType } = req
9
+ let pickup = {}
10
+ let dropoff = {}
11
+ let non_integrated = {}
12
+ let args = {}
13
+
14
+ if (deliveryType?.pickup) {
15
+ var { addressId, pickupTimeId: pickup_time_id } = deliveryType.pickup
16
+ var address_id = parseInt(addressId)
17
+ pickup = { address_id, pickup_time_id }
18
+ args = { order_sn, pickup: { ...pickup } }
19
+ }
20
+
21
+ if (deliveryType?.non_integrated) {
22
+ var { trackingNo: tracking_number } = deliveryType.non_integrated
23
+ non_integrated = { tracking_number }
24
+ args = { order_sn, non_integrated: { tracking_number } }
25
+ }
26
+
27
+ if (deliveryType?.dropoff) {
28
+ var { branchId: branch_id } = deliveryType.dropoff
29
+ dropoff = { branch_id }
30
+ args = { order_sn, dropoff: { ...dropoff } }
31
+ }
32
+
33
+ return args
34
+ },
35
+ normalize(res) {
36
+ return res
37
+ }
38
+ }
39
+ }
@@ -0,0 +1,26 @@
1
+ /* https://open.shopee.com/documents/v2/v2.product.update_stock?module=89&type=1 */
2
+
3
+ export function updateStoreProductStock() {
4
+ return {
5
+ path: '/product/update_stock',
6
+ method: 'postV2',
7
+ denormalize(req) {
8
+ let data = req[0]
9
+ return {
10
+ item_id: parseInt(data.itemId),
11
+ stock_list: [
12
+ {
13
+ seller_stock: [
14
+ {
15
+ stock: data.qty
16
+ }
17
+ ]
18
+ }
19
+ ]
20
+ }
21
+ },
22
+ normalize(res) {
23
+ return res
24
+ }
25
+ }
26
+ }
@@ -0,0 +1,28 @@
1
+ /* https://open.shopee.com/documents/v2/v2.product.update_stock?module=89&type=1 */
2
+
3
+
4
+ export function updateStoreProductVariationStock() {
5
+ return {
6
+ path: '/product/update_stock',
7
+ method: 'postV2',
8
+ denormalize(req) {
9
+ let data = req[0]
10
+ return {
11
+ item_id: parseInt(data.itemId),
12
+ stock_list: [
13
+ {
14
+ model_id: parseInt(data.variationId),
15
+ seller_stock: [
16
+ {
17
+ stock: data.qty
18
+ }
19
+ ]
20
+ }
21
+ ]
22
+ }
23
+ },
24
+ normalize(res) {
25
+ return res
26
+ }
27
+ }
28
+ }
@@ -1,7 +1,16 @@
1
1
  export * from './shopee'
2
2
 
3
+ import { config } from '@things-factory/env'
3
4
  import { StoreAPI } from '../store-api'
4
- import { action } from './platform-action'
5
+ import { action, actionV2 } from './platform-action'
5
6
  import * as APIS from './apis'
7
+ import * as APISV2 from './apis2'
6
8
 
7
- StoreAPI.registerPlatform('shopee', action, APIS)
9
+ const shopeeConfig = config.get('marketplaceIntegrationShopee', {})
10
+ const { v2 } = shopeeConfig
11
+
12
+ if (v2) {
13
+ StoreAPI.registerPlatform('shopee', actionV2, APISV2)
14
+ } else {
15
+ StoreAPI.registerPlatform('shopee', action, APIS)
16
+ }
@@ -1,9 +1,45 @@
1
1
  import { Shopee } from './shopee'
2
2
 
3
3
  import { config } from '@things-factory/env'
4
+ import { refreshAccessToken } from './refresh-access-token'
4
5
  const shopeeConfig = config.get('marketplaceIntegrationShopee', {})
5
6
  const { partnerId, partnerKey, isUAT } = shopeeConfig
6
7
 
8
+ export const actionV2 = async ({ store, path, request, method = 'post' }) => {
9
+ let response = await _action({ store, path, request, method })
10
+ if (response.error) {
11
+ if (response.error == 'error_auth') {
12
+ try {
13
+ const { accessToken } = await refreshAccessToken(store.id, store.storeId, store.refreshToken, store.accessToken)
14
+ store = {
15
+ ...store,
16
+ accessToken
17
+ }
18
+ response = await _action({ store, path, request, method })
19
+ } catch (e) {
20
+ throw e
21
+ }
22
+ } else {
23
+ throw response
24
+ }
25
+ }
26
+ return response.response || response
27
+ }
28
+
29
+ const _action = async ({ store, path, request, method = 'post' }) => {
30
+ const client = new Shopee({
31
+ isUAT: isUAT,
32
+ shopid: Number(store.storeId),
33
+ partner_id: partnerId,
34
+ partner_key: partnerKey,
35
+ access_token: store.accessToken
36
+ })
37
+
38
+ var response = await client[method](path, request)
39
+
40
+ return response
41
+ }
42
+
7
43
  export const action = async ({ store, path, request }) => {
8
44
  const client = new Shopee({
9
45
  isUAT: isUAT,
@@ -0,0 +1,75 @@
1
+ import crypto from 'crypto'
2
+ import fetch from 'node-fetch'
3
+ import { createQueryBuilder, getRepository } from 'typeorm'
4
+ import { config, logger } from '@things-factory/env'
5
+ import { MarketplaceStore } from '../../entities'
6
+
7
+ const shopeeConfig = config.get('marketplaceIntegrationShopee', {})
8
+ const { partnerId, partnerKey, isUAT } = shopeeConfig
9
+ const refreshPath = '/auth/access_token/get'
10
+
11
+ export const refreshAccessToken = async (store_uuid, shop_id, refresh_token, old_access_token) => {
12
+ let marketplaceStore: MarketplaceStore = await getRepository(MarketplaceStore)
13
+ .createQueryBuilder('ms')
14
+ .where('ms.id = :id', { id: store_uuid })
15
+ .getOne()
16
+
17
+ if (old_access_token != marketplaceStore.accessToken) {
18
+ return {
19
+ accessToken: marketplaceStore.accessToken
20
+ }
21
+ }
22
+
23
+ const timestamp = Math.floor(Date.now() / 1000)
24
+ const sign = crypto
25
+ .createHmac('sha256', partnerKey)
26
+ .update(partnerId + '/api/v2' + refreshPath + timestamp)
27
+ .digest('hex')
28
+
29
+ const auth = {
30
+ partner_id: partnerId,
31
+ sign: sign,
32
+ timestamp: timestamp
33
+ }
34
+
35
+ const qs = Object.entries(auth)
36
+ .map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`)
37
+ .join('&')
38
+
39
+ const data = {
40
+ refresh_token: refresh_token,
41
+ partner_id: partnerId,
42
+ shop_id: parseInt(shop_id)
43
+ }
44
+
45
+ const jsondata = JSON.stringify(data)
46
+
47
+ const response = await fetch(`${getAuthUrl()}?${qs}`, {
48
+ method: 'post',
49
+ body: jsondata
50
+ })
51
+
52
+ if (!response.ok) {
53
+ throw 'Failed to get response to refresh Shopee access token'
54
+ }
55
+
56
+ const result = await response.json()
57
+
58
+ if (result.error) {
59
+ logger.error(`Failed to refresh Shopee token: ${result.error} - shop ID (${shop_id})`)
60
+ throw result.error
61
+ }
62
+
63
+ const tokens = {
64
+ accessToken: result.access_token, // expires in 4 hours
65
+ refreshToken: result.refresh_token // expires in 30 days
66
+ }
67
+
68
+ await createQueryBuilder().update(MarketplaceStore).set(tokens).where('id = :id', { id: store_uuid }).execute()
69
+
70
+ return tokens
71
+ }
72
+
73
+ function getAuthUrl() {
74
+ return `https://partner${isUAT ? '.test-stable' : ''}.shopeemobile.com/api/v2${refreshPath}`
75
+ }