View Javadoc
1   package com.foxinmy.weixin4j.mp.api;
2   
3   import java.io.IOException;
4   import java.util.List;
5   
6   import com.alibaba.fastjson.JSON;
7   import com.alibaba.fastjson.JSONArray;
8   import com.alibaba.fastjson.JSONObject;
9   import com.alibaba.fastjson.TypeReference;
10  import com.foxinmy.weixin4j.exception.WeixinException;
11  import com.foxinmy.weixin4j.http.weixin.ApiResult;
12  import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
13  import com.foxinmy.weixin4j.model.Token;
14  import com.foxinmy.weixin4j.model.card.*;
15  import com.foxinmy.weixin4j.model.qr.QRParameter;
16  import com.foxinmy.weixin4j.model.qr.QRResult;
17  import com.foxinmy.weixin4j.token.TokenManager;
18  import com.foxinmy.weixin4j.type.card.CardStatus;
19  import com.foxinmy.weixin4j.type.card.CardType;
20  import com.foxinmy.weixin4j.util.IOUtil;
21  
22  /**
23   * 卡券API
24   *
25   * @className CardApi
26   * @author jinyu(foxinmy@gmail.com)
27   * @date 2016年8月3日
28   * @since JDK 1.6
29   * @see <a
30   *      href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1451025056&token=&lang=zh_CN">卡券说明</a>
31   */
32  public class CardApi extends MpApi {
33  	protected final TokenManager tokenManager;
34  
35  	public CardApi(TokenManager tokenManager) {
36  		this.tokenManager = tokenManager;
37  	}
38  
39  	/**
40  	 * 创建卡券:创建卡券接口是微信卡券的基础接口,用于创建一类新的卡券,获取card_id,创建成功并通过审核后,
41  	 * 商家可以通过文档提供的其他接口将卡券下发给用户,每次成功领取,库存数量相应扣除。
42  	 *
43  	 * <li>1.需自定义Code码的商家必须在创建卡券时候,设定use_custom_code为true,且在调用投放卡券接口时填入指定的Code码。
44  	 * 指定OpenID同理。特别注意:在公众平台创建的卡券均为非自定义Code类型。 <li>
45  	 * 2.can_share字段指领取卡券原生页面是否可分享,建议指定Code码、指定OpenID等强限制条件的卡券填写false。 <li>
46  	 * 3.创建成功后该卡券会自动提交审核
47  	 * ,审核结果将通过事件通知商户。开发者可调用设置白名单接口设置用户白名单,领取未通过审核的卡券,测试整个卡券的使用流程。
48  	 *
49  	 * @param cardCoupon
50  	 *            卡券对象
51  	 * @see <a
52  	 *      href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1451025056&token=&lang=zh_CN">创建卡券</a>
53  	 * @see CardCoupons
54  	 * @see MediaApi#uploadImage(java.io.InputStream, String)
55  	 * @return 卡券ID
56  	 * @throws WeixinException
57  	 */
58  	public String createCardCoupon(CardCoupon cardCoupon)
59  			throws WeixinException {
60  		JSONObject content = new JSONObject();
61  		String cardType = cardCoupon.getCardType().name();
62  		content.put("card_type", cardType);
63  		content.put(cardType.toLowerCase(), cardCoupon);
64  		JSONObject card = new JSONObject();
65  		card.put("card", content);
66  		Token token = tokenManager.getCache();
67  		String card_create_uri = getRequestUri("card_create_uri");
68  		WeixinResponse response = weixinExecutor.post(
69  				String.format(card_create_uri, token.getAccessToken()),
70  				card.toJSONString());
71  		return response.getAsJson().getString("card_id");
72  	}
73  
74  	/**
75  	 * 设置卡券买单:创建卡券之后,开发者可以通过设置微信买单接口设置该card_id支持微信买单功能。值得开发者注意的是,
76  	 * 设置买单的card_id必须已经配置了门店,否则会报错。
77  	 *
78  	 * @param cardId
79  	 *            卡券ID
80  	 * @param isOpen
81  	 *            是否开启买单功能,填true/false
82  	 * @see #createCardCoupon(CardCoupon)
83  	 * @return 操作结果
84  	 * @throws WeixinException
85  	 */
86  	public ApiResult setCardPayCell(String cardId, boolean isOpen)
87  			throws WeixinException {
88  		JSONObject params = new JSONObject();
89  		params.put("card_id", cardId);
90  		params.put("is_open", isOpen);
91  		Token token = tokenManager.getCache();
92  		String card_paycell_uri = getRequestUri("card_paycell_uri");
93  		WeixinResponse response = weixinExecutor.post(
94  				String.format(card_paycell_uri, token.getAccessToken()),
95  				params.toJSONString());
96  		return response.getAsResult();
97  	}
98  
99  	/**
100 	 * 设置自助核销:创建卡券之后,开发者可以通过设置微信买单接口设置该card_id支持自助核销功能。值得开发者注意的是,
101 	 * 设置自助核销的card_id必须已经配置了门店,否则会报错。
102 	 *
103 	 * @param cardId
104 	 *            卡券ID
105 	 * @param isOpen
106 	 *            是否开启买单功能,填true/false
107 	 * @see #createCardCoupon(CardCoupon)
108 	 * @return 操作结果
109 	 * @throws WeixinException
110 	 */
111 	public ApiResult setCardSelfConsumeCell(String cardId, boolean isOpen)
112 			throws WeixinException {
113 		JSONObject params = new JSONObject();
114 		params.put("card_id", cardId);
115 		params.put("is_open", isOpen);
116 		Token token = tokenManager.getCache();
117 		String card_selfconsumecell_uri = getRequestUri("card_selfconsumecell_uri");
118 		WeixinResponse response = weixinExecutor
119 				.post(String.format(card_selfconsumecell_uri,
120 						token.getAccessToken()), params.toJSONString());
121 		return response.getAsResult();
122 	}
123 
124 	/**
125 	 * 创建卡券二维码: 开发者可调用该接口生成一张卡券二维码供用户扫码后添加卡券到卡包。
126 	 *
127 	 * @param expireSeconds
128 	 *            指定二维码的有效时间,范围是60 ~ 1800秒。不填默认为365天有效
129 	 * @param cardQRs
130 	 *            二维码参数:二维码领取单张卡券/多张卡券
131 	 * @return 二维码结果对象
132 	 * @see com.foxinmy.weixin4j.model.qr.QRResult
133 	 * @see com.foxinmy.weixin4j.model.qr.QRParameter
134 	 * @see <a
135 	 *      href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1451025062&token=&lang=zh_CN">投放卡券</a>
136 	 * @throws WeixinException
137 	 */
138 	public QRResult createCardQR(Integer expireSeconds, CardQR... cardQRs)
139 			throws WeixinException {
140 		QRParameter parameter = QRParameter.createCardCouponQR(expireSeconds,
141 				cardQRs);
142 		Token token = tokenManager.getCache();
143 		String qr_uri = getRequestUri("card_qr_ticket_uri");
144 		WeixinResponse response = weixinExecutor.post(
145 				String.format(qr_uri, token.getAccessToken()),
146 				JSON.toJSONString(parameter));
147 		QRResult result = response.getAsObject(new TypeReference<QRResult>() {
148 		});
149 		qr_uri = String.format(getRequestUri("qr_image_uri"),
150 				result.getTicket());
151 		response = weixinExecutor.get(qr_uri);
152 		result.setShowUrl(qr_uri);
153 		try {
154 			result.setContent(IOUtil.toByteArray(response.getBody()));
155 		} catch (IOException e) {
156 			throw new WeixinException(e);
157 		}
158 		return result;
159 	}
160 
161 	/**
162 	 * 由于卡券有审核要求,为方便公众号调试,可以设置一些测试帐号,这些帐号可领取未通过审核的卡券,体验整个流程。
163 	 * 1.同时支持“openid”、“username”两种字段设置白名单,总数上限为10个。
164 	 * 2.设置测试白名单接口为全量设置,即测试名单发生变化时需调用该接口重新传入所有测试人员的ID.
165 	 * 3.白名单用户领取该卡券时将无视卡券失效状态,请开发者注意。
166 	 * 
167 	 * @param openIds
168 	 *            the open ids
169 	 * @param userNames
170 	 *            the user names
171 	 * @author fengyapeng
172 	 * @since 2016 -12-20 11:22:57
173 	 * @see <a href=
174 	 *      'https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1451025062&token=&lang=zh_CN&anchor=6'>设置测试白名单</
175 	 *      a >
176 	 */
177 	public ApiResult setTestWhiteList(List<String> openIds,
178 			List<String> userNames) throws WeixinException {
179 		JSONObject requestObj = new JSONObject();
180 		if (openIds != null && openIds.size() > 0) {
181 			requestObj.put("openid", openIds);
182 		}
183 		if (userNames != null && userNames.size() > 0) {
184 			requestObj.put("username", userNames);
185 		}
186 		String card_set_test_whitelist_uri = getRequestUri("card_set_test_whitelist_uri");
187 		Token token = tokenManager.getCache();
188 		WeixinResponse response = weixinExecutor.post(
189 				String.format(card_set_test_whitelist_uri,
190 						token.getAccessToken()), requestObj.toJSONString());
191 		return response.getAsResult();
192 	}
193 
194 	/**
195 	 * 查看获取卡券的审核状态
196 	 * 
197 	 * @see <a href=
198 	 *      'https://mp.weixin.qq.com/wiki?action=doc&id=mp1451025272&t=0.18670321276182844#3'
199 	 *      > 查看卡券详情</a>
200 	 *
201 	 * @author fengyapeng
202 	 * @since 2016 -12-20 11:48:23
203 	 */
204 	public CardStatus queryCardStatus(String cardId) throws WeixinException {
205 		JSONObject requestObj = new JSONObject();
206 		requestObj.put("card_id", cardId);
207 		String card_get_uri = getRequestUri("card_get_uri");
208 		Token token = tokenManager.getCache();
209 		WeixinResponse response = weixinExecutor.post(
210 				String.format(card_get_uri, token.getAccessToken()),
211 				requestObj.toJSONString());
212 		JSONObject responseAsJson = response.getAsJson();
213 		JSONObject card = responseAsJson.getJSONObject("card");
214 		String cardType = card.getString("card_type");
215 		JSONObject baseInfo = card.getJSONObject(cardType.toLowerCase())
216 				.getJSONObject("base_info");
217 		String status = baseInfo.getString("status");
218 		return CardStatus.valueOf(status);
219 	}
220 
221 	/**
222 	 * 查询某个card_id的创建信息、审核状态以及库存数量。
223 	 *
224 	 * @param cardId
225 	 * @return
226 	 * @throws WeixinException
227 	 */
228 	public JSONObject getCardInfo(String cardId) throws WeixinException {
229 		JSONObject requestObj = new JSONObject();
230 		requestObj.put("card_id", cardId);
231 		String card_get_uri = getRequestUri("card_get_uri");
232 		Token token = tokenManager.getCache();
233 		WeixinResponse response = weixinExecutor.post(
234 				String.format(card_get_uri, token.getAccessToken()),
235 				requestObj.toJSONString());
236 		JSONObject responseJson = response.getAsJson();
237 		return responseJson.getJSONObject("card");
238 	}
239 
240 	/**
241 	 * 支持更新所有卡券类型的部分通用字段及特殊卡券(会员卡、飞机票、电影票、会议门票)中特定字段的信息。
242 	 *
243 	 * @param cardId
244 	 *            the card id
245 	 * @param card
246 	 *            the card
247 	 * @return 是否提交审核,false为修改后不会重新提审,true为修改字段后重新提审,该卡券的状态变为审核中
248 	 * @throws WeixinException
249 	 *             the weixin exception
250 	 * @author fengyapeng
251 	 * @see
252 	 * @since 2016 -12-21 15:29:10
253 	 */
254 	public Boolean updateCardCoupon(String cardId, CardCoupon card)
255 			throws WeixinException {
256 		JSONObject request = new JSONObject();
257 		request.put("card_id", cardId);
258 		CardType cardType = card.getCardType();
259 		card.cleanCantUpdateField();
260 		request.put(cardType.name().toLowerCase(), card);
261 		String card_update_uri = getRequestUri("card_update_uri");
262 		Token token = tokenManager.getCache();
263 		WeixinResponse response = weixinExecutor.post(
264 				String.format(card_update_uri, token.getAccessToken()),
265 				JSON.toJSONString(request));
266 		JSONObject jsonObject = response.getAsJson();
267 		return jsonObject.getBoolean("send_check");
268 	}
269 
270 	/**
271 	 * 激活方式说明 接口激活通常需要开发者开发用户填写资料的网页。通常有两种激活流程: 1.
272 	 * 用户必须在填写资料后才能领卡,领卡后开发者调用激活接口为用户激活会员卡; 2.
273 	 * 是用户可以先领取会员卡,点击激活会员卡跳转至开发者设置的资料填写页面,填写完成后开发者调用激活接口为用户激活会员卡。
274 	 *
275 	 * @see <a href=
276 	 *      'https://mp.weixin.qq.com/wiki?action=doc&id=mp1451025283&t=0.8029895777585161#6.1'>接口激活</
277 	 *      a >
278 	 */
279 	public ApiResult activateMemberCard(MemberInitInfo memberInitInfo)
280 			throws WeixinException {
281 		String card_member_card_activate_uri = getRequestUri("card_member_card_activate_uri");
282 		Token token = tokenManager.getCache();
283 		WeixinResponse response = weixinExecutor.post(
284 				String.format(card_member_card_activate_uri,
285 						token.getAccessToken()),
286 				JSON.toJSONString(memberInitInfo));
287 		return response.getAsResult();
288 	}
289 
290 	/**
291 	 * 设置开卡字段接口 开发者在创建时填入wx_activate字段后, 需要调用该接口设置用户激活时需要填写的选项,否则一键开卡设置不生效。
292 	 *
293 	 * @see <a href=
294 	 *      'https://mp.weixin.qq.com/wiki?action=doc&id=mp1451025283&t=0.8029895777585161#6.2'>一键激活</
295 	 *      a >
296 	 */
297 	public ApiResult setActivateUserForm(MemberUserForm memberUserForm)
298 			throws WeixinException {
299 		String user_form_uri = getRequestUri("card_member_card_activate_user_form_uri");
300 		Token token = tokenManager.getCache();
301 		WeixinResponse response = weixinExecutor.post(
302 				String.format(user_form_uri, token.getAccessToken()),
303 				JSON.toJSONString(memberUserForm));
304 		return response.getAsResult();
305 	}
306 
307 	/**
308 	 * 拉取会员信息接口。
309 	 *
310 	 * @param cardId
311 	 *            the card id
312 	 * @param code
313 	 *            the code
314 	 * @author fengyapeng
315 	 * @since 2016 -12-21 11:28:45
316 	 */
317 	public MemberUserInfo getMemberUserInfo(String cardId, String code)
318 			throws WeixinException {
319 		String user_info_uri = getRequestUri("card_member_card_user_info_uri");
320 		Token token = tokenManager.getCache();
321 		JSONObject jsonObject = new JSONObject();
322 		jsonObject.put("card_id", cardId);
323 		jsonObject.put("code", code);
324 		WeixinResponse response = weixinExecutor.post(
325 				String.format(user_info_uri, token.getAccessToken()),
326 				JSON.toJSONString(jsonObject));
327 		return response.getAsObject(new TypeReference<MemberUserInfo>() {
328 		});
329 	}
330 
331 	/**
332 	 * 更新会员 result_bonus 当前用户积分总额 result_balance 当前用户预存总金额 openid 用户openid
333 	 * 
334 	 * @param updateInfo
335 	 * @return
336 	 * @throws WeixinException
337 	 */
338 	public JSONObject updateMemberUserInfo(MemberUpdateInfo updateInfo)
339 			throws WeixinException {
340 		String card_member_card_update_user_uri = getRequestUri("card_member_card_update_user_uri");
341 		Token token = tokenManager.getCache();
342 		WeixinResponse response = weixinExecutor.post(
343 				String.format(card_member_card_update_user_uri,
344 						token.getAccessToken()), JSON.toJSONString(updateInfo));
345 		return response.getAsJson();
346 	}
347 
348 	/**
349 	 * 创建一个礼品卡货架
350 	 *
351 	 * @param page
352 	 * @return 货架ID
353 	 * @throws WeixinException
354 	 */
355 	public String addGiftCardPage(GiftCardPage page) throws WeixinException {
356 		String card_gift_card_page_add = getRequestUri("card_gift_card_page_add_uri");
357 		JSONObject pageJson = new JSONObject();
358 		pageJson.put("page", page);
359 		Token token = tokenManager.getCache();
360 		WeixinResponse response = weixinExecutor.post(
361 				String.format(card_gift_card_page_add,
362 						token.getAccessToken()), JSON.toJSONString(pageJson));
363 		JSONObject jsonObject = response.getAsJson();
364 		return jsonObject.getString("page_id");
365 	}
366 
367 	/**
368 	 * 查询礼品卡货架信息
369 	 *
370 	 * @param pageId
371 	 * 			货架ID
372 	 * @return
373 	 * @throws WeixinException
374 	 */
375 	public JSONObject getGiftCardPage(String pageId) throws WeixinException {
376 		String card_gift_card_page_get = getRequestUri("card_gift_card_page_get_uri");
377 		JSONObject param = new JSONObject();
378 		param.put("page_id", pageId);
379 		Token token = tokenManager.getCache();
380 		WeixinResponse response = weixinExecutor.post(
381 				String.format(card_gift_card_page_get,
382 						token.getAccessToken()), JSON.toJSONString(param));
383 		JSONObject jsonObject = response.getAsJson();
384 
385 		return jsonObject.getJSONObject("page");
386 	}
387 
388 	/**
389 	 * 查询当前商户下所有的礼品卡货架id
390 	 *
391 	 * @return
392 	 * @throws WeixinException
393 	 */
394 	public String[] getGiftCardPageIdList() throws WeixinException {
395 		String card_gift_card_page_batchget = getRequestUri("card_gift_card_page_batchget_uri");
396 		JSONObject param = new JSONObject();
397 		Token token = tokenManager.getCache();
398 		WeixinResponse response = weixinExecutor.post(
399 				String.format(card_gift_card_page_batchget,
400 						token.getAccessToken()), JSON.toJSONString(param));
401 		JSONObject jsonObject = response.getAsJson();
402 		JSONArray idList = jsonObject.getJSONArray("page_id_list");
403 		if(idList==null || idList.size()==0){
404 			return new String[0];
405 		}
406 
407 		return idList.toArray(new String[idList.size()]);
408 	}
409 
410 	/**
411 	 * 下架礼品卡货架
412 	 *
413 	 * @param pageId
414 	 * 			礼品卡货架ID
415 	 * @return
416 	 * @throws WeixinException
417 	 */
418 	public ApiResult maintainGiftCardPage(String pageId) throws WeixinException {
419 		String card_gift_card_maintain_set = getRequestUri("card_gift_card_maintain_set_uri");
420 		JSONObject param = new JSONObject();
421 		param.put("page_id", pageId);
422 		param.put("maintain", true);
423 		Token token = tokenManager.getCache();
424 		WeixinResponse response = weixinExecutor.post(
425 				String.format(card_gift_card_maintain_set,
426 						token.getAccessToken()), JSON.toJSONString(param));
427 		return response.getAsResult();
428 	}
429 
430 	/**
431 	 * 下架所有礼品卡货架
432 	 *
433 	 * @return
434 	 * @throws WeixinException
435 	 */
436 	public ApiResult maintainAllGiftCardPage() throws WeixinException {
437 		String card_gift_card_maintain_set = getRequestUri("card_gift_card_maintain_set_uri");
438 		JSONObject param = new JSONObject();
439 		param.put("all", true);
440 		param.put("maintain", true);
441 		Token token = tokenManager.getCache();
442 		WeixinResponse response = weixinExecutor.post(
443 				String.format(card_gift_card_maintain_set,
444 						token.getAccessToken()), JSON.toJSONString(param));
445 		return response.getAsResult();
446 	}
447 
448 	/**
449 	 * 查询某个订单号对应的订单详情
450 	 *
451 	 * @param orderId
452 	 * 			礼品卡订单号,商户可以通过购买成功的事件推送或者批量查询订单接口获得
453 	 * @return
454 	 * @throws WeixinException
455 	 */
456 	public JSONObject getOrderInfo(String orderId) throws WeixinException {
457 		String card_gift_card_order_get = getRequestUri("card_gift_card_order_get_uri");
458 		JSONObject param = new JSONObject();
459 		param.put("order_id", orderId);
460 		Token token = tokenManager.getCache();
461 		WeixinResponse response = weixinExecutor.post(
462 				String.format(card_gift_card_order_get,
463 						token.getAccessToken()), JSON.toJSONString(param));
464 
465 		return response.getAsJson();
466 	}
467 
468 	/**
469 	 * 批量查询礼品卡订单信息接口
470 	 *
471 	 * @param beginTime
472 	 * 			查询的时间起点,十位时间戳(utc+8)
473 	 * @param endTime
474 	 * 			查询的时间终点,十位时间戳(utc+8)
475 	 * @param sortType
476 	 * 			填"ASC" / "DESC",表示对订单创建时间进行“升 / 降”排序
477 	 * @param offset
478 	 * 			查询的订单偏移量,如填写100则表示从第100个订单开始拉取
479 	 * @param limit
480 	 * 			查询订单的数量,如offset填写100,count填写10,则表示查询第100个到第110个订单
481 	 * @return
482 	 * @throws WeixinException
483 	 */
484 	public JSONObject getOrders(long beginTime, long endTime, String sortType, int offset, int limit) throws WeixinException {
485 		String card_gift_card_order_batchget_uri = getRequestUri("card_gift_card_order_batchget_uri");
486 		JSONObject param = new JSONObject();
487 		param.put("begin_time", beginTime);
488 		param.put("end_time", endTime);
489 		param.put("sort_type", sortType);
490 		param.put("offset", offset);
491 		param.put("count", limit);
492 		Token token = tokenManager.getCache();
493 		WeixinResponse response = weixinExecutor.post(
494 				String.format(card_gift_card_order_batchget_uri,
495 						token.getAccessToken()), JSON.toJSONString(param));
496 
497 		return response.getAsJson();
498 	}
499 
500 	/**
501 	 * 更新礼品卡货架
502 	 *
503 	 * @param page
504 	 * @return
505 	 * @throws WeixinException
506 	 */
507 	public ApiResult updateGiftCardPage(GiftCardPage page) throws WeixinException {
508 		String card_gift_card_page_update_uri = getRequestUri("card_gift_card_page_update_uri");
509 		JSONObject pageJson = new JSONObject();
510 		pageJson.put("page", page);
511 		Token token = tokenManager.getCache();
512 		WeixinResponse response = weixinExecutor.post(
513 				String.format(card_gift_card_page_update_uri,
514 						token.getAccessToken()), JSON.toJSONString(pageJson));
515 		return response.getAsResult();
516 	}
517 
518 	/**
519 	 * 申请礼品卡的微信支付权限
520 	 *
521 	 * @param subMchId
522 	 * 			微信支付子商户号,须为普通服务商模式或者直连商户号,建议为礼品卡专用商户号;商户号必须为公众号申请的商户号
523 	 * 			公众号须与商户号同主体,非同主体情况须和对接人联系申请
524 	 * @return 商户平台确认地址,请获得后点击打开登录商户平台后台并点击确认
525 	 * @throws WeixinException
526 	 */
527 	public String addGiftCardPayWhitelist(String subMchId) throws WeixinException{
528 		String card_gift_card_pay_whitelist_add = getRequestUri("card_gift_card_pay_whitelist_add_uri");
529 		JSONObject param = new JSONObject();
530 		param.put("sub_mch_id", subMchId);
531 		Token token = tokenManager.getCache();
532 		WeixinResponse response = weixinExecutor.post(
533 				String.format(card_gift_card_pay_whitelist_add,
534 						token.getAccessToken()), JSON.toJSONString(param));
535 		JSONObject jsonObject = response.getAsJson();
536 		return jsonObject.getString("url");
537 	}
538 
539 	/**
540 	 * 绑定商户号到礼品卡小程序
541 	 *
542 	 * @param wxaAppid
543 	 * 			礼品卡小程序APPID
544 	 * @param subMchId
545 	 * 			微信支付商户号
546 	 * @return
547 	 * @throws WeixinException
548 	 */
549 	public ApiResult bindGiftCardPaySubMch(String wxaAppid, String subMchId) throws WeixinException {
550 		String card_gift_card_pay_submch_bind = getRequestUri("card_gift_card_pay_submch_bind_uri");
551 		JSONObject param = new JSONObject();
552 		param.put("sub_mch_id", subMchId);
553 		param.put("wxa_appid", wxaAppid);
554 
555 		Token token = tokenManager.getCache();
556 		WeixinResponse response = weixinExecutor.post(
557 				String.format(card_gift_card_pay_submch_bind,
558 						token.getAccessToken()), JSON.toJSONString(param));
559 
560 		return response.getAsResult();
561 	}
562 
563 	/**
564 	 * 上传礼品卡小程序代码
565 	 * (提供小程序APPID及货架ID,由微信平台为你小程序帐号上传一套现成的礼品卡小程序,直接用于礼品卡售卖)
566 	 *
567 	 * @param wxaAppid
568 	 * 			微信小程序APPID
569 	 * @param pageId
570 	 * 			礼品卡货架ID
571 	 * @return
572 	 * @throws WeixinException
573 	 */
574 	public ApiResult setGiftCardWxaCode(String wxaAppid, String pageId) throws WeixinException {
575 		String card_gift_card_wxa_set = getRequestUri("card_gift_card_wxa_set_uri");
576 		JSONObject param = new JSONObject();
577 		param.put("wxa_appid", wxaAppid);
578 		param.put("page_id", pageId);
579 
580 		Token token = tokenManager.getCache();
581 		WeixinResponse response = weixinExecutor.post(
582 				String.format(card_gift_card_wxa_set,
583 						token.getAccessToken()), JSON.toJSONString(param));
584 
585 		return response.getAsResult();
586 	}
587 
588 	/**
589 	 * 更新用户礼品卡信息
590 	 * 当礼品卡被使用后,可以通过该接口变更某个礼品卡的余额信息。
591 	 *
592 	 * @param cardInfo
593 	 * @return
594 	 * @throws WeixinException
595 	 */
596 	public JSONObject updateGiftCardUserBalance(CardInfo cardInfo) throws WeixinException {
597 		String card_gift_card_wxa_set = getRequestUri("card_general_card_update_user_uri");
598 
599 		Token token = tokenManager.getCache();
600 		WeixinResponse response = weixinExecutor.post(
601 				String.format(card_gift_card_wxa_set,
602 						token.getAccessToken()), JSON.toJSONString(cardInfo));
603 		return response.getAsJson();
604 	}
605 
606 	/**
607 	 * 当礼品卡被使用完毕或者发生转存、绑定等操作后,开发者可以通过该接口核销用户的礼品卡,使礼品卡在列表中沉底并不再被使用。
608 	 *
609 	 * @param code
610 	 * 			卡券Code码。
611 	 * @param cardId
612 	 * 			卡券ID,自定义code卡券必填,否则非必填。
613 	 * @return
614 	 * @throws WeixinException
615 	 */
616 	public ApiResult consumeGiftCard(String code, String cardId) throws WeixinException {
617 		String card_code_consume = getRequestUri("card_code_consume_uri");
618 		JSONObject param = new JSONObject();
619 		param.put("code", code);
620 		if(cardId!=null && cardId.length()>0){
621 			param.put("card_id", cardId);
622 		}
623 
624 		Token token = tokenManager.getCache();
625 		WeixinResponse response = weixinExecutor.post(
626 				String.format(card_code_consume,
627 						token.getAccessToken()), JSON.toJSONString(param));
628 
629 		return response.getAsResult();
630 	}
631 
632 	/**
633 	 * 开发者可以通过该接口查询到code对应的信息,如余额、有效期、订单号等,主要用于防止在交易完成后丢单的情况下,用于核销/余额变动时兜底处理。
634 	 * 注意:需在礼品卡核销前调用,否则会报40099 已核销的错误
635 	 *
636 	 * @param code
637 	 * 			卡券Code码
638 	 * @param cardId
639 	 * 			卡券ID,自定义code卡券必填,否则非必填。
640 	 * @return
641 	 * @throws WeixinException
642 	 */
643 	public JSONObject getGiftCardInfo(String code, String cardId) throws WeixinException {
644 		String card_code_get = getRequestUri("card_code_get_uri");
645 		JSONObject param = new JSONObject();
646 		param.put("code", code);
647 		if(cardId!=null && cardId.length()>0){
648 			param.put("card_id", cardId);
649 		}
650 
651 		Token token = tokenManager.getCache();
652 		WeixinResponse response = weixinExecutor.post(
653 				String.format(card_code_get,
654 						token.getAccessToken()), JSON.toJSONString(param));
655 
656 		return response.getAsJson();
657 	}
658 
659 	/**
660 	 * 对一笔礼品卡订单操作退款
661 	 *
662 	 * @param orderId
663 	 * 			订单ID
664 	 * @return
665 	 * @throws WeixinException
666 	 */
667 	public ApiResult orderRefund(String orderId) throws WeixinException {
668 		String card_gift_card_order_refund_uri = getRequestUri("card_gift_card_order_refund_uri");
669 		JSONObject param = new JSONObject();
670 		param.put("order_id", orderId);
671 
672 		Token token = tokenManager.getCache();
673 		WeixinResponse response = weixinExecutor.post(
674 				String.format(card_gift_card_order_refund_uri,
675 						token.getAccessToken()), JSON.toJSONString(param));
676 
677 		return response.getAsResult();
678 	}
679 }