YouzanYun SDK
=======

[![NPM Version](https://img.shields.io/npm/v/@waywake/youzanyun-sdk.svg?style=flat)](https://www.npmjs.com/package/@waywake/youzanyun-sdk)
[![License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md)
[![Downloads](https://img.shields.io/npm/dt/@waywake/youzanyun-sdk.svg)]()
[![Build Status](https://travis-ci.org/youzan/open-sdk-node.png)](https://travis-ci.org/youzan/open-sdk-node)
[![Coverage Status](https://coveralls.io/repos/github/youzan/open-sdk-node/badge.svg?branch=master)](https://coveralls.io/github/youzan/open-sdk-node?branch=master)

YouzanYun SDK for Node.  

## Install

```bash
npm i @waywake/youzanyun-sdk --save
```

## Usage

可参考 [examples](examples)  

### 1. 获取及刷新access_token

#### 工具型应用 获取access_token

```node
const youzanyun = require('@waywake/youzanyun-sdk');

// 获取token
const resp = youzanyun.token.get({
  authorize_type: 'authorization_code',
  client_id: 'YOUR_CLIENT_ID',
  client_secret: 'YOUR_CLIENT_SECRET',
  code: 'YOUR_CODE',
  redirect_uri: 'YOUR_REDIRECT_URI',
});
```

#### 自用型应用 获取access_token

```node
const youzanyun = require('@waywake/youzanyun-sdk');

const resp = youzanyun.token.get({
  authorize_type: 'silent',
  client_id: 'YOUR_CLIENT_ID',
  client_secret: 'YOUR_CLIENT_SECRET',
  grant_id: 110,
  refresh: true, // 是否获取refresh_token(可通过refresh_token刷新token)
});
```

#### 工具型应用及自用型应用 刷新access_token

```node
const youzanyun = require('@waywake/youzanyun-sdk');

// 刷新token
const resp = youzanyun.token.get({
  authorize_type: 'refresh_token',
  client_id: 'YOUR_CLIENT_ID',
  client_secret: 'YOUR_CLIENT_SECRET',
  refresh_token: 'YOUR_REFRESH_TOKEN',
});
```

### 2. 接口调用

#### Client 实例方式

```node
const youzanyun = require('@waywake/youzanyun-sdk');

const client = new youzanyun.Client({
  getToken: async () => 'YOUR_TOKEN',
});

const resp = await client.tradesSoldGet({
  start_created: '2026-06-01 00:00:00',
  end_created: '2026-06-01 23:59:59',
  page_no: 1,
  page_size: 20,
});
```

调用免登接口时，可通过 `authExempt` 跳过 token 注入：

```node
const resp = await client.call({
  api: 'youzan.shop.get',
  version: '3.0.0',
  authExempt: true,
});
```

#### Token方式

```node
const youzanyun = require('@waywake/youzanyun-sdk');

const token = 'f59b1a6bb04f4eqweqd1c6af315d';
const params = {tid: 'E20190509110527067500013'};

const resp = youzanyun.client.call({
  api: 'youzan.trade.get',
  version: '4.0.0',
  token,
  params,
});
```

#### 文件上传

```node
const youzanyun = require('@waywake/youzanyun-sdk');

const token = 'f59b1a6bb0asdasq613d1c6af315d';
const files = {'image': path.resolve(__dirname, './pic.png')};

const resp = youzanyun.client.call({
  api: 'youzan.materials.storage.platform.img.upload',
  version: '3.0.0',
  token,
  params: {},
  files,
});
```

#### 订单批量查询

```node
const youzanyun = require('@waywake/youzanyun-sdk');

const token = 'YOUR_TOKEN';

const resp = youzanyun.client.tradesSoldGet({
  token,
  params: {
    start_created: '2026-06-01 00:00:00',
    end_created: '2026-06-01 23:59:59',
    page_no: 1,
    page_size: 20,
  },
});
```

#### 新增接口封装

固定 API 封装统一通过 `createTokenApiCaller` 生成。新增接口时，将接口名和版本写入 `src/api-definitions.ts`，在 `src/types.ts` 增加参数类型，再用该参数类型生成对应方法。

### 3. 消息解密

```node
const youzanyun = require('@waywake/youzanyun-sdk');

const messages = 'YOUR_RECEIVED_MESSAGES';
const clientSecret = 'YOUR_CLIENT_SECRET';

const resp = youzanyun.crypto.decrypt(messages, clientSecret);
```

## License

[MIT](LICENSE)
