util = require 'util'
url = require 'url'
Promise = require 'bluebird'
request = Promise.promisifyAll require 'request'
errors = require './errors'
debug = (require './debug') 'merchant'
util = require 'util'
url = require 'url'
Promise = require 'bluebird'
request = Promise.promisifyAll require 'request'
errors = require './errors'
debug = (require './debug') 'merchant'
Merchant use for invoke Wish Merchant API. For more infomation please visit The Wish merchant platform.
module.exports = class Merchant
Create a new instance
new Merchant({ key, [sandbox], [timeout] })
Arguments
true
will invoke sandbox api for test. Default false
.(20 * 1000)
.Return a new instance.
Example
var api = new Merchant({key: 'your api key here'});
constructor: (options) ->
{ @key, @sandbox, @timeout } = options or {}
@sandbox ?= false
@timeout ?= 20 * 1000
@baseUrl = if @sandbox
'https://sandbox.merchant.wish.com/api/v1'
else
'https://merchant.wish.com/api/v1'
Format json result to flatten javascript object.
Example
Before { success:'True'} After { success: true }
Before {Product: {name: 'Fancy toy', tags: [{Tag: {id: 'toy', name: 'toy'}}] variants: [{Variant: {price:'10.5', enable:'True' }}]}} After { name: 'Fancy toy' tags: [{ id: 'toy', name: 'toy' }] variants: [{ price: 10.5, enable: true }] }
Before {Order: {ShippingDetail: {country: ‘US’}, order_time:‘2013-12-06T20:20:20’}} After { country: ‘US’, order_time: new Date(…) }
format: (json) ->
if typeof json.success is 'string'
json.success = json.success is 'True'
return json
if util.isArray json
return json.map (item) => @format item
if json.Product
json = json.Product
json.is_promoted = json.is_promoted is 'True' if json.is_promoted
[ 'number_saves', 'number_sold' ].map (key) ->
json[key] = Number json[key] if json[key]
if json.Variant
json = json.Variant
json.enabled = json.enabled is 'True' if json.enabled
[ 'msrp', 'inventory', 'price', 'shipping' ].map (key) ->
json[key] = Number json[key] if json[key]
if json.Order
json = json.Order
if json.ShippingDetail
json[key] = value for key, value of json.ShippingDetail
delete json.ShippingDetail
[ 'order_total', 'quantity', 'price', 'cost',
'shipping', 'shipping_cost', 'days_to_fulfill' ].map (key) ->
json[key] = Number json[key] if json[key]
[ 'last_updated', 'order_time' ].map (key) ->
json[key] = new Date json[key] if json[key]
json = json.Tag or json
if json.tags
json.tags = @format json.tags
if json.auto_tags
json.auto_tags = @format json.auto_tags
if json.variants
json.variants = @format json.variants
json
Append path and query to base url.
url: (path, query) ->
uri = url.parse @baseUrl
uri.pathname += path
uri.path = ''
uri.query ?= {}
uri.query[key] = value for key, value of query
url.format uri
Handle request. catch error.
handle: (promise) ->
promise
.then ([ res, body ]) ->
debug body
{ code } = body
if code is 0
body
else if code
throw errors.wish body
else
throw new errors.ServerError response: body
Request GET.
get: (path, query = {}) ->
return Promise.reject new errors.ParamMissingError if not @key
query.key = @key
uri = @url path, query
debug 'GET', uri
@handle request.getAsync uri,
json: true
timeout: @timeout
Request POST
post: (path, form = {}) ->
return Promise.reject new errors.ParamMissingError if not @key
uri = @url path
form.key = @key
debug 'POST', uri, form
@handle request.postAsync uri,
json: true
timeout: @timeout
form: form
authTest( [callback] )
Test if api key is valid.
return {success: true}
if success. otherwise error.
authTest: (callback) ->
@authTestJSON()
.then (json) => @format json.data
.nodeify callback
authTestJSON: (callback) ->
@get '/auth_test'
.nodeify callback
product( id, [callback] )
Retrieve the details about a product which exists on the Wish platform.
Arguments
Return product data.
product: (id, callback) ->
@productJSON id
.then (json) => @format json.data
.nodeify callback
productJSON: (id, callback) ->
id = id.id if id.id
@get '/product', id: id
.nodeify callback
products( [start], [limit], [callback] )
List all Products
Arguments
Return an products array.
products: (start, limit, callback) ->
@productsJSON start, limit
.then (json) => @format json.data
.nodeify callback
productsJSON: (start = 0, limit = 50, callback) ->
@get '/product/multi-get',
start: start
limit: limit
.nodeify callback
createProduct( product, [callback] )
Create a Product
Arguments
createProduct: (product, callback) ->
@createProductJSON product
.then (json) => @format json.data
.nodeify callback
createProductJSON: (product, callback) ->
@post '/product/add', product
.nodeify(callback)
updateProduct( product, [callback] )
Update a Product
Arguments
updateProduct: (product, callback) ->
@updateProductJSON product
.then (json) => json.data
.nodeify callback
updateProductJSON: (product, callback) ->
@post '/product/update', product
.nodeify(callback)
enableProduct( {id/parent_sku}, [callback] )`
Enable a Product
Arguments
enableProduct: (args, callback) ->
@enableProductJSON args
.then (json) => json.data
.nodeify callback
enableProductJSON: (args, callback) ->
@post '/product/enable', args
.nodeify(callback)
disableProduct: (args, callback) ->
@disableProductJSON args
.then (json) => json.data
.nodeify callback
disableProductJSON: (args, callback) ->
@post '/product/disable', args
.nodeify(callback)
variant( sku, [callback] )
Retrieves the details of an existing product variation.
Be careful: SKU is case sensitive.
Arguments
variant: (sku, callback) ->
@variantJSON sku
.then (json) => @format json.data
.nodeify callback
variantJSON: (sku, callback) ->
@get '/variant', sku: sku
.nodeify callback
variants( [start], [limit], [callback] )
List all Product Variations
Be careful: The limit is product count limit. Not variants limit.
Arguments
variants: (start, limit, callback) ->
@variantsJSON start, limit
.then (json) => @format json.data
.nodeify callback
variantsJSON: (start = 0, limit = 50, callback) ->
@get '/variant/multi-get',
start: start
limit: limit
.nodeify callback
createVariant( variant, [callback] )
Create a Product Variation
Arguments
createVariant: (variant, callback) ->
@createVariantJSON variant
.then (json) => @format json.data
.nodeify callback
createVariantJSON: (variant, callback) ->
@post '/variant/add', variant
.nodeify(callback)
updateVariant( variant, [callback] )
Update a Product Variation
Arguments
updateVariant: (variant, callback) ->
@updateVariantJSON variant
.then (json) => json.data
.nodeify callback
updateVariantJSON: (variant, callback) ->
@post '/variant/update', variant
.nodeify(callback)
enableVariant( sku, [callback] )
Enable a Product Variation
Arguments
enableVariant: (sku, callback) ->
@enableVariantJSON sku
.then (json) => json.data
.nodeify callback
enableVariantJSON: (sku, callback) ->
@post '/variant/enable', sku: sku
.nodeify(callback)
disableVariant: (sku, callback) ->
@disableVariantJSON sku
.then (json) => json.data
.nodeify callback
disableVariantJSON: (sku, callback) ->
@post '/variant/disable', sku: sku
.nodeify(callback)
order( id, [callback] )
Retrieves the details of an existing order.
Arguments
order: (id, callback) ->
@orderJSON id
.then (json) => @format json.data
.nodeify callback
orderJSON: (id, callback) ->
@get '/order', id: id
.nodeify callback
orders( [start], [limit], [since], [callback] )
Retrieve Recently Changed Orders
Arguments
Jan 20th, 2014
is 2014-01-20
, Jan 20th, 2014 20:10:20
is 2014-01-20T20:10:20
. orders: (start, limit, since, callback) ->
@ordersJSON start, limit, since
.then (json) => @format json.data
.nodeify callback
ordersJSON: (start = 0, limit = 50, since = '', callback) ->
@get '/order/multi-get',
start: start
limit: limit
since: since
.nodeify callback
unfullfiledOrders( [start], [limit], [since], [callback] )
Retrieve Unfulfilled Orders
Arguments same as orders
unfullfiledOrders: (start, limit, since, callback) ->
@unfullfiledOrdersJSON start, limit, since
.then (json) => @format json.data
.nodeify callback
unfullfiledOrdersJSON: (start = 0, limit = 50, since = '', callback) ->
@get '/order/get-fulfill',
start: start
limit: limit
since: since
.nodeify callback
fulfillOrder( order, [callback] )
Fulfill an order
Arguments
fulfillOrder: (order, callback) ->
@fulfillOrderJSON order
.then (json) => @format json.data
.nodeify callback
fulfillOrderJSON: (order, callback) ->
@post '/order/fulfill-one', order
.nodeify(callback)
refundOrder( args, [callback] )
Refund/Cancel an order
Arguments
refundOrder: (args, callback) ->
@refundOrderJSON args
.then (json) => @format json.data
.nodeify callback
cancelOrder: (args, callback) ->
@refundOrder args, callback
refundOrderJSON: (args, callback) ->
@post '/order/refund', args
.nodeify(callback)
modifyOrder( args, [callback] )
Modify Tracking of a Shipped Order
Arguments
modifyOrder: (args, callback) ->
@modifyOrderJSON args
.then (json) => @format json.data
.nodeify callback
modifyOrderJSON: (args, callback) ->
@post '/order/modify-tracking', args
.nodeify(callback)