Files
2025-10-04 01:47:50 +08:00

125 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 微信开放平台模块 (weixin-java-open)
## 模块说明
本模块主要用于**微信第三方平台**的开发,适用于以下场景:
### 适用场景
1. **第三方平台开发**:作为第三方平台,代替多个公众号或小程序进行管理和开发
2. **代公众号实现业务**:通过授权代替公众号进行消息管理、素材管理等操作
3. **代小程序实现业务**:通过授权代替小程序进行代码管理、基本信息设置等操作
### 移动应用开发说明
**如果您要开发移动应用iOS/Android App并接入微信功能请注意**
- **微信登录**
- 移动应用的微信登录(网页授权)需要在**微信开放平台**open.weixin.qq.com创建移动应用
- 服务端处理 OAuth 授权时使用本模块 `weixin-java-open`
- 移动端需集成微信官方SDKiOS/Android本项目仅提供服务端SDK
- **微信支付**
- 使用 `weixin-java-pay` 模块,参考 [微信支付文档](../weixin-java-pay/)
- 移动应用支付使用 APP 支付类型TradeType.APP
- **微信分享**
- 需集成微信官方移动端SDK本项目不涉及客户端功能
**参考资料**
- [微信开放平台官方文档](https://open.weixin.qq.com/)
- [移动应用接入指南](https://developers.weixin.qq.com/doc/oplatform/Mobile_App/Access_Guide/iOS.html)
---
## 代码示例
消息机制未实现,下面为通知回调中设置的代码部分
以下代码可通过腾讯全网发布测试用例
```Java
@RestController
@RequestMapping("notify")
public class NotifyController extends WechatThridBaseController {
@Autowired
protected WxOpenServiceDemo wxOpenService;
@RequestMapping("receive_ticket")
public Object receiveTicket(@RequestBody(required = false) String requestBody, @RequestParam("timestamp") String timestamp,
@RequestParam("nonce") String nonce, @RequestParam("signature") String signature,
@RequestParam(name = "encrypt_type", required = false) String encType,
@RequestParam(name = "msg_signature", required = false) String msgSignature) {
this.logger.info(
"\n接收微信请求[signature=[{}], encType=[{}], msgSignature=[{}],"
+ " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ",
signature, encType, msgSignature, timestamp, nonce, requestBody);
if (!StringUtils.equalsIgnoreCase("aes", encType) || !wxOpenService.getWxOpenComponentService().checkSignature(timestamp, nonce, signature)) {
throw new IllegalArgumentException("非法请求,可能属于伪造的请求!");
}
// aes加密的消息
WxOpenXmlMessage inMessage = WxOpenXmlMessage.fromEncryptedXml(requestBody, wxOpenService.getWxOpenConfigStorage(), timestamp, nonce, msgSignature);
this.logger.debug("\n消息解密后内容为\n{} ", inMessage.toString());
String out = null;
try {
out = wxOpenService.getWxOpenComponentService().route(inMessage);
} catch (WxErrorException e) {
throw new ResponseException(ErrorCodeEnum.ERROR, e);
}
this.logger.debug("\n组装回复信息{}", out);
return out;
}
@RequestMapping("{appId}/callback")
public Object callback(@RequestBody(required = false)String requestBody,
@PathVariable ("appId") String appId,
@RequestParam("signature") String signature,
@RequestParam("timestamp") String timestamp,
@RequestParam("nonce") String nonce,
@RequestParam("openid") String openid,
@RequestParam("encrypt_type") String encType,
@RequestParam("msg_signature") String msgSignature) {
this.logger.info(
"\n接收微信请求[appId=[{}], openid=[{}], signature=[{}], encType=[{}], msgSignature=[{}],"
+ " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ",
appId, openid, signature, encType, msgSignature, timestamp, nonce, requestBody);
logger.info("query:"+getHttpServletRequest().getQueryString()+"\nbody:"+requestBody);
if (!StringUtils.equalsIgnoreCase("aes", encType) || !wxOpenService.getWxOpenComponentService().checkSignature(timestamp, nonce, signature)) {
throw new IllegalArgumentException("非法请求,可能属于伪造的请求!");
}
String out = "";
// aes加密的消息
WxMpXmlMessage inMessage = WxOpenXmlMessage.fromEncryptedMpXml(requestBody, wxOpenService.getWxOpenConfigStorage(), timestamp, nonce, msgSignature);
this.logger.debug("\n消息解密后内容为\n{} ", inMessage.toString());
// 全网发布测试用例
if (StringUtils.equalsAnyIgnoreCase(appId, "wxd101a85aa106f53e", "wx570bc396a51b8ff8")) {
try {
if (StringUtils.equals(inMessage.getMsgType(), "text")) {
if (StringUtils.equals(inMessage.getContent(), "TESTCOMPONENT_MSG_TYPE_TEXT")) {
out = new WxOpenCryptUtil(wxOpenService.getWxOpenConfigStorage()).encrypt(
WxMpXmlOutMessage.TEXT().content("TESTCOMPONENT_MSG_TYPE_TEXT_callback")
.fromUser(inMessage.getToUser())
.toUser(inMessage.getFromUser())
.build()
.toXml()
);
} else if (StringUtils.startsWith(inMessage.getContent(), "QUERY_AUTH_CODE:")) {
String msg = inMessage.getContent().replace("QUERY_AUTH_CODE:", "") + "_from_api";
WxMpKefuMessage kefuMessage = WxMpKefuMessage.TEXT().content(msg).toUser(inMessage.getFromUser()).build();
wxOpenService.getWxOpenComponentService().getWxMpServiceByAppid(appId).getKefuService().sendKefuMessage(kefuMessage);
}
} else if (StringUtils.equals(inMessage.getMsgType(), "event")) {
WxMpKefuMessage kefuMessage = WxMpKefuMessage.TEXT().content(inMessage.getEvent() + "from_callback").toUser(inMessage.getFromUser()).build();
wxOpenService.getWxOpenComponentService().getWxMpServiceByAppid(appId).getKefuService().sendKefuMessage(kefuMessage);
}
} catch (WxErrorException e) {
logger.error("callback", e);
}
}
return out;
}
}
```