1、增加卡券的api_ticket,区分jsapi_ticket,二者的获取逻辑不同; 2、增加小程序审核事件及审核事件推送消息SuccTime和Reason两个字段; 3、增加开放平台获取会员卡开卡插件参数接口。 4、增加开放平台手机端预授权接口实现;master
@@ -250,6 +250,15 @@ public class WxConsts { | |||||
*/ | */ | ||||
public static final String CARD_PAY_ORDER = "card_pay_order"; | public static final String CARD_PAY_ORDER = "card_pay_order"; | ||||
/** | |||||
* 小程序审核事件:审核通过 | |||||
*/ | |||||
public static final String WEAPP_AUDIT_SUCCESS = "weapp_audit_success"; | |||||
/** | |||||
* 小程序审核事件:审核不通过 | |||||
*/ | |||||
public static final String WEAPP_AUDIT_FAIL = "weapp_audit_fail"; | |||||
} | } | ||||
@@ -15,7 +15,26 @@ public interface WxMaJsapiService { | |||||
/** | /** | ||||
* 获得jsapi_ticket的url | * 获得jsapi_ticket的url | ||||
*/ | */ | ||||
String GET_JSAPI_TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi"; | |||||
String GET_JSAPI_TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket"; | |||||
/** | |||||
* 获得卡券api_ticket,不强制刷新api_ticket | |||||
* | |||||
* @see #getJsapiTicket(boolean) | |||||
*/ | |||||
String getCardApiTicket() throws WxErrorException; | |||||
/** | |||||
* <pre> | |||||
* 获得卡券api_ticket | |||||
* 获得时会检查apiToken是否过期,如果过期了,那么就刷新一下,否则就什么都不干 | |||||
* | |||||
* 详情请见:http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&lang=zh_CN | |||||
* </pre> | |||||
* | |||||
* @param forceRefresh 强制刷新 | |||||
*/ | |||||
String getCardApiTicket(boolean forceRefresh) throws WxErrorException; | |||||
/** | /** | ||||
* 获得jsapi_ticket,不强制刷新jsapi_ticket | * 获得jsapi_ticket,不强制刷新jsapi_ticket | ||||
@@ -28,6 +28,32 @@ public class WxMaJsapiServiceImpl implements WxMaJsapiService { | |||||
this.wxMaService = wxMaService; | this.wxMaService = wxMaService; | ||||
} | } | ||||
public String getCardApiTicket() throws WxErrorException { | |||||
return getCardApiTicket(false); | |||||
} | |||||
public String getCardApiTicket(boolean forceRefresh) throws WxErrorException { | |||||
Lock lock = this.wxMaService.getWxMaConfig().getCardApiTicketLock(); | |||||
try { | |||||
lock.lock(); | |||||
if (forceRefresh) { | |||||
this.wxMaService.getWxMaConfig().expireCardApiTicket(); | |||||
} | |||||
if (this.wxMaService.getWxMaConfig().isCardApiTicketExpired()) { | |||||
String responseContent = this.wxMaService.get(GET_JSAPI_TICKET_URL + "?type=wx_card", null); | |||||
JsonElement tmpJsonElement = JSON_PARSER.parse(responseContent); | |||||
JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject(); | |||||
String jsapiTicket = tmpJsonObject.get("ticket").getAsString(); | |||||
int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt(); | |||||
this.wxMaService.getWxMaConfig().updateCardApiTicket(jsapiTicket, expiresInSeconds); | |||||
} | |||||
} finally { | |||||
lock.unlock(); | |||||
} | |||||
return this.wxMaService.getWxMaConfig().getJsapiTicket(); | |||||
} | |||||
@Override | @Override | ||||
public String getJsapiTicket() throws WxErrorException { | public String getJsapiTicket() throws WxErrorException { | ||||
return getJsapiTicket(false); | return getJsapiTicket(false); | ||||
@@ -43,7 +69,7 @@ public class WxMaJsapiServiceImpl implements WxMaJsapiService { | |||||
} | } | ||||
if (this.wxMaService.getWxMaConfig().isJsapiTicketExpired()) { | if (this.wxMaService.getWxMaConfig().isJsapiTicketExpired()) { | ||||
String responseContent = this.wxMaService.get(GET_JSAPI_TICKET_URL, null); | |||||
String responseContent = this.wxMaService.get(GET_JSAPI_TICKET_URL + "?type=jsapi", null); | |||||
JsonElement tmpJsonElement = JSON_PARSER.parse(responseContent); | JsonElement tmpJsonElement = JSON_PARSER.parse(responseContent); | ||||
JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject(); | JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject(); | ||||
String jsapiTicket = tmpJsonObject.get("ticket").getAsString(); | String jsapiTicket = tmpJsonObject.get("ticket").getAsString(); | ||||
@@ -57,6 +57,25 @@ public interface WxMaConfig { | |||||
*/ | */ | ||||
void updateJsapiTicket(String jsapiTicket, int expiresInSeconds); | void updateJsapiTicket(String jsapiTicket, int expiresInSeconds); | ||||
String getCardApiTicket(); | |||||
Lock getCardApiTicketLock(); | |||||
boolean isCardApiTicketExpired(); | |||||
/** | |||||
* 强制将卡券api ticket过期掉 | |||||
*/ | |||||
void expireCardApiTicket(); | |||||
/** | |||||
* 应该是线程安全的 | |||||
* | |||||
* @param 卡券apiTicket 新的卡券api ticket值 | |||||
* @param expiresInSeconds 过期时间,以秒为单位 | |||||
*/ | |||||
void updateCardApiTicket(String apiTicket, int expiresInSeconds); | |||||
String getAppid(); | String getAppid(); | ||||
String getSecret(); | String getSecret(); | ||||
@@ -1,14 +1,13 @@ | |||||
package cn.binarywang.wx.miniapp.config; | package cn.binarywang.wx.miniapp.config; | ||||
import java.io.File; | |||||
import java.util.concurrent.locks.Lock; | |||||
import java.util.concurrent.locks.ReentrantLock; | |||||
import me.chanjar.weixin.common.bean.WxAccessToken; | |||||
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; | |||||
import org.apache.commons.lang3.builder.ToStringBuilder; | import org.apache.commons.lang3.builder.ToStringBuilder; | ||||
import org.apache.commons.lang3.builder.ToStringStyle; | import org.apache.commons.lang3.builder.ToStringStyle; | ||||
import me.chanjar.weixin.common.bean.WxAccessToken; | |||||
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; | |||||
import java.io.File; | |||||
import java.util.concurrent.locks.Lock; | |||||
import java.util.concurrent.locks.ReentrantLock; | |||||
/** | /** | ||||
* 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化 | * 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化 | ||||
@@ -32,8 +31,14 @@ public class WxMaInMemoryConfig implements WxMaConfig { | |||||
protected volatile String jsapiTicket; | protected volatile String jsapiTicket; | ||||
protected volatile long jsapiTicketExpiresTime; | protected volatile long jsapiTicketExpiresTime; | ||||
//微信卡券的ticket单独缓存 | |||||
protected volatile String cardApiTicket; | |||||
protected volatile long cardApiTicketExpiresTime; | |||||
protected Lock accessTokenLock = new ReentrantLock(); | protected Lock accessTokenLock = new ReentrantLock(); | ||||
protected Lock jsapiTicketLock = new ReentrantLock(); | protected Lock jsapiTicketLock = new ReentrantLock(); | ||||
protected Lock cardApiTicketLock = new ReentrantLock(); | |||||
/** | /** | ||||
* 临时文件目录 | * 临时文件目录 | ||||
@@ -103,6 +108,34 @@ public class WxMaInMemoryConfig implements WxMaConfig { | |||||
this.jsapiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L; | this.jsapiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L; | ||||
} | } | ||||
@Override | |||||
public String getCardApiTicket() { | |||||
return this.cardApiTicket; | |||||
} | |||||
@Override | |||||
public Lock getCardApiTicketLock() { | |||||
return this.cardApiTicketLock; | |||||
} | |||||
@Override | |||||
public boolean isCardApiTicketExpired() { | |||||
return System.currentTimeMillis() > this.cardApiTicketExpiresTime; | |||||
} | |||||
@Override | |||||
public void expireCardApiTicket() { | |||||
this.cardApiTicketExpiresTime = 0; | |||||
} | |||||
@Override | |||||
public void updateCardApiTicket(String cardApiTicket, int expiresInSeconds) { | |||||
this.cardApiTicket = cardApiTicket; | |||||
// 预留200秒的时间 | |||||
this.cardApiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L; | |||||
} | |||||
@Override | @Override | ||||
public void expireAccessToken() { | public void expireAccessToken() { | ||||
this.expiresTime = 0; | this.expiresTime = 0; | ||||
@@ -24,6 +24,11 @@ public interface WxMpMemberCardService { | |||||
*/ | */ | ||||
String MEMBER_CARD_ACTIVATEUSERFORM = "https://api.weixin.qq.com/card/membercard/activateuserform/set"; | String MEMBER_CARD_ACTIVATEUSERFORM = "https://api.weixin.qq.com/card/membercard/activateuserform/set"; | ||||
/** | |||||
* 获取会员卡开卡插件参数 | |||||
*/ | |||||
String MEMBER_CARD_ACTIVATE_URL = "https://api.weixin.qq.com/card/membercard/activate/geturl"; | |||||
/** | /** | ||||
* 得到WxMpService | * 得到WxMpService | ||||
*/ | */ | ||||
@@ -88,4 +93,13 @@ public interface WxMpMemberCardService { | |||||
*/ | */ | ||||
MemberCardActivateUserFormResult setActivateUserForm(MemberCardActivateUserFormRequest userFormRequest) throws WxErrorException; | MemberCardActivateUserFormResult setActivateUserForm(MemberCardActivateUserFormRequest userFormRequest) throws WxErrorException; | ||||
/** | |||||
* 获取会员卡开卡插件参数(跳转型开卡组件需要参数) | |||||
* | |||||
* @param cardId | |||||
* @param outStr | |||||
* @return | |||||
* @throws WxErrorException | |||||
*/ | |||||
ActivatePluginParam getActivatePluginParam(String cardId, String outStr) throws WxErrorException; | |||||
} | } |
@@ -19,6 +19,11 @@ import org.apache.commons.lang3.StringUtils; | |||||
import org.slf4j.Logger; | import org.slf4j.Logger; | ||||
import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||
import java.io.UnsupportedEncodingException; | |||||
import java.net.URLDecoder; | |||||
import java.util.HashMap; | |||||
import java.util.Map; | |||||
/** | /** | ||||
* 会员卡相关接口的实现类 | * 会员卡相关接口的实现类 | ||||
* | * | ||||
@@ -237,7 +242,7 @@ public class WxMpMemberCardServiceImpl implements WxMpMemberCardService { | |||||
jsonObject.addProperty("code", code); | jsonObject.addProperty("code", code); | ||||
String responseContent = this.getWxMpService().post(MEMBER_CARD_USER_INFO_GET, jsonObject.toString()); | String responseContent = this.getWxMpService().post(MEMBER_CARD_USER_INFO_GET, jsonObject.toString()); | ||||
log.debug("{}",responseContent); | |||||
log.debug("{}", responseContent); | |||||
JsonElement tmpJsonElement = new JsonParser().parse(responseContent); | JsonElement tmpJsonElement = new JsonParser().parse(responseContent); | ||||
return WxMpGsonBuilder.INSTANCE.create().fromJson(tmpJsonElement, | return WxMpGsonBuilder.INSTANCE.create().fromJson(tmpJsonElement, | ||||
new TypeToken<WxMpMemberCardUserInfoResult>() { | new TypeToken<WxMpMemberCardUserInfoResult>() { | ||||
@@ -280,4 +285,91 @@ public class WxMpMemberCardServiceImpl implements WxMpMemberCardService { | |||||
return MemberCardActivateUserFormResult.fromJson(responseContent); | return MemberCardActivateUserFormResult.fromJson(responseContent); | ||||
} | } | ||||
/** | |||||
* 获取会员卡开卡插件参数(跳转型开卡组件需要参数) | |||||
* | |||||
* @param outStr | |||||
* @return | |||||
* @throws WxErrorException | |||||
*/ | |||||
public ActivatePluginParam getActivatePluginParam(String cardId, String outStr) throws WxErrorException { | |||||
JsonObject params = new JsonObject(); | |||||
params.addProperty("card_id", cardId); | |||||
params.addProperty("outer_str", outStr); | |||||
String response = this.wxMpService.post(MEMBER_CARD_ACTIVATE_URL, GSON.toJson(params)); | |||||
ActivatePluginParamResult result = GSON.fromJson(response, ActivatePluginParamResult.class); | |||||
if (0 == result.getErrcode()) { | |||||
String url = result.getUrl(); | |||||
try { | |||||
String decodedUrl = URLDecoder.decode(url, "UTF-8"); | |||||
Map<String, String> resultMap = parseRequestUrl(decodedUrl); | |||||
ActivatePluginParam activatePluginParam = new ActivatePluginParam(); | |||||
activatePluginParam.setEncryptCardId(resultMap.get("encrypt_card_id")); | |||||
activatePluginParam.setOuterStr(resultMap.get("outer_str")); | |||||
activatePluginParam.setBiz(resultMap.get("biz")+"=="); | |||||
return activatePluginParam; | |||||
} catch (UnsupportedEncodingException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
} | |||||
return null; | |||||
} | |||||
/** | |||||
* 去掉url中的路径,留下请求参数部分 | |||||
* | |||||
* @param strURL url地址 | |||||
* @return url请求参数部分 | |||||
*/ | |||||
private static String truncateUrlPage(String strURL) { | |||||
String strAllParam = null; | |||||
String[] arrSplit = null; | |||||
arrSplit = strURL.split("[?]"); | |||||
if (strURL.length() > 1) { | |||||
if (arrSplit.length > 1) { | |||||
if (arrSplit[1] != null) { | |||||
strAllParam = arrSplit[1]; | |||||
} | |||||
} | |||||
} | |||||
return strAllParam; | |||||
} | |||||
/** | |||||
* 解析出url参数中的键值对 | |||||
* 如 "index.jsp?Action=del&id=123",解析出Action:del,id:123存入map中 | |||||
* | |||||
* @param URL url地址 | |||||
* @return url请求参数部分 | |||||
*/ | |||||
public static Map<String, String> parseRequestUrl(String URL) { | |||||
Map<String, String> mapRequest = new HashMap<String, String>(); | |||||
String[] arrSplit = null; | |||||
String strUrlParam = truncateUrlPage(URL); | |||||
if (strUrlParam == null) { | |||||
return mapRequest; | |||||
} | |||||
arrSplit = strUrlParam.split("[&]"); | |||||
for (String strSplit : arrSplit) { | |||||
String[] arrSplitEqual = null; | |||||
arrSplitEqual = strSplit.split("[=]"); | |||||
//解析出键值 | |||||
if (arrSplitEqual.length > 1) { | |||||
//正确解析 | |||||
mapRequest.put(arrSplitEqual[0], arrSplitEqual[1]); | |||||
} else { | |||||
if (arrSplitEqual[0] != "") { | |||||
//只有参数没有值,不加入 | |||||
mapRequest.put(arrSplitEqual[0], ""); | |||||
} | |||||
} | |||||
} | |||||
return mapRequest; | |||||
} | |||||
} | } |
@@ -0,0 +1,22 @@ | |||||
package me.chanjar.weixin.mp.bean.membercard; | |||||
import com.google.gson.annotations.SerializedName; | |||||
import lombok.Data; | |||||
/** | |||||
* @author yqx | |||||
* @date 2018/9/19 | |||||
*/ | |||||
@Data | |||||
public class ActivatePluginParam { | |||||
@SerializedName("encrypt_card_id") | |||||
String encryptCardId; | |||||
@SerializedName("outer_str") | |||||
String outerStr; | |||||
@SerializedName("biz") | |||||
String biz; | |||||
} |
@@ -0,0 +1,18 @@ | |||||
package me.chanjar.weixin.mp.bean.membercard; | |||||
import lombok.Data; | |||||
/** | |||||
* @author yqx | |||||
* @date 2018/9/19 | |||||
*/ | |||||
@Data | |||||
public class ActivatePluginParamResult { | |||||
private int errcode; | |||||
private String errmsg; | |||||
private String url; | |||||
} |
@@ -541,6 +541,21 @@ public class WxMpXmlMessage implements Serializable { | |||||
@XStreamAlias("DeviceStatus") | @XStreamAlias("DeviceStatus") | ||||
private Integer deviceStatus; | private Integer deviceStatus; | ||||
/////////////////////////////////////// | |||||
// 小程序 审核事件 | |||||
/////////////////////////////////////// | |||||
/** | |||||
* 审核成功时的时间(整形),时间戳 | |||||
*/ | |||||
@XStreamAlias("SuccTime") | |||||
private Long succTime; | |||||
/** | |||||
* 审核失败的原因 | |||||
*/ | |||||
@XStreamAlias("Reason") | |||||
private String reason; | |||||
public static WxMpXmlMessage fromXml(String xml) { | public static WxMpXmlMessage fromXml(String xml) { | ||||
//修改微信变态的消息内容格式,方便解析 | //修改微信变态的消息内容格式,方便解析 | ||||
xml = xml.replace("</PicList><PicList>", ""); | xml = xml.replace("</PicList><PicList>", ""); | ||||
@@ -2,6 +2,7 @@ package me.chanjar.weixin.mp.api.impl; | |||||
import com.google.inject.Inject; | import com.google.inject.Inject; | ||||
import me.chanjar.weixin.mp.api.WxMpCardService; | import me.chanjar.weixin.mp.api.WxMpCardService; | ||||
import me.chanjar.weixin.mp.api.WxMpMemberCardService; | |||||
import me.chanjar.weixin.mp.api.WxMpService; | import me.chanjar.weixin.mp.api.WxMpService; | ||||
import me.chanjar.weixin.mp.api.test.ApiTestModule; | import me.chanjar.weixin.mp.api.test.ApiTestModule; | ||||
import me.chanjar.weixin.mp.bean.card.*; | import me.chanjar.weixin.mp.bean.card.*; | ||||
@@ -22,12 +23,12 @@ public class WxMpMemberCardServiceImplTest { | |||||
@Inject | @Inject | ||||
protected WxMpService wxService; | protected WxMpService wxService; | ||||
private String cardId = "p2iQk1g2d03JXhVRDY5fZRVr236A"; | |||||
private String cardId = "p2iQk1uwOUYlzHm4s-UYdZnABW88"; | |||||
private String code = "435223630779"; | private String code = "435223630779"; | ||||
private String openId = "o2iQk1u5X-XIJkatmAK1Q8VVuS90"; | private String openId = "o2iQk1u5X-XIJkatmAK1Q8VVuS90"; | ||||
@Test | @Test | ||||
public void createMemberCard()throws Exception{ | |||||
public void createMemberCard() throws Exception { | |||||
// String json = "{\"card\":{\"card_type\":\"MEMBER_CARD\",\"member_card\":{\"advanced_info\":{\"business_service\":\"BIZ_SERVICE_FREE_PARK,BIZ_SERVICE_WITH_PET,BIZ_SERVICE_FREE_WIFI\",\"text_image_list\":[{\"image_url\":\"http://mmbiz.qpic.cn/mmbiz_jpg/upuF1LhUF8LjCLCFcQicgEiazFeonwDllGkENppDhyqhR8bz5BiaJkPT7e6bPVcfBx5cAOLro2N3U989n8WJltkjQ/0\",\"text\":\"8月8日随机免单\"}]},\"auto_activate\":false,\"background_pic_url\":\"http://mmbiz.qpic.cn/mmbiz_jpg/upuF1LhUF8LjCLCFcQicgEiazFeonwDllGl6ibk4v5iaJDAbs7dGJU7iclOJ6nh7Hnz6ZsfDL8tGEeQVJyuhKsMFxUQ/0\",\"base_info\":{\"bind_openid\":false,\"brand_name\":\"商户名称\",\"can_give_friend\":false,\"can_share\":false,\"center_sub_title\":\"点击进入\",\"center_title\":\"商城首页\",\"center_url\":\"http://www.baidu.com\",\"code_type\":\"CODE_TYPE_QRCODE\",\"color\":\"Color090\",\"date_info\":{\"type\":\"DATE_TYPE_PERMANENT\"},\"description\":\"使用须知\",\"need_push_on_view\":false,\"notice\":\"测试会员卡\",\"service_phone\":\"4008803016\",\"title\":\"终生铂金卡\",\"use_all_locations\":true,\"use_custom_code\":false},\"prerogative\":\"享有特权说明\",\"supply_balance\":true,\"supply_bonus\":true,\"wx_activate\":false}}}"; | // String json = "{\"card\":{\"card_type\":\"MEMBER_CARD\",\"member_card\":{\"advanced_info\":{\"business_service\":\"BIZ_SERVICE_FREE_PARK,BIZ_SERVICE_WITH_PET,BIZ_SERVICE_FREE_WIFI\",\"text_image_list\":[{\"image_url\":\"http://mmbiz.qpic.cn/mmbiz_jpg/upuF1LhUF8LjCLCFcQicgEiazFeonwDllGkENppDhyqhR8bz5BiaJkPT7e6bPVcfBx5cAOLro2N3U989n8WJltkjQ/0\",\"text\":\"8月8日随机免单\"}]},\"auto_activate\":false,\"background_pic_url\":\"http://mmbiz.qpic.cn/mmbiz_jpg/upuF1LhUF8LjCLCFcQicgEiazFeonwDllGl6ibk4v5iaJDAbs7dGJU7iclOJ6nh7Hnz6ZsfDL8tGEeQVJyuhKsMFxUQ/0\",\"base_info\":{\"bind_openid\":false,\"brand_name\":\"商户名称\",\"can_give_friend\":false,\"can_share\":false,\"center_sub_title\":\"点击进入\",\"center_title\":\"商城首页\",\"center_url\":\"http://www.baidu.com\",\"code_type\":\"CODE_TYPE_QRCODE\",\"color\":\"Color090\",\"date_info\":{\"type\":\"DATE_TYPE_PERMANENT\"},\"description\":\"使用须知\",\"need_push_on_view\":false,\"notice\":\"测试会员卡\",\"service_phone\":\"4008803016\",\"title\":\"终生铂金卡\",\"use_all_locations\":true,\"use_custom_code\":false},\"prerogative\":\"享有特权说明\",\"supply_balance\":true,\"supply_bonus\":true,\"wx_activate\":false}}}"; | ||||
// WxMpMemberCardCreateMessage createMessage = WxMpMemberCardCreateMessage.fromJson(json); | // WxMpMemberCardCreateMessage createMessage = WxMpMemberCardCreateMessage.fromJson(json); | ||||
@@ -105,10 +106,11 @@ public class WxMpMemberCardServiceImplTest { | |||||
/** | /** | ||||
* 测试添加测试openid白名单 | * 测试添加测试openid白名单 | ||||
* | |||||
* @throws Exception | * @throws Exception | ||||
*/ | */ | ||||
@Test | @Test | ||||
public void testAddTestWhiteList()throws Exception { | |||||
public void testAddTestWhiteList() throws Exception { | |||||
WxMpCardService cardService = this.wxService.getCardService(); | WxMpCardService cardService = this.wxService.getCardService(); | ||||
String response = cardService.addTestWhiteList(openId); | String response = cardService.addTestWhiteList(openId); | ||||
System.out.println(response); | System.out.println(response); | ||||
@@ -116,28 +118,38 @@ public class WxMpMemberCardServiceImplTest { | |||||
/** | /** | ||||
* 测试创建会员卡投放二维码 | * 测试创建会员卡投放二维码 | ||||
* | |||||
* @throws Exception | * @throws Exception | ||||
*/ | */ | ||||
@Test | @Test | ||||
public void testCreateQrcodeMemberCard()throws Exception{ | |||||
public void testCreateQrcodeMemberCard() throws Exception { | |||||
WxMpCardService cardService = this.wxService.getCardService(); | WxMpCardService cardService = this.wxService.getCardService(); | ||||
WxMpCardQrcodeCreateResult response = cardService.createQrcodeCard(cardId,"test"); | |||||
WxMpCardQrcodeCreateResult response = cardService.createQrcodeCard(cardId, "test"); | |||||
System.out.println(response); | System.out.println(response); | ||||
} | } | ||||
/** | /** | ||||
* 测试创建货架接口 | * 测试创建货架接口 | ||||
* | |||||
* @throws Exception | * @throws Exception | ||||
*/ | */ | ||||
@Test | @Test | ||||
public void testCreateLandingPage()throws Exception{ | |||||
public void testCreateLandingPage() throws Exception { | |||||
WxMpCardService cardService = this.wxService.getCardService(); | WxMpCardService cardService = this.wxService.getCardService(); | ||||
WxMpCardLandingPageCreateRequest request = new WxMpCardLandingPageCreateRequest(); | WxMpCardLandingPageCreateRequest request = new WxMpCardLandingPageCreateRequest(); | ||||
request.setBanner("http://mmbiz.qpic.cn/mmbiz_jpg/upuF1LhUF8LjCLCFcQicgEiazFeonwDllGl6ibk4v5iaJDAbs7dGJU7iclOJ6nh7Hnz6ZsfDL8tGEeQVJyuhKsMFxUQ/0"); | request.setBanner("http://mmbiz.qpic.cn/mmbiz_jpg/upuF1LhUF8LjCLCFcQicgEiazFeonwDllGl6ibk4v5iaJDAbs7dGJU7iclOJ6nh7Hnz6ZsfDL8tGEeQVJyuhKsMFxUQ/0"); | ||||
request.setTitle("会员卡1"); | request.setTitle("会员卡1"); | ||||
request.setScene(CardSceneType.SCENE_H5.name()); | request.setScene(CardSceneType.SCENE_H5.name()); | ||||
request.addCard(cardId,"http://mmbiz.qpic.cn/mmbiz_jpg/upuF1LhUF8LjCLCFcQicgEiazFeonwDllGl6ibk4v5iaJDAbs7dGJU7iclOJ6nh7Hnz6ZsfDL8tGEeQVJyuhKsMFxUQ/0"); | |||||
request.addCard(cardId, "http://mmbiz.qpic.cn/mmbiz_jpg/upuF1LhUF8LjCLCFcQicgEiazFeonwDllGl6ibk4v5iaJDAbs7dGJU7iclOJ6nh7Hnz6ZsfDL8tGEeQVJyuhKsMFxUQ/0"); | |||||
WxMpCardLandingPageCreateResult response = cardService.createLandingPage(request); | WxMpCardLandingPageCreateResult response = cardService.createLandingPage(request); | ||||
System.out.println(response); | System.out.println(response); | ||||
} | } | ||||
@Test | |||||
public void testGetActivateUrl() throws Exception { | |||||
WxMpMemberCardService memberCardService = this.wxService.getMemberCardService(); | |||||
ActivatePluginParam response = memberCardService.getActivatePluginParam(cardId, "test"); | |||||
System.out.println(response); | |||||
} | |||||
} | } |
@@ -25,6 +25,10 @@ public interface WxOpenComponentService { | |||||
String API_SET_AUTHORIZER_OPTION_URL = "https://api.weixin.qq.com/cgi-bin/component/api_set_authorizer_option"; | String API_SET_AUTHORIZER_OPTION_URL = "https://api.weixin.qq.com/cgi-bin/component/api_set_authorizer_option"; | ||||
String COMPONENT_LOGIN_PAGE_URL = "https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid=%s&pre_auth_code=%s&redirect_uri=%s"; | String COMPONENT_LOGIN_PAGE_URL = "https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid=%s&pre_auth_code=%s&redirect_uri=%s"; | ||||
/** | |||||
* 手机端打开授权链接 | |||||
*/ | |||||
String COMPONENT_MOBILE_LOGIN_PAGE_URL = "https://mp.weixin.qq.com/safe/bindcomponent?action=bindcomponent&no_scan=1&auth_type=3&component_appid=%s&pre_auth_code=%s&redirect_uri=%s&auth_type=xxx&biz_appid=xxx$#wechat_redirect"; | |||||
String CONNECT_OAUTH2_AUTHORIZE_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s&component_appid=%s#wechat_redirect"; | String CONNECT_OAUTH2_AUTHORIZE_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s&component_appid=%s#wechat_redirect"; | ||||
/** | /** | ||||
@@ -66,6 +70,26 @@ public interface WxOpenComponentService { | |||||
*/ | */ | ||||
String getPreAuthUrl(String redirectURI, String authType, String bizAppid) throws WxErrorException; | String getPreAuthUrl(String redirectURI, String authType, String bizAppid) throws WxErrorException; | ||||
/** | |||||
* 获取预授权链接(手机端预授权) | |||||
* | |||||
* @param redirectURI | |||||
* @return | |||||
* @throws WxErrorException | |||||
*/ | |||||
String getMobilePreAuthUrl(String redirectURI) throws WxErrorException; | |||||
/** | |||||
* 获取预授权链接(手机端预授权) | |||||
* | |||||
* @param redirectURI | |||||
* @param authType | |||||
* @param bizAppid | |||||
* @return | |||||
* @throws WxErrorException | |||||
*/ | |||||
String getMobilePreAuthUrl(String redirectURI, String authType, String bizAppid) throws WxErrorException; | |||||
String route(WxOpenXmlMessage wxMessage) throws WxErrorException; | String route(WxOpenXmlMessage wxMessage) throws WxErrorException; | ||||
/** | /** | ||||
@@ -299,11 +299,10 @@ public interface WxOpenMaService extends WxMaService { | |||||
/** | /** | ||||
* 查询最新一次提交的审核状态(仅供第三方代小程序调用) | * 查询最新一次提交的审核状态(仅供第三方代小程序调用) | ||||
* | * | ||||
* @param auditid | |||||
* @return | * @return | ||||
* @throws WxErrorException | * @throws WxErrorException | ||||
*/ | */ | ||||
String getLatestAuditStatus(Long auditid) throws WxErrorException; | |||||
String getLatestAuditStatus() throws WxErrorException; | |||||
/** | /** | ||||
* 发布已通过审核的小程序(仅供第三方代小程序调用) | * 发布已通过审核的小程序(仅供第三方代小程序调用) | ||||
@@ -331,5 +330,5 @@ public interface WxOpenMaService extends WxMaService { | |||||
* @throws WxErrorException | * @throws WxErrorException | ||||
*/ | */ | ||||
String undoCodeAudit() throws WxErrorException; | String undoCodeAudit() throws WxErrorException; | ||||
} | } |
@@ -181,25 +181,50 @@ public class WxOpenComponentServiceImpl implements WxOpenComponentService { | |||||
return getPreAuthUrl(redirectURI, null, null); | return getPreAuthUrl(redirectURI, null, null); | ||||
} | } | ||||
@Override | |||||
public String getPreAuthUrl(String redirectURI, String authType, String bizAppid) throws WxErrorException { | public String getPreAuthUrl(String redirectURI, String authType, String bizAppid) throws WxErrorException { | ||||
return createPreAuthUrl(redirectURI, authType, bizAppid, false); | |||||
} | |||||
public String getMobilePreAuthUrl(String redirectURI) throws WxErrorException { | |||||
return getMobilePreAuthUrl(redirectURI, null, null); | |||||
} | |||||
public String getMobilePreAuthUrl(String redirectURI, String authType, String bizAppid) throws WxErrorException { | |||||
return createPreAuthUrl(redirectURI, authType, bizAppid, true); | |||||
} | |||||
/** | |||||
* 创建预授权链接 | |||||
* | |||||
* @param redirectURI | |||||
* @param authType | |||||
* @param bizAppid | |||||
* @param isMobile 是否移动端预授权 | |||||
* @return | |||||
* @throws WxErrorException | |||||
*/ | |||||
private String createPreAuthUrl(String redirectURI, String authType, String bizAppid, boolean isMobile) throws WxErrorException { | |||||
JsonObject jsonObject = new JsonObject(); | JsonObject jsonObject = new JsonObject(); | ||||
jsonObject.addProperty("component_appid", getWxOpenConfigStorage().getComponentAppId()); | jsonObject.addProperty("component_appid", getWxOpenConfigStorage().getComponentAppId()); | ||||
String responseContent = post(API_CREATE_PREAUTHCODE_URL, jsonObject.toString()); | String responseContent = post(API_CREATE_PREAUTHCODE_URL, jsonObject.toString()); | ||||
jsonObject = WxGsonBuilder.create().fromJson(responseContent, JsonObject.class); | jsonObject = WxGsonBuilder.create().fromJson(responseContent, JsonObject.class); | ||||
StringBuilder preAuthUrl = new StringBuilder(String.format(COMPONENT_LOGIN_PAGE_URL, | |||||
StringBuilder preAuthUrl = new StringBuilder(String.format((isMobile ? COMPONENT_MOBILE_LOGIN_PAGE_URL : COMPONENT_LOGIN_PAGE_URL), | |||||
getWxOpenConfigStorage().getComponentAppId(), | getWxOpenConfigStorage().getComponentAppId(), | ||||
jsonObject.get("pre_auth_code").getAsString(), | jsonObject.get("pre_auth_code").getAsString(), | ||||
URIUtil.encodeURIComponent(redirectURI))); | URIUtil.encodeURIComponent(redirectURI))); | ||||
String preAuthUrlStr = preAuthUrl.toString(); | |||||
if (StringUtils.isNotEmpty(authType)) { | if (StringUtils.isNotEmpty(authType)) { | ||||
preAuthUrl.append("&auth_type=").append(authType); | |||||
preAuthUrlStr = preAuthUrlStr.replace("&auth_type=xxx", "&auth_type=" + authType); | |||||
} else { | |||||
preAuthUrlStr = preAuthUrlStr.replace("&auth_type=xxx", ""); | |||||
} | } | ||||
if (StringUtils.isNotEmpty(bizAppid)) { | if (StringUtils.isNotEmpty(bizAppid)) { | ||||
preAuthUrl.append("&biz_appid=").append(bizAppid); | |||||
preAuthUrlStr = preAuthUrlStr.replace("&biz_appid=xxx", "&biz_appid=" + bizAppid); | |||||
} else { | |||||
preAuthUrlStr = preAuthUrlStr.replace("&biz_appid=xxx", ""); | |||||
} | } | ||||
return preAuthUrl.toString(); | |||||
return preAuthUrlStr; | |||||
} | } | ||||
@@ -275,12 +275,11 @@ public class WxOpenMaServiceImpl extends WxMaServiceImpl implements WxOpenMaServ | |||||
/** | /** | ||||
* 8. 查询最新一次提交的审核状态(仅供第三方代小程序调用) | * 8. 查询最新一次提交的审核状态(仅供第三方代小程序调用) | ||||
* | * | ||||
* @param auditid | |||||
* @return | * @return | ||||
* @throws WxErrorException | * @throws WxErrorException | ||||
*/ | */ | ||||
@Override | @Override | ||||
public String getLatestAuditStatus(Long auditid) throws WxErrorException { | |||||
public String getLatestAuditStatus() throws WxErrorException { | |||||
String response = get(API_GET_LATEST_AUDIT_STATUS, null); | String response = get(API_GET_LATEST_AUDIT_STATUS, null); | ||||
return response; | return response; | ||||
} | } | ||||