├── .gitignore ├── .travis.yml ├── CHANGE_LOG.md ├── LICENSE ├── README-EN.md ├── README.md ├── docs ├── en-US │ ├── basic.md │ ├── card.md │ ├── code.md │ ├── createcard.md │ ├── createshop.md │ ├── index.md │ ├── modifycard.md │ └── shop.md └── zh-CN │ ├── basic.md │ ├── card.md │ ├── code.md │ ├── createcard.md │ ├── createshop.md │ ├── index.md │ ├── modifycard.md │ └── shop.md ├── index.js ├── libs ├── api │ ├── basic.js │ ├── card.js │ ├── code.js │ └── shop.js ├── config.js ├── index.js └── utils │ ├── encrypt.js │ ├── errors.js │ └── request.js ├── package.json └── test └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/* -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.10" 4 | - "0.12" 5 | - "io.js" -------------------------------------------------------------------------------- /CHANGE_LOG.md: -------------------------------------------------------------------------------- 1 | 微信卡券Nodejs版API更新日志 2 | ======================== 3 | 4 | ### V1.0.7 5 | 6 | - 支持方法提供access token 7 | 8 | ### V1.0.6 9 | 10 | - 增加支持创建自定义Code卡券和核销自定义code卡券 11 | - 增加支持指定领取卡券用户接口 12 | - 增加修改卡券Code接口 13 | - 修复config异常 14 | 15 | ### V1.0.5 16 | 17 | - 增加获取JSAPI Ticket方法 18 | - 增加支持创建自定义Code卡券和核销自定义code卡券 19 | - 增加支持指定领取卡券用户接口 20 | 21 | ### V1.0.4 22 | 23 | - 增加JSAPI计算签名方法 24 | 25 | ### V1.0.3 26 | 27 | - 修正了获取Wechat Card TICKET获取不正常的bug 28 | 29 | ### V1.0.2 30 | 31 | - 增加了模块各部分功能的文档(中文/英文) 32 | 33 | ### V1.0.1 34 | 35 | - 修复了AccessToken托管的bug 36 | - 提供了模块接入文档 37 | 38 | ### V1.0.0 39 | 40 | - 支持`礼品券(GIFT)`, `现金券(CASH)`, `折扣券(DISCOUNT)`, `团购券(GROUPON)`, `红包(LUCK_MONEY)`和`通用券(GENERAL_COUPON)` 41 | - 支持以上类型卡券的`创建`, `投放`, `使用`, `修改`, `删除`和`查询`等操作 42 | - 仅支持以上类型卡券非自定义CardId和Code卡券操作 43 | - 支持通过第三方提供AccessToken -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README-EN.md: -------------------------------------------------------------------------------- 1 | wechat-card 2 | ======================== 3 | 4 | > Warning: this repo is too old that compared with the wechat official api, Please do the full test before use in production environment. 5 | 6 | [![NPM](https://nodei.co/npm/wechat-card.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/wechat-card/) 7 | 8 | [![Build Status](https://travis-ci.org/kenticny/wechat-card.svg?branch=master)](https://travis-ci.org/kenticny/wechat-card) 9 | 10 | Wechat Card API for NodeJS 11 | 12 | > **Just support card type: CASH, DISCOUNT, GIFT, GROUPON, GENERAL_COUPON, LUCK_MONEY in this verison** 13 | 14 | ## Install 15 | 16 | npm install wechat-card 17 | 18 | ## Usage 19 | 20 | ```javascript 21 | var wxCard = require("wechat-card"); 22 | 23 | wxCard.setConfig({ 24 | appId: "YOUR APP ID", 25 | appSecret: "YOUR APP SECRET" 26 | 27 | // or config access token service 28 | // accessTokenService: "http://url" 29 | 30 | }); 31 | 32 | wxCard.card.createCard(cardinfo, function(error, cardid) { 33 | // do something 34 | }); 35 | ``` 36 | 37 | ## Documentation 38 | 39 | [Wechat Card API](docs/en-US/index.md) 40 | 41 | ## License 42 | 43 | MIT 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | wechat-card 2 | ======================== 3 | 4 | > 警告:本库使用接口已经与微信当前接口版本相差过多,不能保证可以正常使用,请在正式使用前对各个功能进行严格测试,确认无误后再生产环境使用。由于个人原因导致本库无法继续维护,深感抱歉。 5 | 6 | [![NPM](https://nodei.co/npm/wechat-card.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/wechat-card/) 7 | 8 | [![Build Status](https://travis-ci.org/kenticny/wechat-card.svg?branch=master)](https://travis-ci.org/kenticny/wechat-card) 9 | 10 | #### [English ReadMe](README-EN.md) 11 | 12 | 微信卡券API接口NODEJS版 13 | 14 | > 目前版本仅支持以下几种类型的卡券: `CASH`, `GIFT`, `GROUPON`, `DISCOUNT`, `GENERAL_COUPON`, `LUCK_MONEY`。 15 | 16 | 我们会在之后的版本陆续推出这些功能的支持。 17 | 18 | 19 | ## 安装 20 | 21 | npm install wechat-card 22 | 23 | ## 使用方法 24 | 25 | ```javascript 26 | var wxCard = require("wechat-card"); 27 | 28 | wxCard.setConfig({ 29 | appId: "YOUR APP ID", 30 | appSecret: "YOUR APP SECRET" 31 | 32 | // 可以配置提供access token的服务 33 | // accessTokenService: "http://url" 34 | 35 | }); 36 | 37 | wxCard.card.createCard(cardinfo, function(error, cardid) { 38 | // do something 39 | }); 40 | ``` 41 | 42 | ## 文档 43 | 44 | [卡券详细文档](docs/zh-CN/index.md) 45 | 46 | ## License 47 | 48 | MIT 49 | -------------------------------------------------------------------------------- /docs/en-US/basic.md: -------------------------------------------------------------------------------- 1 | Wechat Basic Document 2 | ====================== 3 | 4 | ### Guide 5 | 6 | - [getAccessToken(callback)](#getaccesstokencallback) 7 | 8 | - [getApiTicket(callback)](#getapiticketcallback) 9 | 10 | - [getColorList(callback)](#getcolorlistcallback) 11 | 12 | - [setWhiteListWithUsername(usernames, callback)](#setwhitelistwithusernameusernames-callback) 13 | 14 | - [setWhiteListWithOpenId(openids, callback)](#setwhitelistwithopenidopenids-callback) 15 | 16 | - [getSignature(data, callback)](#getsignaturedata-callback) 17 | 18 | - [getSignatureSync(data)](#getsignaturesyncdata) 19 | 20 | ====== 21 | 22 | ### Document 23 | 24 | ##### getAccessToken(callback) 25 | 26 | Get the current access token. 27 | 28 | - **parameters:** 29 | 30 | - ***callback***(error, accessToken): `Function` 31 | 32 | ***error***: `Object` contains error code and error message 33 | 34 | ***accessToken***: `String` the current access token 35 | 36 | - **example:** 37 | 38 | ```javascript 39 | wxCard.basic.getAccessToken(function(err, accessToken) { 40 | // do something ... 41 | }); 42 | ``` 43 | 44 | ====== 45 | 46 | ##### getApiTicket(callback) 47 | 48 | Get api ticket, for Wechat Card JSAPI signature. 49 | 50 | - **parameters:** 51 | 52 | - ***callback***(error, ticket): `Function` 53 | 54 | ***error***: `Object` contains error code and error message 55 | 56 | ***ticket***: `String` the current js api ticket 57 | 58 | - **example:** 59 | 60 | ```javascript 61 | wxCard.basic.getApiTicket(function(err, ticket) { 62 | // do something ... 63 | }); 64 | ``` 65 | 66 | ====== 67 | 68 | 69 | ##### getColorList(callback) 70 | 71 | Get wechat card background colors, you have to use color name when create card. 72 | 73 | - **parameters:** 74 | 75 | - ***callback***(error, colors): `Function` 76 | 77 | ***error***: `Object` contains error code and error message 78 | 79 | ***colors***: `Array` color list, contains color name and color value 80 | 81 | - **example:** 82 | 83 | ```javascript 84 | wxCard.basic.getColorList(function(err, colors) { 85 | // colors format: [{name: 'Color010', value: '#55bd47' }, ...] 86 | }); 87 | ``` 88 | 89 | ====== 90 | 91 | 92 | ##### setWhiteListWithUsername(usernames, callback) 93 | 94 | Set whitelist with wechat username. The wechat username in whitelist can get code of card when card does not pass the audit. 95 | 96 | - **parameters:** 97 | 98 | - ***usernames***: `Array` 99 | 100 | the array of wechat username. (not phone number, not QQ number) 101 | 102 | - ***callback***(error): `Function` 103 | 104 | ***error***: `Object` contains error code and error message 105 | 106 | - **example:** 107 | 108 | ```javascript 109 | var usernames = ['kenticny']; 110 | wxCard.basic.setWhiteListWithUsername(usernames, function(err) { 111 | // do something ... 112 | }); 113 | ``` 114 | 115 | ====== 116 | 117 | 118 | ##### setWhiteListWithOpenId(openids, callback) 119 | 120 | Set whitelist with wechat openID. see `setWhiteListWithUsername` 121 | 122 | - **parameters:** 123 | 124 | - ***openids***: `Array` 125 | 126 | the array of wechat openid 127 | 128 | - ***callback***(error): `Function` 129 | 130 | ***error***: `Object` contains error code and error message 131 | 132 | - **example:** 133 | 134 | ```javascript 135 | // just a demo, doesn't exist in fact 136 | var openids = ['c8_tmrjPEct3_9seVe8eTPSOdL3N']; 137 | 138 | wxCard.basic.setWhiteListWithOpenId(openids, function(err) { 139 | // do something ... 140 | }); 141 | ``` 142 | 143 | ====== 144 | 145 | 146 | ##### getSignature(data, callback) 147 | 148 | Get Signature. 149 | 150 | - **parameters:** 151 | 152 | - ***data***: `Array` 153 | 154 | the array of data to be encrypted. 155 | 156 | - ***callback***(error, signature): `Function` 157 | 158 | ***error***: `Object` contains error code and error message 159 | 160 | ***signature***: `String` the signature 161 | 162 | - **example:** 163 | 164 | ```javascript 165 | var data = ['ApiTicket', 'CardId', 'timestamp']; 166 | wxCard.basic.getSignature(data, function(err, signature) { 167 | // do something ... 168 | }); 169 | ``` 170 | 171 | 172 | ====== 173 | 174 | ##### getSignatureSync(data) 175 | 176 | Get Signature Synchronous. 177 | 178 | - **paramters:** 179 | 180 | - ***data***: `Array` 181 | 182 | the array of data to be encrypted. 183 | 184 | - **return:** 185 | 186 | - ***signature***: `String` 187 | 188 | - **example:** 189 | 190 | ```javascript 191 | var data = ['ApiTicket', 'CardId', 'timestamp']; 192 | var signature = wxCard.basic.getSignatureSync(data); 193 | ``` -------------------------------------------------------------------------------- /docs/en-US/card.md: -------------------------------------------------------------------------------- 1 | Wechat Card Document 2 | ====================== 3 | 4 | ### Guide 5 | 6 | - [createCard(card, callback)](#createcardcard-callback) 7 | 8 | - [getCardDetail(cardId, callback)](#getcarddetailcardid-callback) 9 | 10 | - [getCardIdList(offset, count, callback)](#getcardidlistoffset-count-callback) 11 | 12 | - [modifyCard(card, callback)](#modifycardcard-callback) 13 | 14 | - [deleteCard(cardId, callback)](#deletecardcardid-callback) 15 | 16 | - [modifyCardStock(cardId, number, callback)](#modifycardstockcardid-number-callback) 17 | 18 | - [createCardQRCode(cardId, options, callback)](#createcardqrcodecardid-options-callback) 19 | 20 | 21 | ### Document 22 | 23 | ##### createCard(card, callback) 24 | 25 | Create a new card. You need to wait until the audit is completed. During this period, you can set whitelist to test the card. 26 | 27 | - **parameters:** 28 | 29 | - ***card***: `Object` 30 | 31 | the card information. contains card type, base info, special info. See [Card Fields](createcard.md) 32 | 33 | - ***callback***(error, cardId): `Function` 34 | 35 | ***error***: `Object` contains error code and error message 36 | 37 | ***cardId***: `String` the id of card. 38 | 39 | - **example:** 40 | 41 | ```javascript 42 | var card = { 43 | card_type: "DISCOUNT", 44 | base_info: { 45 | // ... 46 | }, 47 | special_info: { 48 | // ... 49 | } 50 | }; 51 | 52 | wxCard.card.createCard(card, function(err, cardId) { 53 | // do something ... 54 | }); 55 | ``` 56 | 57 | ====== 58 | 59 | 60 | ##### getCardDetail(cardId, callback) 61 | 62 | Get card details by card id. 63 | 64 | - **parameters:** 65 | 66 | - ***cardId***: `String` 67 | 68 | the id of card. 69 | 70 | - ***callback***(error, card): `Function` 71 | 72 | ***error***: `Object` contains error code and error message 73 | 74 | ***card***: `Object` the card details. 75 | 76 | - **example:** 77 | 78 | ```javascript 79 | 80 | // this card id just a demo, does not exist in fact 81 | var cardId = "p1Pj9jr90_SQRaVqYI239Ka1erkI"; 82 | 83 | wxCard.card.getCardDetail(cardId, function(err, card) { 84 | // do something ... 85 | }); 86 | ``` 87 | 88 | ====== 89 | 90 | 91 | ##### getCardIdList(offset, count, callback) 92 | 93 | Get the list of card id. Don't contains card details, just id. 94 | 95 | - **parameters:** 96 | 97 | - ***offset***: `Number` 98 | 99 | the coordinates of the first element. the list start at offset. 100 | 101 | - ***count***: `Number` 102 | 103 | the size of list. 104 | 105 | - ***callback***(error, ids): `Function` 106 | 107 | ***error***: `Object` contains error code and error message. 108 | 109 | ***ids***: `Array` the id list. 110 | 111 | 112 | - **example:** 113 | 114 | ```javascript 115 | wxCard.card.getCardIdList(0, 10, function(err, ids) { 116 | // do something ... 117 | }); 118 | ``` 119 | 120 | ====== 121 | 122 | 123 | ##### modifyCard(card, callback) 124 | 125 | Modify the part card base info. 126 | 127 | - **parameters:** 128 | 129 | - ***card***: `Object` 130 | 131 | the new card information. See [Modify Card Fields](modifycard.md) 132 | 133 | - ***callback***(error): `Function` 134 | 135 | ***error***: `Object` contains error code and error message. 136 | 137 | - **example:** 138 | 139 | ```javascript 140 | 141 | // this card id does not exist in fact 142 | var card = { 143 | card_id: "p1Pj9jr90_SQRaVqYI239Ka1erkI", 144 | base_info: { 145 | // .. some of base info 146 | }, 147 | special_info: { 148 | // ... 149 | } 150 | }; 151 | 152 | wxCard.card.modifyCard(card, function(err) { 153 | // do something ... 154 | }); 155 | ``` 156 | 157 | ====== 158 | 159 | 160 | ##### deleteCard(cardId, callback) 161 | 162 | Delete a card by card id. 163 | 164 | - **parameters:** 165 | 166 | - ***cardId***: `String` 167 | 168 | the id of card. 169 | 170 | - ***callback***(error): `Function` 171 | 172 | ***error***: `Object` contains error code and error message. 173 | 174 | - **example:** 175 | 176 | ```javascript 177 | // this card id just a demo, does not exist in fact 178 | var cardId = "p1Pj9jr90_SQRaVqYI239Ka1erkI"; 179 | 180 | wxCard.card.deleteCard(cardId, function(err) { 181 | // do something .. 182 | }); 183 | ``` 184 | 185 | ====== 186 | 187 | 188 | ##### modifyCardStock(cardId, number, callback) 189 | 190 | Modify card stock(base_info.sku.quantity). 191 | 192 | - **parameters:** 193 | 194 | - ***cardId***: `String` 195 | 196 | the id of card. 197 | 198 | - ***number***: `Number` 199 | 200 | the stock value to be modified. the positive number indicates increase, and the negative number indicates reduce 201 | 202 | - ***callback***(error): `Function` 203 | 204 | ***error***: `Object` contains error code and error message 205 | 206 | 207 | - **example:** 208 | 209 | ```javascript 210 | // this card id just a demo, does not exist in fact 211 | var cardId = "p1Pj9jr90_SQRaVqYI239Ka1erkI"; 212 | 213 | // reduce 214 | wxCard.card.modifyCardStock(cardId, -10, function(err) { 215 | // do something ... 216 | }); 217 | 218 | // increase 219 | wxCard.card.modifyCardStock(cardId, 10, function(err) { 220 | // do something ... 221 | }); 222 | ``` 223 | 224 | ====== 225 | 226 | 227 | ##### createCardQRCode(cardId, options, callback) 228 | 229 | Create a QR code to collcet code of card. 230 | 231 | - **parameters:** 232 | 233 | - ***cardId***: `String` 234 | 235 | the id of card 236 | 237 | - ***options***: `Object(Optional)` 238 | 239 | the options of qrcode. 240 | 241 | options: 242 | 243 | - expire_seconds: `Number` the expiration time(second). 244 | 245 | - is_unique_code: `Boolean` disposable qrcode. 246 | 247 | - outer_id: `Number` the custom flag. 248 | 249 | - balance: `Number` the balance of LUCK_MONEY card. just work in `LUCK_MONEY`. 250 | 251 | - code: `String` the code of card. custom code required. 252 | 253 | - openid: `String` the specified user openid. bind openid required. 254 | 255 | - ***callback***(error, url): `Function` 256 | 257 | ***error***: `Object` contains error code and error message 258 | 259 | ***url***: `String` the url of qrcode 260 | 261 | - **example:** 262 | 263 | ```javascript 264 | // this card id just a demo, does not exist in fact 265 | var cardId = "p1Pj9jr90_SQRaVqYI239Ka1erkI"; 266 | 267 | var options = { 268 | expire_seconds: 1200, 269 | is_unique_code: true, 270 | outer_id: 1 271 | }; 272 | 273 | wxCard.card.createCardQRCode(cardId, options, function(err, url) { 274 | // do something ... 275 | }); 276 | ``` 277 | 278 | -------------------------------------------------------------------------------- /docs/en-US/code.md: -------------------------------------------------------------------------------- 1 | Wechat Code Document 2 | ====================== 3 | 4 | ### Guide 5 | 6 | - [consumeCode(code, callback)](#consumecodecode-callback) 7 | 8 | - [getCodeDetail(code, callback)](#getcodedetailcode-callback) 9 | 10 | - [modifyCode(code, cardid, newcode, callback)](#modifycodecode-cardid-newcode-callback) 11 | 12 | - [codeDecrypt(encryptCode, callback)](#codedecryptencryptcode-callback) 13 | 14 | - [setCodeExpire(code, callback)](#setcodeexpirecode-callback) 15 | 16 | - [modifyLuckMoneyBalance(code, balance, callback)](#modifyluckmoneybalancecode-balance-callback) 17 | 18 | 19 | ### Document 20 | 21 | ##### consumeCode(code, [cardId ], callback) 22 | 23 | Consume a code of card. 24 | 25 | - **parameters:** 26 | 27 | - ***code***: `String` 28 | 29 | the code of card 30 | 31 | - ***cardId***: `String(Optional)` 32 | 33 | card id. (Custom code required) 34 | 35 | - ***callback***(error, consumeInfo): `Function` 36 | 37 | ***error***: `Object` contains error code and error message 38 | 39 | ***consumeInfo***: `Object` contains openid and card id 40 | 41 | - **example:** 42 | 43 | ```javascript 44 | // this code does not exist in fact, just a demo 45 | var code = "882077290937"; 46 | 47 | wxCard.code.consumeCode(code, function(err, consumeInfo) { 48 | // do something ... 49 | }); 50 | ``` 51 | 52 | ====== 53 | 54 | 55 | ##### getCodeDetail(code, callback) 56 | 57 | Get code details. 58 | 59 | - **parameters:** 60 | 61 | - ***code***: `String` 62 | 63 | the code of card 64 | 65 | - ***callback***(error, details): `Function` 66 | 67 | ***error***: `Object` contains error code and error message 68 | 69 | ***details***: `Object` contains openid, card id, and times 70 | 71 | 72 | - **example:** 73 | 74 | ```javascript 75 | // this code does not exist in fact, just a demo 76 | var code = "882077290937"; 77 | 78 | wxCard.code.getCodeDetail(code, function(err, details) { 79 | // do something ... 80 | }); 81 | 82 | ``` 83 | 84 | ====== 85 | 86 | ##### modifyCode(code, cardid, newcode, callback) 87 | 88 | modify the code 89 | 90 | Scene:you should modify the code when the code give to friend. 91 | 92 | - **parameters:** 93 | 94 | - ***code***: `String` 95 | 96 | original code 97 | 98 | - ***cardid***: `String` 99 | 100 | the card id of code 101 | 102 | - ***newcode***: `String` 103 | 104 | new code 105 | 106 | - ***callback***(error): `Function` 107 | 108 | ***error***: `Object` contains error code and error message 109 | 110 | - **example:** 111 | 112 | ```javascript 113 | 114 | var code = "882077290937"; 115 | var cardId = "p1Pj9jr90_SQRaVqYI239Ka1erkI"; 116 | var newcode = "883920048827"; 117 | 118 | wxCard.code.modifyCode(code, cardId, newcode, function(err) { 119 | // do something ... 120 | }); 121 | ``` 122 | 123 | ====== 124 | 125 | ##### codeDecrypt(encryptCode, callback) 126 | 127 | Decrypt a code. 128 | 129 | Scene: get card list with jsapi need decrypt code, and redirect a url in card need decrypt code. 130 | 131 | - **parameters:** 132 | 133 | - ***encryptCode***: `String` 134 | 135 | encrypt code. 136 | 137 | - ***callback***(error, code): `Function` 138 | 139 | ***error***: `Object` contains error code and error message 140 | 141 | ***code***: `String` the real code 142 | 143 | - **example:** 144 | 145 | ```javascript 146 | var encryptCode = "XXIzTtMqCxwOaawoE91+VJdsFmv7b8g0VZIZkqf4GWA60Fzpc8ksZ/5ZZ0DVkXdE"; 147 | 148 | wxCard.code.codeDecrypt(encryptCode, function(err, code) { 149 | // do something ... 150 | }); 151 | ``` 152 | 153 | ====== 154 | 155 | ##### setCodeExpire(code, callback) 156 | 157 | Set a code expire. 158 | 159 | - **parameters:** 160 | 161 | - ***code***: `String` 162 | 163 | the code of card. 164 | 165 | - ***callback***(error): `Function` 166 | 167 | ***error***: `Object` contains error code and error message 168 | 169 | - **example:** 170 | 171 | ```javascript 172 | // this code does not exist in fact, just a demo 173 | var code = "882077290937"; 174 | 175 | wxCard.code.setCodeExpire(code, function(err) { 176 | // do something ... 177 | }); 178 | ``` 179 | 180 | ##### modifyLuckMoneyBalance(code, balance, callback) 181 | 182 | Modify the balance of luck money card. 183 | 184 | - **parameters:** 185 | 186 | - ***code***: `String` 187 | 188 | the code of card. 189 | 190 | - ***balance***: `Number` 191 | 192 | the balance to be modified. Must be Positive number. 193 | 194 | - ***callback***(error): `Function` 195 | 196 | ***error***: `Object` contains error code and error message 197 | 198 | - **example:** 199 | 200 | ```javascript 201 | // this code does not exist in fact, just a demo 202 | var code = "882077290937"; 203 | 204 | wxCard.code.modifyLuckMoneyBalance(code, 100, function(err) { 205 | // do something ... 206 | }); 207 | ``` -------------------------------------------------------------------------------- /docs/en-US/createcard.md: -------------------------------------------------------------------------------- 1 | Wechat Create Card Field 2 | ========================== 3 | 4 | - **card_type**: card type include `CASH`, `GROUPON`, `DISCOUNT`, `GIFT`, `GENERAL_COUPON`, `LUCK_MONEY` 5 | 6 | - **base_info**: 7 | 8 | - **logo_url**: (Required) logo url of card. size 300x300 9 | 10 | - **code_type**: (Required) code display type. include: 11 | 12 | `CODE_TYPE_TEXT`: just show code text 13 | 14 | `CODE_TYPE_BARCODE`: show barcode with text 15 | 16 | `CODE_TYPE_QRCODE`: show qrcode with text 17 | 18 | `CODE_TYPE_ONLY_QRCODE`: show qrcode without text 19 | 20 | `CODE_TYPE_ONLY_BARCODE`: show barcode without text 21 | 22 | - **brand_name**: (Required) brand name. 23 | 24 | - **title**: (Required) card name. 25 | 26 | - **sub_title**: (Optional) card sub title. 27 | 28 | - **color**: (Required) card background color, must in color list. 29 | 30 | - **notice**: (Required) notice of use card. 31 | 32 | - **description**: (Required) description of card. 33 | 34 | - **date_info**: (Required) 35 | 36 | - **type**: (Required) date type. include `1` is Fixed date range. `2` is Fixed length of time。 37 | 38 | - **begin_timestamp**: begin timestamp (second). just work when type is `1` 39 | 40 | - **end_timestamp**: end timestamp (second). just work when type is `1` 41 | 42 | - **fixed_term**: the card is valid for the number of days. just work when type is `2` 43 | 44 | - **fixed_begin_term**: the card come into effect after the number of days. just work when type is `2` 45 | 46 | - **sku**: 47 | 48 | - **quantity**: (Required) the stock of card code. 49 | 50 | - **location_id_list**: (Optional) the card can be used in shops. 51 | 52 | - **use_custom_code**: (Optional) custom code. true or false. 53 | 54 | - **bind_openid**: (Optional) specifies the user to get card. 55 | 56 | - **can_share**: (Optional) get card page can be shared or not by wecaht. true or false. 57 | 58 | - **can_give_friend**: (Optional) card can give friend or not. true or false. 59 | 60 | - **get_limit**: (Optional) the maximum number of each person can receive. (default equals to sku.quantity). 61 | 62 | - **service_phone**: (Optional) the phone number of shop provide service. 63 | 64 | - **source**: (Optional) third-party service providers. 65 | 66 | - **url_name_type**: (Optional) custom cell on card. 67 | 68 | `URL_NAME_TYPE_TAKE_AWAY`: 外卖 69 | 70 | `URL_NAME_TYPE_RESERVATION`: 在线预订 71 | 72 | `URL_NAME_TYPE_USE_IMMEDIATELY`: 立即使用 73 | 74 | `URL_NAME_TYPE_APPOINTMENT`: 在线预约 75 | 76 | `URL_NAME_TYPE_EXCHANGE`: 在线兑换 77 | 78 | `URL_NAME_TYPE_VIP_SERVICE`: 会员服务 **(Do not support in this version)** 79 | 80 | - **custom_url**: (with url_name_type) the url of custom cell. 81 | 82 | - **special_info**: 83 | 84 | `general_coupon`: 85 | 86 | - **default_detail**: (Required) the description of general coupon. 87 | 88 | `groupon`: 89 | 90 | - **deal_detail**: (Required) the description of groupon. 91 | 92 | `gift`: 93 | 94 | - **gift**: (Required) the name of gift. 95 | 96 | `cash`: 97 | 98 | - **least_cost**: (Optional) 99 | 100 | - **reduce_cost**: (Required) 101 | 102 | `discount`: 103 | 104 | - **discount**: (Required) 30% off is 30. 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /docs/en-US/createshop.md: -------------------------------------------------------------------------------- 1 | Wechat Create Shop Field 2 | ========================== 3 | 4 | - **business_name**: (Required) shop name. 5 | 6 | - **branch_name**: (Optional) the branch shop name. 7 | 8 | - **province**: (Required) location. 9 | 10 | - **city**: (Required) location. 11 | 12 | - **district**: (Required) location. 13 | 14 | - **address**: (Required) address. 15 | 16 | - **telephone**: (Required) the phone number of shop. 17 | 18 | - **category**: (Required) the category of shop. 19 | 20 | - **longitude**: (Required) langitude of shop. 21 | 22 | - **latitude**: (Required) latitude of shop. -------------------------------------------------------------------------------- /docs/en-US/index.md: -------------------------------------------------------------------------------- 1 | Wechat Card 2 | ====================== 3 | 4 | Wechat card api for NodeJS. 5 | 6 | 7 | ## Notice 8 | 9 | > Just support `CASH`, `GIFT`, `GROUPON`, `DISCOUNT`, `GENERAL_COUPON`, `LUCK_MONEY` 10 | 11 | We will provide a full support in next version. 12 | 13 | 14 | ## Install 15 | 16 | npm install wechat-card 17 | 18 | 19 | ## Usage 20 | 21 | ```javascript 22 | var wxCard = require("wechat-card"); 23 | 24 | wxCard.setConfig({ 25 | appId: "YOUR APP ID", 26 | appSecret: "YOUR APP SECRET" 27 | 28 | // or config url to provide access token service 29 | // accessTokenService: "http://url" 30 | 31 | }); 32 | 33 | // get access token 34 | wxCard.basic.getAccessToken(function(err, accessToken) { 35 | // do something ... 36 | }); 37 | 38 | ``` 39 | 40 | ## Configuration 41 | 42 | In first, you need to set appid and appsecret. call `setConfig` to complete the configuration. 43 | 44 | ```javascript 45 | var wxCard = require("wechat-card"); 46 | 47 | // config with appid and appsecret 48 | wxCard.setConfig({ 49 | appId: "YOUR APP ID", 50 | appSecret: "YOUR APP SECRET" 51 | }); 52 | 53 | ``` 54 | 55 | If you want to manage the access token on the other server, you should set `accessTokenServer` to provide the access token. 56 | 57 | ```javascript 58 | var wxCard = require("wechat-card"); 59 | 60 | // config with the access token service 61 | wxCard.setConfig({ 62 | accessTokenService: "http://url" 63 | }); 64 | 65 | ``` 66 | 67 | > **notice: the url returned data format must be `{access_token: 'ACCEESS_TOKEN'}`** 68 | 69 | ## API Document 70 | 71 | - [Basic](basic.md) 72 | 73 | - [Shop](shop.md) 74 | 75 | - [Card](card.md) 76 | 77 | - [Code](code.md) -------------------------------------------------------------------------------- /docs/en-US/modifycard.md: -------------------------------------------------------------------------------- 1 | Wechat Modify Card Field 2 | ========================== 3 | 4 | - **card_id**: (Required) the id of card. 5 | 6 | - **base_info**: (Required) 7 | 8 | - **logo_url**: (Required) logo url of card. size 300x300 9 | 10 | - **notice**: (Required) notice of use card. 11 | 12 | - **description**: (Required) description of card. 13 | 14 | - **service_phone**: (Optional) the phone number of shop provide service. 15 | 16 | - **color**: (Required) card background color, must in color list. 17 | 18 | - **location_id_list**: (Optional) the card can be used in shops. 19 | 20 | - **url_name_type**: (Optional) custom cell on card. 21 | 22 | `URL_NAME_TYPE_TAKE_AWAY`: 外卖 23 | 24 | `URL_NAME_TYPE_RESERVATION`: 在线预订 25 | 26 | `URL_NAME_TYPE_USE_IMMEDIATELY`: 立即使用 27 | 28 | `URL_NAME_TYPE_APPOINTMENT`: 在线预约 29 | 30 | `URL_NAME_TYPE_EXCHANGE`: 在线兑换 31 | 32 | `URL_NAME_TYPE_VIP_SERVICE`: 会员服务 **(Do not support in this version)** 33 | 34 | - **custom_url**: (with url_name_type) the url of custom cell. 35 | 36 | - **can_share**: (Optional) get card page can be shared or not by wecaht. true or false. 37 | 38 | - **can_give_friend**: (Optional) card can give friend or not. true or false. 39 | 40 | - **get_limit**: (Optional) the maximum number of each person can receive. 41 | 42 | - **date_info**: (Required) 43 | 44 | - **type**: (Required) date type. include `1` is Fixed date range. `2` is Fixed length of time。 45 | 46 | - **begin_timestamp**: begin timestamp (second). just work when type is `1` 47 | 48 | - **end_timestamp**: end timestamp (second). just work when type is `1` 49 | 50 | - **fixed_term**: the card is valid for the number of days. just work when type is `2` 51 | 52 | - **fixed_begin_term**: the card come into effect after the number of days. just work when type is `2` 53 | -------------------------------------------------------------------------------- /docs/en-US/shop.md: -------------------------------------------------------------------------------- 1 | Wechat Shop Document 2 | ====================== 3 | 4 | ### Guide 5 | 6 | - [batchAddShops(shops, callback)](#batchaddshopsshops-callback) 7 | 8 | - [batchGetShops(offset, count, callback)](#batchgetshopsoffset-count-callback) 9 | 10 | ### Document 11 | 12 | ##### batchAddShops(shops, callback) 13 | 14 | Register shop to wechat [MP](https://mp.weixin.qq.com/) (BATCH). 15 | 16 | - **parameters:** 17 | 18 | - ***shops***: `Array` the array of shop information. See [Shop Fields](createshop.md) 19 | 20 | - ***callback***(error, shopids): `Function` 21 | 22 | - ***error***: `Object` contains error code and error message 23 | 24 | - ***shopids***: `Array` the list of shop ids, if failed to add, shop id is -1 25 | 26 | - **example:** 27 | 28 | ```javascript 29 | // the demo data from wechat card official document 30 | var shops = [{ 31 | "business_name":"麦当劳", 32 | "branch_name":"赤岗店", 33 | "province":"广东省", 34 | "city":"广州市", 35 | "district":"海珠区", 36 | "address":"中国广东省广州市海珠区艺苑路 11 号", 37 | "telephone":"020-89772059", 38 | "category":"房产小区", 39 | "longitude":"115.32375", 40 | "latitude":"25.097486" 41 | }, { 42 | "business_name":"麦当劳", 43 | "branch_name":"珠江店", 44 | "province":"广东省", 45 | "city":"广州市", 46 | "district":"海珠区", 47 | "address":"中国广东省广州市海珠区艺苑路 12 号", 48 | "telephone":"020-89772059", 49 | "category":"房产小区", 50 | "longitude":"113.32375", 51 | "latitude":"23.097486" 52 | }]; 53 | 54 | wxCard.shop.batchAddShops(shops, function(err, ids) { 55 | // do something ... 56 | }); 57 | ``` 58 | 59 | ##### batchGetShops(offset, count, callback) 60 | 61 | Get list of shops information. (BATCH) 62 | 63 | - **parameters:** 64 | 65 | - ***offset***: `Number` 66 | 67 | the coordinates of the first element. the list start at offset. 68 | 69 | - ***count***: `Number` 70 | 71 | the size of list. 72 | 73 | - ***callback***(error, shops): `Function` 74 | 75 | ***error***: `Object` contains error code and error message. 76 | 77 | ***shops***: `Array` the shop list. 78 | 79 | - **example:** 80 | 81 | ```javascript 82 | wxCard.shop.batchGetShops(0, 10, function(err, shops) { 83 | // do something ... 84 | }); 85 | ``` -------------------------------------------------------------------------------- /docs/zh-CN/basic.md: -------------------------------------------------------------------------------- 1 | Wechat Basic Document 2 | ====================== 3 | 4 | ### 向导 5 | 6 | - [getAccessToken(callback)](#getaccesstokencallback) 7 | 8 | - [getApiTicket(callback)](#getapiticketcallback) 9 | 10 | - [getColorList(callback)](#getcolorlistcallback) 11 | 12 | - [setWhiteListWithUsername(usernames, callback)](#setwhitelistwithusernameusernames-callback) 13 | 14 | - [setWhiteListWithOpenId(openids, callback)](#setwhitelistwithopenidopenids-callback) 15 | 16 | - [getSignature(data, callback)](#getsignaturedata-callback) 17 | 18 | - [getSignatureSync(data)](#getsignaturesyncdata) 19 | 20 | 21 | ====== 22 | 23 | ### 文档 24 | 25 | ##### getAccessToken(callback) 26 | 27 | 获取当前的access token 28 | 29 | - **参数:** 30 | 31 | - ***callback***(error, accessToken): `Function` 32 | 33 | ***error***: `Object` 包含错误码和错误信息 34 | 35 | ***accessToken***: `String` 当前的access token 36 | 37 | - **示例:** 38 | 39 | ```javascript 40 | wxCard.basic.getAccessToken(function(err, accessToken) { 41 | // do something ... 42 | }); 43 | ``` 44 | 45 | ====== 46 | 47 | ##### getApiTicket(callback) 48 | 49 | 获取API TICKET,用于JSAPI计算签名时使用 50 | 51 | - **参数:** 52 | 53 | - ***callback***(error, ticket): `Function` 54 | 55 | ***error***: `Object` 包含错误码和错误信息 56 | 57 | ***ticket***: `String` 当前的ticket 58 | 59 | - **示例:** 60 | 61 | ```javascript 62 | wxCard.basic.getApiTicket(function(err, ticket) { 63 | // do something ... 64 | }); 65 | ``` 66 | 67 | ====== 68 | 69 | 70 | ##### getColorList(callback) 71 | 72 | 获取微信卡券允许使用的背景颜色,创建卡券时只能从其中选择 73 | 74 | - **参数:** 75 | 76 | - ***callback***(error, colors): `Function` 77 | 78 | ***error***: `Object` 包含错误码和错误信息 79 | 80 | ***colors***: `Array` 颜色列表,包含颜色名称和颜色代码 81 | 82 | - **示例:** 83 | 84 | ```javascript 85 | wxCard.basic.getColorList(function(err, colors) { 86 | // colors 的格式: [{name: 'Color010', value: '#55bd47' }, ...] 87 | }); 88 | ``` 89 | 90 | ====== 91 | 92 | 93 | ##### setWhiteListWithUsername(usernames, callback) 94 | 95 | 使用微信号(非手机号)设置测试白名单,当创建的卡券未通过审核时,可以通过白名单的微信号进行测试领取等操作 96 | 97 | - **参数:** 98 | 99 | - ***usernames***: `Array` 100 | 101 | 微信号数组 102 | 103 | - ***callback***(error): `Function` 104 | 105 | ***error***: `Object` 包含错误码和错误信息 106 | 107 | - **示例:** 108 | 109 | ```javascript 110 | var usernames = ['kenticny']; 111 | wxCard.basic.setWhiteListWithUsername(usernames, function(err) { 112 | // do something ... 113 | }); 114 | ``` 115 | 116 | ====== 117 | 118 | 119 | ##### setWhiteListWithOpenId(openids, callback) 120 | 121 | 使用微信openid设置白名单, 作用和 `setWhiteListWithUsername`相同 122 | 123 | - **参数:** 124 | 125 | - ***openids***: `Array` 126 | 127 | openid数组 128 | 129 | - ***callback***(error): `Function` 130 | 131 | ***error***: `Object` 包含错误码和错误信息 132 | 133 | - **示例:** 134 | 135 | ```javascript 136 | // 这个openid仅用于demo,实际不存在 137 | var openids = ['c8_tmrjPEct3_9seVe8eTPSOdL3N']; 138 | 139 | wxCard.basic.setWhiteListWithOpenId(openids, function(err) { 140 | // do something ... 141 | }); 142 | ``` 143 | 144 | 145 | ====== 146 | 147 | 148 | ##### getSignature(data, callback) 149 | 150 | 计算签名,用于JSAPI. 151 | 152 | - **参数:** 153 | 154 | - ***data***: `Array` 155 | 156 | 要签名的数据. 157 | 158 | - ***callback***(error, signature): `Function` 159 | 160 | ***error***: `Object` 包含错误码和错误信息 161 | 162 | ***signature***: `String` 签名 163 | 164 | - **示例:** 165 | 166 | ```javascript 167 | var data = ['ApiTicket', 'CardId', 'timestamp']; 168 | wxCard.basic.getSignature(data, function(err, signature) { 169 | // do something ... 170 | }); 171 | ``` 172 | 173 | 174 | ====== 175 | 176 | ##### getSignatureSync(data) 177 | 178 | 计算签名 (同步方法). 179 | 180 | - **参数:** 181 | 182 | - ***data***: `Array` 183 | 184 | 要签名的数据. 185 | 186 | - **返回:** 187 | 188 | - ***signature***: `String` 签名 189 | 190 | - **示例:** 191 | 192 | ```javascript 193 | var data = ['ApiTicket', 'CardId', 'timestamp']; 194 | var signature = wxCard.basic.getSignatureSync(data); 195 | ``` -------------------------------------------------------------------------------- /docs/zh-CN/card.md: -------------------------------------------------------------------------------- 1 | Wechat Card Document 2 | ====================== 3 | 4 | ### 向导 5 | 6 | - [createCard(card, callback)](#createcardcard-callback) 7 | 8 | - [getCardDetail(cardId, callback)](#getcarddetailcardid-callback) 9 | 10 | - [getCardIdList(offset, count, callback)](#getcardidlistoffset-count-callback) 11 | 12 | - [modifyCard(card, callback)](#modifycardcard-callback) 13 | 14 | - [deleteCard(cardId, callback)](#deletecardcardid-callback) 15 | 16 | - [modifyCardStock(cardId, number, callback)](#modifycardstockcardid-number-callback) 17 | 18 | - [createCardQRCode(cardId, options, callback)](#createcardqrcodecardid-options-callback) 19 | 20 | 21 | ### 文档 22 | 23 | ##### createCard(card, callback) 24 | 25 | 创建一个新的卡券,卡券需要通过审核后才可以领取(可通过添加白名单进行测试) 26 | 27 | - **参数:** 28 | 29 | - ***card***: `Object` 30 | 31 | 卡券信息,包括卡券类型,基本信息和特殊信息。详细请查看 [卡券信息字段](createcard.md) 32 | 33 | - ***callback***(error, cardId): `Function` 34 | 35 | ***error***: `Object` 包含错误码和错误信息 36 | 37 | ***cardId***: `String` 卡券id. 38 | 39 | - **示例:** 40 | 41 | ```javascript 42 | var card = { 43 | card_type: "DISCOUNT", 44 | base_info: { 45 | // ... 46 | }, 47 | special_info: { 48 | // ... 49 | } 50 | }; 51 | 52 | wxCard.card.createCard(card, function(err, cardId) { 53 | // do something ... 54 | }); 55 | ``` 56 | 57 | ====== 58 | 59 | 60 | ##### getCardDetail(cardId, callback) 61 | 62 | 通过卡券id获取卡券详细信息 63 | 64 | - **参数:** 65 | 66 | - ***cardId***: `String` 67 | 68 | 卡券id. 69 | 70 | - ***callback***(error, card): `Function` 71 | 72 | ***error***: `Object` 包含错误码和错误信息 73 | 74 | ***card***: `Object` 卡券详情. 75 | 76 | - **示例:** 77 | 78 | ```javascript 79 | 80 | // 下列卡券id仅用于demo,在实际中不存在 81 | var cardId = "p1Pj9jr90_SQRaVqYI239Ka1erkI"; 82 | 83 | wxCard.card.getCardDetail(cardId, function(err, card) { 84 | // do something ... 85 | }); 86 | ``` 87 | 88 | ====== 89 | 90 | 91 | ##### getCardIdList(offset, count, callback) 92 | 93 | 批量获取卡券id,不包含卡券详细信息 94 | 95 | - **参数:** 96 | 97 | - ***offset***: `Number` 98 | 99 | 列表中第一个元素的位置 100 | 101 | - ***count***: `Number` 102 | 103 | 获取的数量 104 | 105 | - ***callback***(error, ids): `Function` 106 | 107 | ***error***: `Object` 包括错误码和错误信息 108 | 109 | ***ids***: `Array` 卡券id列表 110 | 111 | 112 | - **示例:** 113 | 114 | ```javascript 115 | wxCard.card.getCardIdList(0, 10, function(err, ids) { 116 | // do something ... 117 | }); 118 | ``` 119 | 120 | ====== 121 | 122 | 123 | ##### modifyCard(card, callback) 124 | 125 | 修改卡券部分信息 126 | 127 | - **参数:** 128 | 129 | - ***card***: `Object` 130 | 131 | 修改的卡券信息, 详情查看[修改卡券字段](modifycard.md) 132 | 133 | - ***callback***(error): `Function` 134 | 135 | ***error***: `Object` 包含错误码和错误信息 136 | 137 | - **示例:** 138 | 139 | ```javascript 140 | 141 | // 下面的cardid仅用于demo,实际中不存在 142 | var card = { 143 | card_id: "p1Pj9jr90_SQRaVqYI239Ka1erkI", 144 | base_info: { 145 | // .. some of base info 146 | }, 147 | special_info: { 148 | // ... 149 | } 150 | }; 151 | 152 | wxCard.card.modifyCard(card, function(err) { 153 | // do something ... 154 | }); 155 | ``` 156 | 157 | ====== 158 | 159 | 160 | ##### deleteCard(cardId, callback) 161 | 162 | 通过卡券ID删除卡券信息 163 | 164 | - **参数:** 165 | 166 | - ***cardId***: `String` 167 | 168 | 卡券ID 169 | 170 | - ***callback***(error): `Function` 171 | 172 | ***error***: `Object` 包含错误码和错误信息 173 | 174 | - **示例:** 175 | 176 | ```javascript 177 | // 下面的cardid仅用于demo,实际中不存在 178 | var cardId = "p1Pj9jr90_SQRaVqYI239Ka1erkI"; 179 | 180 | wxCard.card.deleteCard(cardId, function(err) { 181 | // do something .. 182 | }); 183 | ``` 184 | 185 | ====== 186 | 187 | 188 | ##### modifyCardStock(cardId, number, callback) 189 | 190 | 修改卡券库存(base_info.sku.quantity). 191 | 192 | - **参数:** 193 | 194 | - ***cardId***: `String` 195 | 196 | 卡券ID 197 | 198 | - ***number***: `Number` 199 | 200 | 要修改的库存值,正数表示增加,负数表示减少 201 | 202 | - ***callback***(error): `Function` 203 | 204 | ***error***: `Object` 包含错误码和错误信息 205 | 206 | 207 | - **示例:** 208 | 209 | ```javascript 210 | // 下面的cardid仅用于demo,实际中不存在 211 | var cardId = "p1Pj9jr90_SQRaVqYI239Ka1erkI"; 212 | 213 | // 减少10库存 214 | wxCard.card.modifyCardStock(cardId, -10, function(err) { 215 | // do something ... 216 | }); 217 | 218 | // 增加10库存 219 | wxCard.card.modifyCardStock(cardId, 10, function(err) { 220 | // do something ... 221 | }); 222 | ``` 223 | 224 | ====== 225 | 226 | 227 | ##### createCardQRCode(cardId, options, callback) 228 | 229 | 生成一个用于领取卡券的二维码 230 | 231 | - **参数:** 232 | 233 | - ***cardId***: `String` 234 | 235 | 卡券ID 236 | 237 | - ***options***: `Object(Optional)` 238 | 239 | 二维码的配置 240 | 241 | options: 242 | 243 | - expire_seconds: `Number` 二维码过期时间(单位/秒). 244 | 245 | - is_unique_code: `Boolean` 是否为一次性 246 | 247 | - outer_id: `Number` 自定义标志,用于区分领取场景 248 | 249 | - balance: `Number` 红包余额,仅在卡券类型为`红包(LUCK_MONEY)`是生效 250 | 251 | - code: `String` 卡券code, 自定义卡券code时为**必填** 252 | 253 | - openid: `String` 指定领取用户openid, bind_openid为true时**必填** 254 | 255 | - ***callback***(error, url): `Function` 256 | 257 | ***error***: `Object` 包括错误码和错误信息 258 | 259 | ***url***: `String` 二维码的链接 260 | 261 | - **示例:** 262 | 263 | ```javascript 264 | // 下面的cardid仅用于demo,实际中不存在 265 | var cardId = "p1Pj9jr90_SQRaVqYI239Ka1erkI"; 266 | 267 | var options = { 268 | expire_seconds: 1200, 269 | is_unique_code: true, 270 | outer_id: 1 271 | }; 272 | 273 | wxCard.card.createCardQRCode(cardId, options, function(err, url) { 274 | // do something ... 275 | }); 276 | ``` 277 | 278 | -------------------------------------------------------------------------------- /docs/zh-CN/code.md: -------------------------------------------------------------------------------- 1 | Wechat Code Document 2 | ====================== 3 | 4 | ### 向导 5 | 6 | - [consumeCode(code, callback)](#consumecodecode-callback) 7 | 8 | - [getCodeDetail(code, callback)](#getcodedetailcode-callback) 9 | 10 | - [modifyCode(code, cardid, newcode, callback)](#modifycodecode-cardid-newcode-callback) 11 | 12 | - [codeDecrypt(encryptCode, callback)](#codedecryptencryptcode-callback) 13 | 14 | - [setCodeExpire(code, callback)](#setcodeexpirecode-callback) 15 | 16 | - [modifyLuckMoneyBalance(code, balance, callback)](#modifyluckmoneybalancecode-balance-callback) 17 | 18 | 19 | ### 文档 20 | 21 | ##### consumeCode(code, [cardId ], callback) 22 | 23 | 使用卡券code 24 | 25 | - **参数:** 26 | 27 | - ***code***: `String` 28 | 29 | 卡券code 30 | 31 | - ***cardId***: `String(可选)` 32 | 33 | 卡券ID, code为自定义code时为必填 34 | 35 | - ***callback***(error, consumeInfo): `Function` 36 | 37 | ***error***: `Object` 包含错误代码和错误信息 38 | 39 | ***consumeInfo***: `Object` 包含用户openid和卡券id 40 | 41 | - **示例:** 42 | 43 | ```javascript 44 | // 下面的code仅用于demo,实际中不存在 45 | var code = "882077290937"; 46 | 47 | wxCard.code.consumeCode(code, function(err, consumeInfo) { 48 | // do something ... 49 | }); 50 | ``` 51 | 52 | ====== 53 | 54 | 55 | ##### getCodeDetail(code, callback) 56 | 57 | 查询卡券code的详细信息 58 | 59 | - **参数:** 60 | 61 | - ***code***: `String` 62 | 63 | 卡券code 64 | 65 | - ***callback***(error, details): `Function` 66 | 67 | ***error***: `Object` 包含错误代码和错误信息 68 | 69 | ***details***: `Object` 包含用户openid,卡券id和卡券有效时间 70 | 71 | 72 | - **示例:** 73 | 74 | ```javascript 75 | // 下面的code仅用于demo,实际中不存在 76 | var code = "882077290937"; 77 | 78 | wxCard.code.getCodeDetail(code, function(err, details) { 79 | // do something ... 80 | }); 81 | 82 | ``` 83 | 84 | ====== 85 | 86 | ##### modifyCode(code, cardid, newcode, callback) 87 | 88 | 修改Code 89 | 90 | 使用场景:在自定义SN时,当卡券转增后建议修改Code. 91 | 92 | - **参数:** 93 | 94 | - ***code***: `String` 95 | 96 | 原始Code 97 | 98 | - ***cardid***: `String` 99 | 100 | code所属的卡券ID 101 | 102 | - ***newcode***: `String` 103 | 104 | 新的Code 105 | 106 | - ***callback***(error): `Function` 107 | 108 | ***error***: `Object` 包含错误代码和错误信息 109 | 110 | - **实例:** 111 | 112 | ```javascript 113 | 114 | // 下面的卡券id和code仅用于demo,实际中不存在 115 | var code = "882077290937"; 116 | var cardId = "p1Pj9jr90_SQRaVqYI239Ka1erkI"; 117 | var newcode = "883920048827"; 118 | 119 | wxCard.code.modifyCode(code, cardId, newcode, function(err) { 120 | // do something ... 121 | }); 122 | ``` 123 | 124 | ====== 125 | 126 | ##### codeDecrypt(encryptCode, callback) 127 | 128 | 解码code 129 | 130 | 使用场景: 通过JSAPI拉取卡券列表时需要解码code; 在卡券内跳转第三方链接是需要解码得到真实code. 131 | 132 | - **参数:** 133 | 134 | - ***encryptCode***: `String` 135 | 136 | 加密的code 137 | 138 | - ***callback***(error, code): `Function` 139 | 140 | ***error***: `Object` 包含错误代码和错误信息 141 | 142 | ***code***: `String` 真实code 143 | 144 | - **示例:** 145 | 146 | ```javascript 147 | var encryptCode = "XXIzTtMqCxwOaawoE91+VJdsFmv7b8g0VZIZkqf4GWA60Fzpc8ksZ/5ZZ0DVkXdE"; 148 | 149 | wxCard.code.codeDecrypt(encryptCode, function(err, code) { 150 | // do something ... 151 | }); 152 | ``` 153 | 154 | ====== 155 | 156 | ##### setCodeExpire(code, callback) 157 | 158 | 是一个卡券code 159 | 160 | - **参数:** 161 | 162 | - ***code***: `String` 163 | 164 | 卡券code 165 | 166 | - ***callback***(error): `Function` 167 | 168 | ***error***: `Object` 包含错误代码和错误信息 169 | 170 | - **示例:** 171 | 172 | ```javascript 173 | // 下面的code仅用于demo,实际中不存在 174 | var code = "882077290937"; 175 | 176 | wxCard.code.setCodeExpire(code, function(err) { 177 | // do something ... 178 | }); 179 | ``` 180 | 181 | ##### modifyLuckMoneyBalance(code, balance, callback) 182 | 183 | 修改红包余额 184 | 185 | - **参数:** 186 | 187 | - ***code***: `String` 188 | 189 | 卡券code 190 | 191 | - ***balance***: `Number` 192 | 193 | 要修改的红包余额,必须为正数 194 | 195 | - ***callback***(error): `Function` 196 | 197 | ***error***: `Object` 包含错误代码和错误信息 198 | 199 | - **示例:** 200 | 201 | ```javascript 202 | // 下面的code仅用于demo,实际中不存在 203 | var code = "882077290937"; 204 | 205 | wxCard.code.modifyLuckMoneyBalance(code, 100, function(err) { 206 | // do something ... 207 | }); 208 | ``` -------------------------------------------------------------------------------- /docs/zh-CN/createcard.md: -------------------------------------------------------------------------------- 1 | 微信创建卡券字段 2 | ========================== 3 | 4 | - **card_type**: 卡券类型包括 `CASH`, `GROUPON`, `DISCOUNT`, `GIFT`, `GENERAL_COUPON`, `LUCK_MONEY` 5 | 6 | - **base_info**: 7 | 8 | - **logo_url**: (必填) 卡券LOGO,尺寸为 300x300 9 | 10 | - **code_type**: (必填) 卡券的显示类型: 11 | 12 | `CODE_TYPE_TEXT`: 仅显示文本 13 | 14 | `CODE_TYPE_BARCODE`: 显示条形码和文本 15 | 16 | `CODE_TYPE_QRCODE`: 显示二维码和文本 17 | 18 | `CODE_TYPE_ONLY_QRCODE`: 仅显示二维码 19 | 20 | `CODE_TYPE_ONLY_BARCODE`: 仅显示条形码 21 | 22 | - **brand_name**: (必填) 商户名. 23 | 24 | - **title**: (必填) 卡券名称. 25 | 26 | - **sub_title**: (可选) 卡券副标题. 27 | 28 | - **color**: (必填) 卡券背景颜色,必须在颜色列表中选择. 29 | 30 | - **notice**: (必填) 卡券使用提醒. 31 | 32 | - **description**: (必填) 使用说明. 33 | 34 | - **date_info**: (必填) 35 | 36 | - **type**: (必填) 日期类型. 1:固定日期区间,2:固定时长 (自领取后按天算)。 37 | 38 | - **begin_timestamp**: 起始时间戳 (秒). 仅在固定日期区间类型生效 39 | 40 | - **end_timestamp**: 结束时间戳 (秒). 仅在固定日期区间类型生效 41 | 42 | - **fixed_term**: 自领取后多少天内有效(天). 仅在固定时长类型生效 43 | 44 | - **fixed_begin_term**: 自领取后多少天开始生效(天). 仅在固定时长类型生效 45 | 46 | - **sku**: 47 | 48 | - **quantity**: (必填) 卡券库存数量. 49 | 50 | - **location_id_list**: (可选) 门店ID,显示在卡券适用门店中. 51 | 52 | - **use_custom_code**: (可选) 自定义code. true 或者 false. 53 | 54 | - **bind_openid**: (可选) 指定领取用户. 55 | 56 | - **can_share**: (可选) 卡券领取页面是否可以分享。true 或者 false 57 | 58 | - **can_give_friend**: (可选) 卡券是否可以赠送. true 或者 false. 59 | 60 | - **get_limit**: (可选) 每人可以领取的最大数量 (不填写默认为 sku.quantity 的值). 61 | 62 | - **service_phone**: (可选) 服务电话. 63 | 64 | - **source**: (可选) 第三方来源名. 65 | 66 | - **url_name_type**: (可选) 自定义CELL. 67 | 68 | `URL_NAME_TYPE_TAKE_AWAY`: 外卖 69 | 70 | `URL_NAME_TYPE_RESERVATION`: 在线预订 71 | 72 | `URL_NAME_TYPE_USE_IMMEDIATELY`: 立即使用 73 | 74 | `URL_NAME_TYPE_APPOINTMENT`: 在线预约 75 | 76 | `URL_NAME_TYPE_EXCHANGE`: 在线兑换 77 | 78 | `URL_NAME_TYPE_VIP_SERVICE`: 会员服务 **(当前版本不支持)** 79 | 80 | - **custom_url**: (和url_name_type同时存在) 自定义CELL跳转的链接. 81 | 82 | - **special_info**: 83 | 84 | `general_coupon`: 85 | 86 | - **default_detail**: (必填) 描述文本. 87 | 88 | `groupon`: 89 | 90 | - **deal_detail**: (必填) 团购券专用,团购详情. 91 | 92 | `gift`: 93 | 94 | - **gift**: (必填) 礼品券专用,表示礼品名字. 95 | 96 | `cash`: 97 | 98 | - **least_cost**: (可选) 代金券专用,表示起用金额(单位为分) 99 | 100 | - **reduce_cost**: (必填) 代金券专用,表示减免金额(单位为分) 101 | 102 | `discount`: 103 | 104 | - **discount**: (必填) 折扣券专用,表示打折额度(百 分比)。填 30 就是七折. 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /docs/zh-CN/createshop.md: -------------------------------------------------------------------------------- 1 | 微信创建门店字段 2 | ========================== 3 | 4 | - **business_name**: (必填) 店铺名称. 5 | 6 | - **branch_name**: (可选) 分店名称. 7 | 8 | - **province**: (必填) 省. 9 | 10 | - **city**: (必填) 市. 11 | 12 | - **district**: (必填) 区. 13 | 14 | - **address**: (必填) 地址. 15 | 16 | - **telephone**: (必填) 联系电话. 17 | 18 | - **category**: (必填) 类别. 19 | 20 | - **longitude**: (必填) 经度. 21 | 22 | - **latitude**: (必填) 纬度. -------------------------------------------------------------------------------- /docs/zh-CN/index.md: -------------------------------------------------------------------------------- 1 | Wechat Card 2 | ====================== 3 | 4 | 微信卡券API接口NODEJS版。 5 | 6 | 7 | ## 特别提醒 8 | 9 | > 目前版本仅支持以下几种类型的卡券: `CASH`, `GIFT`, `GROUPON`, `DISCOUNT`, `GENERAL_COUPON`, `LUCK_MONEY`。 10 | 11 | 我们会在之后的版本陆续推出这些功能的支持。 12 | 13 | 14 | ## 安装 15 | 16 | npm install wechat-card 17 | 18 | 19 | ## 使用方法 20 | 21 | ```javascript 22 | var wxCard = require("wechat-card"); 23 | 24 | wxCard.setConfig({ 25 | appId: "YOUR APP ID", 26 | appSecret: "YOUR APP SECRET" 27 | 28 | // 或者配置其他提供access token的服务 29 | // accessTokenService: "http://url" 30 | 31 | }); 32 | 33 | // 获取 access token 34 | wxCard.basic.getAccessToken(function(err, accessToken) { 35 | // do something ... 36 | }); 37 | 38 | ``` 39 | 40 | ## 配置项 41 | 42 | 首先你需要调用`setConfig`配置微信APPID和APPSECRET 43 | 44 | 45 | ```javascript 46 | var wxCard = require("wechat-card"); 47 | 48 | // 使用appid和appsecret配置 49 | wxCard.setConfig({ 50 | appId: "YOUR APP ID", 51 | appSecret: "YOUR APP SECRET" 52 | }); 53 | 54 | ``` 55 | 56 | 如果你的ACCESS TOKEN是由其他的服务提供的,那么可以按照下面进行配置 57 | 58 | ```javascript 59 | var wxCard = require("wechat-card"); 60 | 61 | // 使用提供access token服务进行配置 62 | wxCard.setConfig({ 63 | accessTokenService: "http://url" 64 | }); 65 | 66 | ``` 67 | 68 | > **注意:提供access token的服务返回的数据格式必须为 `{access_token: 'ACCEESS_TOKEN'}`** 69 | 70 | ## API文档 71 | 72 | - [Basic](basic.md) 73 | 74 | - [Shop](shop.md) 75 | 76 | - [Card](card.md) 77 | 78 | - [Code](code.md) -------------------------------------------------------------------------------- /docs/zh-CN/modifycard.md: -------------------------------------------------------------------------------- 1 | 微信修改卡券字段 2 | ========================== 3 | 4 | - **card_id**: (必填) 卡券ID. 5 | 6 | - **base_info**: (必填) 7 | 8 | - **logo_url**: (必填) 卡券LOGO,尺寸为 300x300 9 | 10 | - **notice**: (必填) 卡券使用提醒. 11 | 12 | - **description**: (必填) 使用说明. 13 | 14 | - **service_phone**: (可选) 服务电话. 15 | 16 | - **color**: (必填) 卡券背景颜色,必须在颜色列表中选择. 17 | 18 | - **location_id_list**: (可选) 门店ID,显示在卡券适用门店中. 19 | 20 | - **url_name_type**: (可选) 自定义CELL. 21 | 22 | `URL_NAME_TYPE_TAKE_AWAY`: 外卖 23 | 24 | `URL_NAME_TYPE_RESERVATION`: 在线预订 25 | 26 | `URL_NAME_TYPE_USE_IMMEDIATELY`: 立即使用 27 | 28 | `URL_NAME_TYPE_APPOINTMENT`: 在线预约 29 | 30 | `URL_NAME_TYPE_EXCHANGE`: 在线兑换 31 | 32 | `URL_NAME_TYPE_VIP_SERVICE`: 会员服务 **(当前版本不支持)** 33 | 34 | - **custom_url**: (和url_name_type同时存在) 自定义CELL跳转的链接. 35 | 36 | - **can_share**: (可选) 卡券领取页面是否可以分享。true 或者 false. 37 | 38 | - **can_give_friend**: (可选) 卡券是否可以赠送. true 或者 false. 39 | 40 | - **get_limit**: (可选) 每人可以领取的最大数量. 41 | 42 | - **date_info**: (必填) 43 | 44 | - **type**: (必填) 日期类型. 1:固定日期区间,2:固定时长 (自领取后按天算)。 45 | 46 | - **begin_timestamp**: 起始时间戳 (秒). 仅在固定日期区间类型生效 47 | 48 | - **end_timestamp**: 结束时间戳 (秒). 仅在固定日期区间类型生效 49 | 50 | - **fixed_term**: 自领取后多少天内有效(天). 仅在固定时长类型生效 51 | 52 | - **fixed_begin_term**: 自领取后多少天开始生效(天). 仅在固定时长类型生效 -------------------------------------------------------------------------------- /docs/zh-CN/shop.md: -------------------------------------------------------------------------------- 1 | Wechat Shop Document 2 | ====================== 3 | 4 | ### 向导 5 | 6 | - [batchAddShops(shops, callback)](#batchaddshopsshops-callback) 7 | 8 | - [batchGetShops(offset, count, callback)](#batchgetshopsoffset-count-callback) 9 | 10 | ### 文档 11 | 12 | ##### batchAddShops(shops, callback) 13 | 14 | 批量注册门店到 [MP](https://mp.weixin.qq.com/) . 15 | 16 | - **参数:** 17 | 18 | - ***shops***: `Array` 门店信息数组 19 | 20 | - ***callback***(error, shopids): `Function` 21 | 22 | - ***error***: `Object` 包含错误代码和错误信息,详情查看[门店信息字段](createshop.md) 23 | 24 | - ***shopids***: `Array` 门店ID, 如果门店添加失败,则id为-1 25 | 26 | - **示例:** 27 | 28 | ```javascript 29 | // demo数据来自于微信卡券官方文档 30 | var shops = [{ 31 | "business_name":"麦当劳", 32 | "branch_name":"赤岗店", 33 | "province":"广东省", 34 | "city":"广州市", 35 | "district":"海珠区", 36 | "address":"中国广东省广州市海珠区艺苑路 11 号", 37 | "telephone":"020-89772059", 38 | "category":"房产小区", 39 | "longitude":"115.32375", 40 | "latitude":"25.097486" 41 | }, { 42 | "business_name":"麦当劳", 43 | "branch_name":"珠江店", 44 | "province":"广东省", 45 | "city":"广州市", 46 | "district":"海珠区", 47 | "address":"中国广东省广州市海珠区艺苑路 12 号", 48 | "telephone":"020-89772059", 49 | "category":"房产小区", 50 | "longitude":"113.32375", 51 | "latitude":"23.097486" 52 | }]; 53 | 54 | wxCard.shop.batchAddShops(shops, function(err, ids) { 55 | // do something ... 56 | }); 57 | ``` 58 | 59 | ##### batchGetShops(offset, count, callback) 60 | 61 | 批量获取门店信息 62 | 63 | - **参数:** 64 | 65 | - ***offset***: `Number` 66 | 67 | 列表第一个元素的位置 68 | 69 | - ***count***: `Number` 70 | 71 | 列表的大小 72 | 73 | - ***callback***(error, shops): `Function` 74 | 75 | ***error***: `Object` 包含错误代码和错误信息 76 | 77 | ***shops***: `Array` 门店列表 78 | 79 | - **示例:** 80 | 81 | ```javascript 82 | wxCard.shop.batchGetShops(0, 10, function(err, shops) { 83 | // do something ... 84 | }); 85 | ``` -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | module.exports = require("./libs"); -------------------------------------------------------------------------------- /libs/api/basic.js: -------------------------------------------------------------------------------- 1 | var config = require("../config"); 2 | var request = require("../utils/request"); 3 | var encrypt = require("../utils/encrypt"); 4 | var error = require("../utils/errors"); 5 | 6 | /** 7 | * get current access token (获取当前的access token) 8 | * @param {Function} callback(error, accessToken) 9 | */ 10 | exports.getAccessToken = function(callback) { 11 | callback = callback || function() {}; 12 | config.getAccessToken(callback); 13 | }; 14 | 15 | /** 16 | * get current api ticket (获取当前api ticket,用于JSAPI计算签名) 17 | * @param {Function} callback(error, ticket) 18 | */ 19 | exports.getApiTicket = function(callback) { 20 | callback = callback || function() {}; 21 | config.getTicket("wx_card", callback); 22 | }; 23 | 24 | /** 25 | * get current jsapi ticket 26 | * @param {Function} callback(error, ticket) 27 | */ 28 | exports.getJsApiTicket = function(callback) { 29 | callback = callback || function() {}; 30 | config.getTicket("jsapi", callback); 31 | }; 32 | 33 | /** 34 | * get wechat card colors (获取创建卡券允许使用的颜色列表) 35 | * @param {Function} callback(error, colors) 36 | */ 37 | exports.getColorList = function(callback) { 38 | callback = callback || function() {}; 39 | request.get(config.api.COLORS, function(err, result) { 40 | if(err) {return callback(err); } 41 | callback(null, result.colors); 42 | }); 43 | }; 44 | 45 | /** 46 | * set test whitelist with wechat username (用微信号来设置测试白名单) 47 | * @param {Array} usernames [username list 微信号列表] 48 | * @param {Function} callback(error) 49 | */ 50 | exports.setWhiteListWithUsername = function(usernames, callback) { 51 | if(!usernames instanceof Array || typeof callback !== "function") { 52 | return callback(error.MISSING_PARAMS()); 53 | } 54 | request.post(config.api.SET_WHITELIST, { 55 | form: JSON.stringify({ 56 | username: usernames 57 | }) 58 | }, function(err, result) { 59 | if(err) {return callback(err); } 60 | callback(null); 61 | }); 62 | }; 63 | 64 | /** 65 | * set test whitelist with wechat openid (使用微信openid设置测试白名单) 66 | * @param {Array} openids [openid list 用户openid列表] 67 | * @param {Function} callback(error) 68 | */ 69 | exports.setWhiteListWithOpenId = function(openids, callback) { 70 | if(!openids instanceof Array || typeof callback !== "function") { 71 | return callback(error.MISSING_PARAMS()); 72 | } 73 | request.post(config.api.SET_WHITELIST, { 74 | form: JSON.stringify({ 75 | openid: openids 76 | }) 77 | }, function(err, result) { 78 | if(err) {return callback(err); } 79 | callback(null); 80 | }); 81 | }; 82 | 83 | /** 84 | * calculate signature (计算签名) 85 | * @param {Array} data [The data to be encrypted 待加密数据] 86 | * @param {Function} callback(error, signature) 87 | */ 88 | exports.getSignature = function(data, callback) { 89 | if(!data instanceof Array || typeof callback !== "function") { 90 | return callback(error.MISSING_PARAMS()); 91 | } 92 | var signatureStr = data.sort().join(""); 93 | if(signatureStr === "") { 94 | return callback(error.SIGN_DATA_CANNOT_NULL()); 95 | } 96 | callback(null, encrypt.sha1(signatureStr)); 97 | }; 98 | 99 | /** 100 | * calculate signature sync (计算签名 同步) 101 | * @param {Array} data [The data to be encrypted 待加密数据] 102 | * @return {String} [signature 签名] 103 | */ 104 | exports.getSignatureSync = function(data) { 105 | if(!data instanceof Array) { 106 | return error.MISSING_PARAMS(); 107 | } 108 | var signatureStr = data.sort().join(""); 109 | if(signatureStr === "") { 110 | return error.SIGN_DATA_CANNOT_NULL(); 111 | } 112 | return encrypt.sha1(signatureStr); 113 | }; -------------------------------------------------------------------------------- /libs/api/card.js: -------------------------------------------------------------------------------- 1 | var config = require("../config"); 2 | var request = require("../utils/request"); 3 | var error = require("../utils/errors"); 4 | 5 | /** 6 | * create a wechat card (创建卡券) 7 | * @param {object} card [card info 卡券信息] 8 | * @param {Function} callback(error, cardid) 9 | */ 10 | exports.createCard = function(card, callback) { 11 | if(typeof card !== "object" || typeof callback !== "function") { 12 | return callback(error.MISSING_PARAMS()); 13 | } 14 | 15 | var card_type = card.card_type; 16 | var base_info = card.base_info; 17 | var special_info = card.special_info; 18 | 19 | // check the necessary parameters 20 | if(!card_type || typeof card_type !== "string" || !base_info) { 21 | return callback(error.MISSING_CARD_OPTION()); 22 | } 23 | 24 | // assembling create card request data 25 | var cardData = {}; 26 | cardData["card_type"] = card_type; 27 | cardData[card_type.toLowerCase()] = {}; 28 | cardData[card_type.toLowerCase()]["base_info"] = base_info; 29 | 30 | if(special_info && typeof special_info === "object") { 31 | for(var i in special_info) { 32 | cardData[card_type.toLowerCase()][i] = special_info[i]; 33 | } 34 | } 35 | 36 | request.post(config.api.CREATE_CARD, { 37 | form: JSON.stringify({card: cardData }) 38 | }, function(err, result) { 39 | if(err) {return callback(err); } 40 | callback(null, result.card_id); 41 | }); 42 | }; 43 | 44 | /** 45 | * get card detail info by card id (通过cardid获取卡券详细信息) 46 | * @param {string} cardId [card id 卡券id] 47 | * @param {Function} callback(error, card) 48 | */ 49 | exports.getCardDetail = function(cardId, callback) { 50 | if(typeof cardId !== "string" || typeof callback !== "function") { 51 | return callback(error.MISSING_PARAMS()); 52 | } 53 | 54 | request.post(config.api.GET_CARD_DETAIL, { 55 | form: JSON.stringify({card_id: cardId }) 56 | }, function(err, result) { 57 | if(err) {return callback(err); } 58 | 59 | // assembling format card information 60 | var cardData = {}; 61 | cardData["card_type"] = result.card.card_type; 62 | var cardInfo = result.card[result.card.card_type.toLowerCase()]; 63 | cardData["base_info"] = cardInfo.base_info; 64 | delete cardInfo.base_info; 65 | cardData["special_info"] = cardInfo; 66 | 67 | callback(null, cardData); 68 | }); 69 | }; 70 | 71 | /** 72 | * get card id list, just ids (获取卡券id列表, 仅有卡券id) 73 | * @param {number} offset [the id list start at offset 列表的起始位置] 74 | * @param {number} count [the quantity of list 列表数量] 75 | * @param {Function} callback(error, ids) 76 | */ 77 | exports.getCardIdList = function(offset, count, callback) { 78 | 79 | // set the default parameters 80 | if(arguments.length < 3) { 81 | if(typeof offset === "function") { 82 | callback = offset; 83 | } 84 | if(typeof count === "function") { 85 | callback = count; 86 | } 87 | callback = callback || function(){}; 88 | offset = 0; count = 5; 89 | } 90 | 91 | request.post(config.api.GET_CARD_ID_LIST, { 92 | form: JSON.stringify({offset: offset, count: count }) 93 | }, function(err, result) { 94 | if(err) {return callback(err); } 95 | callback(null, result.card_id_list); 96 | }); 97 | 98 | }; 99 | 100 | /** 101 | * modify card info (修改卡券信息) 102 | * @param {object} card [new card info 卡券信息] 103 | * @param {Function} callback(error) 104 | */ 105 | exports.modifyCard = function(card, callback) { 106 | if(typeof card !== "object" || typeof callback !== "function") { 107 | return callback(error.MISSING_PARAMS()); 108 | } 109 | 110 | var cardId = card.card_id; 111 | var baseInfo = card.base_info; 112 | var specialInfo = card.special_info; 113 | 114 | if(!cardId || typeof cardId !== "string") { 115 | return callback(error.MISSING_CARD_OPTION()); 116 | } 117 | 118 | // get the card type 119 | exports.getCardDetail(cardId, function(err, currentCard) { 120 | var card_type = currentCard.card_type; 121 | 122 | // set card update info 123 | var updateData = {}; 124 | updateData["card_id"] = cardId; 125 | updateData[card_type.toLowerCase()] = {}; 126 | updateData[card_type.toLowerCase()]["base_info"] = baseInfo; 127 | 128 | if(specialInfo && typeof specialInfo === "object") { 129 | for(var i in specialInfo) { 130 | updateData[card_type.toLowerCase()][i] = specialInfo[i]; 131 | } 132 | } 133 | 134 | request.post(config.api.MODIFY_CARD, { 135 | form: JSON.stringify(updateData) 136 | }, function(err, result) { 137 | if(err) {return callback(err); } 138 | callback(null); 139 | }); 140 | }); 141 | 142 | }; 143 | 144 | /** 145 | * delete card by card id (通过cardid删除卡券) 146 | * @param {string} cardId [card id 卡券id] 147 | * @param {Function} callback(error) 148 | */ 149 | exports.deleteCard = function(cardId, callback) { 150 | if(typeof cardId !== "string" || typeof callback !== "function") { 151 | return callback(error.MISSING_PARAMS()); 152 | } 153 | request.post(config.api.DELETE_CARD, { 154 | form: JSON.stringify({card_id: cardId }) 155 | }, function(err, result) { 156 | if(err) {return callback(err); } 157 | callback(null); 158 | }); 159 | }; 160 | 161 | /** 162 | * modify card stock (base_info.sku.quantity) (修改卡券库存) 163 | * @param {string} cardId [card id 卡券id] 164 | * @param {number} number [value to be modified 修改的数量] 165 | * positive number -> increase (正数表示增加) 166 | * negative number -> reduce (负数表示减少) 167 | * @param {Function} callback(error) 168 | */ 169 | exports.modifyCardStock = function(cardId, number, callback) { 170 | if(typeof cardId !== "string" || typeof number !== "number" 171 | || typeof callback !== "function") { 172 | return callback(error.MISSING_PARAMS()); 173 | } 174 | 175 | // set modify parameters 176 | var params = {}; 177 | params["card_id"] = cardId; 178 | var field = number > 0 ? "increase_stock_value" : "reduce_stock_value"; 179 | params[field] = Math.abs(number); 180 | 181 | request.post(config.api.MODIFY_CARD_STOCK, { 182 | form: JSON.stringify(params) 183 | }, function(err, result) { 184 | if(err) {return callback(err); } 185 | callback(null); 186 | }); 187 | 188 | }; 189 | 190 | /** 191 | * create card qrcode (创建卡券二维码,用于领取卡券) 192 | * @param {string} cardId [cardid 卡券id] 193 | * @param {object} options [qrcode options 二维码配置信息] 194 | * @param {Function} callback(error, qrcodeurl) 195 | */ 196 | exports.createCardQRCode = function(cardId, options, callback) { 197 | 198 | // set options optional 199 | if(typeof options === "function" && !callback) { 200 | callback = options; options = {}; 201 | } 202 | if(typeof cardId !== "string" || typeof options !== "object" 203 | || typeof callback !== "function") { 204 | return callback(error.MISSING_PARAMS()); 205 | } 206 | 207 | // qrcode options 208 | var qrcodeOptions = { 209 | action_name: "QR_CARD", 210 | action_info: { 211 | card: { 212 | card_id: cardId 213 | } 214 | } 215 | }; 216 | 217 | // optional parameters 218 | if(options.expire_seconds) { 219 | qrcodeOptions.action_info.card.expire_seconds = options.expire_seconds; 220 | } 221 | if(options.is_unique_code) { 222 | qrcodeOptions.action_info.card.is_unique_code = options.is_unique_code; 223 | } 224 | if(options.outer_id) { 225 | qrcodeOptions.action_info.card.outer_id = options.outer_id; 226 | } 227 | 228 | // balance option need card type luck money 229 | if(options.balance) { 230 | qrcodeOptions.action_info.card.balance = options.balance; 231 | } 232 | 233 | // custom code 234 | if(options.code) { 235 | qrcodeOptions.action_info.card.code = options.code; 236 | } 237 | 238 | // bind user 239 | if(options.openid) { 240 | qrcodeOptions.action_info.card.openid = options.openid; 241 | } 242 | 243 | // generate card qrcode ticket 244 | // and get qrcode url by ticket 245 | request.post(config.api.CREATE_CARD_QR_CODE_TICKET, { 246 | form: JSON.stringify(qrcodeOptions) 247 | }, function(err, result) { 248 | if(err) {return callback(err); } 249 | var qrcodeUrl = config.api.SHOW_CARD_QR_CODE + "?ticket=" + encodeURI(result.ticket); 250 | callback(null, qrcodeUrl); 251 | }); 252 | }; -------------------------------------------------------------------------------- /libs/api/code.js: -------------------------------------------------------------------------------- 1 | var config = require("../config"); 2 | var request = require("../utils/request"); 3 | var error = require("../utils/errors"); 4 | 5 | /** 6 | * consume a code (使用卡券) 7 | * @param {string} code [code of card 卡券兑换码] 8 | * @param {Function} callback(error, consumeinfo) 9 | */ 10 | exports.consumeCode = function(code, cardId, callback) { 11 | if(typeof cardId === "function" && !callback) { 12 | callback = cardId; cardId = ""; 13 | } 14 | if(typeof code !== "string" || typeof cardId !== "string" 15 | || typeof callback !== "function") { 16 | return callback(error.MISSING_PARAMS()); 17 | } 18 | var codeObj = {code: code}; 19 | 20 | // custom code have to fill card id 21 | if(cardId) { 22 | codeObj["card_id"] = cardId; 23 | } 24 | request.post(config.api.CONSUME_CODE, { 25 | form: JSON.stringify(codeObj) 26 | }, function(err, result) { 27 | if(err) {return callback(err); } 28 | var consumeInfo = result.card; 29 | consumeInfo.openid = result.openid; 30 | callback(null, consumeInfo); 31 | }); 32 | }; 33 | 34 | /** 35 | * get code detail information (获取卡券兑换码的详细信息) 36 | * @param {string} code [code of card 卡券兑换码] 37 | * @param {Function} callback(error, codeinfo) 38 | */ 39 | exports.getCodeDetail = function(code, callback) { 40 | if(typeof code !== "string" || typeof callback !== "function") { 41 | return callback(error.MISSING_PARAMS()); 42 | } 43 | request.post(config.api.GET_CODE_DETAIL, { 44 | form: JSON.stringify({code: code }) 45 | }, function(err, result) { 46 | if(err) {return callback(err); } 47 | var codeDetail = result.card; 48 | codeDetail.openid = result.openid; 49 | callback(null, codeDetail); 50 | }); 51 | }; 52 | 53 | /** 54 | * modify code (修改code) 55 | * @param {string} code [code ] 56 | * @param {string} cardid [card id] 57 | * @param {string} newcode [new code] 58 | * @param {Function} callback(error) 59 | */ 60 | exports.modifyCode = function(code, cardid, newcode, callback) { 61 | if(typeof code !== "string" || typeof cardid !== "string" 62 | || typeof newcode !== "string" || typeof callback !== "function") { 63 | return callback(error.MISSING_PARAMS()); 64 | } 65 | request.post(config.api.MODIFY_CODE, { 66 | form: JSON.stringify({ 67 | code: code, 68 | card_id: cardid, 69 | new_code: newcode 70 | }) 71 | }, function(err, result) { 72 | if(err) {return callback(err); } 73 | callback(null); 74 | }); 75 | }; 76 | 77 | /** 78 | * decrypt code (code解码) 79 | * @param {string} encryptCode [encrypt code 加密的兑换码] 80 | * @param {Function} callback(error, code) 81 | */ 82 | exports.codeDecrypt = function(encryptCode, callback) { 83 | if(typeof encryptCode !== "string" || typeof callback !== "function") { 84 | return callback(error.MISSING_PARAMS()); 85 | } 86 | request.post(config.api.CODE_DECRYPT, { 87 | form: JSON.stringify({encrypt_code: encryptCode }) 88 | }, function(err, result) { 89 | if(err) {return callback(err); } 90 | callback(null, result.code); 91 | }); 92 | }; 93 | 94 | /** 95 | * set a code expire (设置卡券兑换码过期) 96 | * @param {string} code [code of card 卡券兑换码] 97 | * @param {Function} callback(error) 98 | */ 99 | exports.setCodeExpire = function(code, callback) { 100 | if(typeof code !== "string" || typeof callback !== "function") { 101 | return callback(error.MISSING_PARAMS()); 102 | } 103 | request.post(config.api.SET_CODE_EXPIRE, { 104 | form: JSON.stringify({code: code }) 105 | }, function(err, result) { 106 | if(err) {return callback(err); } 107 | callback(null); 108 | }); 109 | }; 110 | 111 | /** 112 | * modify luck money balance(just work when card type is LUCK_MONEY) 113 | * (修改红包余额,仅适用于卡券类型为红包) 114 | * @param {string} code [code of card 卡券兑换码] 115 | * @param {number} balance [the balance of luck money 红包余额] 116 | * @param {Function} callback(error) 117 | */ 118 | exports.modifyLuckMoneyBalance = function(code, balance, callback) { 119 | if(typeof code !== "string" || typeof balance !== "number" 120 | || typeof callback !== "function") { 121 | return callback(error.MISSING_PARAMS()); 122 | } 123 | if(balance < 0) { 124 | return callback(error.LUCK_MONEY_BALANCE_ERROR()); 125 | } 126 | request.post(config.api.MODIFY_LUCK_MONEY_BALANCE, { 127 | form: JSON.stringify({code: code, balance: balance}) 128 | }, function(err, result) { 129 | if(err) {return callback(err); } 130 | callback(null); 131 | }); 132 | }; 133 | -------------------------------------------------------------------------------- /libs/api/shop.js: -------------------------------------------------------------------------------- 1 | var config = require("../config"); 2 | var request = require("../utils/request"); 3 | var error = require("../utils/errors"); 4 | 5 | /** 6 | * batch add shop(location) (批量添加门店) 7 | * @param {array} shops [shop list 门店列表] 8 | * @param {Function} callback(error, ids) 9 | */ 10 | exports.batchAddShops = function(shops, callback) { 11 | if(!shops instanceof Array || typeof callback !== "function") { 12 | return callback(error.MISSING_PARAMS()); 13 | } 14 | if(shops.length < 1) { 15 | return callback(error.SHOPS_LIST_CANNOT_NULL()); 16 | } 17 | request.post(config.api.CREATE_SHOP, { 18 | form: JSON.stringify({location_list: shops }) 19 | }, function(err, result) { 20 | if(err) {return callback(err); } 21 | 22 | // returns location id list, -1 is failed to add 23 | callback(null, result.location_id_list); 24 | }); 25 | }; 26 | 27 | /** 28 | * batch get shop information (批量获取门店信息) 29 | * @param {number} offset [the shop list start at offset 列表起始位置] 30 | * @param {number} count [the quantity of list 列表数量] 31 | * @param {Function} callback(error, shops) 32 | */ 33 | exports.batchGetShops = function(offset, count, callback) { 34 | 35 | // set the default parameters 36 | if(arguments.length < 3) { 37 | if(typeof offset === "function") { 38 | callback = offset; 39 | } 40 | if(typeof count === "function") { 41 | callback = count; 42 | } 43 | callback = callback || function(){}; 44 | offset = 0; count = 5; 45 | } 46 | 47 | request.post(config.api.GET_SHOP_LIST, { 48 | form: JSON.stringify({offset: offset, count: count }) 49 | }, function(err, result) { 50 | if(err) {return callback(err); } 51 | callback(null, result.location_list); 52 | }); 53 | }; -------------------------------------------------------------------------------- /libs/config.js: -------------------------------------------------------------------------------- 1 | var request = require("request"); 2 | 3 | var error = require("./utils/errors"); 4 | 5 | var config = { 6 | _token: true 7 | }; 8 | 9 | var privateConfig = { 10 | access_token: {}, 11 | jsapi_ticket: {} 12 | }; 13 | 14 | var api = { 15 | 16 | // BASIC 17 | ACCESS_TOKEN: "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential", 18 | API_TICKET: "https://api.weixin.qq.com/cgi-bin/ticket/getticket", 19 | 20 | // BATCH MANAGE SHOP 21 | CREATE_SHOP: "https://api.weixin.qq.com/card/location/batchadd", 22 | GET_SHOP_LIST: "https://api.weixin.qq.com/card/location/batchget", 23 | 24 | // CARD 25 | CREATE_CARD: "https://api.weixin.qq.com/card/create", 26 | GET_CARD_DETAIL: "https://api.weixin.qq.com/card/get", 27 | GET_CARD_ID_LIST: "https://api.weixin.qq.com/card/batchget", 28 | MODIFY_CARD: "https://api.weixin.qq.com/card/update", 29 | DELETE_CARD: "https://api.weixin.qq.com/card/delete", 30 | MODIFY_CARD_STOCK: "https://api.weixin.qq.com/card/modifystock", 31 | CREATE_CARD_QR_CODE_TICKET: "https://api.weixin.qq.com/card/qrcode/create", 32 | SHOW_CARD_QR_CODE: "https://mp.weixin.qq.com/cgi-bin/showqrcode", 33 | 34 | // CODE 35 | CONSUME_CODE: "https://api.weixin.qq.com/card/code/consume", 36 | GET_CODE_DETAIL: "https://api.weixin.qq.com/card/code/get", 37 | MODIFY_CODE: "https://api.weixin.qq.com/card/code/update", 38 | CODE_DECRYPT: "https://api.weixin.qq.com/card/code/decrypt", 39 | SET_CODE_EXPIRE: "https://api.weixin.qq.com/card/code/unavailable", 40 | MODIFY_LUCK_MONEY_BALANCE: "https://api.weixin.qq.com/card/luckymoney/updateuserbalance", 41 | 42 | // OTHER 43 | COLORS: "https://api.weixin.qq.com/card/getcolors", 44 | SET_WHITELIST: "https://api.weixin.qq.com/card/testwhitelist/set" 45 | 46 | }; 47 | 48 | function setConfig(newConfig) { 49 | if(newConfig.appId && newConfig.appSecret) { 50 | config.appId = newConfig.appId; 51 | config.appSecret = newConfig.appSecret; 52 | } else if(newConfig.accessTokenService){ 53 | config.accessTokenService = newConfig.accessTokenService; 54 | config._token = false; 55 | } else { 56 | throw new Error("an error occurred when init access token"); 57 | } 58 | } 59 | 60 | function getConfig() { 61 | return config; 62 | } 63 | 64 | function setPrivateConfig(key, value) { 65 | if(typeof key === "string") { 66 | privateConfig[key] = value; 67 | } 68 | } 69 | 70 | /** 71 | * check the token is expire or not (检查token是否过期) 72 | * @param {string} type [access_token or jsapi_ticket] 73 | * @return {Boolean} [true or false] 74 | */ 75 | function isNotExpire(type, expireTime) { 76 | var op = privateConfig[type]; 77 | if(Date.now() - op.expireTime > (expireTime || 3600000)) { 78 | return false; 79 | } 80 | return true; 81 | } 82 | 83 | /** 84 | * get access token 85 | * @param {Function} callback [description] 86 | * @return {[type]} [description] 87 | */ 88 | function getAccessToken(callback) { 89 | 90 | // parse response and return access token 91 | var returnsFunc = function(body, isNew, callback) { 92 | var token = (typeof body === "string") ? 93 | JSON.parse(body).access_token : body.access_token; 94 | if(isNew) { 95 | setPrivateConfig("access_token", {cred: token, expireTime: Date.now() }); 96 | } 97 | callback(null, token); 98 | return; 99 | }; 100 | 101 | // get access token from wechat server or configure server 102 | if(config._token) { 103 | 104 | // from wechat server 105 | if(privateConfig.access_token.cred && isNotExpire("access_token")) { 106 | return returnsFunc({access_token: privateConfig.access_token.cred }, false, callback); 107 | } 108 | var accessTokenUrl = api.ACCESS_TOKEN + "&appid=" + config.appId + "&secret=" + config.appSecret; 109 | request.post(accessTokenUrl, function(err, res, body) { 110 | if(err) { 111 | return callback(error.REQUEST_ERROR(err)); 112 | } 113 | returnsFunc(body, true, callback); 114 | }); 115 | }else { 116 | 117 | // from custom server 118 | request.get(config.accessTokenService, function(err, res, body) { 119 | if(err) { 120 | return callback(error.REQUEST_ERROR(err)); 121 | } 122 | try { 123 | body = JSON.parse(body); 124 | } catch (e) { 125 | body = null; 126 | } 127 | if(!body || !body.access_token) { 128 | return callback(error.TOKEN_SERVICE_FORMAT_ERROR()); 129 | } 130 | returnsFunc(body, false, callback); 131 | }); 132 | } 133 | } 134 | 135 | /** 136 | * get ticket 137 | * @param {String} type [ticket type] 138 | * @param {Function} callback(error, ticket) 139 | */ 140 | function getTicket(type, callback) { 141 | 142 | // parse the response object and return ticket 143 | var returnsFunc = function(body, isNew, callback) { 144 | var token = (typeof body === "string") ? 145 | JSON.parse(body).ticket : body.ticket; 146 | if(isNew) { 147 | setPrivateConfig(type + "_ticket", {cred: token, expireTime: Date.now() }); 148 | } 149 | callback(null, token); 150 | return; 151 | }; 152 | 153 | // get ticket if not expire 154 | if(privateConfig.jsapi_ticket.cred && isNotExpire(type + "_ticket", 7200000)) { 155 | return returnsFunc({ticket: privateConfig.jsapi_ticket.cred }, false, callback); 156 | } 157 | 158 | // request jsapi ticket if it expired 159 | formatUrl(api.API_TICKET, function(err, url) { 160 | if(err) {return callback(err); } 161 | request.get(url + "&type=" + type, function(err, res, body) { 162 | if(err) { 163 | return callback(error.REQUEST_ERROR(err)); 164 | } 165 | returnsFunc(body, true, callback); 166 | }); 167 | }); 168 | } 169 | 170 | /** 171 | * get url with access token (获得带有access token的url) 172 | * @param {String} url [api key] 173 | * @param {Function} callback(error, url) 174 | */ 175 | function formatUrl(url, callback) { 176 | getAccessToken(function(err, token) { 177 | if(err) {return callback(err); } 178 | callback(null, url + "?access_token=" + token); 179 | }); 180 | } 181 | 182 | module.exports = { 183 | getConfig: getConfig, 184 | setConfig: setConfig, 185 | getTicket: getTicket, 186 | getAccessToken: getAccessToken, 187 | getUrl: formatUrl, 188 | api: api 189 | }; -------------------------------------------------------------------------------- /libs/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | basic: require("./api/basic"), 3 | shop: require("./api/shop"), 4 | card: require("./api/card"), 5 | code: require("./api/code"), 6 | setConfig: require("./config").setConfig, 7 | config: require("./config").setConfig 8 | }; -------------------------------------------------------------------------------- /libs/utils/encrypt.js: -------------------------------------------------------------------------------- 1 | var crypto = require("crypto"); 2 | 3 | exports.sha1 = function(msg) { 4 | var enc = crypto.createHash("sha1"); 5 | enc.update(msg); 6 | return enc.digest("hex"); 7 | }; -------------------------------------------------------------------------------- /libs/utils/errors.js: -------------------------------------------------------------------------------- 1 | var errors = { 2 | REQUEST_ERROR: function(err) { 3 | return {code: 9001, msg: "request error: " + err}; 4 | }, 5 | MISSING_PARAMS: function() { 6 | return {code: 9002, msg: "missing parameters"}; 7 | }, 8 | MISSING_CARD_OPTION: function() { 9 | return {code: 9003, msg: "missing card options parameters"}; 10 | }, 11 | ACCESS_TOKEN_ERROR: function() { 12 | return {code: 9004, msg: "get access token error"}; 13 | }, 14 | SHOPS_LIST_CANNOT_NULL: function() { 15 | return {code: 9005, msg: "shop list cannot null"}; 16 | }, 17 | LUCK_MONEY_BALANCE_ERROR: function() { 18 | return {code: 9006, msg: "luck money balance error"}; 19 | }, 20 | SIGN_DATA_CANNOT_NULL: function() { 21 | return {code: 9007, msg: "signature array cannot empty"}; 22 | }, 23 | TOKEN_SERVICE_FORMAT_ERROR: function(err) { 24 | return {code: 9008, msg: "access token service format error, must be {access_token: \"\"}"} 25 | }, 26 | TOKEN_METHOD_TYPE_ERROR: function(err) { 27 | return {code: 9009, msg: "token method have to be a function"}; 28 | }, 29 | INTERFACE_ERROR: function(err) { 30 | return {code: err.errcode, msg: "wechat interface error: " + err.errmsg}; 31 | } 32 | }; 33 | 34 | module.exports = errors; -------------------------------------------------------------------------------- /libs/utils/request.js: -------------------------------------------------------------------------------- 1 | var request = require("request"); 2 | var config = require("../config"); 3 | var error = require("./errors"); 4 | 5 | exports.post = function(api, options, callback) { 6 | config.getUrl(api, function(err, url) { 7 | 8 | // get access token error 9 | if(err) { 10 | return callback(err); 11 | } 12 | request.post(url, options, function(err, res, body) { 13 | 14 | // request error 15 | if(err) { 16 | return callback(error.REQUEST_ERROR(err)); 17 | } 18 | var result = JSON.parse(body); 19 | 20 | // wechat interface error 21 | if(result.errcode != 0) { 22 | return callback(error.INTERFACE_ERROR(result)); 23 | } 24 | callback(null, result); 25 | }); 26 | }); 27 | }; 28 | 29 | exports.get = function(api, callback) { 30 | config.getUrl(api, function(err, url) { 31 | 32 | // get access token error 33 | if(err) { 34 | return callback(err); 35 | } 36 | request.get(url, function(err, res, body) { 37 | 38 | // request error 39 | if(err) { 40 | return callback(error.REQUEST_ERROR(err)); 41 | } 42 | var result = JSON.parse(body); 43 | 44 | // wechat interface error 45 | if(result.errcode != 0) { 46 | return callback(error.INTERFACE_ERROR(result)); 47 | } 48 | callback(null, result); 49 | }); 50 | }); 51 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wechat-card", 3 | "version": "1.0.8", 4 | "description": "微信卡券接口. Wechat( Weixin ) Card, include coupon , discount, cash, gift, etc..", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "./node_modules/mocha/bin/mocha --timeout 5000 test/test.js" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/kenticny/wechat-card.git" 12 | }, 13 | "author": "kenticny", 14 | "license": "MIT", 15 | "bugs": { 16 | "url": "https://github.com/kenticny/wechat-card/issues" 17 | }, 18 | "homepage": "https://github.com/kenticny/wechat-card", 19 | "keywords": [ 20 | "weixin", 21 | "wechat", 22 | "card", 23 | "coupon" 24 | ], 25 | "dependencies": { 26 | "request": "^2.51.0" 27 | }, 28 | "devDependencies": { 29 | "mocha": "^2.2.1" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | var wxCard = require("../index"); 2 | 3 | describe("Wechat Card Basic API", function() { 4 | it("Get Access Token", function(done) { 5 | wxCard.basic.getAccessToken(function(err, res) { 6 | done(); 7 | }); 8 | }); 9 | 10 | it("Get Api Ticket", function(done) { 11 | wxCard.basic.getApiTicket(function(err, res) { 12 | done(); 13 | }); 14 | }); 15 | 16 | it("Get JsApi Ticket", function(done) { 17 | wxCard.basic.getJsApiTicket(function(err, res) { 18 | done(); 19 | }); 20 | }); 21 | }); 22 | 23 | describe("Wechat Card Card API", function() { 24 | it("Create Card", function(done) { 25 | wxCard.card.createCard({}, function(err, res) { 26 | done(); 27 | }); 28 | }); 29 | 30 | it("Get Card Detail", function(done) { 31 | wxCard.card.createCard({}, function(err, res) { 32 | done(); 33 | }); 34 | }); 35 | 36 | it("Get Card Id List", function(done) { 37 | wxCard.card.getCardIdList(function(err, res){ 38 | done(); 39 | }); 40 | }); 41 | 42 | it("Modify Card", function(done) { 43 | wxCard.card.modifyCard({}, function(err, res) { 44 | done(); 45 | }); 46 | }); 47 | 48 | it("Delete Card", function(done) { 49 | wxCard.card.deleteCard("pyRSqjpOxaMX_nEh_wum_jUHARz8", function(err, res) { 50 | done(); 51 | }); 52 | }); 53 | 54 | it("Modify Card Stock", function(done) { 55 | wxCard.card.modifyCardStock("pyRSqjpOxaMX_nEh_wum_jUHARz8", -10, function(err, res) { 56 | done(); 57 | }); 58 | }); 59 | 60 | it("Create Card QR Code", function(done) { 61 | wxCard.card.createCardQRCode("pyRSqjpOxaMX_nEh_wum_jUHARz8", function(err, res) { 62 | done(); 63 | }); 64 | }); 65 | 66 | }); 67 | 68 | describe("Wechat Card Code API", function() { 69 | it("Consume Code", function(done) { 70 | wxCard.code.consumeCode("344964648644", function(err, res) { 71 | done(); 72 | }); 73 | }); 74 | 75 | it("Get Code Detail", function(done) { 76 | wxCard.code.getCodeDetail("344964648644", function(err, res) { 77 | done(); 78 | }); 79 | }); 80 | 81 | it("Decrypt Code", function(done) { 82 | wxCard.code.codeDecrypt("aa", function(err, res) { 83 | done(); 84 | }); 85 | }); 86 | 87 | it("Set Code Expire", function(done) { 88 | wxCard.code.setCodeExpire("957871595617", function(err, res) { 89 | done(); 90 | }); 91 | }); 92 | 93 | it("Modify Luck Money Balance", function(done) { 94 | wxCard.code.modifyLuckMoneyBalance("aa", 50, function(err, res) { 95 | done(); 96 | }); 97 | }); 98 | 99 | it("Modify Code", function(done) { 100 | wxCard.code.modifyCode("123123123123", "pyRSqjpOxaMX_nEh_wum_jUHARz8", 101 | "21123123124", function() { 102 | done(); 103 | }); 104 | }); 105 | }); 106 | --------------------------------------------------------------------------------