weixin-mp & pay
This commit is contained in:
+34
-48
@@ -1,66 +1,52 @@
|
||||
weixin4j-mp
|
||||
===========
|
||||
|
||||
tencent weixin platform java sdk 微信公众平台开发工具包 http://mp.weixin.qq.com/wiki
|
||||
@(weixin4j)[公众平台]
|
||||
|
||||
微信[公众平台](http://mp.weixin.qq.com/wiki)开发工具包
|
||||
----------------------------------------------------
|
||||
|
||||
功能列表
|
||||
-------
|
||||
* weixin4j-mp-api
|
||||
|
||||
* TokenHolder token的实现
|
||||
|
||||
* MediaApi 上传/下载媒体文件API
|
||||
|
||||
* NotifyApi 客服消息API
|
||||
|
||||
* MassApi 群发消息API
|
||||
|
||||
* UserApi 用户管理API
|
||||
|
||||
* GroupApi 分组管理API
|
||||
|
||||
* MenuApi 底部菜单API
|
||||
|
||||
* QrApi 二维码API
|
||||
|
||||
* TmplApi 模板消息API
|
||||
|
||||
* HelperApi 辅助API
|
||||
|
||||
* netty服务器 & 消息分发
|
||||
|
||||
|
||||
如何使用
|
||||
--------
|
||||
1.编辑classweixin.properties并填入appid/appsecret,当然也可通过构造函数传入.
|
||||
|
||||
2.实例化一个WeixinProxy对象,调用API.
|
||||
|
||||
WeixinProxy weixinProxy = new WeixinProxy();
|
||||
// weixinProxy = new WeixinProxy(appid,appsecret);
|
||||
weixinProxy.getUser(openId);
|
||||
|
||||
3.针对token存储有两种方案,File存储/Redis存储,当然也可自己实现TokenHolder(继承AbstractTokenHolder类并重写getToken方法),默认使用文件(xml)的方式保存token,如果环境中支持redis,建议使用RedisTokenHolder.
|
||||
|
||||
WeixinProxy weixinProxy = new WeixinProxy(new RedisTokenHolder());
|
||||
// weixinProxy = new WeixinProxy(new RedisTokenHolder(appid,appsecret));
|
||||
|
||||
4.mvn package,得到一个zip的压缩包,解压到启动目录(见src/main/startup.sh/APP_HOME)
|
||||
|
||||
5.启动netty服务
|
||||
|
||||
com.foxinmy.weixin4j.mp.startup.WeixinServiceBootstrap
|
||||
sh startup.sh start
|
||||
+ MediaApi `上传/下载媒体文件API`
|
||||
|
||||
+ NotifyApi `客服消息API`
|
||||
|
||||
+ MassApi `群发消息API`
|
||||
|
||||
+ UserApi `用户管理API`
|
||||
|
||||
+ GroupApi `分组管理API`
|
||||
|
||||
+ MenuApi `底部菜单API`
|
||||
|
||||
+ QrApi `二维码API`
|
||||
|
||||
+ TmplApi `模板消息API`
|
||||
|
||||
+ HelperApi `辅助API`
|
||||
|
||||
* weixin4j-mp-server
|
||||
`netty服务器 & 消息分发`
|
||||
|
||||
更新LOG
|
||||
-------
|
||||
* 2014-10-27
|
||||
|
||||
1).用netty构建http服务器并支持消息分发
|
||||
+ 用netty构建http服务器并支持消息分发
|
||||
|
||||
* 2014-10-28
|
||||
|
||||
1).调整ActionMapping抽象化
|
||||
+ 调整`ActionMapping`抽象化
|
||||
|
||||
* 2014-10-31
|
||||
|
||||
1).weixin.properties切分为API调用地址/公众号信息两部分
|
||||
+ `weixin.properties`切分为API调用地址/公众号信息两部分
|
||||
|
||||
* 2014-11-03
|
||||
|
||||
+ `weixin-mp`分离为`weixin-mp-api`和`weixin-mp-server`两个工程
|
||||
|
||||
+ `weixin-mp`:加入支付模块
|
||||
+8
-39
@@ -8,54 +8,23 @@
|
||||
<artifactId>weixin4j</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<groupId>com.foxinmy.weixin</groupId>
|
||||
<artifactId>weixin4j-mp</artifactId>
|
||||
<name>weixin4j-mp</name>
|
||||
|
||||
<packaging>pom</packaging>
|
||||
<url>https://github.com/foxinmy/weixin4j/tree/master/weixin4j-mp</url>
|
||||
<description>微信公众号工具包</description>
|
||||
<modules>
|
||||
<module>weixin4j-mp-api</module>
|
||||
<module>weixin4j-mp-server</module>
|
||||
</modules>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>2.2.1</version>
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<descriptor>src/main/assembly.xml</descriptor>
|
||||
</descriptors>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<finalName>weixin4j-mp</finalName>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jsoup</groupId>
|
||||
<artifactId>jsoup</artifactId>
|
||||
<version>${jsoup.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jaxen</groupId>
|
||||
<artifactId>jaxen</artifactId>
|
||||
<version>${jaxen.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
<version>${netty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.foxinmy.weixin4j</groupId>
|
||||
<artifactId>weixin4j-base</artifactId>
|
||||
<version>${weixin4j.version}</version>
|
||||
<version>${weixin4j.base.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
||||
*~
|
||||
|
||||
# eclipse ignore
|
||||
*.settings/*
|
||||
/.project
|
||||
/.classpath
|
||||
/.tomcatplugin
|
||||
|
||||
# maven ignore
|
||||
target/*
|
||||
|
||||
# other ignore
|
||||
*.log
|
||||
*.tmp
|
||||
Thumbs.db
|
||||
/target/
|
||||
.DS_Store
|
||||
@@ -0,0 +1,87 @@
|
||||
weixin4j-mp-api
|
||||
===============
|
||||
|
||||
@(weixin4j)[公众平台]
|
||||
|
||||
微信[公众平台](http://mp.weixin.qq.com/wiki)开发工具包
|
||||
|
||||
功能列表
|
||||
-------
|
||||
* MediaApi `上传/下载媒体文件API`
|
||||
|
||||
* NotifyApi `客服消息API`
|
||||
|
||||
* MassApi `群发消息API`
|
||||
|
||||
* UserApi `用户管理API`
|
||||
|
||||
* GroupApi `分组管理API`
|
||||
|
||||
* MenuApi `底部菜单API`
|
||||
|
||||
* QrApi `二维码API`
|
||||
|
||||
* TmplApi `模板消息API`
|
||||
|
||||
* HelperApi `辅助API`
|
||||
|
||||
* PayApi `支付API`
|
||||
|
||||
如何使用
|
||||
--------
|
||||
1.API工程可以单独使用,需新增或拷贝`weixin.properties`文件到classpath
|
||||
|
||||
weixin.properties
|
||||
|
||||
| 属性名 | 说明 |
|
||||
| :---------- | :-------------- |
|
||||
| account | 微信公众号信息 `json格式` |
|
||||
| token_path | 使用FileTokenHolder时token保存的物理路径 |
|
||||
| qr_path | 调用二维码接口时保存的物理路径 |
|
||||
|
||||
示例
|
||||
|
||||
>**`account={"appId":"appId","appSecret":"appSecret",
|
||||
"token":"开放者的token 非必须","openId":"公众号的openid 非必须",
|
||||
"mchId":"V3.x版本下的微信商户号",
|
||||
"partnerId":"财付通的商户号","partnerKey":"财付通商户权限密钥Key",
|
||||
"paySignKey":"微信支付中调用API的密钥"}
|
||||
token_path=/tmp/weixin/token`
|
||||
`qr_path=/tmp/weixin/qr`
|
||||
`media_path=/tmp/weixin/media`
|
||||
`bill_path=/tmp/weixin/bill`**
|
||||
|
||||
2.实例化一个`WeixinProxy`对象,调用API.
|
||||
``` java
|
||||
WeixinProxy weixinProxy = new WeixinProxy();
|
||||
// weixinProxy = new WeixinProxy(appid,appsecret);
|
||||
weixinProxy.getUser(openId);
|
||||
```
|
||||
|
||||
3.针对`token`存储有两种方案,`File存储`/`Redis存储`,当然也可自己实现`TokenHolder`(继承`AbstractTokenHolder`类并重写`getToken`方法),默认使用文件(xml)的方式保存token,如果环境中支持`redis`,建议使用`RedisTokenHolder`.
|
||||
``` java
|
||||
WeixinProxy weixinProxy = new WeixinProxy(new RedisTokenHolder());
|
||||
// weixinProxy = new WeixinProxy(new RedisTokenHolder(appid,appsecret));
|
||||
```
|
||||
|
||||
4.mvn package.
|
||||
|
||||
更新LOG
|
||||
-------
|
||||
* 2014-10-27
|
||||
|
||||
+ 用netty构建http服务器并支持消息分发
|
||||
|
||||
* 2014-10-28
|
||||
|
||||
+ 调整`ActionMapping`抽象化
|
||||
|
||||
* 2014-10-31
|
||||
|
||||
+ `weixin.properties`切分为API调用地址/公众号信息两部分
|
||||
|
||||
* 2014-11-03
|
||||
|
||||
+ 分离为`weixin-mp-api`和`weixin-mp-server`两个工程
|
||||
|
||||
+ 加入支付模块
|
||||
@@ -0,0 +1,59 @@
|
||||
<?xml version="1.0"?>
|
||||
<project
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.foxinmy.weixin4j</groupId>
|
||||
<artifactId>weixin4j-mp</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>weixin4j-mp-api</artifactId>
|
||||
<name>weixin4j-mp-api</name>
|
||||
<url>https://github.com/foxinmy/weixin4j/tree/master/weixin4j-mp</url>
|
||||
<description>微信公众号API</description>
|
||||
<build>
|
||||
<finalName>weixin4j-mp-api</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<excludes>
|
||||
<exclude>*.*</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jsoup</groupId>
|
||||
<artifactId>jsoup</artifactId>
|
||||
<version>${jsoup.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jaxen</groupId>
|
||||
<artifactId>jaxen</artifactId>
|
||||
<version>${jaxen.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi</artifactId>
|
||||
<version>${poi.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml</artifactId>
|
||||
<version>${poi.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml-schemas</artifactId>
|
||||
<version>${poi.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
+125
-41
@@ -2,13 +2,14 @@ package com.foxinmy.weixin4j.mp;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.BaseResult;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccountV2;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccountV3;
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.XmlResult;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.mp.api.GroupApi;
|
||||
import com.foxinmy.weixin4j.mp.api.HelperApi;
|
||||
import com.foxinmy.weixin4j.mp.api.MassApi;
|
||||
@@ -30,7 +31,11 @@ import com.foxinmy.weixin4j.mp.model.UserToken;
|
||||
import com.foxinmy.weixin4j.mp.msg.model.Article;
|
||||
import com.foxinmy.weixin4j.mp.msg.model.BaseMsg;
|
||||
import com.foxinmy.weixin4j.mp.msg.notify.BaseNotify;
|
||||
import com.foxinmy.weixin4j.mp.payment.BillType;
|
||||
import com.foxinmy.weixin4j.mp.payment.IdQuery;
|
||||
import com.foxinmy.weixin4j.mp.payment.IdType;
|
||||
import com.foxinmy.weixin4j.mp.payment.v2.Order;
|
||||
import com.foxinmy.weixin4j.mp.payment.v3.Refund;
|
||||
import com.foxinmy.weixin4j.mp.response.TemplateMessage;
|
||||
import com.foxinmy.weixin4j.token.FileTokenHolder;
|
||||
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
@@ -74,17 +79,17 @@ public class WeixinProxy {
|
||||
this(new FileTokenHolder(appid, appsecret));
|
||||
}
|
||||
|
||||
public WeixinProxy(TokenHolder tokenApi) {
|
||||
this.mediaApi = new MediaApi(tokenApi);
|
||||
this.notifyApi = new NotifyApi(tokenApi);
|
||||
this.massApi = new MassApi(tokenApi);
|
||||
this.userApi = new UserApi(tokenApi);
|
||||
this.groupApi = new GroupApi(tokenApi);
|
||||
this.menuApi = new MenuApi(tokenApi);
|
||||
this.qrApi = new QrApi(tokenApi);
|
||||
this.tmplApi = new TmplApi(tokenApi);
|
||||
this.helperApi = new HelperApi(tokenApi);
|
||||
this.payApi = new PayApi(tokenApi);
|
||||
public WeixinProxy(TokenHolder tokenHolder) {
|
||||
this.mediaApi = new MediaApi(tokenHolder);
|
||||
this.notifyApi = new NotifyApi(tokenHolder);
|
||||
this.massApi = new MassApi(tokenHolder);
|
||||
this.userApi = new UserApi(tokenHolder);
|
||||
this.groupApi = new GroupApi(tokenHolder);
|
||||
this.menuApi = new MenuApi(tokenHolder);
|
||||
this.qrApi = new QrApi(tokenHolder);
|
||||
this.tmplApi = new TmplApi(tokenHolder);
|
||||
this.helperApi = new HelperApi(tokenHolder);
|
||||
this.payApi = new PayApi(tokenHolder);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -182,7 +187,7 @@ public class WeixinProxy {
|
||||
* @see com.foxinmy.weixin4j.mp.msg.notify.ArticleNotify
|
||||
* @see com.foxinmy.weixin4j.mp.api.NotifyApi
|
||||
*/
|
||||
public BaseResult sendNotify(BaseNotify notify) throws WeixinException {
|
||||
public JsonResult sendNotify(BaseNotify notify) throws WeixinException {
|
||||
return notifyApi.sendNotify(notify);
|
||||
}
|
||||
|
||||
@@ -199,7 +204,7 @@ public class WeixinProxy {
|
||||
* @see com.foxinmy.weixin4j.mp.msg.notify.ArticleNotify
|
||||
* @see com.foxinmy.weixin4j.mp.api.NotifyApi
|
||||
*/
|
||||
public BaseResult sendNotify(String touser, List<Article> articles)
|
||||
public JsonResult sendNotify(String touser, List<Article> articles)
|
||||
throws WeixinException {
|
||||
return notifyApi.sendNotify(touser, articles);
|
||||
}
|
||||
@@ -220,7 +225,7 @@ public class WeixinProxy {
|
||||
* @see com.foxinmy.weixin4j.mp.msg.model.Voice
|
||||
* @see com.foxinmy.weixin4j.mp.api.NotifyApi
|
||||
*/
|
||||
public BaseResult sendNotify(String touser, BaseMsg baseMsg)
|
||||
public JsonResult sendNotify(String touser, BaseMsg baseMsg)
|
||||
throws WeixinException {
|
||||
return notifyApi.sendNotify(touser, baseMsg);
|
||||
}
|
||||
@@ -393,7 +398,7 @@ public class WeixinProxy {
|
||||
* @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#massByGroup(JSONObject, String)}
|
||||
* @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#massByOpenIds(JSONObject, String...)
|
||||
*/
|
||||
public BaseResult deleteMassNews(String msgid) throws WeixinException {
|
||||
public JsonResult deleteMassNews(String msgid) throws WeixinException {
|
||||
return massApi.deleteMassNews(msgid);
|
||||
}
|
||||
|
||||
@@ -498,7 +503,7 @@ public class WeixinProxy {
|
||||
* href="http://mp.weixin.qq.com/wiki/index.php?title=%E8%AE%BE%E7%BD%AE%E7%94%A8%E6%88%B7%E5%A4%87%E6%B3%A8%E5%90%8D%E6%8E%A5%E5%8F%A3">设置用户备注名</a>
|
||||
* @see com.foxinmy.weixin4j.mp.api.UserApi
|
||||
*/
|
||||
public BaseResult remarkUserName(String openId, String remark)
|
||||
public JsonResult remarkUserName(String openId, String remark)
|
||||
throws WeixinException {
|
||||
return userApi.remarkUserName(openId, remark);
|
||||
}
|
||||
@@ -564,7 +569,7 @@ public class WeixinProxy {
|
||||
* @see com.foxinmy.weixin4j.mp.model.Group#toModifyJson()
|
||||
* @see com.foxinmy.weixin4j.mp.api.GroupApi
|
||||
*/
|
||||
public BaseResult modifyGroup(int groupId, String name)
|
||||
public JsonResult modifyGroup(int groupId, String name)
|
||||
throws WeixinException {
|
||||
return groupApi.modifyGroup(groupId, name);
|
||||
}
|
||||
@@ -582,7 +587,7 @@ public class WeixinProxy {
|
||||
* @see com.foxinmy.weixin4j.mp.model.Group
|
||||
* @see com.foxinmy.weixin4j.mp.api.GroupApi
|
||||
*/
|
||||
public BaseResult moveGroup(String openId, int groupId)
|
||||
public JsonResult moveGroup(String openId, int groupId)
|
||||
throws WeixinException {
|
||||
return groupApi.moveGroup(openId, groupId);
|
||||
}
|
||||
@@ -598,7 +603,7 @@ public class WeixinProxy {
|
||||
* @see com.foxinmy.weixin4j.type.ButtonType
|
||||
* @see com.foxinmy.weixin4j.mp.api.MenuApi
|
||||
*/
|
||||
public BaseResult createMenu(List<Button> btnList) throws WeixinException {
|
||||
public JsonResult createMenu(List<Button> btnList) throws WeixinException {
|
||||
return menuApi.createMenu(btnList);
|
||||
}
|
||||
|
||||
@@ -625,7 +630,7 @@ public class WeixinProxy {
|
||||
* @see com.foxinmy.weixin4j.mp.model.Button
|
||||
* @see com.foxinmy.weixin4j.mp.api.MenuApi
|
||||
*/
|
||||
public BaseResult deleteMenu() throws WeixinException {
|
||||
public JsonResult deleteMenu() throws WeixinException {
|
||||
return menuApi.deleteMenu();
|
||||
}
|
||||
|
||||
@@ -692,7 +697,7 @@ public class WeixinProxy {
|
||||
* @seee com.foxinmy.weixin4j.msg.event.TemplatesendjobfinishMessage
|
||||
* @see com.foxinmy.weixin4j.mp.api.TmplApi
|
||||
*/
|
||||
public BaseResult sendTmplMessage(TemplateMessage tplMessage)
|
||||
public JsonResult sendTmplMessage(TemplateMessage tplMessage)
|
||||
throws WeixinException {
|
||||
return tmplApi.sendTmplMessage(tplMessage);
|
||||
}
|
||||
@@ -714,8 +719,8 @@ public class WeixinProxy {
|
||||
/**
|
||||
* 发货通知
|
||||
*
|
||||
* @param weixinConfig
|
||||
* V2版本
|
||||
* @param weixinAccount
|
||||
* 商户信息
|
||||
* @param transid
|
||||
* 交易单号
|
||||
* @param orderNo
|
||||
@@ -724,31 +729,32 @@ public class WeixinProxy {
|
||||
* 成功|失败
|
||||
* @param statusMsg
|
||||
* status为失败时携带的信息
|
||||
* @return
|
||||
* @return 调用结果
|
||||
* @throws WeixinException
|
||||
* @see com.foxinmy.weixin4j.mp.api.PayApi
|
||||
*/
|
||||
public BaseResult deliverNotify(WeixinAccountV2 weixinConfig,
|
||||
public JsonResult deliverNotify(WeixinAccount weixinAccount,
|
||||
String transid, String orderNo, boolean status, String statusMsg)
|
||||
throws WeixinException {
|
||||
return payApi.deliverNotify(weixinConfig, transid, orderNo, status,
|
||||
return payApi.deliverNotify(weixinAccount, transid, orderNo, status,
|
||||
statusMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单查询
|
||||
*
|
||||
* @param weixinConfig
|
||||
* V2版本
|
||||
* @param weixinAccount
|
||||
* 商户信息
|
||||
* @param orderNo
|
||||
* 订单号
|
||||
* @return
|
||||
* @return 订单信息
|
||||
* @throws WeixinException
|
||||
* @see com.foxinmy.weixin4j.mp.api.PayApi
|
||||
*/
|
||||
public Order orderQuery(WeixinAccountV2 weixinConfig, String orderNo)
|
||||
public Order orderQueryV2(WeixinAccount weixinAccount, String orderNo)
|
||||
throws WeixinException {
|
||||
return payApi.orderQuery(weixinConfig, orderNo);
|
||||
return payApi.orderQueryV2(weixinAccount, new IdQuery(orderNo,
|
||||
IdType.ORDERNO));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -758,28 +764,106 @@ public class WeixinProxy {
|
||||
* 用户ID
|
||||
* @param feedbackId
|
||||
* 维权单号
|
||||
* @return
|
||||
* @return 调用结果
|
||||
* @see com.foxinmy.weixin4j.mp.api.PayApi
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public BaseResult updateFeedback(String openId, String feedbackId)
|
||||
public JsonResult updateFeedback(String openId, String feedbackId)
|
||||
throws WeixinException {
|
||||
return payApi.updateFeedback(openId, feedbackId);
|
||||
}
|
||||
|
||||
/**
|
||||
* V3订单查询
|
||||
*
|
||||
* @param weixinAccount
|
||||
* 商户信息
|
||||
* @param idQuery
|
||||
* 商户系统内部的订单号, transaction_id、out_trade_no 二 选一,如果同时存在优先级:
|
||||
* transaction_id> out_trade_no
|
||||
* @see com.foxinmy.weixin4j.mp.api.PayApi
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public com.foxinmy.weixin4j.mp.payment.v3.Order orderQueryV3(
|
||||
WeixinAccount weixinAccount, IdQuery idQuery)
|
||||
throws WeixinException {
|
||||
return payApi.orderQueryV3(weixinAccount, idQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载对账单<br>
|
||||
* 1.微信侧未成功下单的交易不会出现在对账单中。支付成功后撤销的交易会出现在对账 单中,跟原支付单订单号一致,bill_type 为
|
||||
* REVOKED;<br>
|
||||
* 2.微信在次日 9 点启动生成前一天的对账单,建议商户 9 点半后再获取;<br>
|
||||
* 3.对账单中涉及金额的字段单位为“元”。<br>
|
||||
*
|
||||
* @param weixinAccount
|
||||
* 商户配置
|
||||
* @param billDate
|
||||
* 下载对账单的日期
|
||||
* @param billType
|
||||
* 下载对账单的类型 ALL,返回当日所有订单信息, 默认值 SUCCESS,返回当日成功支付的订单
|
||||
* REFUND,返回当日退款订单
|
||||
* @return excel表格
|
||||
* @see com.foxinmy.weixin4j.mp.api.PayApi
|
||||
* @throws WeixinException
|
||||
* @throws IOException
|
||||
*/
|
||||
public File downloadbill(WeixinAccount weixinAccount, Date billDate,
|
||||
BillType billType) throws WeixinException, IOException {
|
||||
return payApi.downloadbill(weixinAccount, billDate, billType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款查询<br/>
|
||||
* 退款有一定延时,用零钱支付的退款20分钟内到账,银行卡支付的退款 3 个工作日后重新查询退款状态
|
||||
*
|
||||
* @param weixinAccount
|
||||
* @param idQuery
|
||||
* 单号 refund_id、out_refund_no、 out_trade_no 、 transaction_id
|
||||
* 四个参数必填一个,优先级为:
|
||||
* refund_id>out_refund_no>transaction_id>out_trade_no
|
||||
* @see com.foxinmy.weixin4j.mp.api.PayApi
|
||||
* @return 退款记录
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public Refund refundQuery(WeixinAccount weixinAccount, IdQuery idQuery)
|
||||
throws WeixinException {
|
||||
return payApi.refundQuery(weixinAccount, idQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭订单<br/>
|
||||
* 当订单支付失败,调用关单接口后用新订单号重新发起支付,如果关单失败,返回已完
|
||||
* 成支付请按正常支付处理。如果出现银行掉单,调用关单成功后,微信后台会主动发起退款。
|
||||
*
|
||||
* @param weixinAccount
|
||||
* 商户信息
|
||||
* @param order
|
||||
* 商户系统内部的订单号
|
||||
* @return 执行结果
|
||||
* @see com.foxinmy.weixin4j.mp.api.PayApi
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public XmlResult closeOrder(WeixinAccount weixinAccount, String orderNo)
|
||||
throws WeixinException {
|
||||
return payApi.orderQueryV3(weixinAccount, new IdQuery(orderNo,
|
||||
IdType.ORDERNO));
|
||||
}
|
||||
|
||||
/**
|
||||
* native支付URL转短链接
|
||||
*
|
||||
* @param weixinConfig
|
||||
* 商户配置
|
||||
* @param weixinAccount
|
||||
* 商户信息
|
||||
* @param url
|
||||
* native支付URL
|
||||
* 具有native标识的支付URL
|
||||
* @return 转换后的短链接
|
||||
* @see com.foxinmy.weixin4j.mp.api.PayApi
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public String getShorturl(WeixinAccountV3 weixinConfig, String url)
|
||||
public String getShorturl(WeixinAccount weixinAccount, String url)
|
||||
throws WeixinException {
|
||||
return payApi.getShorturl(weixinConfig, url);
|
||||
return payApi.getShorturl(weixinAccount, url);
|
||||
}
|
||||
}
|
||||
+17
-1
@@ -2,12 +2,16 @@ package com.foxinmy.weixin4j.mp.api;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.foxinmy.weixin4j.http.HttpRequest;
|
||||
import com.foxinmy.weixin4j.xml.Map2ObjectConverter;
|
||||
import com.foxinmy.weixin4j.xml.XStream;
|
||||
import com.thoughtworks.xstream.core.ClassLoaderReference;
|
||||
import com.thoughtworks.xstream.mapper.DefaultMapper;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -19,12 +23,24 @@ import com.foxinmy.weixin4j.xml.XStream;
|
||||
*/
|
||||
public class BaseApi {
|
||||
protected final HttpRequest request = new HttpRequest();
|
||||
protected final XStream xStream = XStream.get();
|
||||
protected final static XStream mapXstream = XStream.get();
|
||||
protected final Charset utf8 = StandardCharsets.UTF_8;
|
||||
private final static ResourceBundle weixinBundle;
|
||||
static {
|
||||
weixinBundle = ResourceBundle
|
||||
.getBundle("com/foxinmy/weixin4j/mp/api/weixin");
|
||||
mapXstream.alias("xml", Map.class);
|
||||
mapXstream.registerConverter(new Map2ObjectConverter(new DefaultMapper(
|
||||
new ClassLoaderReference(XStream.class.getClassLoader()))));
|
||||
}
|
||||
|
||||
protected String map2xml(Map<?, ?> map) {
|
||||
return mapXstream.toXML(map).replaceAll("__", "_");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Map<String, String> xml2map(String xml) {
|
||||
return mapXstream.fromXML(xml,Map.class);
|
||||
}
|
||||
|
||||
protected String getRequestUri(String key) {
|
||||
+13
-13
@@ -4,7 +4,7 @@ import java.util.List;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.BaseResult;
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.Response;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.mp.model.Group;
|
||||
@@ -23,9 +23,9 @@ import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
*/
|
||||
public class GroupApi extends BaseApi {
|
||||
|
||||
private final TokenHolder tokenApi;
|
||||
public GroupApi(TokenHolder tokenApi) {
|
||||
this.tokenApi = tokenApi;
|
||||
private final TokenHolder tokenHolder;
|
||||
public GroupApi(TokenHolder tokenHolder) {
|
||||
this.tokenHolder = tokenHolder;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -42,7 +42,7 @@ public class GroupApi extends BaseApi {
|
||||
*/
|
||||
public Group createGroup(String name) throws WeixinException {
|
||||
String group_create_uri = getRequestUri("group_create_uri");
|
||||
Token token = tokenApi.getToken();
|
||||
Token token = tokenHolder.getToken();
|
||||
Group group = new Group(name);
|
||||
Response response = request.post(
|
||||
String.format(group_create_uri, token.getAccessToken()),
|
||||
@@ -62,7 +62,7 @@ public class GroupApi extends BaseApi {
|
||||
*/
|
||||
public List<Group> getGroups() throws WeixinException {
|
||||
String group_get_uri = getRequestUri("group_get_uri");
|
||||
Token token = tokenApi.getToken();
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.get(String.format(group_get_uri,
|
||||
token.getAccessToken()));
|
||||
|
||||
@@ -83,7 +83,7 @@ public class GroupApi extends BaseApi {
|
||||
*/
|
||||
public int getGroupByOpenId(String openId) throws WeixinException {
|
||||
String group_getid_uri = getRequestUri("group_getid_uri");
|
||||
Token token = tokenApi.getToken();
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.post(
|
||||
String.format(group_getid_uri, token.getAccessToken()),
|
||||
String.format("{\"openid\":\"%s\"}", openId));
|
||||
@@ -104,16 +104,16 @@ public class GroupApi extends BaseApi {
|
||||
* @see com.foxinmy.weixin4j.mp.model.Group
|
||||
* @see com.foxinmy.weixin4j.mp.model.Group#toModifyJson()
|
||||
*/
|
||||
public BaseResult modifyGroup(int groupId, String name)
|
||||
public JsonResult modifyGroup(int groupId, String name)
|
||||
throws WeixinException {
|
||||
String group_modify_uri = getRequestUri("group_modify_uri");
|
||||
Token token = tokenApi.getToken();
|
||||
Token token = tokenHolder.getToken();
|
||||
Group group = new Group(groupId, name);
|
||||
|
||||
Response response = request.post(
|
||||
String.format(group_modify_uri, token.getAccessToken()),
|
||||
group.toModifyJson());
|
||||
return response.getAsResult();
|
||||
return response.getAsJsonResult();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -128,14 +128,14 @@ public class GroupApi extends BaseApi {
|
||||
* href="http://mp.weixin.qq.com/wiki/index.php?title=%E5%88%86%E7%BB%84%E7%AE%A1%E7%90%86%E6%8E%A5%E5%8F%A3#.E7.A7.BB.E5.8A.A8.E7.94.A8.E6.88.B7.E5.88.86.E7.BB.84">移动分组</a>
|
||||
* @see com.foxinmy.weixin4j.mp.model.Group
|
||||
*/
|
||||
public BaseResult moveGroup(String openId, int groupId)
|
||||
public JsonResult moveGroup(String openId, int groupId)
|
||||
throws WeixinException {
|
||||
String group_move_uri = getRequestUri("group_move_uri");
|
||||
Token token = tokenApi.getToken();
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.post(String.format(group_move_uri,
|
||||
token.getAccessToken()), String.format(
|
||||
"{\"openid\":\"%s\",\"to_groupid\":%d}", openId, groupId));
|
||||
|
||||
return response.getAsResult();
|
||||
return response.getAsJsonResult();
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -17,10 +17,10 @@ import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
*/
|
||||
public class HelperApi extends BaseApi {
|
||||
|
||||
private final TokenHolder tokenApi;
|
||||
private final TokenHolder tokenHolder;
|
||||
|
||||
public HelperApi(TokenHolder tokenApi) {
|
||||
this.tokenApi = tokenApi;
|
||||
public HelperApi(TokenHolder tokenHolder) {
|
||||
this.tokenHolder = tokenHolder;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -34,7 +34,7 @@ public class HelperApi extends BaseApi {
|
||||
*/
|
||||
public String getShorturl(String url) throws WeixinException {
|
||||
String shorturl_uri = getRequestUri("shorturl_uri");
|
||||
Token token = tokenApi.getToken();
|
||||
Token token = tokenHolder.getToken();
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("action", "long2short");
|
||||
obj.put("long_url", url);
|
||||
+11
-11
@@ -5,7 +5,7 @@ import java.util.List;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.BaseResult;
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.Response;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.mp.model.MpArticle;
|
||||
@@ -25,10 +25,10 @@ import com.foxinmy.weixin4j.type.MediaType;
|
||||
*/
|
||||
public class MassApi extends BaseApi {
|
||||
|
||||
private final TokenHolder tokenApi;
|
||||
private final TokenHolder tokenHolder;
|
||||
|
||||
public MassApi(TokenHolder tokenApi) {
|
||||
this.tokenApi = tokenApi;
|
||||
public MassApi(TokenHolder tokenHolder) {
|
||||
this.tokenHolder = tokenHolder;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -47,7 +47,7 @@ public class MassApi extends BaseApi {
|
||||
public String uploadArticle(List<MpArticle> articles)
|
||||
throws WeixinException {
|
||||
String article_upload_uri = getRequestUri("article_upload_uri");
|
||||
Token token = tokenApi.getToken();
|
||||
Token token = tokenHolder.getToken();
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("articles", articles);
|
||||
Response response = request.post(
|
||||
@@ -75,7 +75,7 @@ public class MassApi extends BaseApi {
|
||||
public String uploadVideo(String mediaId, String title, String desc)
|
||||
throws WeixinException {
|
||||
String video_upload_uri = getRequestUri("video_upload_uri");
|
||||
Token token = tokenApi.getToken();
|
||||
Token token = tokenHolder.getToken();
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("media_id", mediaId);
|
||||
obj.put("title", title);
|
||||
@@ -109,7 +109,7 @@ public class MassApi extends BaseApi {
|
||||
private String massByGroup(JSONObject jsonPara, String groupId)
|
||||
throws WeixinException {
|
||||
String mass_group_uri = getRequestUri("mass_group_uri");
|
||||
Token token = tokenApi.getToken();
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.post(
|
||||
String.format(mass_group_uri, token.getAccessToken()),
|
||||
jsonPara.toJSONString());
|
||||
@@ -133,7 +133,7 @@ public class MassApi extends BaseApi {
|
||||
private String massByOpenIds(JSONObject jsonPara, String... openIds)
|
||||
throws WeixinException {
|
||||
String mass_openid_uri = getRequestUri("mass_openid_uri");
|
||||
Token token = tokenApi.getToken();
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.post(
|
||||
String.format(mass_openid_uri, token.getAccessToken()),
|
||||
jsonPara.toJSONString());
|
||||
@@ -255,15 +255,15 @@ public class MassApi extends BaseApi {
|
||||
* @see {@link com.foxinmy.weixin4j.mp.api.MassApi#massByGroup(JSONObject, String)}
|
||||
* @see {@link com.foxinmy.weixin4j.mp.api.MassApi#massByOpenIds(JSONObject, String...)
|
||||
*/
|
||||
public BaseResult deleteMassNews(String msgid) throws WeixinException {
|
||||
public JsonResult deleteMassNews(String msgid) throws WeixinException {
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("msgid", msgid);
|
||||
String mass_delete_uri = getRequestUri("mass_delete_uri");
|
||||
Token token = tokenApi.getToken();
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.post(
|
||||
String.format(mass_delete_uri, token.getAccessToken()),
|
||||
obj.toJSONString());
|
||||
|
||||
return response.getAsResult();
|
||||
return response.getAsJsonResult();
|
||||
}
|
||||
}
|
||||
+7
-13
@@ -28,10 +28,10 @@ import com.foxinmy.weixin4j.util.IOUtil;
|
||||
*/
|
||||
public class MediaApi extends BaseApi {
|
||||
|
||||
private final TokenHolder tokenApi;
|
||||
private final TokenHolder tokenHolder;
|
||||
|
||||
public MediaApi(TokenHolder tokenApi) {
|
||||
this.tokenApi = tokenApi;
|
||||
public MediaApi(TokenHolder tokenHolder) {
|
||||
this.tokenHolder = tokenHolder;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -72,7 +72,7 @@ public class MediaApi extends BaseApi {
|
||||
*/
|
||||
public String uploadMedia(String fileName, byte[] bytes, MediaType mediaType)
|
||||
throws WeixinException {
|
||||
Token token = tokenApi.getToken();
|
||||
Token token = tokenHolder.getToken();
|
||||
String file_upload_uri = getRequestUri("file_upload_uri");
|
||||
Response response = request.post(String.format(file_upload_uri,
|
||||
token.getAccessToken(), mediaType.name()), new PartParameter(
|
||||
@@ -107,14 +107,8 @@ public class MediaApi extends BaseApi {
|
||||
if (file.exists()) {
|
||||
return file;
|
||||
}
|
||||
FileOutputStream out = null;
|
||||
try {
|
||||
file.createNewFile();
|
||||
} catch (IOException e) {
|
||||
file.getParentFile().mkdirs();
|
||||
file.createNewFile();
|
||||
}
|
||||
out = new FileOutputStream(file);
|
||||
file.createNewFile();
|
||||
FileOutputStream out = new FileOutputStream(file);
|
||||
out.write(datas);
|
||||
out.close();
|
||||
return file;
|
||||
@@ -131,7 +125,7 @@ public class MediaApi extends BaseApi {
|
||||
*/
|
||||
public byte[] downloadMediaData(String mediaId, MediaType mediaType)
|
||||
throws WeixinException {
|
||||
Token token = tokenApi.getToken();
|
||||
Token token = tokenHolder.getToken();
|
||||
String file_download_uri = getRequestUri("file_download_uri");
|
||||
Response response = request.get(String.format(file_download_uri,
|
||||
token.getAccessToken(), mediaId));
|
||||
+11
-11
@@ -5,7 +5,7 @@ import java.util.List;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.BaseResult;
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.Response;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.mp.model.Button;
|
||||
@@ -22,10 +22,10 @@ import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
*/
|
||||
public class MenuApi extends BaseApi {
|
||||
|
||||
private final TokenHolder tokenApi;
|
||||
private final TokenHolder tokenHolder;
|
||||
|
||||
public MenuApi(TokenHolder tokenApi) {
|
||||
this.tokenApi = tokenApi;
|
||||
public MenuApi(TokenHolder tokenHolder) {
|
||||
this.tokenHolder = tokenHolder;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -37,16 +37,16 @@ public class MenuApi extends BaseApi {
|
||||
* href="http://mp.weixin.qq.com/wiki/index.php?title=%E8%87%AA%E5%AE%9A%E4%B9%89%E8%8F%9C%E5%8D%95%E5%88%9B%E5%BB%BA%E6%8E%A5%E5%8F%A3">创建自定义菜单</a>
|
||||
* @see com.foxinmy.weixin4j.mp.model.Button
|
||||
*/
|
||||
public BaseResult createMenu(List<Button> btnList) throws WeixinException {
|
||||
public JsonResult createMenu(List<Button> btnList) throws WeixinException {
|
||||
String menu_create_uri = getRequestUri("menu_create_uri");
|
||||
Token token = tokenApi.getToken();
|
||||
Token token = tokenHolder.getToken();
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("button", btnList);
|
||||
Response response = request.post(
|
||||
String.format(menu_create_uri, token.getAccessToken()),
|
||||
obj.toJSONString());
|
||||
|
||||
return response.getAsResult();
|
||||
return response.getAsJsonResult();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,7 +60,7 @@ public class MenuApi extends BaseApi {
|
||||
*/
|
||||
public List<Button> getMenu() throws WeixinException {
|
||||
String menu_get_uri = getRequestUri("menu_get_uri");
|
||||
Token token = tokenApi.getToken();
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.get(String.format(menu_get_uri,
|
||||
token.getAccessToken()));
|
||||
|
||||
@@ -77,12 +77,12 @@ public class MenuApi extends BaseApi {
|
||||
* href="http://mp.weixin.qq.com/wiki/index.php?title=%E8%87%AA%E5%AE%9A%E4%B9%89%E8%8F%9C%E5%8D%95%E5%88%A0%E9%99%A4%E6%8E%A5%E5%8F%A3">删除菜单</a>
|
||||
* @see com.foxinmy.weixin4j.mp.model.Button
|
||||
*/
|
||||
public BaseResult deleteMenu() throws WeixinException {
|
||||
public JsonResult deleteMenu() throws WeixinException {
|
||||
String menu_delete_uri = getRequestUri("menu_delete_uri");
|
||||
Token token = tokenApi.getToken();
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.get(String.format(menu_delete_uri,
|
||||
token.getAccessToken()));
|
||||
|
||||
return response.getAsResult();
|
||||
return response.getAsJsonResult();
|
||||
}
|
||||
}
|
||||
+11
-11
@@ -5,7 +5,7 @@ import java.util.List;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.BaseResult;
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.Response;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.mp.model.CustomRecord;
|
||||
@@ -33,10 +33,10 @@ import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
*/
|
||||
public class NotifyApi extends BaseApi {
|
||||
|
||||
private final TokenHolder tokenApi;
|
||||
private final TokenHolder tokenHolder;
|
||||
|
||||
public NotifyApi(TokenHolder tokenApi) {
|
||||
this.tokenApi = tokenApi;
|
||||
public NotifyApi(TokenHolder tokenHolder) {
|
||||
this.tokenHolder = tokenHolder;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -48,14 +48,14 @@ public class NotifyApi extends BaseApi {
|
||||
* @see <a
|
||||
* href="http://mp.weixin.qq.com/wiki/index.php?title=%E5%8F%91%E9%80%81%E5%AE%A2%E6%9C%8D%E6%B6%88%E6%81%AF#.E5.8F.91.E9.80.81.E9.9F.B3.E4.B9.90.E6.B6.88.E6.81.AF">发送客服消息</a>
|
||||
*/
|
||||
private BaseResult sendNotify(String jsonPara) throws WeixinException {
|
||||
private JsonResult sendNotify(String jsonPara) throws WeixinException {
|
||||
String custom_notify_uri = getRequestUri("custom_notify_uri");
|
||||
Token token = tokenApi.getToken();
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.post(
|
||||
String.format(custom_notify_uri, token.getAccessToken()),
|
||||
jsonPara);
|
||||
|
||||
return response.getAsResult();
|
||||
return response.getAsJsonResult();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,7 +74,7 @@ public class NotifyApi extends BaseApi {
|
||||
* @see com.foxinmy.weixin4j.mp.msg.notify.ArticleNotify
|
||||
* @see {@link com.foxinmy.weixin4j.mp.api.NotifyApi#sendNotify(String)}
|
||||
*/
|
||||
public BaseResult sendNotify(BaseNotify notify) throws WeixinException {
|
||||
public JsonResult sendNotify(BaseNotify notify) throws WeixinException {
|
||||
return sendNotify(notify.toJson());
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ public class NotifyApi extends BaseApi {
|
||||
* @see com.foxinmy.weixin4j.mp.msg.model.Article
|
||||
* @see com.foxinmy.weixin4j.mp.msg.notify.ArticleNotify
|
||||
*/
|
||||
public BaseResult sendNotify(String touser, List<Article> articles)
|
||||
public JsonResult sendNotify(String touser, List<Article> articles)
|
||||
throws WeixinException {
|
||||
ArticleNotify notify = new ArticleNotify(touser);
|
||||
notify.pushAll(articles);
|
||||
@@ -114,7 +114,7 @@ public class NotifyApi extends BaseApi {
|
||||
* @see {@link com.foxinmy.weixin4j.mp.msg.model.BaseMsg#toNotifyJson()}
|
||||
* @see {@link com.foxinmy.weixin4j.mp.api.NotifyApi#sendNotify(String)}
|
||||
*/
|
||||
public BaseResult sendNotify(String touser, BaseMsg baseMsg)
|
||||
public JsonResult sendNotify(String touser, BaseMsg baseMsg)
|
||||
throws WeixinException {
|
||||
StringBuilder jsonPara = new StringBuilder();
|
||||
String mediaType = baseMsg.getMediaType().name();
|
||||
@@ -154,7 +154,7 @@ public class NotifyApi extends BaseApi {
|
||||
obj.put("pagesize", pagesize > 1000 ? 1000 : pagesize);
|
||||
obj.put("pageindex", pageindex);
|
||||
String custom_record_uri = getRequestUri("custom_record_uri");
|
||||
Token token = tokenApi.getToken();
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.post(
|
||||
String.format(custom_record_uri, token.getAccessToken()),
|
||||
obj.toJSONString());
|
||||
@@ -0,0 +1,368 @@
|
||||
package com.foxinmy.weixin4j.mp.api;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.alibaba.fastjson.parser.Feature;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.Response;
|
||||
import com.foxinmy.weixin4j.http.XmlResult;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.mp.payment.BillType;
|
||||
import com.foxinmy.weixin4j.mp.payment.IdQuery;
|
||||
import com.foxinmy.weixin4j.mp.payment.IdType;
|
||||
import com.foxinmy.weixin4j.mp.payment.PayUtil;
|
||||
import com.foxinmy.weixin4j.mp.payment.RefundConverter;
|
||||
import com.foxinmy.weixin4j.mp.payment.v2.Order;
|
||||
import com.foxinmy.weixin4j.mp.payment.v3.Refund;
|
||||
import com.foxinmy.weixin4j.mp.util.ExcelUtil;
|
||||
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||
import com.foxinmy.weixin4j.util.DateUtil;
|
||||
import com.foxinmy.weixin4j.util.MapUtil;
|
||||
import com.foxinmy.weixin4j.util.RandomUtil;
|
||||
|
||||
/**
|
||||
* 支付API
|
||||
*
|
||||
* @className PayApi
|
||||
* @author jy
|
||||
* @date 2014年10月28日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class PayApi extends BaseApi {
|
||||
private final TokenHolder tokenHolder;
|
||||
|
||||
public PayApi(TokenHolder tokenHolder) {
|
||||
this.tokenHolder = tokenHolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发货通知
|
||||
*
|
||||
* @param weixinAccount
|
||||
* @param transid
|
||||
* 交易单号
|
||||
* @param orderNo
|
||||
* 订单号
|
||||
* @param status
|
||||
* 成功|失败
|
||||
* @param statusMsg
|
||||
* status为失败时携带的信息
|
||||
* @return
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public JsonResult deliverNotify(WeixinAccount weixinAccount,
|
||||
String transid, String orderNo, boolean status, String statusMsg)
|
||||
throws WeixinException {
|
||||
String delivernotify_uri = getRequestUri("delivernotify_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
|
||||
Map<String, String> param = new HashMap<String, String>();
|
||||
param.put("appid", weixinAccount.getAppId());
|
||||
param.put("appkey", weixinAccount.getPaySignKey());
|
||||
// 用户购买的openId
|
||||
param.put("openid", weixinAccount.getOpenId());
|
||||
param.put("transid", transid);
|
||||
param.put("out_trade_no", orderNo);
|
||||
param.put("deliver_timestamp", System.currentTimeMillis() / 1000 + "");
|
||||
param.put("deliver_status", status ? "1" : "0");
|
||||
param.put("deliver_msg", statusMsg);
|
||||
param.put("app_signature", DigestUtils.sha1Hex(MapUtil.toJoinString(
|
||||
param, false, true, null)));
|
||||
param.put("sign_method", "sha1");
|
||||
|
||||
Response response = request.post(
|
||||
String.format(delivernotify_uri, token.getAccessToken()),
|
||||
JSON.toJSONString(param));
|
||||
|
||||
return response.getAsJsonResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单查询
|
||||
*
|
||||
* @param weixinAccount
|
||||
* 商户信息
|
||||
* @param orderNo
|
||||
* 订单号
|
||||
* @return
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public Order orderQueryV2(WeixinAccount weixinAccount, IdQuery idQuery)
|
||||
throws WeixinException {
|
||||
String orderquery_uri = getRequestUri("orderquery_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(idQuery.getType().getName()).append(idQuery.getId());
|
||||
sb.append("&partner=").append(weixinAccount.getPartnerId());
|
||||
String part = sb.toString();
|
||||
sb.append("&key=").append(weixinAccount.getPartnerKey());
|
||||
String sign = DigestUtils.md5Hex(sb.toString()).toUpperCase();
|
||||
sb.delete(0, sb.length());
|
||||
sb.append(part).append("&sign=").append(sign);
|
||||
|
||||
String timestamp = System.currentTimeMillis() / 1000 + "";
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("appid", weixinAccount.getAppId());
|
||||
obj.put("appkey", weixinAccount.getPaySignKey());
|
||||
obj.put("package", sb.toString());
|
||||
obj.put("timestamp", timestamp);
|
||||
String signature = DigestUtils.sha1Hex(MapUtil.toJoinString(obj, false,
|
||||
true, null));
|
||||
|
||||
obj = new JSONObject();
|
||||
obj.put("appid", weixinAccount.getAppId());
|
||||
obj.put("package", sb.toString());
|
||||
obj.put("timestamp", timestamp);
|
||||
obj.put("app_signature", signature);
|
||||
obj.put("sign_method", "sha1");
|
||||
|
||||
Response response = request.post(
|
||||
String.format(orderquery_uri, token.getAccessToken()),
|
||||
obj.toJSONString());
|
||||
|
||||
String order_info = response.getAsJson().getString("order_info");
|
||||
Order order = JSON.parseObject(order_info, Order.class,
|
||||
Feature.IgnoreNotMatch);
|
||||
order.setMapData(JSON.parseObject(order_info,
|
||||
new TypeReference<Map<String, String>>() {
|
||||
}));
|
||||
return order;
|
||||
}
|
||||
|
||||
/**
|
||||
* 维权处理
|
||||
*
|
||||
* @param openId
|
||||
* 用户ID
|
||||
* @param feedbackId
|
||||
* 维权单号
|
||||
* @return
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public JsonResult updateFeedback(String openId, String feedbackId)
|
||||
throws WeixinException {
|
||||
String payfeedback_update_uri = ConfigUtil
|
||||
.getValue("payfeedback_update_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.get(String.format(payfeedback_update_uri,
|
||||
token.getAccessToken(), openId, feedbackId));
|
||||
return response.getAsJsonResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* V3订单查询
|
||||
*
|
||||
* @param weixinAccount
|
||||
* 商户信息
|
||||
* @param idQuery
|
||||
* 商户系统内部的订单号, transaction_id、out_trade_no 二 选一,如果同时存在优先级:
|
||||
* transaction_id> out_trade_no
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public com.foxinmy.weixin4j.mp.payment.v3.Order orderQueryV3(
|
||||
WeixinAccount weixinAccount, IdQuery idQuery)
|
||||
throws WeixinException {
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
map.put("appid", weixinAccount.getAppId());
|
||||
map.put("mch_id", weixinAccount.getMchId());
|
||||
map.put("nonce_str", RandomUtil.generateString(16));
|
||||
map.put(idQuery.getType().getName(), idQuery.getId());
|
||||
String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey());
|
||||
map.put("sign", sign);
|
||||
String param = map2xml(map);
|
||||
String orderquery_uri = getRequestUri("orderquery_v3_uri");
|
||||
Response response = request.post(orderquery_uri, param);
|
||||
return response
|
||||
.getAsObject(new TypeReference<com.foxinmy.weixin4j.mp.payment.v3.Order>() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* native支付URL转短链接
|
||||
*
|
||||
* @param weixinAccount
|
||||
* 商户信息
|
||||
* @param url
|
||||
* 具有native标识的支付URL
|
||||
* @return 转换后的短链接
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public String getShorturl(WeixinAccount weixinAccount, String url)
|
||||
throws WeixinException {
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
map.put("appid", weixinAccount.getAppId());
|
||||
map.put("mch_id", weixinAccount.getMchId());
|
||||
map.put("long_url", url);
|
||||
map.put("nonce_str", RandomUtil.generateString(16));
|
||||
String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey());
|
||||
map.put("sign", sign);
|
||||
try {
|
||||
map.put("long_url", URLEncoder.encode(url, utf8.name()));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
;
|
||||
}
|
||||
String param = map2xml(map);
|
||||
String shorturl_uri = getRequestUri("p_shorturl_uri");
|
||||
Response response = request.post(shorturl_uri, param);
|
||||
map = xml2map(response.getAsString());
|
||||
return map.get("short_url");
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭订单<br/>
|
||||
* 当订单支付失败,调用关单接口后用新订单号重新发起支付,如果关单失败,返回已完
|
||||
* 成支付请按正常支付处理。如果出现银行掉单,调用关单成功后,微信后台会主动发起退款。
|
||||
*
|
||||
* @param weixinAccount
|
||||
* 商户信息
|
||||
* @param idQuery
|
||||
* 商户系统内部的订单号
|
||||
* @return
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public XmlResult closeOrder(WeixinAccount weixinAccount, IdQuery idQuery)
|
||||
throws WeixinException {
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
map.put("appid", weixinAccount.getAppId());
|
||||
map.put("mch_id", weixinAccount.getMchId());
|
||||
map.put("nonce_str", RandomUtil.generateString(16));
|
||||
map.put(idQuery.getType().getName(), idQuery.getId());
|
||||
String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey());
|
||||
map.put("sign", sign);
|
||||
String param = map2xml(map);
|
||||
String closeorder_uri = getRequestUri("closeorder_uri");
|
||||
Response response = request.post(closeorder_uri, param);
|
||||
return response.getAsXmlResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载对账单<br>
|
||||
* 1.微信侧未成功下单的交易不会出现在对账单中。支付成功后撤销的交易会出现在对账 单中,跟原支付单订单号一致,bill_type 为
|
||||
* REVOKED;<br>
|
||||
* 2.微信在次日 9 点启动生成前一天的对账单,建议商户 9 点半后再获取;<br>
|
||||
* 3.对账单中涉及金额的字段单位为“元”。<br>
|
||||
*
|
||||
* @param weixinAccount
|
||||
* 商户配置
|
||||
* @param billDate
|
||||
* 下载对账单的日期
|
||||
* @param billType
|
||||
* 下载对账单的类型 ALL,返回当日所有订单信息, 默认值 SUCCESS,返回当日成功支付的订单
|
||||
* REFUND,返回当日退款订单
|
||||
* @return excel表格
|
||||
* @throws WeixinException
|
||||
* @throws IOException
|
||||
*/
|
||||
public File downloadbill(WeixinAccount weixinAccount, Date billDate,
|
||||
BillType billType) throws WeixinException, IOException {
|
||||
|
||||
if (billDate == null) {
|
||||
Calendar now = Calendar.getInstance();
|
||||
now.add(Calendar.DAY_OF_MONTH, -10);
|
||||
billDate = now.getTime();
|
||||
}
|
||||
if (billType == null) {
|
||||
billType = BillType.ALL;
|
||||
}
|
||||
String _billDate = DateUtil.fortmatYYYYMMDD(billDate);
|
||||
String bill_path = ConfigUtil.getValue("bill_path");
|
||||
String fileName = String.format("%s_%s_%s.xls", _billDate, billType
|
||||
.name().toLowerCase(), weixinAccount.getAppId());
|
||||
File file = new File(String.format("%s/%s", bill_path, fileName));
|
||||
if (file.exists()) {
|
||||
return file;
|
||||
}
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
map.put("appid", weixinAccount.getAppId());
|
||||
map.put("mch_id", weixinAccount.getMchId());
|
||||
map.put("nonce_str", RandomUtil.generateString(16));
|
||||
map.put("device_info", weixinAccount.getDeviceInfo());
|
||||
map.put("bill_date", _billDate);
|
||||
map.put("bill_type", billType.name());
|
||||
String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey());
|
||||
map.put("sign", sign);
|
||||
String param = map2xml(map);
|
||||
String downloadbill_uri = getRequestUri("downloadbill_uri");
|
||||
Response response = request.post(downloadbill_uri, param);
|
||||
|
||||
BufferedReader reader = new BufferedReader(new StringReader(
|
||||
response.getAsString()));
|
||||
String line = null;
|
||||
List<String[]> bills = new LinkedList<String[]>();
|
||||
while ((line = reader.readLine()) != null) {
|
||||
bills.add(line.replaceAll("`", "").split(","));
|
||||
}
|
||||
reader.close();
|
||||
List<String> headers = Arrays.asList(bills.remove(0));
|
||||
List<String> totalDatas = Arrays.asList(bills.remove(bills.size() - 1));
|
||||
List<String> totalHeaders = Arrays
|
||||
.asList(bills.remove(bills.size() - 1));
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
wb.createSheet(_billDate + "对账单");
|
||||
ExcelUtil.list2excel(wb, headers, bills);
|
||||
ExcelUtil.list2excel(wb, totalHeaders, totalDatas);
|
||||
wb.write(new FileOutputStream(file));
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款查询<br/>
|
||||
* 退款有一定延时,用零钱支付的退款20分钟内到账,银行卡支付的退款 3 个工作日后重新查询退款状态
|
||||
*
|
||||
* @param weixinAccount
|
||||
* @param idQuery
|
||||
* 单号 refund_id、out_refund_no、 out_trade_no 、 transaction_id
|
||||
* 四个参数必填一个,优先级为:
|
||||
* refund_id>out_refund_no>transaction_id>out_trade_no
|
||||
* @return 退款记录
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public Refund refundQuery(WeixinAccount weixinAccount, IdQuery idQuery)
|
||||
throws WeixinException {
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
map.put("appid", weixinAccount.getAppId());
|
||||
map.put("mch_id", weixinAccount.getMchId());
|
||||
map.put("nonce_str", RandomUtil.generateString(16));
|
||||
map.put("device_info", weixinAccount.getDeviceInfo());
|
||||
map.put(idQuery.getType().getName(), idQuery.getId());
|
||||
String sign = PayUtil.paysignMd5(map, weixinAccount.getPaySignKey());
|
||||
map.put("sign", sign);
|
||||
String param = map2xml(map);
|
||||
String refundquery_uri = getRequestUri("refundquery_uri");
|
||||
Response response = request.post(refundquery_uri, param);
|
||||
return new RefundConverter().fromXML(response.getAsString());
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
WeixinAccount weixinAccount = new WeixinAccount("wx0d1d598c0c03c999",
|
||||
null, "GATFzDwbQdbbci3QEQxX2rUBvwTrsMiZ", "10020674");
|
||||
PayApi payApi = new PayApi(null);
|
||||
|
||||
System.out.println(payApi.refundQuery(weixinAccount, new IdQuery(
|
||||
"T0002", IdType.ORDERNO)));
|
||||
}
|
||||
}
|
||||
+6
-12
@@ -24,10 +24,10 @@ import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
*/
|
||||
public class QrApi extends BaseApi {
|
||||
|
||||
private final TokenHolder tokenApi;
|
||||
private final TokenHolder tokenHolder;
|
||||
|
||||
public QrApi(TokenHolder tokenApi) {
|
||||
this.tokenApi = tokenApi;
|
||||
public QrApi(TokenHolder tokenHolder) {
|
||||
this.tokenHolder = tokenHolder;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,7 +39,7 @@ public class QrApi extends BaseApi {
|
||||
* @see {@link com.foxinmy.weixin4j.mp.api.QrApi#getQR(QRParameter)}
|
||||
*/
|
||||
public byte[] getQRData(QRParameter parameter) throws WeixinException {
|
||||
Token token = tokenApi.getToken();
|
||||
Token token = tokenHolder.getToken();
|
||||
String qr_uri = getRequestUri("qr_ticket_uri");
|
||||
Response response = request.post(
|
||||
String.format(qr_uri, token.getAccessToken()),
|
||||
@@ -97,14 +97,8 @@ public class QrApi extends BaseApi {
|
||||
return file;
|
||||
}
|
||||
byte[] datas = getQRData(parameter);
|
||||
FileOutputStream out = null;
|
||||
try {
|
||||
file.createNewFile();
|
||||
} catch (IOException e) {
|
||||
file.getParentFile().mkdirs();
|
||||
file.createNewFile();
|
||||
}
|
||||
out = new FileOutputStream(file);
|
||||
file.createNewFile();
|
||||
FileOutputStream out = new FileOutputStream(file);
|
||||
out.write(datas);
|
||||
out.close();
|
||||
return file;
|
||||
+7
-7
@@ -1,7 +1,7 @@
|
||||
package com.foxinmy.weixin4j.mp.api;
|
||||
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.BaseResult;
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.Response;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.mp.response.TemplateMessage;
|
||||
@@ -18,10 +18,10 @@ import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
*/
|
||||
public class TmplApi extends BaseApi {
|
||||
|
||||
private final TokenHolder tokenApi;
|
||||
private final TokenHolder tokenHolder;
|
||||
|
||||
public TmplApi(TokenHolder tokenApi) {
|
||||
this.tokenApi = tokenApi;
|
||||
public TmplApi(TokenHolder tokenHolder) {
|
||||
this.tokenHolder = tokenHolder;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -35,14 +35,14 @@ public class TmplApi extends BaseApi {
|
||||
* @see com.foxinmy.weixin4j.mp.response.TemplateMessage
|
||||
* @seee com.foxinmy.weixin4j.msg.event.TemplatesendjobfinishMessage
|
||||
*/
|
||||
public BaseResult sendTmplMessage(TemplateMessage tplMessage)
|
||||
public JsonResult sendTmplMessage(TemplateMessage tplMessage)
|
||||
throws WeixinException {
|
||||
Token token = tokenApi.getToken();
|
||||
Token token = tokenHolder.getToken();
|
||||
String template_send_uri = getRequestUri("template_send_uri");
|
||||
Response response = request.post(
|
||||
String.format(template_send_uri, token.getAccessToken()),
|
||||
tplMessage.toJson());
|
||||
|
||||
return response.getAsResult();
|
||||
return response.getAsJsonResult();
|
||||
}
|
||||
}
|
||||
+19
-13
@@ -5,8 +5,9 @@ import java.util.List;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.BaseResult;
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.Response;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.mp.model.Following;
|
||||
@@ -25,10 +26,10 @@ import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
*/
|
||||
public class UserApi extends BaseApi {
|
||||
|
||||
private final TokenHolder tokenApi;
|
||||
private final TokenHolder tokenHolder;
|
||||
|
||||
public UserApi(TokenHolder tokenApi) {
|
||||
this.tokenApi = tokenApi;
|
||||
public UserApi(TokenHolder tokenHolder) {
|
||||
this.tokenHolder = tokenHolder;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,7 +47,8 @@ public class UserApi extends BaseApi {
|
||||
String user_token_uri = getRequestUri("sns_user_token_uri");
|
||||
Response response = request.get(String.format(user_token_uri, code));
|
||||
|
||||
return response.getAsObject(UserToken.class);
|
||||
return response.getAsObject(new TypeReference<UserToken>() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -67,7 +69,8 @@ public class UserApi extends BaseApi {
|
||||
Response response = request.get(String.format(user_info_uri,
|
||||
token.getAccessToken(), token.getOpenid()));
|
||||
|
||||
return response.getAsObject(User.class);
|
||||
return response.getAsObject(new TypeReference<User>() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,11 +90,12 @@ public class UserApi extends BaseApi {
|
||||
*/
|
||||
public User getUser(String openId) throws WeixinException {
|
||||
String user_info_uri = getRequestUri("api_user_info_uri");
|
||||
Token token = tokenApi.getToken();
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.get(String.format(user_info_uri,
|
||||
token.getAccessToken(), openId));
|
||||
|
||||
return response.getAsObject(User.class);
|
||||
return response.getAsObject(new TypeReference<User>() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,11 +111,13 @@ public class UserApi extends BaseApi {
|
||||
*/
|
||||
public Following getFollowing(String nextOpenId) throws WeixinException {
|
||||
String fllowing_uri = getRequestUri("following_uri");
|
||||
Token token = tokenApi.getToken();
|
||||
Token token = tokenHolder.getToken();
|
||||
Response response = request.get(String.format(fllowing_uri,
|
||||
token.getAccessToken(), nextOpenId == null ? "" : nextOpenId));
|
||||
|
||||
Following following = response.getAsObject(Following.class);
|
||||
Following following = response
|
||||
.getAsObject(new TypeReference<Following>() {
|
||||
});
|
||||
|
||||
if (following.getCount() > 0) {
|
||||
List<String> openIds = JSON.parseArray(following.getDataJson()
|
||||
@@ -165,10 +171,10 @@ public class UserApi extends BaseApi {
|
||||
* @see <a
|
||||
* href="http://mp.weixin.qq.com/wiki/index.php?title=%E8%AE%BE%E7%BD%AE%E7%94%A8%E6%88%B7%E5%A4%87%E6%B3%A8%E5%90%8D%E6%8E%A5%E5%8F%A3">设置用户备注名</a>
|
||||
*/
|
||||
public BaseResult remarkUserName(String openId, String remark)
|
||||
public JsonResult remarkUserName(String openId, String remark)
|
||||
throws WeixinException {
|
||||
String updateremark_uri = getRequestUri("updateremark_uri");
|
||||
Token token = tokenApi.getToken();
|
||||
Token token = tokenHolder.getToken();
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("openid", openId);
|
||||
obj.put("remark", remark);
|
||||
@@ -176,6 +182,6 @@ public class UserApi extends BaseApi {
|
||||
String.format(updateremark_uri, token.getAccessToken()),
|
||||
obj.toJSONString());
|
||||
|
||||
return response.getAsResult();
|
||||
return response.getAsJsonResult();
|
||||
}
|
||||
}
|
||||
+10
-2
@@ -65,9 +65,17 @@ p_shorturl_uri={mch_base_url}/tools/shorturl
|
||||
updateremark_uri={api_base_url}/user/info/updateremark?access_token=%s
|
||||
# \u6a21\u677f\u6d88\u606f
|
||||
template_send_uri={api_base_url}/message/template/send?access_token=%s
|
||||
# \u67e5\u8be2\u8ba2\u5355
|
||||
# \u8ba2\u5355\u67e5\u8be2
|
||||
orderquery_uri={api_base_url}/pay/orderquery?access_token=%s
|
||||
# \u53d1\u8d27\u901a\u77e5
|
||||
delivernotify_uri={api_base_url}/pay/delivernotify?access_token=%s
|
||||
# \u7ef4\u6743\u5904\u7406
|
||||
payfeedback_update_uri={api_base_url}/payfeedback/update?access_token=%s&openid=%s&feedbackid=%s
|
||||
payfeedback_update_uri={api_base_url}/payfeedback/update?access_token=%s&openid=%s&feedbackid=%s
|
||||
# \u8ba2\u5355\u67e5\u8be2
|
||||
orderquery_v3_uri={mch_base_url}/pay/orderquery
|
||||
# \u5173\u95ed\u8ba2\u5355
|
||||
closeorder_uri={mch_base_url}/pay/closeorder
|
||||
# \u5bf9\u8d26\u5355\u4e0b\u8f7d
|
||||
downloadbill_uri={mch_base_url}/pay/downloadbill
|
||||
# \u9000\u6b3e\u67e5\u8be2
|
||||
refundquery_uri={mch_base_url}/pay/refundquery
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
package com.foxinmy.weixin4j.mp.payment;
|
||||
|
||||
import com.foxinmy.weixin4j.http.XmlResult;
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
|
||||
/**
|
||||
* 调用V3.x接口返回的公用字段
|
||||
*
|
||||
* @className ApiResult
|
||||
* @author jy
|
||||
* @date 2014年10月21日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class ApiResult extends XmlResult {
|
||||
|
||||
private static final long serialVersionUID = -8430005768959715444L;
|
||||
|
||||
@XStreamAlias("appid")
|
||||
private String appId;// 微信分配的公众账号 ID商户号 非空
|
||||
@XStreamAlias("mch_id")
|
||||
private String mchId;// 微信支付分配的商户号 非空
|
||||
@XStreamAlias("nonce_str")
|
||||
private String nonceStr;// 随机字符串 非空
|
||||
private String sign;// 签名 非空
|
||||
@XStreamAlias("device_info")
|
||||
private String deviceInfo;// 微信支付分配的终端设备号 可能为空
|
||||
|
||||
public ApiResult() {
|
||||
|
||||
}
|
||||
|
||||
public ApiResult(String returnCode, String returnMsg) {
|
||||
super(returnCode, returnMsg);
|
||||
}
|
||||
|
||||
public String getAppId() {
|
||||
return appId;
|
||||
}
|
||||
|
||||
public void setAppId(String appId) {
|
||||
this.appId = appId;
|
||||
}
|
||||
|
||||
public String getMchId() {
|
||||
return mchId;
|
||||
}
|
||||
|
||||
public void setMchId(String mchId) {
|
||||
this.mchId = mchId;
|
||||
}
|
||||
|
||||
public String getNonceStr() {
|
||||
return nonceStr;
|
||||
}
|
||||
|
||||
public void setNonceStr(String nonceStr) {
|
||||
this.nonceStr = nonceStr;
|
||||
}
|
||||
|
||||
public String getSign() {
|
||||
return sign;
|
||||
}
|
||||
|
||||
public void setSign(String sign) {
|
||||
this.sign = sign;
|
||||
}
|
||||
|
||||
public String getDeviceInfo() {
|
||||
return deviceInfo;
|
||||
}
|
||||
|
||||
public void setDeviceInfo(String deviceInfo) {
|
||||
this.deviceInfo = deviceInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ApiResult [appId=" + appId + ", mchId=" + mchId + ", nonceStr="
|
||||
+ nonceStr + ", sign=" + sign + ", deviceInfo=" + deviceInfo
|
||||
+ "]";
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.foxinmy.weixin4j.mp.payment;
|
||||
|
||||
/**
|
||||
* 对账单类型
|
||||
* @className BillType
|
||||
* @author jy
|
||||
* @date 2014年10月31日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public enum BillType {
|
||||
ALL, SUCCESS, REFUND
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.foxinmy.weixin4j.mp.payment;
|
||||
|
||||
/**
|
||||
* 币种
|
||||
*
|
||||
* @className CurrencyType
|
||||
* @author jy
|
||||
* @date 2014年11月2日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public enum CurrencyType {
|
||||
CNY("人民币"), HKD("港元"), TWD("台币"), EUR("欧元"), USD("美元"), GBP("英镑"), JPY("日元");
|
||||
private String desc;
|
||||
|
||||
CurrencyType(String desc) {
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public String getDesc() {
|
||||
return desc;
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package com.foxinmy.weixin4j.mp.payment;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* ID查询
|
||||
*
|
||||
* @className IdQuery
|
||||
* @author jy
|
||||
* @date 2014年11月1日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class IdQuery implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -5273675987521807370L;
|
||||
private String id;
|
||||
private IdType type;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public IdType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(IdType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public IdQuery(String id, IdType idType) {
|
||||
this.id = id;
|
||||
this.type = idType;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.foxinmy.weixin4j.mp.payment;
|
||||
|
||||
/**
|
||||
* ID类型
|
||||
*
|
||||
* @className IdType
|
||||
* @author jy
|
||||
* @date 2014年11月1日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public enum IdType {
|
||||
REFUNDID("refund_id"), // 微信退款单号
|
||||
TRANSACTIONID("transaction_id"), // 微信订单号
|
||||
ORDERNO("out_trade_no"), // 商户订单号
|
||||
REFUNDNO("out_refund_no"); // 商户退款号
|
||||
private String name;
|
||||
|
||||
IdType(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
package com.foxinmy.weixin4j.mp.payment;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
|
||||
/**
|
||||
* JSAPI支付回调时的POST信息
|
||||
*
|
||||
* @className JsPayNotify
|
||||
* @author jy
|
||||
* @date 2014年8月19日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class JsPayNotify implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -4659030958445259803L;
|
||||
|
||||
@XStreamAlias("AppId")
|
||||
private String appid; // 公众号ID
|
||||
|
||||
@XStreamAlias("TimeStamp")
|
||||
private String timestamp; // 时间戳
|
||||
|
||||
@XStreamAlias("NonceStr")
|
||||
private String noncestr; // 随机字符串
|
||||
|
||||
@XStreamAlias("OpenId")
|
||||
private String openid; // 用户ID
|
||||
|
||||
@XStreamAlias("AppSignature")
|
||||
private String appsignature; // 签名结果
|
||||
|
||||
@XStreamAlias("IsSubscribe")
|
||||
private int issubscribe;
|
||||
|
||||
@XStreamAlias("SignMethod")
|
||||
private String signmethod; // 签名方式
|
||||
|
||||
public String getAppid() {
|
||||
return appid;
|
||||
}
|
||||
|
||||
public void setAppid(String appid) {
|
||||
this.appid = appid;
|
||||
}
|
||||
|
||||
public String getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(String timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public String getNoncestr() {
|
||||
return noncestr;
|
||||
}
|
||||
|
||||
public void setNoncestr(String noncestr) {
|
||||
this.noncestr = noncestr;
|
||||
}
|
||||
|
||||
public String getOpenid() {
|
||||
return openid;
|
||||
}
|
||||
|
||||
public void setOpenid(String openid) {
|
||||
this.openid = openid;
|
||||
}
|
||||
|
||||
public String getAppsignature() {
|
||||
return appsignature;
|
||||
}
|
||||
|
||||
public void setAppsignature(String appsignature) {
|
||||
this.appsignature = appsignature;
|
||||
}
|
||||
|
||||
public int getIssubscribe() {
|
||||
return issubscribe;
|
||||
}
|
||||
|
||||
public void setIssubscribe(int issubscribe) {
|
||||
this.issubscribe = issubscribe;
|
||||
}
|
||||
|
||||
public String getSignmethod() {
|
||||
return signmethod;
|
||||
}
|
||||
|
||||
public void setSignmethod(String signmethod) {
|
||||
this.signmethod = signmethod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("[JsPayNotify appid=").append(appid);
|
||||
sb.append(", timestamp=").append(timestamp);
|
||||
sb.append(", noncestr=").append(noncestr);
|
||||
sb.append(", openid=").append(openid);
|
||||
sb.append(", appsignature=").append(appsignature);
|
||||
sb.append(", issubscribe=").append(issubscribe);
|
||||
sb.append(", signmethod=").append(signmethod).append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
+314
@@ -0,0 +1,314 @@
|
||||
package com.foxinmy.weixin4j.mp.payment;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.foxinmy.weixin4j.exception.PayException;
|
||||
import com.foxinmy.weixin4j.http.XmlResult;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.mp.payment.v2.NativePayNotifyV2;
|
||||
import com.foxinmy.weixin4j.mp.payment.v2.NativePayResponseV2;
|
||||
import com.foxinmy.weixin4j.mp.payment.v2.PayFeedback;
|
||||
import com.foxinmy.weixin4j.mp.payment.v2.PayPackageV2;
|
||||
import com.foxinmy.weixin4j.mp.payment.v3.NativePayNotifyV3;
|
||||
import com.foxinmy.weixin4j.mp.payment.v3.NativePayResponseV3;
|
||||
import com.foxinmy.weixin4j.mp.payment.v3.PayPackageV3;
|
||||
import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||
import com.foxinmy.weixin4j.xml.XStream;
|
||||
|
||||
/**
|
||||
* 支付示例
|
||||
*
|
||||
* @className PayAction
|
||||
* @author jy
|
||||
* @date 2014年10月28日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class PayAction {
|
||||
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
|
||||
/**
|
||||
* JSAPI支付
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public JSONObject jsPay() {
|
||||
JSONObject obj = new JSONObject();
|
||||
PayPackage payPackage = null;
|
||||
// V3 支付
|
||||
// 此处的openid为微信用户的openid
|
||||
WeixinAccount weixinAccount = ConfigUtil.getWeixinAccount();
|
||||
weixinAccount.setOpenId("用户的openId");
|
||||
payPackage = new PayPackageV3(weixinAccount, "商品描述", "系统内部订单号", 1d,
|
||||
"IP地址", TradeType.JSAPI);
|
||||
// V2 支付
|
||||
payPackage = new PayPackageV2("商品描述", weixinAccount.getPartnerId(),
|
||||
"系统内部订单号", 1d, "回调地址", "IP地址");
|
||||
payPackage.setAttach("ID");
|
||||
String jspay = null;
|
||||
try {
|
||||
jspay = PayUtil.createPayJsRequestJson(payPackage, weixinAccount);
|
||||
jspay = PayUtil.createPayJsRequestJson(payPackage, weixinAccount);
|
||||
} catch (PayException e) {
|
||||
log.error("create jspay error,{}", weixinAccount, e);
|
||||
}
|
||||
if (StringUtils.isBlank(jspay)) {
|
||||
obj.put("code", "-2");
|
||||
obj.put("msg", "创建支付链接失败!");
|
||||
return obj;
|
||||
}
|
||||
obj.put("code", "0");
|
||||
obj.put("jspay", jspay);
|
||||
|
||||
/*
|
||||
* 编辑收货地址 SnsToken token = (SnsToken) getSession("AccessToken");
|
||||
* obj.put("editaddress", PayUtil.createAddressRequestJson(
|
||||
* wx.getAppId(), getFullLoction(), token.getAccess_token()));
|
||||
*/
|
||||
log.info("js pay....{}", obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* JSAPI(V2)支付成功时的回调通知=<br>
|
||||
* <xml><br/>
|
||||
* <OpenId><![CDATA[111222]]></OpenId><br/>
|
||||
* <AppId><![CDATA[wwwwb4f85f3a797777]]></AppId><br/>
|
||||
* <IsSubscribe>1</IsSubscribe><br/>
|
||||
* <TimeStamp>1369743511</TimeStamp><br/>
|
||||
* <NonceStr><![CDATA[jALldRTHAFd5Tgs5]]></NonceStr><br/>
|
||||
* <AppSignature><![CDATA[bafe07f060f22dcda0bfdb4b5ff756f973aecffa]]>
|
||||
* </AppSignature><br/>
|
||||
* <SignMethod><![CDATA[sha1]]></SignMethod><br/>
|
||||
* </xml><br/>
|
||||
* 参与签名的字段为: appid、appkey、timestamp、noncestr、openid、issubscribe
|
||||
*
|
||||
* @param 订单信息
|
||||
* @param inputStream
|
||||
* 用户信息
|
||||
*
|
||||
* @see com.foxinmy.weixin4j.mp.payment.JsPayNotify
|
||||
* @return success或其他
|
||||
*/
|
||||
public String jsNotifyV2(InputStream inputStream) {
|
||||
Map<String, String> objMap = new HashMap<String, String>();
|
||||
/*
|
||||
* 收集url中携带的参数 /pay/notify/back?attach=8&bank_billno=201410293351060&
|
||||
* bank_type=2032&discount=0&fee_type=1&input_charset=UTF-8&
|
||||
* notify_id=9fKbVf_qg6y-
|
||||
* wSjtSMV0PLXeEn2oGfTM1s9dWSvR2B9U6iFQRTzmjrMWKUxvh9mpBLvnh8aqFbC_OFk1pTvFnFUO00Lln4fh
|
||||
* & out_trade_no=D14102900031&partner=1221928801&product_fee=1&sign=
|
||||
* B9D6E772C271C9B86B8436FC9F5DFC1A&
|
||||
* sign_type=MD5&time_end=20141029183707
|
||||
* &total_fee=1&trade_mode=1&trade_state=0&
|
||||
* transaction_id=1221928801201410296039230054&transport_fee=0
|
||||
*/
|
||||
log.info("pay_notify_orderinfo,{}", objMap);
|
||||
JsPayNotify payNotify = XStream.get(inputStream, JsPayNotify.class);
|
||||
log.info("pay_notify_userinfo,{}", payNotify);
|
||||
WeixinAccount weixinAccount = ConfigUtil.getWeixinAccount();
|
||||
// 验证财付通签名
|
||||
String sign = objMap.get("sign");
|
||||
objMap.remove("sign");
|
||||
String _sign = PayUtil
|
||||
.paysignMd5(objMap, weixinAccount.getPartnerKey());
|
||||
log.info("财付通签名----->sign={},vaild_sign={}", sign, _sign);
|
||||
if (!sign.equals(_sign)) {
|
||||
return "fail";
|
||||
}
|
||||
objMap.clear();
|
||||
// 验证微信签名
|
||||
sign = payNotify.getAppsignature();
|
||||
payNotify.setAppsignature(null);
|
||||
payNotify.setSignmethod(null);
|
||||
String vaild_sign = PayUtil.paysignSha(payNotify,
|
||||
weixinAccount.getPaySignKey());
|
||||
log.info("微信签名----->sign={},vaild_sign={}", sign, vaild_sign);
|
||||
if (!sign.equals(vaild_sign)) {
|
||||
return "fail";
|
||||
}
|
||||
// 处理业务逻辑
|
||||
return "success";
|
||||
}
|
||||
|
||||
/**
|
||||
* JSAPI(V3)支付成功时的回调通知
|
||||
*
|
||||
*
|
||||
* @param inputStream
|
||||
* 订单细腻
|
||||
* @return <xml><br>
|
||||
* <return_code>SUCCESS/FAIL</return_code><br>
|
||||
* <return_msg>如非空,为错误 原因签名失败参数格式校验错误</return_msg><br>
|
||||
* </xml>
|
||||
*/
|
||||
public String jsNotifyV3(InputStream inputStream) {
|
||||
com.foxinmy.weixin4j.mp.payment.v3.Order order = XStream.get(
|
||||
inputStream, com.foxinmy.weixin4j.mp.payment.v3.Order.class);
|
||||
log.info("order_info:", order);
|
||||
String sign = order.getSign();
|
||||
order.setSign(null);
|
||||
WeixinAccount weixinAccount = ConfigUtil.getWeixinAccount();
|
||||
String valid_sign = PayUtil.paysignMd5(order,
|
||||
weixinAccount.getPaySignKey());
|
||||
log.info("微信签名----->sign={},vaild_sign={}", sign, valid_sign);
|
||||
if (!sign.equals(valid_sign)) {
|
||||
return XStream.to(new XmlResult(XmlResult.FAIL, "签名错误"));
|
||||
}
|
||||
return XStream.to(new XmlResult());
|
||||
}
|
||||
|
||||
/**
|
||||
* 告警通知 需要成功返回 success <br/>
|
||||
* <xml><br/>
|
||||
* <AppId><![CDATA[wxf8b4f85f3a794e77]]></AppId><br/>
|
||||
* <ErrorType>1001</ErrorType><br/>
|
||||
* <Description><![CDATA[错误描述]]></Description><br/>
|
||||
* <AlarmContent><![CDATA[错误详情]]></AlarmContent><br/>
|
||||
* <TimeStamp>1393860740</TimeStamp><br/>
|
||||
* <AppSignature><![CDATA[签名方式跟JsPayRequest中的paySign一样]]></
|
||||
* AppSignature><br/>
|
||||
* <SignMethod><![CDATA[sha1]]></SignMethod><br/>
|
||||
* </xml><br/>
|
||||
* 参与签名字段:alarmcontent、appid、appkey、description、errortype、timestamp
|
||||
*
|
||||
* @param inputStream
|
||||
* xml数据
|
||||
* @see com.foxinmy.weixin4j.mp.payment.PayWarn
|
||||
* @return
|
||||
*/
|
||||
public String warning(InputStream inputStream) {
|
||||
PayWarn payWarn = XStream.get(inputStream, PayWarn.class);
|
||||
log.info("pay_warning,{}", payWarn);
|
||||
WeixinAccount weixinAccount = ConfigUtil.getWeixinAccount();
|
||||
String sign = payWarn.getAppsignature();
|
||||
payWarn.setSignmethod(null);
|
||||
payWarn.setAppsignature(null);
|
||||
// 验证微信签名
|
||||
String vaild_sign = PayUtil.paysignSha(payWarn,
|
||||
weixinAccount.getPaySignKey());
|
||||
log.info("微信签名----->sign={},vaild_sign={}", sign, vaild_sign);
|
||||
return "success";
|
||||
}
|
||||
|
||||
/**
|
||||
* V2.x版本Native支付时POST数据<br>
|
||||
* <xml><br/>
|
||||
* <OpenId><![CDATA[111222]]></OpenId><br/>
|
||||
* <AppId><![CDATA[wwwwb4f85f3a797777]]></AppId><br/>
|
||||
* <IsSubscribe>1</IsSubscribe><br/>
|
||||
* <ProductId>[CDATA[000000]]</ProductId><br/>
|
||||
* <TimeStamp>1369743511</TimeStamp><br/>
|
||||
* <NonceStr><![CDATA[jALldRTHAFd5Tgs5]]></NonceStr><br/>
|
||||
* <AppSignature><![CDATA[bafe07f060f22dcda0bfdb4b5ff756f973aecffa]]>
|
||||
* </AppSignature><br/>
|
||||
* <SignMethod><![CDATA[sha1]]></SignMethod><br/>
|
||||
* </xml><br/>
|
||||
* 参与签名的字段为: appid、appkey、timestamp、noncestr、openid、issubscribe、productId
|
||||
*
|
||||
* @param inputStream
|
||||
*
|
||||
* @return 必须返回一个带有Package信息的xml字符串
|
||||
*/
|
||||
public String nativeNotifyV2(InputStream inputStream) {
|
||||
// V2.x版本
|
||||
NativePayNotifyV2 payNotify = XStream.get(inputStream,
|
||||
NativePayNotifyV2.class);
|
||||
log.info("native_pay_notify,{}", payNotify);
|
||||
WeixinAccount weixinAccount = ConfigUtil.getWeixinAccount();
|
||||
String sign = payNotify.getAppsignature();
|
||||
payNotify.setAppsignature(null);
|
||||
payNotify.setSignmethod(null);
|
||||
// 验证微信签名
|
||||
String vaild_sign = PayUtil.paysignSha(payNotify,
|
||||
weixinAccount.getPaySignKey());
|
||||
log.info("微信签名----->sign={},vaild_sign={}", sign, vaild_sign);
|
||||
if (!sign.equals(vaild_sign)) {
|
||||
return "fail";
|
||||
}
|
||||
// 构造订单信息
|
||||
PayPackageV2 payPackage = new PayPackageV2("商品描述",
|
||||
weixinAccount.getPartnerId(), "系统内部订单号", 1d, "回调地址", "IP地址");
|
||||
NativePayResponseV2 payResponse = new NativePayResponseV2(
|
||||
weixinAccount, payPackage);
|
||||
return XStream.to(payResponse);
|
||||
}
|
||||
|
||||
/**
|
||||
* V3.x版本native回调<br>
|
||||
* <xml><br/>
|
||||
* <openid><![CDATA[111222]]></openid><br/>
|
||||
* <appid><![CDATA[wwwwb4f85f3a797777]]></appid><br/>
|
||||
* <mch_id><![CDATA[1100022]]></mch_id><br/>
|
||||
* <is_subscribe>1</is_subscribe><br/>
|
||||
* <product_id>[CDATA[000000]]</product_id><br/>
|
||||
* <nonce_str><![CDATA[jALldRTHAFd5Tgs5]]></nonce_str><br/>
|
||||
* <sign><![CDATA[bafe07f060f22dcda0bfdb4b5ff756f973aecffa]]></sign&
|
||||
* gt<br/>
|
||||
* </xml><br/>
|
||||
*
|
||||
* @return
|
||||
* @throws PayException
|
||||
*/
|
||||
public String nativeNotifyV3(InputStream inputStream) throws PayException {
|
||||
NativePayNotifyV3 payNotify = XStream.get(inputStream,
|
||||
NativePayNotifyV3.class);
|
||||
String sign = payNotify.getSign();
|
||||
payNotify.setSign(null);
|
||||
WeixinAccount weixinAccount = ConfigUtil.getWeixinAccount();
|
||||
String valid_sign = PayUtil.paysignMd5(payNotify,
|
||||
weixinAccount.getPaySignKey());
|
||||
log.info("微信签名----->sign={},vaild_sign={}", sign, valid_sign);
|
||||
// 生成Package
|
||||
PayPackageV3 payPackage = new PayPackageV3(weixinAccount, "商品描述",
|
||||
"系统内部订单号", 1d, "IP地址", TradeType.NATIVE);
|
||||
payPackage.setProduct_id(payNotify.getProductId());
|
||||
if (!sign.equals(valid_sign)) {
|
||||
NativePayResponseV3 payReponse = new NativePayResponseV3(
|
||||
payPackage, "签名失败", null);
|
||||
payReponse.setSign(PayUtil.paysignMd5(payReponse,
|
||||
weixinAccount.getPaySignKey()));
|
||||
return XStream.to(payReponse);
|
||||
|
||||
}
|
||||
NativePayResponseV3 payReponse = new NativePayResponseV3(payPackage,
|
||||
null, null);
|
||||
payReponse.setSign(PayUtil.paysignMd5(payReponse,
|
||||
weixinAccount.getPaySignKey()));
|
||||
return XStream.to(payReponse);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户维权
|
||||
*
|
||||
* @param inputStream
|
||||
* @see com.foxinmy.weixin4j.mp.payment.v2.PayFeedback
|
||||
* @return
|
||||
*/
|
||||
public String feedback(InputStream inputStream) {
|
||||
PayFeedback feedback = XStream.get(inputStream, PayFeedback.class);
|
||||
log.info("pay_feedback_info:{}", feedback);
|
||||
WeixinAccount weixinAccount = ConfigUtil.getWeixinAccount();
|
||||
// 验证微信签名
|
||||
Map<String, String> obj = new HashMap<String, String>();
|
||||
obj.put("openid", feedback.getOpenId());
|
||||
obj.put("appid", feedback.getAppId());
|
||||
obj.put("timestamp", feedback.getTimeStamp());
|
||||
String sign = PayUtil.paysignSha(obj, weixinAccount.getPaySignKey());
|
||||
log.info("微信签名----->sign={},vaild_sign={}", sign,
|
||||
feedback.getAppSignature());
|
||||
return "success";
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
}
|
||||
}
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
package com.foxinmy.weixin4j.mp.payment;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.text.DateFormat;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
public class PayPackage implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 3450161267802545790L;
|
||||
protected static final NumberFormat FEE_FORMAT = new DecimalFormat("#");
|
||||
protected static final DateFormat DATE_FORMAT = new SimpleDateFormat(
|
||||
"yyyyMMddHHmmss");
|
||||
private String body; // 商品描述 必须
|
||||
private String attach; // 附加数据,原样返回 非必须
|
||||
private String out_trade_no; // 商户系统内部的订单号 ,32 个字符内 、可包含字母 ,确保 在商户系统唯一 必须
|
||||
private String total_fee; // 订单总金额,单位为分,不 能带小数点 必须
|
||||
private String spbill_create_ip; // 订单生成的机器 IP 必须
|
||||
private String time_start; // 订单生成时间,格式 为 yyyyMMddHHmmss,如 2009 年
|
||||
// 12月25日9点10分10秒表 示为 20091225091010。时区 为 GMT+8
|
||||
// beijing。该时间取 自商户服务器 非必须
|
||||
private String time_expire; // 订单失效时间,格式 为 yyyyMMddHHmmss,如 2009 年
|
||||
// 12月27日9点10分10秒表 示为 20091227091010。时区 为 GMT+8
|
||||
// beijing。该时间取 自商户服务商品标记 非必须
|
||||
private String goods_tag; // 商品标记,该字段不能随便 填,不使用请填空 非必须
|
||||
private String notify_url; // 通知地址接收微信支付成功通知 必须
|
||||
public String getBody() {
|
||||
return body;
|
||||
}
|
||||
public void setBody(String body) {
|
||||
this.body = body;
|
||||
}
|
||||
public String getAttach() {
|
||||
return attach;
|
||||
}
|
||||
public void setAttach(String attach) {
|
||||
this.attach = attach;
|
||||
}
|
||||
public String getOut_trade_no() {
|
||||
return out_trade_no;
|
||||
}
|
||||
public void setOut_trade_no(String out_trade_no) {
|
||||
this.out_trade_no = out_trade_no;
|
||||
}
|
||||
public String getTotal_fee() {
|
||||
return total_fee;
|
||||
}
|
||||
public void setTotal_fee(double total_fee) {
|
||||
this.total_fee = FEE_FORMAT.format(total_fee);
|
||||
}
|
||||
public String getSpbill_create_ip() {
|
||||
return spbill_create_ip;
|
||||
}
|
||||
public void setSpbill_create_ip(String spbill_create_ip) {
|
||||
this.spbill_create_ip = spbill_create_ip;
|
||||
}
|
||||
public String getTime_start() {
|
||||
return time_start;
|
||||
}
|
||||
public void setTime_start(String time_start) {
|
||||
this.time_start = time_start;
|
||||
}
|
||||
|
||||
public void setTime_expire(String time_expire) {
|
||||
this.time_expire = time_expire;
|
||||
}
|
||||
|
||||
public void setTime_start(Date time_start) {
|
||||
this.time_start = time_start != null
|
||||
? DATE_FORMAT.format(time_start)
|
||||
: null;;
|
||||
}
|
||||
public String getTime_expire() {
|
||||
return time_expire;
|
||||
}
|
||||
public void setTime_expire(Date time_expire) {
|
||||
this.time_expire = time_expire != null ? DATE_FORMAT
|
||||
.format(time_expire) : null;;
|
||||
}
|
||||
public String getGoods_tag() {
|
||||
return goods_tag;
|
||||
}
|
||||
public void setGoods_tag(String goods_tag) {
|
||||
this.goods_tag = goods_tag;
|
||||
}
|
||||
public String getNotify_url() {
|
||||
return notify_url;
|
||||
}
|
||||
public void setNotify_url(String notify_url) {
|
||||
this.notify_url = notify_url;
|
||||
}
|
||||
public PayPackage() {
|
||||
}
|
||||
public PayPackage(String body, String attach, String out_trade_no,
|
||||
double total_fee, String spbill_create_ip, Date time_start,
|
||||
Date time_expire, String goods_tag, String notify_url) {
|
||||
this.body = body;
|
||||
this.attach = attach;
|
||||
this.out_trade_no = out_trade_no;
|
||||
this.total_fee = FEE_FORMAT.format(total_fee * 100);
|
||||
this.spbill_create_ip = spbill_create_ip;
|
||||
this.time_start = time_start != null
|
||||
? DATE_FORMAT.format(time_start)
|
||||
: null;
|
||||
this.time_expire = time_expire != null ? DATE_FORMAT
|
||||
.format(time_expire) : null;
|
||||
this.goods_tag = goods_tag;
|
||||
this.notify_url = notify_url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PayPackage [body=" + body + ", attach=" + attach
|
||||
+ ", out_trade_no=" + out_trade_no + ", total_fee=" + total_fee
|
||||
+ ", spbill_create_ip=" + spbill_create_ip + ", time_start="
|
||||
+ time_start + ", time_expire=" + time_expire + ", goods_tag="
|
||||
+ goods_tag + ", notify_url=" + notify_url + "]";
|
||||
}
|
||||
}
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
package com.foxinmy.weixin4j.mp.payment;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.util.RandomUtil;
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
|
||||
public class PayRequest implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -453746488398523883L;
|
||||
|
||||
// 公众号ID
|
||||
@XStreamAlias("AppId")
|
||||
private String appId;
|
||||
// 当前时间戳
|
||||
@XStreamAlias("TimeStamp")
|
||||
private String timeStamp;
|
||||
// 随机字符串
|
||||
@XStreamAlias("NonceStr")
|
||||
private String nonceStr;
|
||||
// 订单详情扩展 订单信息组成该字符串
|
||||
@XStreamAlias("Package")
|
||||
private String packageInfo;
|
||||
// 签名方式 数取值"SHA1"
|
||||
@XStreamAlias("SignMethod")
|
||||
private String signType;
|
||||
// 商户将接口列表中的参数按照指定方式进行 签名,签名方式使用 signType中标示的签名方式,
|
||||
@XStreamAlias("Appsignature")
|
||||
private String paySign;
|
||||
|
||||
public PayRequest() {
|
||||
this.timeStamp = System.currentTimeMillis() / 1000 + "";
|
||||
this.nonceStr = RandomUtil.generateString(16);
|
||||
}
|
||||
|
||||
public PayRequest(String appId, String packageInfo, SignType signType,
|
||||
String paySign) {
|
||||
this.appId = appId;
|
||||
this.timeStamp = System.currentTimeMillis() / 1000 + "";
|
||||
this.nonceStr = RandomUtil.generateString(16);
|
||||
this.packageInfo = packageInfo;
|
||||
this.signType = signType.name();
|
||||
this.paySign = paySign;
|
||||
}
|
||||
|
||||
public String getAppId() {
|
||||
return appId;
|
||||
}
|
||||
|
||||
public void setAppId(String appId) {
|
||||
this.appId = appId;
|
||||
}
|
||||
|
||||
public String getTimeStamp() {
|
||||
return timeStamp;
|
||||
}
|
||||
|
||||
public void setTimeStamp(String timeStamp) {
|
||||
this.timeStamp = timeStamp;
|
||||
}
|
||||
|
||||
public String getNonceStr() {
|
||||
return nonceStr;
|
||||
}
|
||||
|
||||
public void setNonceStr(String nonceStr) {
|
||||
this.nonceStr = nonceStr;
|
||||
}
|
||||
|
||||
@JSONField(name = "package")
|
||||
public String getPackageInfo() {
|
||||
return packageInfo;
|
||||
}
|
||||
|
||||
public void setPackageInfo(String packageInfo) {
|
||||
this.packageInfo = packageInfo;
|
||||
}
|
||||
|
||||
public String getSignType() {
|
||||
return signType;
|
||||
}
|
||||
|
||||
public void setSignType(SignType signType) {
|
||||
this.signType = signType.name();
|
||||
}
|
||||
|
||||
public String getPaySign() {
|
||||
return paySign;
|
||||
}
|
||||
|
||||
public void setPaySign(String paySign) {
|
||||
this.paySign = paySign;
|
||||
}
|
||||
}
|
||||
+369
@@ -0,0 +1,369 @@
|
||||
package com.foxinmy.weixin4j.mp.payment;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.StatusLine;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.foxinmy.weixin4j.exception.PayException;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.mp.payment.v2.JsPayRequestV2;
|
||||
import com.foxinmy.weixin4j.mp.payment.v2.NativePayResponseV2;
|
||||
import com.foxinmy.weixin4j.mp.payment.v2.PayPackageV2;
|
||||
import com.foxinmy.weixin4j.mp.payment.v3.PayRequestV3;
|
||||
import com.foxinmy.weixin4j.mp.payment.v3.PayPackageV3;
|
||||
import com.foxinmy.weixin4j.mp.payment.v3.PrePay;
|
||||
import com.foxinmy.weixin4j.util.MapUtil;
|
||||
import com.foxinmy.weixin4j.util.RandomUtil;
|
||||
import com.foxinmy.weixin4j.xml.XStream;
|
||||
|
||||
/**
|
||||
* 支付工具类
|
||||
*
|
||||
* @className PayUtil
|
||||
* @author jy
|
||||
* @date 2014年10月28日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class PayUtil {
|
||||
|
||||
private static final String UNIFIEDORDER = "https://api.mch.weixin.qq.com/pay/unifiedorder";
|
||||
private static final String NATIVEURLV2 = "weixin://wxpay/bizpayurl?sign=%s&appid=%s&productid=%s×tamp=%s&noncestr=%s";
|
||||
private static final String NATIVEURLV3 = "weixin://wxpay/bizpayurl?sign=%s&appid=%s&mch_id=%s&product_id=%s&time_stamp=%s&nonce_str=%s";
|
||||
|
||||
/**
|
||||
* 生成JSAPI字符串
|
||||
*
|
||||
* @param payPackage
|
||||
* 订单信息
|
||||
* @param weixinConfig
|
||||
* appid等信息
|
||||
* @return
|
||||
* @throws PayException
|
||||
*/
|
||||
public static String createPayJsRequestJson(PayPackage payPackage,
|
||||
WeixinAccount weixinAccount) throws PayException {
|
||||
if (payPackage instanceof PayPackageV2) {
|
||||
return createPayJsRequestJsonV2((PayPackageV2) payPackage,
|
||||
weixinAccount);
|
||||
} else if (payPackage instanceof PayPackageV3) {
|
||||
return createPayJsRequestJsonV3((PayPackageV3) payPackage,
|
||||
weixinAccount);
|
||||
}
|
||||
throw new PayException("-1", "unknown pay");
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成V2.x版本JSAPI支付字符串
|
||||
*
|
||||
* @param payPackage
|
||||
* 订单信息
|
||||
* @param weixinConfig
|
||||
* appid等信息
|
||||
* @return
|
||||
*/
|
||||
public static String createPayJsRequestJsonV2(PayPackageV2 payPackage,
|
||||
WeixinAccount weixinAccount) {
|
||||
if (StringUtils.isBlank(payPackage.getPartner())) {
|
||||
payPackage.setPartner(weixinAccount.getPartnerId());
|
||||
}
|
||||
JsPayRequestV2 jsPayRequest = new JsPayRequestV2(weixinAccount,
|
||||
payPackage);
|
||||
jsPayRequest.setPaySign(paysignSha(jsPayRequest,
|
||||
weixinAccount.getPaySignKey()));
|
||||
jsPayRequest.setSignType(SignType.SHA1);
|
||||
return JSON.toJSONString(jsPayRequest);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成V2.x版本JSAPI支付字符串
|
||||
*
|
||||
* @param body
|
||||
* 支付详情
|
||||
* @param orderNo
|
||||
* 订单号
|
||||
* @param orderFee
|
||||
* 订单总额
|
||||
* @param ip
|
||||
* @param weixinConfig
|
||||
* appid等信息
|
||||
* @return
|
||||
*/
|
||||
public static String createPayJsRequestJsonV2(String body, String orderNo,
|
||||
double orderFee, String ip, WeixinAccount weixinAccount) {
|
||||
PayPackageV2 payPackage = new PayPackageV2(body, orderNo, orderFee, ip);
|
||||
payPackage.setPartner(weixinAccount.getPartnerId());
|
||||
return createPayJsRequestJsonV2(payPackage, weixinAccount);
|
||||
}
|
||||
|
||||
/**
|
||||
* V2.x版本的PayRequest签名
|
||||
*
|
||||
* @param jsPayRequestV2
|
||||
* 支付请求
|
||||
* @param paySignKey
|
||||
* 支付API的密钥
|
||||
* @return
|
||||
*/
|
||||
public static String paysignSha(Object obj, String paySignKey) {
|
||||
JSONObject extra = null;
|
||||
if (StringUtils.isNotBlank(paySignKey)) {
|
||||
extra = new JSONObject();
|
||||
extra.put("appKey", paySignKey);
|
||||
}
|
||||
return DigestUtils.sha1Hex(MapUtil
|
||||
.toJoinString(obj, false, true, extra));
|
||||
}
|
||||
|
||||
/**
|
||||
* V3.x版本的PayRequest签名
|
||||
*
|
||||
* @param jsPayRequestV3
|
||||
* 支付请求
|
||||
* @param paySignKey
|
||||
* 支付API的密钥
|
||||
* @return
|
||||
*/
|
||||
public static String paysignMd5(Object obj, String paySignKey) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
// a--->string1
|
||||
sb.append(MapUtil.toJoinString(obj, false, false, null));
|
||||
// b--->
|
||||
// 在 string1 最后拼接上 key=paternerKey 得到 stringSignTemp 字符串,并 对
|
||||
// stringSignTemp 进行 md5 运算
|
||||
// 再将得到的 字符串所有字符转换为大写 ,得到 sign 值 signValue。
|
||||
sb.append("&key=").append(paySignKey);
|
||||
return DigestUtils.md5Hex(sb.toString()).toUpperCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成V3.x版本JSAPI支付字符串
|
||||
*
|
||||
* @param body
|
||||
* 订单描述
|
||||
* @param orderNo
|
||||
* 订单号
|
||||
* @param orderFee
|
||||
* 订单总额
|
||||
* @param ip
|
||||
* @param notifyUrl
|
||||
* 支付通知地址
|
||||
* @param weixinConfig
|
||||
* appid等信息
|
||||
* @return
|
||||
* @throws PayException
|
||||
*/
|
||||
public static String createPayJsRequestJsonV3(String body, String orderNo,
|
||||
double orderFee, String ip, String notifyUrl,
|
||||
WeixinAccount weixinAccount) throws PayException {
|
||||
PayPackageV3 payPackage = new PayPackageV3(weixinAccount, body,
|
||||
orderNo, orderFee, ip, TradeType.JSAPI);
|
||||
payPackage.setNotify_url(notifyUrl);
|
||||
return createPayJsRequestJsonV3(payPackage, weixinAccount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成V3.x版本JSAPI支付字符串
|
||||
*
|
||||
* @param payPackage
|
||||
* 订单信息
|
||||
* @param weixinConfig
|
||||
* appid等信息
|
||||
* @return
|
||||
* @throws PayException
|
||||
*/
|
||||
public static String createPayJsRequestJsonV3(PayPackageV3 payPackage,
|
||||
WeixinAccount weixinAccount) throws PayException {
|
||||
String paySignKey = weixinAccount.getPaySignKey();
|
||||
payPackage.setSign(paysignMd5(payPackage, paySignKey));
|
||||
PrePay prePay = createPrePay(payPackage);
|
||||
PayRequestV3 jsPayRequest = new PayRequestV3(prePay);
|
||||
jsPayRequest.setPaySign(paysignMd5(jsPayRequest, paySignKey));
|
||||
jsPayRequest.setSignType(SignType.MD5);
|
||||
return JSON.toJSONString(jsPayRequest);
|
||||
}
|
||||
|
||||
public static PrePay createPrePay(PayPackageV3 payPackage) {
|
||||
String payJsRequestXml = XStream.to(payPackage).replaceAll("__", "_");
|
||||
HttpClient client = null;
|
||||
try {
|
||||
client = new DefaultHttpClient();
|
||||
HttpPost post = new HttpPost(UNIFIEDORDER);
|
||||
post.setEntity(new StringEntity(payJsRequestXml,
|
||||
StandardCharsets.UTF_8));
|
||||
HttpResponse response = client.execute(post);
|
||||
StatusLine statusLine = response.getStatusLine();
|
||||
if (statusLine.getStatusCode() != HttpStatus.SC_OK) {
|
||||
return new PrePay("-1", "网络异常[" + statusLine.getStatusCode()
|
||||
+ "," + statusLine.getReasonPhrase() + "]!");
|
||||
}
|
||||
String returnXml = EntityUtils.toString(response.getEntity(),
|
||||
StandardCharsets.UTF_8);
|
||||
return XStream.get(returnXml, PrePay.class);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
client.getConnectionManager().shutdown();
|
||||
}
|
||||
return new PrePay("-1", "request fail");
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 生成编辑地址请求
|
||||
* </p>
|
||||
*
|
||||
* err_msg edit_address:ok获取编辑收货地址成功<br/>
|
||||
* edit_address:fail获取编辑收货地址失败<br/>
|
||||
* userName 收货人姓名<br/>
|
||||
* telNumber 收货人电话<br/>
|
||||
* addressPostalCode 邮编<br/>
|
||||
* proviceFirstStageName 国标收货地址第一级地址<br/>
|
||||
* addressCitySecondStageName 国标收货地址第二级地址<br/>
|
||||
* addressCountiesThirdStageName 国标收货地址第三级地址<br/>
|
||||
* addressDetailInfo 详细收货地址信息<br/>
|
||||
* nationalCode 收货地址国家码<br/>
|
||||
*
|
||||
* @param appId
|
||||
* 公众号的ID
|
||||
* @param url
|
||||
* 当前访问页的URL
|
||||
* @param accessToken
|
||||
* snsapi_base授权时产生的token
|
||||
* @return
|
||||
*/
|
||||
public static String createAddressRequestJson(String appId, String url,
|
||||
String accessToken) {
|
||||
Map<String, String> param = new HashMap<String, String>();
|
||||
param.put("appId", appId);
|
||||
param.put("url", url);
|
||||
param.put("timeStamp", System.currentTimeMillis() / 1000 + "");
|
||||
param.put("nonceStr", RandomUtil.generateString(16));
|
||||
param.put("accessToken", accessToken);
|
||||
String sign = paysignSha(param, null);
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("appId", appId);
|
||||
obj.put("scope", "jsapi_address");
|
||||
obj.put("signType", "sha1");
|
||||
obj.put("addrSign", sign);
|
||||
obj.put("timeStamp", param.get("timeStamp"));
|
||||
obj.put("nonceStr", param.get("nonceStr"));
|
||||
|
||||
return obj.toJSONString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建V2.x NativePay支付链接
|
||||
*
|
||||
* @param weixinConfig
|
||||
* 支付配置信息
|
||||
* @param productId
|
||||
* 与订单ID等价
|
||||
* @return
|
||||
*/
|
||||
public String createNativePayRequestURLV2(WeixinAccount weixinAccount,
|
||||
String productId) {
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
String timestamp = System.currentTimeMillis() / 1000 + "";
|
||||
String noncestr = RandomUtil.generateString(16);
|
||||
map.put("appid", weixinAccount.getAppId());
|
||||
map.put("timestamp", timestamp);
|
||||
map.put("noncestr", noncestr);
|
||||
map.put("productid", productId);
|
||||
String sign = paysignSha(map, weixinAccount.getPaySignKey());
|
||||
return String.format(NATIVEURLV2, sign, weixinAccount.getAppId(),
|
||||
productId, timestamp, noncestr);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建V3.x NativePay支付链接
|
||||
*
|
||||
* @param weixinConfig
|
||||
* 支付配置信息
|
||||
* @param productId
|
||||
* 与订单ID等价
|
||||
* @return
|
||||
*/
|
||||
public String createNativePayRequestURLV3(WeixinAccount weixinAccount,
|
||||
String productId) {
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
String timestamp = System.currentTimeMillis() / 1000 + "";
|
||||
String noncestr = RandomUtil.generateString(16);
|
||||
map.put("appid", weixinAccount.getAppId());
|
||||
map.put("mch_id", weixinAccount.getMchId());
|
||||
map.put("time_stamp", timestamp);
|
||||
map.put("nonce_str", noncestr);
|
||||
map.put("product_id", productId);
|
||||
String sign = paysignMd5(map, weixinAccount.getPaySignKey());
|
||||
return String.format(NATIVEURLV3, sign, weixinAccount.getAppId(),
|
||||
weixinAccount.getMchId(), productId, timestamp, noncestr);
|
||||
}
|
||||
|
||||
public static String createNativePayRequestV2(WeixinAccount weixinAccount,
|
||||
PayPackageV2 payPackage) {
|
||||
NativePayResponseV2 payRequest = new NativePayResponseV2(weixinAccount,
|
||||
payPackage);
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
String timestamp = System.currentTimeMillis() / 1000 + "";
|
||||
String noncestr = RandomUtil.generateString(16);
|
||||
map.put("appid", weixinAccount.getAppId());
|
||||
map.put("timestamp", timestamp);
|
||||
map.put("noncestr", noncestr);
|
||||
map.put("package", payRequest.getPackageInfo());
|
||||
map.put("retcode", payRequest.getRetCode());
|
||||
map.put("reterrmsg", payRequest.getRetMsg());
|
||||
payRequest.setPaySign(paysignSha(map, weixinAccount.getPaySignKey()));
|
||||
return XStream.to(payRequest);
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试js支付请求
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private static void createTestPayJsRequestJson() {
|
||||
// V2.xAPI支付
|
||||
PayPackageV2 payPackage = new PayPackageV2("pay_test", "1220403701",
|
||||
"D123456", 0.01, "http://182.92.74.85:8082/pay/notify",
|
||||
"192.168.1.1");
|
||||
WeixinAccount weixinAccount = new WeixinAccount("wx0d1d598c0c03c999",
|
||||
"2270e6c67cf4ff48fe2c6d7cc5a42157",
|
||||
"GATFzDwbQdbbci3QEQxX2rUBvwTrsMiZ", "1221966601",
|
||||
"6b506ef5fefba3142653a9affd2648d8");
|
||||
System.out.println(PayUtil.createPayJsRequestJsonV2(payPackage,
|
||||
weixinAccount));
|
||||
// V3.xJSAPI支付
|
||||
try {
|
||||
weixinAccount = new WeixinAccount("wx0d1d598c0c03c999",
|
||||
"2270e6c67cf4ff48fe2c6d7cc5a42157",
|
||||
"6b506ef5fefba3142653a9affd2648d8", "10020674",
|
||||
"oyFLst1bqtuTcxK-ojF8hOGtLQao");
|
||||
System.out.println(PayUtil.createPayJsRequestJsonV3("测试", "T001",
|
||||
1d, "192.0.0.1", "http://182.92.74.85:8082/pay/notify",
|
||||
weixinAccount));
|
||||
} catch (PayException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// V2.xNative支付
|
||||
System.out.println(PayUtil.createNativePayRequestV2(weixinAccount,
|
||||
payPackage));
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
createTestPayJsRequestJson();
|
||||
}
|
||||
}
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
package com.foxinmy.weixin4j.mp.payment;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
|
||||
@XStreamAlias("xml")
|
||||
public class PayWarn implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 2334592957844332640L;
|
||||
|
||||
@XStreamAlias("AppId")
|
||||
private String appid;
|
||||
|
||||
@XStreamAlias("ErrorType")
|
||||
private String errortype;
|
||||
|
||||
@XStreamAlias("Description")
|
||||
private String description;
|
||||
|
||||
@XStreamAlias("AlarmContent")
|
||||
private String alarmcontent;
|
||||
|
||||
@XStreamAlias("TimeStamp")
|
||||
private String timestamp;
|
||||
|
||||
@XStreamAlias("AppSignature")
|
||||
private String appsignature;
|
||||
|
||||
@XStreamAlias("SignMethod")
|
||||
private String signmethod;
|
||||
|
||||
public String getAppid() {
|
||||
return appid;
|
||||
}
|
||||
|
||||
public void setAppid(String appid) {
|
||||
this.appid = appid;
|
||||
}
|
||||
|
||||
public String getErrortype() {
|
||||
return errortype;
|
||||
}
|
||||
|
||||
public void setErrortype(String errortype) {
|
||||
this.errortype = errortype;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getAlarmcontent() {
|
||||
return alarmcontent;
|
||||
}
|
||||
|
||||
public void setAlarmcontent(String alarmcontent) {
|
||||
this.alarmcontent = alarmcontent;
|
||||
}
|
||||
|
||||
public String getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(String timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public String getAppsignature() {
|
||||
return appsignature;
|
||||
}
|
||||
|
||||
public void setAppsignature(String appsignature) {
|
||||
this.appsignature = appsignature;
|
||||
}
|
||||
|
||||
public String getSignmethod() {
|
||||
return signmethod;
|
||||
}
|
||||
|
||||
public void setSignmethod(String signmethod) {
|
||||
this.signmethod = signmethod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PayWarn [appid=" + appid + ", errortype=" + errortype
|
||||
+ ", description=" + description + ", alarmcontent="
|
||||
+ alarmcontent + ", timestamp=" + timestamp + ", appsignature="
|
||||
+ appsignature + ", signmethod=" + signmethod + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
支付模块【JSP AY】【NATIVE PAY】【APP PAY】
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
package com.foxinmy.weixin4j.mp.payment;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.foxinmy.weixin4j.mp.payment.v3.Refund;
|
||||
import com.foxinmy.weixin4j.mp.payment.v3.RefundDetail;
|
||||
import com.foxinmy.weixin4j.xml.XStream;
|
||||
import com.thoughtworks.xstream.converters.Converter;
|
||||
import com.thoughtworks.xstream.converters.MarshallingContext;
|
||||
import com.thoughtworks.xstream.converters.UnmarshallingContext;
|
||||
import com.thoughtworks.xstream.converters.reflection.ReflectionConverter;
|
||||
import com.thoughtworks.xstream.converters.reflection.ReflectionProvider;
|
||||
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
|
||||
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
|
||||
import com.thoughtworks.xstream.mapper.Mapper;
|
||||
|
||||
/**
|
||||
* 退款查询接口调用结果转换类
|
||||
* @className RefundConverter
|
||||
* @author jy
|
||||
* @date 2014年11月2日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class RefundConverter {
|
||||
private final static XStream xStream = XStream.get();
|
||||
private final ReflectionConverter reflectionConverter;
|
||||
|
||||
public RefundConverter() {
|
||||
xStream.processAnnotations(Refund.class);
|
||||
xStream.registerConverter(new RefundConverter.$());
|
||||
reflectionConverter = new ReflectionConverter(xStream.getMapper(),
|
||||
xStream.getReflectionProvider());
|
||||
}
|
||||
|
||||
public String toXML(Refund refund) {
|
||||
return xStream.toXML(refund);
|
||||
}
|
||||
|
||||
public Refund fromXML(String xml) {
|
||||
return xStream.fromXML(xml, Refund.class);
|
||||
}
|
||||
|
||||
private class $ implements Converter {
|
||||
@Override
|
||||
public boolean canConvert(@SuppressWarnings("rawtypes") Class clazz) {
|
||||
return clazz.equals(Refund.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void marshal(Object source, HierarchicalStreamWriter writer,
|
||||
MarshallingContext context) {
|
||||
reflectionConverter.marshal(source, writer, context);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Object unmarshal(HierarchicalStreamReader reader,
|
||||
UnmarshallingContext context) {
|
||||
Refund refund = new Refund();
|
||||
Mapper mapper = xStream.getMapper();
|
||||
ReflectionProvider reflectionProvider = xStream
|
||||
.getReflectionProvider();
|
||||
Pattern pattern = Pattern.compile("(_\\d)$");
|
||||
Matcher matcher = null;
|
||||
Map<String, Map<String, String>> outMap = new HashMap<String, Map<String, String>>();
|
||||
while (reader.hasMoreChildren()) {
|
||||
reader.moveDown();
|
||||
String nodeName = reader.getNodeName();
|
||||
String fieldName = mapper.realMember(Refund.class, nodeName);
|
||||
Field field = reflectionProvider.getFieldOrNull(Refund.class,
|
||||
fieldName);
|
||||
if (field != null) {
|
||||
Object value = context.convertAnother(refund,
|
||||
field.getType());
|
||||
reflectionProvider.writeField(refund, fieldName, value,
|
||||
field.getDeclaringClass());
|
||||
} else if ((matcher = pattern.matcher(nodeName)).find()) {
|
||||
String key = matcher.group();
|
||||
Map<String, String> innerMap = null;
|
||||
if ((innerMap = outMap.get(key)) == null) {
|
||||
innerMap = new HashMap<String, String>();
|
||||
outMap.put(key, innerMap);
|
||||
}
|
||||
innerMap.put(nodeName.replace(key, ""), reader.getValue());
|
||||
}
|
||||
reader.moveUp();
|
||||
}
|
||||
StringBuilder detailXml = new StringBuilder();
|
||||
detailXml.append("<list>");
|
||||
String detailCanonicalName = RefundDetail.class.getCanonicalName();
|
||||
for (Iterator<Entry<String, Map<String, String>>> outIt = outMap
|
||||
.entrySet().iterator(); outIt.hasNext();) {
|
||||
detailXml.append("<").append(detailCanonicalName).append(">");
|
||||
for (Iterator<Entry<String, String>> innerIt = outIt.next()
|
||||
.getValue().entrySet().iterator(); innerIt.hasNext();) {
|
||||
Entry<String, String> entry = innerIt.next();
|
||||
detailXml.append("<").append(entry.getKey()).append(">");
|
||||
detailXml.append(entry.getValue());
|
||||
detailXml.append("</").append(entry.getKey()).append(">");
|
||||
}
|
||||
detailXml.append("</").append(detailCanonicalName).append(">");
|
||||
}
|
||||
detailXml.append("</list>");
|
||||
xStream.processAnnotations(RefundDetail.class);
|
||||
refund.setDetails(xStream.fromXML(detailXml.toString(), List.class));
|
||||
return refund;
|
||||
}
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package com.foxinmy.weixin4j.mp.payment;
|
||||
|
||||
/**
|
||||
* 退款状态
|
||||
*
|
||||
* @className RefundStatus
|
||||
* @author jy
|
||||
* @date 2014年11月2日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public enum RefundStatus {
|
||||
SUCCES, // 退款成功
|
||||
FAIL, // 退款失败
|
||||
PROCESSING, // 退款处理中
|
||||
NOTSURE, // 未确定,需要商户 原退款单号重新发起
|
||||
// 转入代发,退款到银行发现用户的卡作废或者冻结了,导致原路退款银行卡失败,资金回流到商户的现金帐号,需要商户人工干
|
||||
// 预,通过线下或者财付通转 账的方式进行退款。
|
||||
CHANGE;
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package com.foxinmy.weixin4j.mp.payment;
|
||||
|
||||
public enum SignType {
|
||||
SHA1,MD5
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.foxinmy.weixin4j.mp.payment;
|
||||
|
||||
/**
|
||||
* 交易状态
|
||||
*
|
||||
* @className TradeState
|
||||
* @author jy
|
||||
* @date 2014年11月2日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public enum TradeState {
|
||||
SUCCESS, // 支付成功
|
||||
REFUND, // 转入退款
|
||||
NOTPAY, // 未支付
|
||||
CLOSED, // 已关闭
|
||||
REVOKED, // 已撤销
|
||||
USERPAYING, // 用户支付中
|
||||
NOPAY, // 未支付(输入密码或 确认支付超时)
|
||||
PAYERROR;// 支付失败(其他 原因,如银行返回失败)
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package com.foxinmy.weixin4j.mp.payment;
|
||||
|
||||
/**
|
||||
* 微信支付类型
|
||||
*
|
||||
* @className TradeType
|
||||
* @author jy
|
||||
* @date 2014年10月21日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public enum TradeType {
|
||||
JSAPI, MICROPAY, NATIVE, APP;
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
package com.foxinmy.weixin4j.mp.payment.v2;
|
||||
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.mp.payment.PayRequest;
|
||||
import com.foxinmy.weixin4j.util.MapUtil;
|
||||
|
||||
/**
|
||||
* 微信JS支付:get_brand_wcpay_request<br/>
|
||||
* <font color="red">所列参数均为非空字符串</font>
|
||||
* <p>
|
||||
* get_brand_wcpay_request:ok 支付成功<br>
|
||||
* get_brand_wcpay_request:cancel 支付过程中用户取消<br>
|
||||
* get_brand_wcpay_request:fail 支付失败
|
||||
* </p>
|
||||
*
|
||||
* @className JsPayRequestV2
|
||||
* @author jy
|
||||
* @date 2014年8月17日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class JsPayRequestV2 extends PayRequest {
|
||||
|
||||
private static final long serialVersionUID = -5972173459255255197L;
|
||||
|
||||
public JsPayRequestV2(WeixinAccount weixinAccount, PayPackageV2 payPackage) {
|
||||
this.setAppId(weixinAccount.getAppId());
|
||||
this.setPackageInfo(package2string(payPackage,
|
||||
weixinAccount.getPartnerKey()));
|
||||
}
|
||||
|
||||
@JSONField(serialize = false)
|
||||
private String package2string(PayPackageV2 payPackage, String partnerKey) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
// a.对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序) 后,
|
||||
// 使用 URL 键值 对的格式(即 key1=value1&key2=value2...)拼接成字符串 string1
|
||||
// 注意:值为空的参数不参与签名
|
||||
sb.append(MapUtil.toJoinString(payPackage, false, false, null));
|
||||
// b--->
|
||||
// 在 string1 最后拼接上 key=paternerKey 得到 stringSignTemp 字符串,并 对
|
||||
// stringSignTemp 进行 md5 运算
|
||||
// 再将得到的 字符串所有字符转换为大写 ,得到 sign 值 signValue。
|
||||
sb.append("&key=").append(partnerKey);
|
||||
// c---> & d---->
|
||||
String sign = DigestUtils.md5Hex(sb.toString()).toUpperCase();
|
||||
sb.delete(0, sb.length());
|
||||
// c.对传入参数中所有键值对的 value 进行 urlencode 转码后重新拼接成字符串 string2
|
||||
sb.append(MapUtil.toJoinString(payPackage, true, false, null))
|
||||
.append("&sign=").append(sign);
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JsPayRequest [getAppId()=" + getAppId() + ", getTimeStamp()="
|
||||
+ getTimeStamp() + ", getNonceStr()=" + getNonceStr()
|
||||
+ ", getPackageInfo()=" + getPackageInfo() + ", getSignType()="
|
||||
+ getSignType() + ", getPaySign()=" + getPaySign() + "]";
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package com.foxinmy.weixin4j.mp.payment.v2;
|
||||
|
||||
import com.foxinmy.weixin4j.mp.payment.JsPayNotify;
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
|
||||
/**
|
||||
* Native支付回调时POST的信息
|
||||
*
|
||||
* @className PayNativeNotifyV2
|
||||
* @author jy
|
||||
* @date 2014年10月28日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class NativePayNotifyV2 extends JsPayNotify {
|
||||
|
||||
private static final long serialVersionUID = 1868431159301749988L;
|
||||
@XStreamAlias("ProductId")
|
||||
private String productId;
|
||||
|
||||
public String getProductId() {
|
||||
return productId;
|
||||
}
|
||||
|
||||
public void setProductId(String productId) {
|
||||
this.productId = productId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PayNativeNotifyV2 [productId=" + productId + ", getAppid()="
|
||||
+ getAppid() + ", getTimestamp()=" + getTimestamp()
|
||||
+ ", getNoncestr()=" + getNoncestr() + ", getOpenid()="
|
||||
+ getOpenid() + ", getAppsignature()=" + getAppsignature()
|
||||
+ ", getIssubscribe()=" + getIssubscribe()
|
||||
+ ", getSignmethod()=" + getSignmethod() + "]";
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
package com.foxinmy.weixin4j.mp.payment.v2;
|
||||
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
|
||||
/**
|
||||
* Native支付响应
|
||||
*
|
||||
* @className NativePayResponseV2
|
||||
* @author jy
|
||||
* @date 2014年10月28日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
@XStreamAlias("xml")
|
||||
public class NativePayResponseV2 extends JsPayRequestV2 {
|
||||
|
||||
private static final long serialVersionUID = 6119895998783333012L;
|
||||
@XStreamAlias("RetCode")
|
||||
private String retCode;
|
||||
@XStreamAlias("RetErrMsg")
|
||||
private String retMsg;
|
||||
|
||||
public NativePayResponseV2(WeixinAccount weixinAccount,
|
||||
PayPackageV2 payPackage) {
|
||||
super(weixinAccount, payPackage);
|
||||
this.retCode = "0";
|
||||
this.retMsg = "OK";
|
||||
}
|
||||
|
||||
public String getRetCode() {
|
||||
return retCode;
|
||||
}
|
||||
|
||||
public void setRetCode(String retCode) {
|
||||
this.retCode = retCode;
|
||||
}
|
||||
|
||||
public String getRetMsg() {
|
||||
return retMsg;
|
||||
}
|
||||
|
||||
public void setRetMsg(String retMsg) {
|
||||
this.retMsg = retMsg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NativePayResponseV2 [retCode=" + retCode + ", retMsg=" + retMsg
|
||||
+ ", getAppId()=" + getAppId() + ", getTimeStamp()="
|
||||
+ getTimeStamp() + ", getNonceStr()=" + getNonceStr()
|
||||
+ ", getPackageInfo()=" + getPackageInfo() + ", getSignType()="
|
||||
+ getSignType() + ", getPaySign()=" + getPaySign() + "]";
|
||||
}
|
||||
}
|
||||
+245
@@ -0,0 +1,245 @@
|
||||
package com.foxinmy.weixin4j.mp.payment.v2;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
|
||||
/**
|
||||
* 订单信息
|
||||
*
|
||||
* @className Order
|
||||
* @author jy
|
||||
* @date 2014年11月2日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class Order extends JsonResult {
|
||||
|
||||
private static final long serialVersionUID = 4543552984506609920L;
|
||||
|
||||
// 是查询结果状态码,0 表明成功,其他表明错误;
|
||||
private String ret_code;
|
||||
// 是查询结果出错信息;
|
||||
private String ret_msg;
|
||||
// 是返回信息中的编码方式;
|
||||
private String input_charset;
|
||||
// 是订单状态,0 为成功,其他为失败;
|
||||
private String trade_state;
|
||||
// 是交易模式,1 为即时到帐,其他保留;
|
||||
private String trade_mode;
|
||||
// 是财付通商户号,即前文的 partnerid;
|
||||
private String partner;
|
||||
// 是银行类型;
|
||||
private String bank_type;
|
||||
// 是银行订单号;
|
||||
private String bank_billno;
|
||||
// 是总金额,单位为分;
|
||||
private String total_fee;
|
||||
// 是币种,1 为人民币;
|
||||
private String fee_type;
|
||||
// 是财付通订单号;
|
||||
private String transaction_id;
|
||||
// 是第三方订单号;
|
||||
private String out_trade_no;
|
||||
// 表明是否分账,false 为无分账,true 为有分账;
|
||||
private boolean is_split;
|
||||
// 表明是否退款,false 为无退款,ture 为退款;
|
||||
private boolean is_refund;
|
||||
// attach 是商户数据包,即生成订单package 时商户填入的 attach;
|
||||
private String attach;
|
||||
// 支付完成时间;
|
||||
private String time_end;
|
||||
// 物流费用,单位为分;
|
||||
private String transport_fee;
|
||||
// 物品费用,单位为分;
|
||||
private String product_fee;
|
||||
// 折扣价格,单位为分;
|
||||
private String discount;
|
||||
// 换算成人民币之后的总金额,单位为分,一般看 total_fee 即可。
|
||||
private String rmb_total_fee;
|
||||
|
||||
public String getRet_code() {
|
||||
return ret_code;
|
||||
}
|
||||
|
||||
public void setRet_code(String ret_code) {
|
||||
this.ret_code = ret_code;
|
||||
}
|
||||
|
||||
public String getRet_msg() {
|
||||
return ret_msg;
|
||||
}
|
||||
|
||||
public void setRet_msg(String ret_msg) {
|
||||
this.ret_msg = ret_msg;
|
||||
}
|
||||
|
||||
public String getInput_charset() {
|
||||
return input_charset;
|
||||
}
|
||||
|
||||
public void setInput_charset(String input_charset) {
|
||||
this.input_charset = input_charset;
|
||||
}
|
||||
|
||||
public String getTrade_state() {
|
||||
return trade_state;
|
||||
}
|
||||
|
||||
public void setTrade_state(String trade_state) {
|
||||
this.trade_state = trade_state;
|
||||
}
|
||||
|
||||
public String getTrade_mode() {
|
||||
return trade_mode;
|
||||
}
|
||||
|
||||
public void setTrade_mode(String trade_mode) {
|
||||
this.trade_mode = trade_mode;
|
||||
}
|
||||
|
||||
public String getPartner() {
|
||||
return partner;
|
||||
}
|
||||
|
||||
public void setPartner(String partner) {
|
||||
this.partner = partner;
|
||||
}
|
||||
|
||||
public String getBank_type() {
|
||||
return bank_type;
|
||||
}
|
||||
|
||||
public void setBank_type(String bank_type) {
|
||||
this.bank_type = bank_type;
|
||||
}
|
||||
|
||||
public String getBank_billno() {
|
||||
return bank_billno;
|
||||
}
|
||||
|
||||
public void setBank_billno(String bank_billno) {
|
||||
this.bank_billno = bank_billno;
|
||||
}
|
||||
|
||||
public String getTotal_fee() {
|
||||
return total_fee;
|
||||
}
|
||||
|
||||
public void setTotal_fee(String total_fee) {
|
||||
this.total_fee = total_fee;
|
||||
}
|
||||
|
||||
public String getFee_type() {
|
||||
return fee_type;
|
||||
}
|
||||
|
||||
public void setFee_type(String fee_type) {
|
||||
this.fee_type = fee_type;
|
||||
}
|
||||
|
||||
public String getTransaction_id() {
|
||||
return transaction_id;
|
||||
}
|
||||
|
||||
public void setTransaction_id(String transaction_id) {
|
||||
this.transaction_id = transaction_id;
|
||||
}
|
||||
|
||||
public String getOut_trade_no() {
|
||||
return out_trade_no;
|
||||
}
|
||||
|
||||
public void setOut_trade_no(String out_trade_no) {
|
||||
this.out_trade_no = out_trade_no;
|
||||
}
|
||||
|
||||
public boolean isIs_split() {
|
||||
return is_split;
|
||||
}
|
||||
|
||||
public void setIs_split(boolean is_split) {
|
||||
this.is_split = is_split;
|
||||
}
|
||||
|
||||
public boolean isIs_refund() {
|
||||
return is_refund;
|
||||
}
|
||||
|
||||
public void setIs_refund(boolean is_refund) {
|
||||
this.is_refund = is_refund;
|
||||
}
|
||||
|
||||
public String getAttach() {
|
||||
return attach;
|
||||
}
|
||||
|
||||
public void setAttach(String attach) {
|
||||
this.attach = attach;
|
||||
}
|
||||
|
||||
public String getTime_end() {
|
||||
return time_end;
|
||||
}
|
||||
|
||||
public void setTime_end(String time_end) {
|
||||
this.time_end = time_end;
|
||||
}
|
||||
|
||||
public String getTransport_fee() {
|
||||
return transport_fee;
|
||||
}
|
||||
|
||||
public void setTransport_fee(String transport_fee) {
|
||||
this.transport_fee = transport_fee;
|
||||
}
|
||||
|
||||
public String getProduct_fee() {
|
||||
return product_fee;
|
||||
}
|
||||
|
||||
public void setProduct_fee(String product_fee) {
|
||||
this.product_fee = product_fee;
|
||||
}
|
||||
|
||||
public String getDiscount() {
|
||||
return discount;
|
||||
}
|
||||
|
||||
public void setDiscount(String discount) {
|
||||
this.discount = discount;
|
||||
}
|
||||
|
||||
public String getRmb_total_fee() {
|
||||
return rmb_total_fee;
|
||||
}
|
||||
|
||||
public void setRmb_total_fee(String rmb_total_fee) {
|
||||
this.rmb_total_fee = rmb_total_fee;
|
||||
}
|
||||
|
||||
private Map<String, String> mapData;
|
||||
|
||||
public Map<String, String> getMapData() {
|
||||
return mapData;
|
||||
}
|
||||
|
||||
public void setMapData(Map<String, String> mapData) {
|
||||
this.mapData = mapData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Order [ret_code=" + ret_code + ", ret_msg=" + ret_msg
|
||||
+ ", input_charset=" + input_charset + ", trade_state="
|
||||
+ trade_state + ", trade_mode=" + trade_mode + ", partner="
|
||||
+ partner + ", bank_type=" + bank_type + ", bank_billno="
|
||||
+ bank_billno + ", total_fee=" + total_fee + ", fee_type="
|
||||
+ fee_type + ", transaction_id=" + transaction_id
|
||||
+ ", out_trade_no=" + out_trade_no + ", is_split=" + is_split
|
||||
+ ", is_refund=" + is_refund + ", attach=" + attach
|
||||
+ ", time_end=" + time_end + ", transport_fee=" + transport_fee
|
||||
+ ", product_fee=" + product_fee + ", discount=" + discount
|
||||
+ ", rmb_total_fee=" + rmb_total_fee + "]";
|
||||
}
|
||||
}
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
package com.foxinmy.weixin4j.mp.payment.v2;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
|
||||
/**
|
||||
* 维权POST的数据
|
||||
*
|
||||
* @className PayFeedback
|
||||
* @author jy
|
||||
* @date 2014年10月29日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
@XStreamAlias("xml")
|
||||
public class PayFeedback implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 7230049346213966310L;
|
||||
|
||||
@XStreamAlias("FeedBackId")
|
||||
private String feedbackId;
|
||||
@XStreamAlias("OpenId")
|
||||
private String openId;
|
||||
@XStreamAlias("TransId")
|
||||
private String transId;
|
||||
@XStreamAlias("Reason")
|
||||
private String reason;
|
||||
@XStreamAlias("Solution")
|
||||
private String solution;
|
||||
@XStreamAlias("ExtInfo")
|
||||
private String extInfo;
|
||||
@XStreamAlias("PicInfo")
|
||||
private String picInfo;
|
||||
@XStreamAlias("MsgType")
|
||||
private String status;
|
||||
@XStreamAlias("AppId")
|
||||
private String appId;
|
||||
@XStreamAlias("TimeStamp")
|
||||
private String timeStamp;
|
||||
@XStreamAlias("AppSignature")
|
||||
private String appSignature;
|
||||
|
||||
public String getFeedbackId() {
|
||||
return feedbackId;
|
||||
}
|
||||
|
||||
public void setFeedbackId(String feedbackId) {
|
||||
this.feedbackId = feedbackId;
|
||||
}
|
||||
|
||||
public String getOpenId() {
|
||||
return openId;
|
||||
}
|
||||
|
||||
public void setOpenId(String openId) {
|
||||
this.openId = openId;
|
||||
}
|
||||
|
||||
public String getTransId() {
|
||||
return transId;
|
||||
}
|
||||
|
||||
public void setTransId(String transId) {
|
||||
this.transId = transId;
|
||||
}
|
||||
|
||||
public String getReason() {
|
||||
return reason;
|
||||
}
|
||||
|
||||
public void setReason(String reason) {
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
public String getSolution() {
|
||||
return solution;
|
||||
}
|
||||
|
||||
public void setSolution(String solution) {
|
||||
this.solution = solution;
|
||||
}
|
||||
|
||||
public String getExtInfo() {
|
||||
return extInfo;
|
||||
}
|
||||
|
||||
public void setExtInfo(String extInfo) {
|
||||
this.extInfo = extInfo;
|
||||
}
|
||||
|
||||
public String getPicInfo() {
|
||||
return picInfo;
|
||||
}
|
||||
|
||||
public void setPicInfo(String picInfo) {
|
||||
this.picInfo = picInfo;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getAppId() {
|
||||
return appId;
|
||||
}
|
||||
|
||||
public void setAppId(String appId) {
|
||||
this.appId = appId;
|
||||
}
|
||||
|
||||
public String getTimeStamp() {
|
||||
return timeStamp;
|
||||
}
|
||||
|
||||
public void setTimeStamp(String timeStamp) {
|
||||
this.timeStamp = timeStamp;
|
||||
}
|
||||
|
||||
public String getAppSignature() {
|
||||
return appSignature;
|
||||
}
|
||||
|
||||
public void setAppSignature(String appSignature) {
|
||||
this.appSignature = appSignature;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PayFeedback [feedbackId=" + feedbackId + ", openId=" + openId
|
||||
+ ", transId=" + transId + ", reason=" + reason + ", solution="
|
||||
+ solution + ", extInfo=" + extInfo + ", picInfo=" + picInfo
|
||||
+ ", status=" + status + ", appId=" + appId + ", timeStamp="
|
||||
+ timeStamp + ", appSignature=" + appSignature + "]";
|
||||
}
|
||||
}
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
package com.foxinmy.weixin4j.mp.payment.v2;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.foxinmy.weixin4j.mp.payment.PayPackage;
|
||||
|
||||
/**
|
||||
* 微信支付的订单详情
|
||||
*
|
||||
* @className PayPackageV2
|
||||
* @author jy
|
||||
* @date 2014年8月17日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class PayPackageV2 extends PayPackage {
|
||||
|
||||
private static final long serialVersionUID = 5557542103637795834L;
|
||||
|
||||
// 银行通道类型 固定为"WX" 非空
|
||||
private String bank_type;
|
||||
// 商户号 注册时分配的财付通商户号 非空
|
||||
private String partner;
|
||||
// 支付币种 默认值是"1" 非空
|
||||
private String fee_type;
|
||||
// 物流费用 可为空 如果有值,必须保 证 transport_fee + product_fee=total_fee【传进来的参数按照实际金额即可
|
||||
// 也就是元为单位】
|
||||
private String transport_fee;
|
||||
// 商品费用 可为空 商品费用,单位为分。如果有值,必须保 证 transport_fee +
|
||||
// product_fee=total_fee;【传进来的参数按照实际金额即可 也就是元为单位】
|
||||
private String product_fee;
|
||||
// 传入参数字符编码 取值范围:"GBK"、"UTF-8",默认:"GBK" 可为空
|
||||
private String input_charset;
|
||||
private String goods_tag;// 商品标记优惠券可能用到
|
||||
// 可为空
|
||||
public String getBank_type() {
|
||||
return bank_type;
|
||||
}
|
||||
public void setBank_type(String bank_type) {
|
||||
this.bank_type = bank_type;
|
||||
}
|
||||
public void setBody(String body) {
|
||||
super.setBody(StringUtils.isBlank(body) ? "服务费用" : body);
|
||||
}
|
||||
public String getPartner() {
|
||||
return partner;
|
||||
}
|
||||
public void setPartner(String partner) {
|
||||
this.partner = partner;
|
||||
}
|
||||
public String getFee_type() {
|
||||
return fee_type;
|
||||
}
|
||||
public void setFee_type(String fee_type) {
|
||||
this.fee_type = fee_type;
|
||||
}
|
||||
|
||||
public void setNotify_url(String notify_url) {
|
||||
super.setNotify_url(notify_url);
|
||||
}
|
||||
|
||||
public String getTransport_fee() {
|
||||
return transport_fee;
|
||||
}
|
||||
public void setTransport_fee(double transport_fee) {
|
||||
this.transport_fee = FEE_FORMAT.format(transport_fee);
|
||||
}
|
||||
public String getProduct_fee() {
|
||||
return product_fee;
|
||||
}
|
||||
public void setProduct_fee(double product_fee) {
|
||||
this.product_fee = FEE_FORMAT.format(product_fee);
|
||||
}
|
||||
public String getGoods_tag() {
|
||||
return goods_tag;
|
||||
}
|
||||
public void setGoods_tag(String goods_tag) {
|
||||
this.goods_tag = goods_tag;
|
||||
}
|
||||
public String getInput_charset() {
|
||||
return input_charset;
|
||||
}
|
||||
public void setInput_charset(String input_charset) {
|
||||
this.input_charset = input_charset;
|
||||
}
|
||||
|
||||
public PayPackageV2() {
|
||||
this.bank_type = "WX";
|
||||
this.fee_type = "1";
|
||||
this.input_charset = "UTF-8";
|
||||
}
|
||||
|
||||
public PayPackageV2(String out_trade_no, double total_fee,
|
||||
String spbill_create_ip) {
|
||||
this(null, null, null, out_trade_no, total_fee, null, spbill_create_ip,
|
||||
null, null, 0d, 0d, null);
|
||||
}
|
||||
public PayPackageV2(String body, String out_trade_no, double total_fee,
|
||||
String spbill_create_ip) {
|
||||
this(body, null, null, out_trade_no, total_fee, null, spbill_create_ip,
|
||||
null, null, 0d, 0d, null);
|
||||
}
|
||||
public PayPackageV2(String body, String partner, String out_trade_no,
|
||||
double total_fee, String notify_url, String spbill_create_ip) {
|
||||
this(body, null, partner, out_trade_no, total_fee, notify_url,
|
||||
spbill_create_ip, null, null, 0d, 0d, null);
|
||||
}
|
||||
|
||||
public PayPackageV2(String body, String attach, String partner,
|
||||
String out_trade_no, double total_fee, String notify_url,
|
||||
String spbill_create_ip, Date time_start, Date time_expire,
|
||||
double transport_fee, double product_fee, String goods_tag) {
|
||||
super(body, attach, out_trade_no, total_fee, spbill_create_ip,
|
||||
time_start, time_expire, goods_tag, notify_url);
|
||||
this.bank_type = "WX";
|
||||
this.fee_type = "1";
|
||||
this.input_charset = "UTF-8";
|
||||
this.transport_fee = transport_fee > 0d ? FEE_FORMAT
|
||||
.format(transport_fee * 100) : null;
|
||||
this.product_fee = product_fee > 0 ? FEE_FORMAT
|
||||
.format(product_fee * 100) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PayPackageV2 [bank_type=" + bank_type + ", partner=" + partner
|
||||
+ ", fee_type=" + fee_type + ", transport_fee=" + transport_fee
|
||||
+ ", product_fee=" + product_fee + ", input_charset="
|
||||
+ input_charset + ", goods_tag=" + goods_tag
|
||||
+ ", getBank_type()=" + getBank_type() + ", getPartner()="
|
||||
+ getPartner() + ", getFee_type()=" + getFee_type()
|
||||
+ ", getTransport_fee()=" + getTransport_fee()
|
||||
+ ", getProduct_fee()=" + getProduct_fee()
|
||||
+ ", getGoods_tag()=" + getGoods_tag()
|
||||
+ ", getInput_charset()=" + getInput_charset() + "]";
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package com.foxinmy.weixin4j.mp.payment.v3;
|
||||
|
||||
import com.foxinmy.weixin4j.mp.payment.ApiResult;
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
|
||||
/**
|
||||
* V3 Native支付回调时POST的信息
|
||||
*
|
||||
* @className PayNativeNotifyV3
|
||||
* @author jy
|
||||
* @date 2014年10月30日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
@XStreamAlias("xml")
|
||||
public class NativePayNotifyV3 extends ApiResult {
|
||||
|
||||
private static final long serialVersionUID = 4515471400239795492L;
|
||||
|
||||
@XStreamAlias("mch_id")
|
||||
private String mchId;
|
||||
@XStreamAlias("product_id")
|
||||
private String productId;
|
||||
|
||||
public String getProductId() {
|
||||
return productId;
|
||||
}
|
||||
|
||||
public void setProductId(String productId) {
|
||||
this.productId = productId;
|
||||
}
|
||||
|
||||
public String getMchId() {
|
||||
return mchId;
|
||||
}
|
||||
|
||||
public void setMchId(String mchId) {
|
||||
this.mchId = mchId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NativePayNotifyV3 [mchId=" + mchId + ", productId=" + productId
|
||||
+ ", getAppId()=" + getAppId() + ", getNonceStr()="
|
||||
+ getNonceStr() + ", getSign()=" + getSign()
|
||||
+ ", getDeviceInfo()=" + getDeviceInfo() + ", toString()="
|
||||
+ super.toString() + ", getReturnCode()=" + getReturnCode()
|
||||
+ ", getReturnMsg()=" + getReturnMsg() + ", getResultCode()="
|
||||
+ getResultCode() + ", getErrCode()=" + getErrCode()
|
||||
+ ", getErrCodeDes()=" + getErrCodeDes() + "]";
|
||||
}
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
package com.foxinmy.weixin4j.mp.payment.v3;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.foxinmy.weixin4j.exception.PayException;
|
||||
import com.foxinmy.weixin4j.mp.payment.ApiResult;
|
||||
import com.foxinmy.weixin4j.mp.payment.PayUtil;
|
||||
import com.foxinmy.weixin4j.util.RandomUtil;
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
|
||||
/**
|
||||
* Native支付响应
|
||||
*
|
||||
* @className NativePayResponseV3
|
||||
* @author jy
|
||||
* @date 2014年10月28日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
@XStreamAlias("xml")
|
||||
public class NativePayResponseV3 extends ApiResult {
|
||||
|
||||
private static final long serialVersionUID = 6119895998783333012L;
|
||||
|
||||
private String prepay_id;
|
||||
|
||||
public NativePayResponseV3(PayPackageV3 payPackage, String returnMsg,
|
||||
String resultMsg) throws PayException {
|
||||
super.setReturnMsg(returnMsg);
|
||||
super.setReturnCode(StringUtils.isNotBlank(returnMsg) ? FAIL : SUCCESS);
|
||||
this.setErrCodeDes(resultMsg);
|
||||
this.setResultCode(StringUtils.isNotBlank(resultMsg) ? FAIL : SUCCESS);
|
||||
this.setMchId(payPackage.getMch_id());
|
||||
this.setAppId(payPackage.getAppid());
|
||||
this.setNonceStr(RandomUtil.generateString(16));
|
||||
this.prepay_id = PayUtil.createPrePay(payPackage).getPrepayId();
|
||||
}
|
||||
|
||||
public String getPrepay_id() {
|
||||
return prepay_id;
|
||||
}
|
||||
|
||||
public void setPrepay_id(String prepay_id) {
|
||||
this.prepay_id = prepay_id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NativePayResponseV3 [prepay_id=" + prepay_id + ", getAppId()="
|
||||
+ getAppId() + ", getMchId()=" + getMchId()
|
||||
+ ", getNonceStr()=" + getNonceStr() + ", getSign()="
|
||||
+ getSign() + ", getDeviceInfo()=" + getDeviceInfo()
|
||||
+ ", toString()=" + super.toString() + ", getReturnCode()="
|
||||
+ getReturnCode() + ", getReturnMsg()=" + getReturnMsg()
|
||||
+ ", getResultCode()=" + getResultCode() + ", getErrCode()="
|
||||
+ getErrCode() + ", getErrCodeDes()=" + getErrCodeDes() + "]";
|
||||
}
|
||||
}
|
||||
+172
@@ -0,0 +1,172 @@
|
||||
package com.foxinmy.weixin4j.mp.payment.v3;
|
||||
|
||||
import com.foxinmy.weixin4j.mp.payment.ApiResult;
|
||||
import com.foxinmy.weixin4j.mp.payment.CurrencyType;
|
||||
import com.foxinmy.weixin4j.mp.payment.TradeState;
|
||||
import com.foxinmy.weixin4j.mp.payment.TradeType;
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
|
||||
/**
|
||||
* 订单信息
|
||||
*
|
||||
* @className Order
|
||||
* @author jy
|
||||
* @date 2014年11月2日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
@XStreamAlias("xml")
|
||||
public class Order extends ApiResult {
|
||||
|
||||
private static final long serialVersionUID = 5636828325595317079L;
|
||||
// SUCCESS—支付成功 REFUND—转入退款 NOTPAY—未支付 CLOSED—已关闭 REVOKED—已撤销
|
||||
// USERPAYING--用户支付中 NOPAY--未支付(输入密码或 确认支付超时) PAYERROR--支付失败(其他 原因,如银行返回失败)
|
||||
// 以下字段在 return_code 和 result_code 都为 SUCCESS 的时候有返回
|
||||
@XStreamAlias("trade_state")
|
||||
private TradeState tradeState;
|
||||
// 用户标识ID
|
||||
@XStreamAlias("openid")
|
||||
private String openId;
|
||||
// 用户是否关注公众账号,Y- 关注,N-未关注,仅在公众 账号类型支付有效
|
||||
private String isSubscribe;
|
||||
// 交易类型
|
||||
@XStreamAlias("trade_type")
|
||||
private TradeType tradeType;
|
||||
// 银行类型
|
||||
@XStreamAlias("bank_type")
|
||||
private String bankType;
|
||||
// 订单总金额,单位为分
|
||||
@XStreamAlias("total_fee")
|
||||
private int totalFee;
|
||||
// 现金券支付金额<=订单总金 额,订单总金额-现金券金额 为现金支付金额
|
||||
@XStreamAlias("coupon_fee")
|
||||
private int couponFee;
|
||||
// 货币类型,符合 ISO 4217 标准的三位字母代码,默认人民币:CNY
|
||||
@XStreamAlias("fee_type")
|
||||
private CurrencyType feeType;
|
||||
// 微信支付订单号
|
||||
@XStreamAlias("transaction_id")
|
||||
private String transactionId;
|
||||
// 商户订单号
|
||||
@XStreamAlias("out_rade_no")
|
||||
private String outTradeNo;
|
||||
// 商家数据包
|
||||
@XStreamAlias("attach")
|
||||
private String attach;
|
||||
// 支付完成时间,格式为 yyyyMMddhhmmss
|
||||
@XStreamAlias("time_end")
|
||||
private String timeEnd;
|
||||
|
||||
public TradeState getTradeState() {
|
||||
return tradeState;
|
||||
}
|
||||
|
||||
public void setTradeState(TradeState tradeState) {
|
||||
this.tradeState = tradeState;
|
||||
}
|
||||
|
||||
public String getOpenId() {
|
||||
return openId;
|
||||
}
|
||||
|
||||
public void setOpenId(String openId) {
|
||||
this.openId = openId;
|
||||
}
|
||||
|
||||
public String getIsSubscribe() {
|
||||
return isSubscribe;
|
||||
}
|
||||
|
||||
public void setIsSubscribe(String isSubscribe) {
|
||||
this.isSubscribe = isSubscribe;
|
||||
}
|
||||
|
||||
public TradeType getTradeType() {
|
||||
return tradeType;
|
||||
}
|
||||
|
||||
public void setTradeType(TradeType tradeType) {
|
||||
this.tradeType = tradeType;
|
||||
}
|
||||
|
||||
public String getBankType() {
|
||||
return bankType;
|
||||
}
|
||||
|
||||
public void setBankType(String bankType) {
|
||||
this.bankType = bankType;
|
||||
}
|
||||
|
||||
public int getTotalFee() {
|
||||
return totalFee;
|
||||
}
|
||||
|
||||
public void setTotalFee(int totalFee) {
|
||||
this.totalFee = totalFee;
|
||||
}
|
||||
|
||||
public int getCouponFee() {
|
||||
return couponFee;
|
||||
}
|
||||
|
||||
public void setCouponFee(int couponFee) {
|
||||
this.couponFee = couponFee;
|
||||
}
|
||||
|
||||
public CurrencyType getFeeType() {
|
||||
return feeType;
|
||||
}
|
||||
|
||||
public void setFeeType(CurrencyType feeType) {
|
||||
this.feeType = feeType;
|
||||
}
|
||||
|
||||
public String getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
public void setTransactionId(String transactionId) {
|
||||
this.transactionId = transactionId;
|
||||
}
|
||||
|
||||
public String getOutTradeNo() {
|
||||
return outTradeNo;
|
||||
}
|
||||
|
||||
public void setOutTradeNo(String outTradeNo) {
|
||||
this.outTradeNo = outTradeNo;
|
||||
}
|
||||
|
||||
public String getAttach() {
|
||||
return attach;
|
||||
}
|
||||
|
||||
public void setAttach(String attach) {
|
||||
this.attach = attach;
|
||||
}
|
||||
|
||||
public String getTimeEnd() {
|
||||
return timeEnd;
|
||||
}
|
||||
|
||||
public void setTimeEnd(String timeEnd) {
|
||||
this.timeEnd = timeEnd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Order [tradeState=" + tradeState + ", openId=" + openId
|
||||
+ ", isSubscribe=" + isSubscribe + ", tradeType=" + tradeType
|
||||
+ ", bankType=" + bankType + ", totalFee=" + totalFee
|
||||
+ ", couponFee=" + couponFee + ", feeType=" + feeType
|
||||
+ ", transactionId=" + transactionId + ", outTradeNo="
|
||||
+ outTradeNo + ", attach=" + attach + ", timeEnd=" + timeEnd
|
||||
+ ", getAppId()=" + getAppId() + ", getMchId()=" + getMchId()
|
||||
+ ", getNonceStr()=" + getNonceStr() + ", getSign()="
|
||||
+ getSign() + ", getDeviceInfo()=" + getDeviceInfo()
|
||||
+ ", toString()=" + super.toString() + ", getReturnCode()="
|
||||
+ getReturnCode() + ", getReturnMsg()=" + getReturnMsg()
|
||||
+ ", getResultCode()=" + getResultCode() + ", getErrCode()="
|
||||
+ getErrCode() + ", getErrCodeDes()=" + getErrCodeDes() + "]";
|
||||
}
|
||||
}
|
||||
+161
@@ -0,0 +1,161 @@
|
||||
package com.foxinmy.weixin4j.mp.payment.v3;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.mp.payment.PayPackage;
|
||||
import com.foxinmy.weixin4j.mp.payment.TradeType;
|
||||
import com.foxinmy.weixin4j.util.RandomUtil;
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
|
||||
/**
|
||||
* 微信支付V3<br/>
|
||||
* 注意:
|
||||
* <font color="red">total_fee字段传入时单位为元,创建支付时会转换为分</font>
|
||||
* @className PayPackageV3
|
||||
* @author jy
|
||||
* @date 2014年10月21日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
@XStreamAlias("xml")
|
||||
public class PayPackageV3 extends PayPackage {
|
||||
|
||||
private static final long serialVersionUID = 8944928173669656177L;
|
||||
|
||||
private String appid; // 微信分配的公众账号 必须
|
||||
private String mch_id; // 微信支付分配的商户号 必须
|
||||
private String device_info; // 微信支付分配的终端设备号 非必须
|
||||
private String nonce_str; // 随机字符串,不长于 32 位 必须
|
||||
private String sign; // 签名 必须
|
||||
private String trade_type; // 交易类型JSAPI、NATIVE、APP 必须
|
||||
private String openid; // 用户在商户 appid 下的唯一 标识, trade_type 为 JSAPI 时,此参数必传
|
||||
private String product_id; // 只在 trade_type 为 NATIVE 时需要填写 非必须
|
||||
|
||||
public PayPackageV3() {
|
||||
|
||||
}
|
||||
|
||||
public PayPackageV3(WeixinAccount weixinAccount, String body,
|
||||
String out_trade_no, double total_fee, String spbill_create_ip,
|
||||
TradeType tradeType) {
|
||||
this(weixinAccount.getAppId(), weixinAccount.getMchId(), null,
|
||||
RandomUtil.generateString(16), body, null, out_trade_no,
|
||||
total_fee, spbill_create_ip, null, null, null, null, tradeType,
|
||||
weixinAccount.getOpenId(), null, weixinAccount.getPaySignKey());
|
||||
}
|
||||
|
||||
public PayPackageV3(WeixinAccount weixinAccount, String body,
|
||||
String attach, String out_trade_no, double total_fee,
|
||||
String spbill_create_ip, String notify_url, TradeType tradeType) {
|
||||
this(weixinAccount.getAppId(), weixinAccount.getMchId(), null, RandomUtil
|
||||
.generateString(16), body, attach, out_trade_no, total_fee,
|
||||
spbill_create_ip, null, null, null, notify_url, tradeType,
|
||||
weixinAccount.getOpenId(), null, weixinAccount.getPaySignKey());
|
||||
}
|
||||
|
||||
public PayPackageV3(String appid, String mch_id, String device_info,
|
||||
String nonce_str, String body, String attach, String out_trade_no,
|
||||
double total_fee, String spbill_create_ip, Date time_start,
|
||||
Date time_expire, String goods_tag, String notify_url,
|
||||
TradeType tradeType, String openid, String product_id,
|
||||
String paySignKey) {
|
||||
super(body, attach, out_trade_no, total_fee, spbill_create_ip,
|
||||
time_start, time_expire, goods_tag, notify_url);
|
||||
this.appid = appid;
|
||||
this.mch_id = mch_id;
|
||||
this.device_info = device_info;
|
||||
this.nonce_str = nonce_str;
|
||||
this.trade_type = tradeType.name();
|
||||
this.openid = openid;
|
||||
this.product_id = product_id;
|
||||
}
|
||||
|
||||
public String getAppid() {
|
||||
return appid;
|
||||
}
|
||||
|
||||
public void setAppid(String appid) {
|
||||
this.appid = appid;
|
||||
}
|
||||
|
||||
public String getMch_id() {
|
||||
return mch_id;
|
||||
}
|
||||
|
||||
public void setMch_id(String mch_id) {
|
||||
this.mch_id = mch_id;
|
||||
}
|
||||
|
||||
public String getDevice_info() {
|
||||
return device_info;
|
||||
}
|
||||
|
||||
public void setDevice_info(String device_info) {
|
||||
this.device_info = device_info;
|
||||
}
|
||||
|
||||
public String getNonce_str() {
|
||||
return nonce_str;
|
||||
}
|
||||
|
||||
public void setNonce_str(String nonce_str) {
|
||||
this.nonce_str = nonce_str;
|
||||
}
|
||||
|
||||
public String getSign() {
|
||||
return sign;
|
||||
}
|
||||
|
||||
public void setSign(String sign) {
|
||||
this.sign = sign;
|
||||
}
|
||||
|
||||
public void setBody(String body) {
|
||||
super.setBody(StringUtils.isBlank(body) ? "服务费用" : body);
|
||||
}
|
||||
|
||||
public void setNotify_url(String notify_url) {
|
||||
super.setNotify_url(notify_url);
|
||||
}
|
||||
|
||||
public String getTrade_type() {
|
||||
return trade_type;
|
||||
}
|
||||
|
||||
public void setTrade_type(TradeType tradeType) {
|
||||
this.trade_type = tradeType.name();
|
||||
}
|
||||
|
||||
public String getOpenid() {
|
||||
return openid;
|
||||
}
|
||||
|
||||
public void setOpenid(String openid) {
|
||||
this.openid = openid;
|
||||
}
|
||||
|
||||
public String getProduct_id() {
|
||||
return product_id;
|
||||
}
|
||||
|
||||
public void setProduct_id(String product_id) {
|
||||
this.product_id = product_id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PayPackageV3 [appid=" + appid + ", mch_id=" + mch_id
|
||||
+ ", device_info=" + device_info + ", nonce_str=" + nonce_str
|
||||
+ ", sign=" + sign + ", trade_type=" + trade_type + ", openid="
|
||||
+ openid + ", product_id=" + product_id + ", getAppid()="
|
||||
+ getAppid() + ", getMch_id()=" + getMch_id()
|
||||
+ ", getDevice_info()=" + getDevice_info()
|
||||
+ ", getNonce_str()=" + getNonce_str() + ", getSign()="
|
||||
+ getSign() + ", getTrade_type()=" + getTrade_type()
|
||||
+ ", getOpenid()=" + getOpenid() + ", getProduct_id()="
|
||||
+ getProduct_id() + "]";
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
package com.foxinmy.weixin4j.mp.payment.v3;
|
||||
|
||||
import java.beans.Transient;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.exception.PayException;
|
||||
import com.foxinmy.weixin4j.http.XmlResult;
|
||||
import com.foxinmy.weixin4j.mp.payment.PayRequest;
|
||||
import com.thoughtworks.xstream.annotations.XStreamOmitField;
|
||||
|
||||
/**
|
||||
* JS支付:get_brand_wcpay_request<br/>
|
||||
* <p>
|
||||
* get_brand_wcpay_request:ok 支付成功<br>
|
||||
* get_brand_wcpay_request:cancel 支付过程中用户取消<br>
|
||||
* get_brand_wcpay_request:fail 支付失败
|
||||
* </p>
|
||||
* <p>
|
||||
* NATIVE支付:PayRequest.TradeType=NATIVE
|
||||
* </p>
|
||||
*
|
||||
* @className PayRequestV3
|
||||
* @author jy
|
||||
* @date 2014年8月17日
|
||||
* @since JDK 1.7
|
||||
* @see com.foxinmy.weixin4j.mp.payment.v3.PayRequestV3.PrePay
|
||||
*/
|
||||
public class PayRequestV3 extends PayRequest {
|
||||
|
||||
private static final long serialVersionUID = -5972173459255255197L;
|
||||
|
||||
@XStreamOmitField
|
||||
private PrePay prePay;
|
||||
|
||||
public PayRequestV3(PrePay prePay) throws PayException {
|
||||
if (!prePay.getReturnCode().equalsIgnoreCase(XmlResult.SUCCESS)) {
|
||||
throw new PayException(prePay.getReturnMsg(),
|
||||
prePay.getReturnCode());
|
||||
}
|
||||
if (!prePay.getResultCode().equalsIgnoreCase(XmlResult.SUCCESS)) {
|
||||
throw new PayException(prePay.getResultCode(),
|
||||
prePay.getErrCodeDes());
|
||||
}
|
||||
this.prePay = prePay;
|
||||
this.setAppId(prePay.getAppId());
|
||||
this.setPackageInfo("prepay_id=" + prePay.getPrepayId());
|
||||
}
|
||||
|
||||
@Transient
|
||||
@JSONField(serialize = false)
|
||||
public PrePay getPrePay() {
|
||||
return prePay;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PayRequestV3 [getAppId()=" + getAppId() + ", getTimeStamp()="
|
||||
+ getTimeStamp() + ", getNonceStr()=" + getNonceStr()
|
||||
+ ", getPackageInfo()=" + getPackageInfo() + ", getSignType()="
|
||||
+ getSignType() + "]";
|
||||
}
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
package com.foxinmy.weixin4j.mp.payment.v3;
|
||||
|
||||
import com.foxinmy.weixin4j.mp.payment.ApiResult;
|
||||
import com.foxinmy.weixin4j.mp.payment.TradeType;
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
|
||||
/**
|
||||
* 预生成订单信息
|
||||
*
|
||||
* @className PrePay
|
||||
* @author jy
|
||||
* @date 2014年10月21日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
@XStreamAlias("xml")
|
||||
public class PrePay extends ApiResult {
|
||||
|
||||
private static final long serialVersionUID = -8430005768959715444L;
|
||||
|
||||
@XStreamAlias("trade_type")
|
||||
private TradeType tradeType;// 交易类型JSAPI、NATIVE、APP 非空
|
||||
@XStreamAlias("prepay_id")
|
||||
private String prepayId;// 微信生成的预支付 ID,用于后续接口调用中使用二维码链接 非空
|
||||
@XStreamAlias("code_url")
|
||||
private String codeUrl;// trade_type 为 NATIVE 是有 返回,此参数可直接生成二 维码展示出来进行扫码支付
|
||||
// 可能为空
|
||||
|
||||
public PrePay() {
|
||||
|
||||
}
|
||||
|
||||
public PrePay(String returnCode, String returnMsg) {
|
||||
super(returnCode, returnMsg);
|
||||
}
|
||||
|
||||
public TradeType getTradeType() {
|
||||
return tradeType;
|
||||
}
|
||||
|
||||
public void setTradeType(TradeType tradeType) {
|
||||
this.tradeType = tradeType;
|
||||
}
|
||||
|
||||
public String getPrepayId() {
|
||||
return prepayId;
|
||||
}
|
||||
|
||||
public void setPrepayId(String prepayId) {
|
||||
this.prepayId = prepayId;
|
||||
}
|
||||
|
||||
public String getCodeUrl() {
|
||||
return codeUrl;
|
||||
}
|
||||
|
||||
public void setCodeUrl(String codeUrl) {
|
||||
this.codeUrl = codeUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PrePay [tradeType=" + tradeType + ", prepayId=" + prepayId
|
||||
+ ", codeUrl=" + codeUrl + ", getAppId()=" + getAppId()
|
||||
+ ", getMchId()=" + getMchId() + ", getNonceStr()="
|
||||
+ getNonceStr() + ", getSign()=" + getSign()
|
||||
+ ", getDeviceInfo()=" + getDeviceInfo() + ", toString()="
|
||||
+ super.toString() + ", getReturnCode()=" + getReturnCode()
|
||||
+ ", getReturnMsg()=" + getReturnMsg() + ", getResultCode()="
|
||||
+ getResultCode() + ", getErrCode()=" + getErrCode()
|
||||
+ ", getErrCodeDes()=" + getErrCodeDes() + "]";
|
||||
}
|
||||
}
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
package com.foxinmy.weixin4j.mp.payment.v3;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.foxinmy.weixin4j.mp.payment.ApiResult;
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
import com.thoughtworks.xstream.annotations.XStreamOmitField;
|
||||
|
||||
/**
|
||||
* 退款记录
|
||||
*
|
||||
* @className Refund
|
||||
* @author jy
|
||||
* @date 2014年11月1日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
@XStreamAlias("xml")
|
||||
public class Refund extends ApiResult {
|
||||
|
||||
private static final long serialVersionUID = -2971132874939642721L;
|
||||
|
||||
@XStreamAlias("transaction_id")
|
||||
private String transactionId;// 微信订单号
|
||||
@XStreamAlias("out_trade_no")
|
||||
private String orderNo;// 商户订单号
|
||||
@XStreamAlias("sub_mch_id")
|
||||
private String subMchId; //
|
||||
@XStreamAlias("refund_count")
|
||||
private int count;// 退款笔数
|
||||
@XStreamOmitField
|
||||
private List<RefundDetail> details;
|
||||
|
||||
public String getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
public void setTransactionId(String transactionId) {
|
||||
this.transactionId = transactionId;
|
||||
}
|
||||
|
||||
public String getOrderNo() {
|
||||
return orderNo;
|
||||
}
|
||||
|
||||
public void setOrderNo(String orderNo) {
|
||||
this.orderNo = orderNo;
|
||||
}
|
||||
|
||||
public String getSubMchId() {
|
||||
return subMchId;
|
||||
}
|
||||
|
||||
public void setSubMchId(String subMchId) {
|
||||
this.subMchId = subMchId;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(int count) {
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
public List<RefundDetail> getDetails() {
|
||||
return details;
|
||||
}
|
||||
|
||||
public void setDetails(List<RefundDetail> details) {
|
||||
this.details = details;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Refund [transactionId=" + transactionId + ", subMchId="
|
||||
+ subMchId + ", orderNo=" + orderNo + ", count=" + count
|
||||
+ ", details=" + details + ", getAppId()=" + getAppId()
|
||||
+ ", getMchId()=" + getMchId() + ", getNonceStr()="
|
||||
+ getNonceStr() + ", getSign()=" + getSign()
|
||||
+ ", getDeviceInfo()=" + getDeviceInfo() + ", toString()="
|
||||
+ super.toString() + ", getReturnCode()=" + getReturnCode()
|
||||
+ ", getReturnMsg()=" + getReturnMsg() + ", getResultCode()="
|
||||
+ getResultCode() + ", getErrCode()=" + getErrCode()
|
||||
+ ", getErrCodeDes()=" + getErrCodeDes() + "]";
|
||||
}
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
package com.foxinmy.weixin4j.mp.payment.v3;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.foxinmy.weixin4j.mp.payment.RefundStatus;
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
|
||||
/**
|
||||
* 退款详细
|
||||
*
|
||||
* @className RefundDetail
|
||||
* @author jy
|
||||
* @date 2014年11月2日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class RefundDetail implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 2828640496307351988L;
|
||||
|
||||
@XStreamAlias("out_refund_no")
|
||||
private String outRefundNo; // 商户退款单号
|
||||
@XStreamAlias("refund_id")
|
||||
private String refundId; // 微信退款单号
|
||||
@XStreamAlias("refund_channel")
|
||||
private String refundChannel; // 退款渠道 ORIGINAL—原路退款 BALANCE—退回到余额
|
||||
@XStreamAlias("refund_fee")
|
||||
private int refundFee; // 退款总金额,单位为分,可以做部分退款
|
||||
@XStreamAlias("coupon_refund_fee")
|
||||
private int couponRefundFee; // 现金券退款金额<=退款金额,退款金额-现金券退款金额为现金
|
||||
@XStreamAlias("refund_status")
|
||||
private RefundStatus refundStatus; // 退款状态
|
||||
|
||||
public String getOutRefundNo() {
|
||||
return outRefundNo;
|
||||
}
|
||||
|
||||
public void setOutRefundNo(String outRefundNo) {
|
||||
this.outRefundNo = outRefundNo;
|
||||
}
|
||||
|
||||
public String getRefundId() {
|
||||
return refundId;
|
||||
}
|
||||
|
||||
public void setRefundId(String refundId) {
|
||||
this.refundId = refundId;
|
||||
}
|
||||
|
||||
public String getRefundChannel() {
|
||||
return refundChannel;
|
||||
}
|
||||
|
||||
public void setRefundChannel(String refundChannel) {
|
||||
this.refundChannel = refundChannel;
|
||||
}
|
||||
|
||||
public int getRefundFee() {
|
||||
return refundFee;
|
||||
}
|
||||
|
||||
public void setRefundFee(int refundFee) {
|
||||
this.refundFee = refundFee;
|
||||
}
|
||||
|
||||
public int getCouponRefundFee() {
|
||||
return couponRefundFee;
|
||||
}
|
||||
|
||||
public void setCouponRefundFee(int couponRefundFee) {
|
||||
this.couponRefundFee = couponRefundFee;
|
||||
}
|
||||
|
||||
public RefundStatus getRefundStatus() {
|
||||
return refundStatus;
|
||||
}
|
||||
|
||||
public void setRefundStatus(RefundStatus refundStatus) {
|
||||
this.refundStatus = refundStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RefundDetail [outRefundNo=" + outRefundNo + ", refundId="
|
||||
+ refundId + ", refundChannel=" + refundChannel
|
||||
+ ", refundFee=" + refundFee + ", couponRefundFee="
|
||||
+ couponRefundFee + ", refundStatus=" + refundStatus + "]";
|
||||
}
|
||||
}
|
||||
+434
@@ -0,0 +1,434 @@
|
||||
package com.foxinmy.weixin4j.mp.util;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFCell;
|
||||
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
|
||||
import org.apache.poi.hssf.usermodel.HSSFFont;
|
||||
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
|
||||
import org.apache.poi.hssf.usermodel.HSSFRow;
|
||||
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.hssf.util.HSSFColor;
|
||||
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||
import org.apache.poi.ss.usermodel.Cell;
|
||||
import org.apache.poi.ss.usermodel.CellStyle;
|
||||
import org.apache.poi.ss.usermodel.DateUtil;
|
||||
import org.apache.poi.ss.usermodel.Font;
|
||||
import org.apache.poi.ss.usermodel.Row;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
/**
|
||||
* excel工具类
|
||||
* @className ExcelUtil
|
||||
* @author jy
|
||||
* @date 2014年11月1日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class ExcelUtil {
|
||||
|
||||
/**
|
||||
* 读取Excel2003,2007的内容,第一维数组存储的是一行中格列的值,二维数组存储的是多少个行
|
||||
*
|
||||
* @param file
|
||||
* 输入流
|
||||
* @param fileName
|
||||
* 是2003还是2007 xls:2003,xlsx:2007
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String[][] read(File file) throws Exception {
|
||||
String fileExt = getExtension(file.getName());
|
||||
|
||||
if (null != fileExt && fileExt.toLowerCase().equals("xls")) {// 2003
|
||||
BufferedInputStream in = new BufferedInputStream(
|
||||
new FileInputStream(file));
|
||||
// 打开HSSFWorkbook
|
||||
POIFSFileSystem fs = new POIFSFileSystem(in);
|
||||
Workbook wb = new HSSFWorkbook(fs);
|
||||
in.close();
|
||||
return readExcel(wb);
|
||||
} else if (null != fileExt && fileExt.toLowerCase().equals("xlsx")) {// 2007
|
||||
Workbook wb = new XSSFWorkbook(new FileInputStream(file));
|
||||
return readExcel(wb);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String[][] read4Special(File file, String fileName,
|
||||
int columnSize) throws Exception {
|
||||
String fileExt = getExtension(fileName);
|
||||
|
||||
if (null != fileExt && fileExt.toLowerCase().equals("xls")) {// 2003
|
||||
BufferedInputStream in = new BufferedInputStream(
|
||||
new FileInputStream(file));
|
||||
// 打开HSSFWorkbook
|
||||
POIFSFileSystem fs = new POIFSFileSystem(in);
|
||||
Workbook wb = new HSSFWorkbook(fs);
|
||||
in.close();
|
||||
return readExcel4Special(wb, columnSize);
|
||||
} else if (null != fileExt && fileExt.toLowerCase().equals("xlsx")) {// 2007
|
||||
Workbook wb = new XSSFWorkbook(new FileInputStream(file));
|
||||
return readExcel4Special(wb, columnSize);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取Excel文件中的值
|
||||
*
|
||||
* @param wb
|
||||
* @return String[][]
|
||||
*/
|
||||
private static String[][] readExcel(Workbook wb) throws Exception {
|
||||
List<String[]> result = new ArrayList<String[]>();
|
||||
int rowSize = 0;
|
||||
Cell cell = null;
|
||||
for (int sheetIndex = 0; sheetIndex < wb.getNumberOfSheets(); sheetIndex++) {
|
||||
Sheet st = wb.getSheetAt(sheetIndex);
|
||||
// 第一行为标题,不取
|
||||
for (int rowIndex = 1; rowIndex <= st.getLastRowNum(); rowIndex++) {
|
||||
Row row = st.getRow(rowIndex);
|
||||
if (row == null) {
|
||||
continue;
|
||||
}
|
||||
int tempRowSize = row.getLastCellNum() + 1;
|
||||
if (tempRowSize > rowSize) {
|
||||
rowSize = tempRowSize;
|
||||
}
|
||||
String[] values = new String[rowSize];
|
||||
Arrays.fill(values, "");
|
||||
boolean hasValue = false;
|
||||
for (short columnIndex = 0; columnIndex <= row.getLastCellNum(); columnIndex++) {
|
||||
String value = "";
|
||||
cell = row.getCell(columnIndex);
|
||||
if (cell != null) {
|
||||
// 注意:一定要设成这个,否则可能会出现乱码
|
||||
// cell.setEncoding(HSSFCell.ENCODING_UTF_16);
|
||||
switch (cell.getCellType()) {
|
||||
case Cell.CELL_TYPE_STRING:
|
||||
value = cell.getStringCellValue();
|
||||
break;
|
||||
case Cell.CELL_TYPE_NUMERIC:
|
||||
if (DateUtil.isCellDateFormatted(cell)) {
|
||||
Date date = cell.getDateCellValue();
|
||||
if (date != null) {
|
||||
value = new SimpleDateFormat(
|
||||
"yyyy-MM-dd HH:mm:ss").format(date);
|
||||
} else {
|
||||
value = "";
|
||||
}
|
||||
} else {
|
||||
value = getRightStr(cell.getNumericCellValue()
|
||||
+ "");
|
||||
// value =
|
||||
// String.valueOf(cell.getNumericCellValue());
|
||||
}
|
||||
break;
|
||||
case Cell.CELL_TYPE_FORMULA:
|
||||
// 导入时如果为公式生成的数据则无值
|
||||
if (!("").equals(cell.getStringCellValue())) {
|
||||
value = cell.getStringCellValue();
|
||||
} else {
|
||||
value = cell.getNumericCellValue() + "";
|
||||
}
|
||||
break;
|
||||
case Cell.CELL_TYPE_BLANK:
|
||||
break;
|
||||
case Cell.CELL_TYPE_ERROR:
|
||||
value = "";
|
||||
break;
|
||||
case Cell.CELL_TYPE_BOOLEAN:
|
||||
value = (cell.getBooleanCellValue() == true ? "true"
|
||||
: "false");
|
||||
break;
|
||||
default:
|
||||
value = "";
|
||||
}
|
||||
}
|
||||
if (columnIndex == 0 && value.trim().equals("")) {
|
||||
break;
|
||||
}
|
||||
values[columnIndex] = rightTrim(value);
|
||||
hasValue = true;
|
||||
}
|
||||
if (hasValue) {
|
||||
result.add(values);
|
||||
}
|
||||
}
|
||||
}
|
||||
String[][] returnArray = new String[result.size()][rowSize];
|
||||
for (int i = 0; i < returnArray.length; i++) {
|
||||
returnArray[i] = result.get(i);
|
||||
}
|
||||
return returnArray;
|
||||
}
|
||||
|
||||
/*
|
||||
* 读取excel数据
|
||||
*/
|
||||
private static String[][] readExcel4Special(Workbook wb, int columnSize)
|
||||
throws Exception {
|
||||
List<String[]> result = new ArrayList<String[]>();
|
||||
int rowSize = 0;
|
||||
Cell cell = null;
|
||||
for (int sheetIndex = 0; sheetIndex < wb.getNumberOfSheets(); sheetIndex++) {
|
||||
Sheet st = wb.getSheetAt(sheetIndex);
|
||||
// 第一行为标题,不取
|
||||
for (int rowIndex = 1; rowIndex <= st.getLastRowNum(); rowIndex++) {
|
||||
Row row = st.getRow(rowIndex);
|
||||
if (row == null) {
|
||||
continue;
|
||||
}
|
||||
int tempRowSize = row.getLastCellNum() + 1;
|
||||
if (tempRowSize > rowSize) {
|
||||
rowSize = tempRowSize;
|
||||
}
|
||||
String[] values = new String[columnSize];
|
||||
Arrays.fill(values, "");
|
||||
boolean hasValue = false;
|
||||
for (short columnIndex = 0; columnIndex < columnSize; columnIndex++) {
|
||||
String value = "";
|
||||
cell = row.getCell(columnIndex);
|
||||
if (cell != null) {
|
||||
// 注意:一定要设成这个,否则可能会出现乱码
|
||||
// cell.setEncoding(HSSFCell.ENCODING_UTF_16);
|
||||
switch (cell.getCellType()) {
|
||||
case Cell.CELL_TYPE_STRING:
|
||||
value = cell.getStringCellValue();
|
||||
break;
|
||||
case Cell.CELL_TYPE_NUMERIC:
|
||||
if (DateUtil.isCellDateFormatted(cell)) {
|
||||
Date date = cell.getDateCellValue();
|
||||
if (date != null) {
|
||||
value = new SimpleDateFormat(
|
||||
"yyyy-MM-dd HH:mm:ss").format(date);
|
||||
} else {
|
||||
value = "";
|
||||
}
|
||||
} else {
|
||||
value = getRightStr(cell.getNumericCellValue()
|
||||
+ "");
|
||||
// value =
|
||||
// String.valueOf(cell.getNumericCellValue());
|
||||
}
|
||||
break;
|
||||
case Cell.CELL_TYPE_FORMULA:
|
||||
// 导入时如果为公式生成的数据则无值
|
||||
if (!("").equals(cell.getStringCellValue())) {
|
||||
value = cell.getStringCellValue();
|
||||
} else {
|
||||
value = cell.getNumericCellValue() + "";
|
||||
}
|
||||
break;
|
||||
case Cell.CELL_TYPE_BLANK:
|
||||
break;
|
||||
case Cell.CELL_TYPE_ERROR:
|
||||
value = "";
|
||||
break;
|
||||
case Cell.CELL_TYPE_BOOLEAN:
|
||||
value = (cell.getBooleanCellValue() == true ? "true"
|
||||
: "false");
|
||||
break;
|
||||
default:
|
||||
value = "";
|
||||
}
|
||||
} else {
|
||||
value = "";
|
||||
}
|
||||
if (columnIndex == 0 && value.trim().equals("")) {
|
||||
break;
|
||||
}
|
||||
values[columnIndex] = rightTrim(value);
|
||||
hasValue = true;
|
||||
}
|
||||
if (hasValue) {
|
||||
result.add(values);
|
||||
}
|
||||
}
|
||||
}
|
||||
String[][] returnArray = new String[result.size()][columnSize];
|
||||
for (int i = 0; i < returnArray.length; i++) {
|
||||
returnArray[i] = result.get(i);
|
||||
}
|
||||
return returnArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* double 类型数据转换
|
||||
*
|
||||
* @param sNum
|
||||
* @return
|
||||
*/
|
||||
private static String getRightStr(String sNum) {
|
||||
DecimalFormat decimalFormat = new DecimalFormat("#.000000");
|
||||
|
||||
String resultStr = decimalFormat.format(new Double(sNum));
|
||||
if (resultStr.equals(".000000"))
|
||||
return String.valueOf(0d);
|
||||
if (resultStr.matches("^[-+]?\\d+\\.[0]+$")) {
|
||||
resultStr = resultStr.substring(0, resultStr.indexOf("."));
|
||||
}
|
||||
return resultStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 去掉字符串右边的空格
|
||||
*
|
||||
* @param str要处理的字符串
|
||||
* @return 处理后的字符串
|
||||
*/
|
||||
|
||||
public static String rightTrim(String str) {
|
||||
if (str == null) {
|
||||
return "";
|
||||
}
|
||||
int length = str.length();
|
||||
for (int i = length - 1; i >= 0; i--) {
|
||||
if (str.charAt(i) != 0x20) {
|
||||
break;
|
||||
}
|
||||
length--;
|
||||
}
|
||||
return str.substring(0, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件扩展名
|
||||
*
|
||||
* @param filename
|
||||
* @return
|
||||
*/
|
||||
private static String getExtension(String filename) {
|
||||
if ((filename != null) && (filename.length() > 0)) {
|
||||
int i = filename.lastIndexOf('.');
|
||||
|
||||
if ((i > 0) && (i < (filename.length() - 1))) {
|
||||
return filename.substring(i + 1);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static void list2excel(HSSFWorkbook workbook, List<String> headers,
|
||||
Collection<?> datas) {
|
||||
|
||||
JSONArray arrays = null; //
|
||||
|
||||
String[] strings = null; //
|
||||
|
||||
HSSFSheet sheet = null; // 工作表
|
||||
|
||||
HSSFRow row = null; // 单元行
|
||||
|
||||
HSSFCell cell = null; // 单元格
|
||||
|
||||
HSSFRichTextString richText = null; // 单元格内容
|
||||
|
||||
sheet = workbook.getSheetAt(0); // 创建表格
|
||||
|
||||
int rowNum = sheet.getLastRowNum(); // 数据行号
|
||||
if (rowNum != 0) {
|
||||
rowNum++;
|
||||
sheet.createRow(rowNum);
|
||||
rowNum++;
|
||||
}
|
||||
|
||||
HSSFCellStyle cellStyle = workbook.createCellStyle();// 创建单元格样式(用于表头)
|
||||
cellStyle.setFillForegroundColor(HSSFColor.SKY_BLUE.index);// 设置单元格样式
|
||||
cellStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
|
||||
cellStyle.setBorderBottom(CellStyle.BORDER_THIN);
|
||||
cellStyle.setBorderLeft(CellStyle.BORDER_THIN);
|
||||
cellStyle.setBorderRight(CellStyle.BORDER_THIN);
|
||||
cellStyle.setBorderTop(CellStyle.BORDER_THIN);
|
||||
cellStyle.setAlignment(CellStyle.ALIGN_CENTER);
|
||||
|
||||
HSSFFont f = workbook.createFont();
|
||||
f.setColor(HSSFColor.BLUE.index);
|
||||
|
||||
HSSFFont font = workbook.createFont(); // 创建字体
|
||||
font.setColor(HSSFColor.VIOLET.index); // 设置字体属性
|
||||
font.setFontHeightInPoints((short) 12);
|
||||
font.setBoldweight(Font.BOLDWEIGHT_BOLD);
|
||||
|
||||
cellStyle.setFont(font); // 设置单元格的字体
|
||||
|
||||
row = sheet.createRow(rowNum); // 创建表格标题行
|
||||
|
||||
for (int i = 0; i < headers.size(); i++) {
|
||||
// 填充标题行的单元格数据
|
||||
cell = row.createCell(i);
|
||||
cell.setCellStyle(cellStyle);
|
||||
richText = new HSSFRichTextString(headers.get(i));
|
||||
cell.setCellValue(richText);
|
||||
sheet.autoSizeColumn(i);
|
||||
}
|
||||
rowNum++;
|
||||
HSSFCellStyle contentStyle = workbook.createCellStyle();// 创建单元格样式(用于表内容)
|
||||
contentStyle.setFillForegroundColor(HSSFColor.LIGHT_YELLOW.index);
|
||||
contentStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
|
||||
contentStyle.setBorderBottom(CellStyle.BORDER_THIN);
|
||||
contentStyle.setBorderLeft(CellStyle.BORDER_THIN);
|
||||
contentStyle.setBorderRight(CellStyle.BORDER_THIN);
|
||||
contentStyle.setBorderTop(CellStyle.BORDER_THIN);
|
||||
contentStyle.setAlignment(CellStyle.ALIGN_CENTER);
|
||||
contentStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
|
||||
|
||||
font = workbook.createFont(); // 创建字体
|
||||
font.setBoldweight(Font.BOLDWEIGHT_NORMAL); // 设置字体粗细
|
||||
contentStyle.setFont(font); // 设置单元格的字体样式
|
||||
|
||||
int j = 0;
|
||||
for (Object obj : datas) {
|
||||
row = sheet.getRow(rowNum);
|
||||
if (row == null) {
|
||||
row = sheet.createRow(rowNum);
|
||||
}
|
||||
if (obj instanceof JSONArray) {
|
||||
arrays = (JSONArray) obj;
|
||||
// 只能是 JSONObject
|
||||
for (int i = 0; i < arrays.size(); i++) {
|
||||
JSONObject jsonObj = arrays.getJSONObject(i);
|
||||
cell = row.createCell(i);
|
||||
cell.setCellStyle(contentStyle);
|
||||
String val = jsonObj.getString(headers.get(i));
|
||||
richText = new HSSFRichTextString(val);
|
||||
richText.applyFont(f);
|
||||
cell.setCellValue(richText);
|
||||
}
|
||||
rowNum++;
|
||||
} else if (obj instanceof String[]) {
|
||||
strings = (String[]) obj;
|
||||
for (int i = 0; i < strings.length; i++) {
|
||||
cell = row.createCell(i);
|
||||
cell.setCellStyle(contentStyle);
|
||||
richText = new HSSFRichTextString(strings[i]);
|
||||
richText.applyFont(f);
|
||||
cell.setCellValue(richText);
|
||||
}
|
||||
rowNum++;
|
||||
} else {
|
||||
cell = row.createCell(j);
|
||||
cell.setCellStyle(contentStyle);
|
||||
richText = new HSSFRichTextString((String) obj);
|
||||
richText.applyFont(f);
|
||||
cell.setCellValue(richText);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
# \u7f16\u7801\u6d4b\u8bd5\u4e4b\u7528 \u6b63\u5f0f\u73af\u5883\u4e0bcopy\u4e00\u4efd\u5230classpath
|
||||
# \u516c\u4f17\u53f7\u4fe1\u606f
|
||||
account={"appId":"wx4ab8f8de58159a57","appSecret":"1d4eb0f4bf556aaed539f30ed05ca795",\
|
||||
"token":"\u5f00\u653e\u8005\u7684token \u975e\u5fc5\u987b","openId":"\u516c\u4f17\u53f7\u7684openid \u975e\u5fc5\u987b",\
|
||||
"mchId":"V3.x\u7248\u672c\u4e0b\u7684\u5fae\u4fe1\u5546\u6237\u53f7",\
|
||||
"partnerId":"\u8d22\u4ed8\u901a\u7684\u5546\u6237\u53f7","partnerKey":"\u8d22\u4ed8\u901a\u5546\u6237\u6743\u9650\u5bc6\u94a5Key",\
|
||||
"paySignKey":"\u5fae\u4fe1\u652f\u4ed8\u4e2d\u8c03\u7528API\u7684\u5bc6\u94a5"}
|
||||
|
||||
# \u4f7f\u7528FileTokenHolder\u65f6token\u7684\u5b58\u653e\u8def\u5f84
|
||||
token_path=/tmp/weixin/token
|
||||
# \u4e8c\u7ef4\u7801\u4fdd\u5b58\u8def\u5f84
|
||||
qr_path=/tmp/weixin/qr
|
||||
# \u5a92\u4f53\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84
|
||||
media_path=/tmp/weixin/media
|
||||
# \u5bf9\u8d26\u5355\u4fdd\u5b58\u8def\u5f84
|
||||
bill_path=/tmp/weixin/bill
|
||||
+6
-6
@@ -7,7 +7,7 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.BaseResult;
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
import com.foxinmy.weixin4j.mp.api.GroupApi;
|
||||
import com.foxinmy.weixin4j.mp.model.Group;
|
||||
|
||||
@@ -24,7 +24,7 @@ public class GroupTest extends TokenTest {
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
groupApi = new GroupApi(tokenApi);
|
||||
groupApi = new GroupApi(tokenHolder);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -50,14 +50,14 @@ public class GroupTest extends TokenTest {
|
||||
|
||||
@Test
|
||||
public void modify() throws WeixinException {
|
||||
BaseResult result = groupApi.modifyGroup(100, "my1");
|
||||
Assert.assertEquals(0, result.getErrcode());
|
||||
JsonResult result = groupApi.modifyGroup(100, "my1");
|
||||
Assert.assertEquals(0, result.getCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void move() throws WeixinException {
|
||||
BaseResult result = groupApi.moveGroup("owGBft_vbBbOaQOmpEUE4xDLeRSU",
|
||||
JsonResult result = groupApi.moveGroup("owGBft_vbBbOaQOmpEUE4xDLeRSU",
|
||||
100);
|
||||
Assert.assertEquals(0, result.getErrcode());
|
||||
Assert.assertEquals(0, result.getCode());
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -26,7 +26,7 @@ public class MediaTest extends TokenTest {
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
mediaApi = new MediaApi(tokenApi);
|
||||
mediaApi = new MediaApi(tokenHolder);
|
||||
}
|
||||
|
||||
@Test
|
||||
+6
-6
@@ -8,7 +8,7 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.BaseResult;
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
import com.foxinmy.weixin4j.mp.api.MenuApi;
|
||||
import com.foxinmy.weixin4j.mp.model.Button;
|
||||
import com.foxinmy.weixin4j.type.ButtonType;
|
||||
@@ -28,7 +28,7 @@ public class MenuTest extends TokenTest {
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
menuApi = new MenuApi(tokenApi);
|
||||
menuApi = new MenuApi(tokenHolder);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -43,8 +43,8 @@ public class MenuTest extends TokenTest {
|
||||
b = new Button("qq", "http://www.qq.com");
|
||||
btnList.add(b);
|
||||
|
||||
BaseResult result = menuApi.createMenu(btnList);
|
||||
Assert.assertEquals(0, result.getErrcode());
|
||||
JsonResult result = menuApi.createMenu(btnList);
|
||||
Assert.assertEquals(0, result.getCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -58,7 +58,7 @@ public class MenuTest extends TokenTest {
|
||||
|
||||
@Test
|
||||
public void delete() throws WeixinException {
|
||||
BaseResult result = menuApi.deleteMenu();
|
||||
Assert.assertEquals(0, result.getErrcode());
|
||||
JsonResult result = menuApi.deleteMenu();
|
||||
Assert.assertEquals(0, result.getCode());
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -25,7 +25,7 @@ public class QRTest extends TokenTest {
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
qrApi = new QrApi(tokenApi);
|
||||
qrApi = new QrApi(tokenHolder);
|
||||
}
|
||||
|
||||
@Test
|
||||
+3
-3
@@ -18,15 +18,15 @@ import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
*/
|
||||
public class TokenTest {
|
||||
|
||||
protected TokenHolder tokenApi;
|
||||
protected TokenHolder tokenHolder;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
tokenApi = new FileTokenHolder();
|
||||
tokenHolder = new FileTokenHolder();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() throws WeixinException {
|
||||
Assert.assertNotNull(tokenApi.getToken());
|
||||
Assert.assertNotNull(tokenHolder.getToken());
|
||||
}
|
||||
}
|
||||
+5
-4
@@ -7,7 +7,7 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.BaseResult;
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
import com.foxinmy.weixin4j.mp.api.UserApi;
|
||||
import com.foxinmy.weixin4j.mp.model.User;
|
||||
|
||||
@@ -24,13 +24,14 @@ public class UserTest extends TokenTest {
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
userApi = new UserApi(tokenApi);
|
||||
userApi = new UserApi(tokenHolder);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getUser() throws WeixinException {
|
||||
User user = userApi.getUser("owGBft_vbBbOaQOmpEUE4xDLeRSU");
|
||||
Assert.assertNotNull(user);
|
||||
System.out.println(user);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -44,8 +45,8 @@ public class UserTest extends TokenTest {
|
||||
|
||||
@Test
|
||||
public void remark() throws WeixinException {
|
||||
BaseResult result = userApi.remarkUserName(
|
||||
JsonResult result = userApi.remarkUserName(
|
||||
"owGBft_vbBbOaQOmpEUE4xDLeRSU", "foo");
|
||||
Assert.assertEquals(0, result.getErrcode());
|
||||
Assert.assertEquals(0, result.getCode());
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -10,7 +10,7 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.BaseResult;
|
||||
import com.foxinmy.weixin4j.http.JsonResult;
|
||||
import com.foxinmy.weixin4j.mp.api.MassApi;
|
||||
import com.foxinmy.weixin4j.mp.api.MediaApi;
|
||||
import com.foxinmy.weixin4j.mp.model.MpArticle;
|
||||
@@ -32,8 +32,8 @@ public class MassMsgTest extends TokenTest {
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
this.massApi = new MassApi(tokenApi);
|
||||
this.mediaApi = new MediaApi(tokenApi);
|
||||
this.massApi = new MassApi(tokenHolder);
|
||||
this.mediaApi = new MediaApi(tokenHolder);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -87,7 +87,7 @@ public class MassMsgTest extends TokenTest {
|
||||
|
||||
@Test
|
||||
public void deleteMass() throws WeixinException {
|
||||
BaseResult result = massApi.deleteMassNews("34182");
|
||||
Assert.assertEquals(0, result.getErrcode());
|
||||
JsonResult result = massApi.deleteMassNews("34182");
|
||||
Assert.assertEquals(0, result.getCode());
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user