Browse Source

Merge branch 'develop'

master
Daniel Qian 9 years ago
parent
commit
f0432e6930
17 changed files with 325 additions and 43 deletions
  1. +1
    -0
      .gitignore
  2. +2
    -2
      README.md
  3. +1
    -1
      pom.xml
  4. +1
    -1
      weixin-java-common/pom.xml
  5. +1
    -1
      weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java
  6. +5
    -22
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/SHA1.java
  7. +32
    -2
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/WxCryptUtil.java
  8. +1
    -1
      weixin-java-cp/pom.xml
  9. +1
    -1
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java
  10. +18
    -7
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java
  11. +1
    -1
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpTagAPITest.java
  12. +1
    -1
      weixin-java-mp/pom.xml
  13. +4
    -0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpConfigStorage.java
  14. +22
    -0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java
  15. +42
    -0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java
  16. +94
    -3
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java
  17. +98
    -0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpPrepayIdResult.java

+ 1
- 0
.gitignore View File

@@ -19,3 +19,4 @@ target
sw-pom.xml sw-pom.xml
*.iml *.iml
test-config.xml test-config.xml
.idea

+ 2
- 2
README.md View File

@@ -17,7 +17,7 @@ weixin-java-tools
<dependency> <dependency>
<groupId>me.chanjar</groupId> <groupId>me.chanjar</groupId>
<artifactId>weixin-java-mp</artifactId> <artifactId>weixin-java-mp</artifactId>
<version>1.1.4</version>
<version>1.1.5</version>
</dependency> </dependency>
``` ```


@@ -27,7 +27,7 @@ weixin-java-tools
<dependency> <dependency>
<groupId>me.chanjar</groupId> <groupId>me.chanjar</groupId>
<artifactId>weixin-java-cp</artifactId> <artifactId>weixin-java-cp</artifactId>
<version>1.1.4</version>
<version>1.1.5</version>
</dependency> </dependency>
``` ```




+ 1
- 1
pom.xml View File

@@ -5,7 +5,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>me.chanjar</groupId> <groupId>me.chanjar</groupId>
<artifactId>weixin-java-parent</artifactId> <artifactId>weixin-java-parent</artifactId>
<version>1.1.4</version>
<version>1.1.5</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>WeiXin Java Tools - Parent</name> <name>WeiXin Java Tools - Parent</name>
<description>微信公众号、企业号上级POM</description> <description>微信公众号、企业号上级POM</description>


+ 1
- 1
weixin-java-common/pom.xml View File

@@ -6,7 +6,7 @@
<parent> <parent>
<groupId>me.chanjar</groupId> <groupId>me.chanjar</groupId>
<artifactId>weixin-java-parent</artifactId> <artifactId>weixin-java-parent</artifactId>
<version>1.1.4</version>
<version>1.1.5</version>
</parent> </parent>


<artifactId>weixin-java-common</artifactId> <artifactId>weixin-java-common</artifactId>


+ 1
- 1
weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java View File

@@ -105,7 +105,7 @@ public class WxConsts {
/////////////////////// ///////////////////////
public static final String FILE_JPG = "jpeg"; public static final String FILE_JPG = "jpeg";
public static final String FILE_MP3 = "mp3"; public static final String FILE_MP3 = "mp3";
public static final String FILE_ARM = "arm";
public static final String FILE_AMR = "amr";
public static final String FILE_MP4 = "mp4"; public static final String FILE_MP4 = "mp4";






+ 5
- 22
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/SHA1.java View File

@@ -1,5 +1,7 @@
package me.chanjar.weixin.common.util.crypto; package me.chanjar.weixin.common.util.crypto;


import org.apache.commons.codec.digest.DigestUtils;

import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.Arrays; import java.util.Arrays;
@@ -21,7 +23,7 @@ public class SHA1 {
for (String a : arr) { for (String a : arr) {
sb.append(a); sb.append(a);
} }
return genStr(sb.toString());
return DigestUtils.sha1Hex(sb.toString());
} }


/** /**
@@ -40,25 +42,6 @@ public class SHA1 {
sb.append('&'); sb.append('&');
} }
} }
return genStr(sb.toString());
}

public static String genStr(String str) throws NoSuchAlgorithmException {
MessageDigest sha1 = MessageDigest.getInstance("SHA1");
sha1.update(str.getBytes());
byte[] output = sha1.digest();
return bytesToHex(output);
return DigestUtils.sha1Hex(sb.toString());
} }

protected static String bytesToHex(byte[] b) {
char hexDigit[] = { '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
StringBuffer buf = new StringBuffer();
for (int j = 0; j < b.length; j++) {
buf.append(hexDigit[(b[j] >> 4) & 0x0f]);
buf.append(hexDigit[b[j] & 0x0f]);
}
return buf.toString();
}

}
}

+ 32
- 2
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/WxCryptUtil.java View File

@@ -14,6 +14,7 @@
package me.chanjar.weixin.common.util.crypto; package me.chanjar.weixin.common.util.crypto;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
@@ -27,8 +28,7 @@ import javax.xml.parsers.ParserConfigurationException;
import java.io.StringReader; import java.io.StringReader;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Random;
import java.util.*;
public class WxCryptUtil { public class WxCryptUtil {
@@ -224,6 +224,36 @@ public class WxCryptUtil {
} }
/**
* 微信公众号支付签名算法(详见:http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=4_3)
* @param packageParams 原始参数
* @param signKey 加密Key(即 商户Key)
* @param charset 编码
* @return 签名字符串
*/
public static String createSign(Map<String, String> packageParams, String signKey) {
SortedMap<String, String> sortedMap = new TreeMap<String, String>();
sortedMap.putAll(packageParams);
List<String> keys = new ArrayList<String>(packageParams.keySet());
Collections.sort(keys);
StringBuffer toSign = new StringBuffer();
for (String key : keys) {
String value = packageParams.get(key);
if (null != value && !"".equals(value) && !"sign".equals(key)
&& !"key".equals(key)) {
toSign.append(key + "=" + value + "&");
}
}
toSign.append("key=" + signKey);
System.out.println(toSign.toString());
String sign = DigestUtils.md5Hex(toSign.toString())
.toUpperCase();
return sign;
}
/** /**
* 将一个数字转换成生成4个字节的网络字节序bytes数组 * 将一个数字转换成生成4个字节的网络字节序bytes数组
* *


+ 1
- 1
weixin-java-cp/pom.xml View File

@@ -6,7 +6,7 @@
<parent> <parent>
<groupId>me.chanjar</groupId> <groupId>me.chanjar</groupId>
<artifactId>weixin-java-parent</artifactId> <artifactId>weixin-java-parent</artifactId>
<version>1.1.4</version>
<version>1.1.5</version>
</parent> </parent>


<artifactId>weixin-java-cp</artifactId> <artifactId>weixin-java-cp</artifactId>


+ 1
- 1
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java View File

@@ -399,7 +399,7 @@ public interface WxCpService {
* @param tagId * @param tagId
* @param userIds * @param userIds
*/ */
void tagAddUsers(String tagId, List<String> userIds) throws WxErrorException;
void tagAddUsers(String tagId, List<String> userIds, List<String> partyIds) throws WxErrorException;


/** /**
* <pre> * <pre>


+ 18
- 7
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java View File

@@ -271,7 +271,8 @@ public class WxCpServiceImpl implements WxCpService {
return WxCpGsonBuilder.INSTANCE.create() return WxCpGsonBuilder.INSTANCE.create()
.fromJson( .fromJson(
tmpJsonElement.getAsJsonObject().get("department"), tmpJsonElement.getAsJsonObject().get("department"),
new TypeToken<List<WxCpDepart>>() { }.getType()
new TypeToken<List<WxCpDepart>>() {
}.getType()
); );
} }


@@ -389,7 +390,8 @@ public class WxCpServiceImpl implements WxCpService {
return WxCpGsonBuilder.INSTANCE.create() return WxCpGsonBuilder.INSTANCE.create()
.fromJson( .fromJson(
tmpJsonElement.getAsJsonObject().get("taglist"), tmpJsonElement.getAsJsonObject().get("taglist"),
new TypeToken<List<WxCpTag>>() { }.getType()
new TypeToken<List<WxCpTag>>() {
}.getType()
); );
} }


@@ -406,15 +408,24 @@ public class WxCpServiceImpl implements WxCpService {
} }


@Override @Override
public void tagAddUsers(String tagId, List<String> userIds) throws WxErrorException {
public void tagAddUsers(String tagId, List<String> userIds, List<String> partyIds) throws WxErrorException {
String url = "https://qyapi.weixin.qq.com/cgi-bin/tag/addtagusers"; String url = "https://qyapi.weixin.qq.com/cgi-bin/tag/addtagusers";
JsonObject jsonObject = new JsonObject(); JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("tagid", tagId); jsonObject.addProperty("tagid", tagId);
JsonArray jsonArray = new JsonArray();
for (String userId : userIds) {
jsonArray.add(new JsonPrimitive(userId));
if (userIds != null) {
JsonArray jsonArray = new JsonArray();
for (String userId : userIds) {
jsonArray.add(new JsonPrimitive(userId));
}
jsonObject.add("userlist", jsonArray);
}
if (partyIds != null) {
JsonArray jsonArray = new JsonArray();
for (String userId : partyIds) {
jsonArray.add(new JsonPrimitive(userId));
}
jsonObject.add("partylist", jsonArray);
} }
jsonObject.add("userlist", jsonArray);
post(url, jsonObject.toString()); post(url, jsonObject.toString());
} }




+ 1
- 1
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpTagAPITest.java View File

@@ -42,7 +42,7 @@ public class WxCpTagAPITest {
public void testTagAddUsers() throws Exception { public void testTagAddUsers() throws Exception {
List<String> userIds = new ArrayList<String>(); List<String> userIds = new ArrayList<String>();
userIds.add(((ApiTestModule.WxXmlCpInMemoryConfigStorage)configStorage).getUserId()); userIds.add(((ApiTestModule.WxXmlCpInMemoryConfigStorage)configStorage).getUserId());
wxService.tagAddUsers(tagId, userIds);
wxService.tagAddUsers(tagId, userIds, null);
} }


@Test(dependsOnMethods = "testTagAddUsers") @Test(dependsOnMethods = "testTagAddUsers")


+ 1
- 1
weixin-java-mp/pom.xml View File

@@ -6,7 +6,7 @@
<parent> <parent>
<groupId>me.chanjar</groupId> <groupId>me.chanjar</groupId>
<artifactId>weixin-java-parent</artifactId> <artifactId>weixin-java-parent</artifactId>
<version>1.1.4</version>
<version>1.1.5</version>
</parent> </parent>
<artifactId>weixin-java-mp</artifactId> <artifactId>weixin-java-mp</artifactId>
<name>WeiXin Java Tools - MP</name> <name>WeiXin Java Tools - MP</name>


+ 4
- 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpConfigStorage.java View File

@@ -50,6 +50,10 @@ public interface WxMpConfigStorage {


public String getSecret(); public String getSecret();


public String getPartnerId();

public String getPartnerKey();

public String getToken(); public String getToken();


public String getAesKey(); public String getAesKey();


+ 22
- 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java View File

@@ -11,6 +11,8 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage {


protected volatile String appId; protected volatile String appId;
protected volatile String secret; protected volatile String secret;
protected volatile String partnerId;
protected volatile String partnerKey;
protected volatile String token; protected volatile String token;
protected volatile String accessToken; protected volatile String accessToken;
protected volatile String aesKey; protected volatile String aesKey;
@@ -168,6 +170,8 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage {
"appId='" + appId + '\'' + "appId='" + appId + '\'' +
", secret='" + secret + '\'' + ", secret='" + secret + '\'' +
", token='" + token + '\'' + ", token='" + token + '\'' +
", partnerId='" + partnerId + '\'' +
", partnerKey='" + partnerKey + '\'' +
", accessToken='" + accessToken + '\'' + ", accessToken='" + accessToken + '\'' +
", aesKey='" + aesKey + '\'' + ", aesKey='" + aesKey + '\'' +
", expiresTime=" + expiresTime + ", expiresTime=" + expiresTime +
@@ -179,4 +183,22 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage {
", jsapiTicketExpiresTime='" + jsapiTicketExpiresTime + '\'' + ", jsapiTicketExpiresTime='" + jsapiTicketExpiresTime + '\'' +
'}'; '}';
} }

@Override
public String getPartnerId() {
return partnerId;
}

public void setPartnerId(String partnerId) {
this.partnerId = partnerId;
}

@Override
public String getPartnerKey() {
return partnerKey;
}

public void setPartnerKey(String partnerKey) {
this.partnerKey = partnerKey;
}
} }

+ 42
- 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java View File

@@ -11,9 +11,11 @@ import me.chanjar.weixin.mp.bean.result.*;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map;


/** /**
* 微信API的Service * 微信API的Service
@@ -332,6 +334,18 @@ public interface WxMpService {
*/ */
public WxMpQrCodeTicket qrCodeCreateLastTicket(int scene_id) throws WxErrorException; public WxMpQrCodeTicket qrCodeCreateLastTicket(int scene_id) throws WxErrorException;


/**
* <pre>
* 换取永久字符串二维码ticket
* 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=生成带参数的二维码
* </pre>
*
* @param scene_str 参数。字符串类型长度现在为1到64
* @return
* @throws WxErrorException
*/
public WxMpQrCodeTicket qrCodeCreateLastTicket(String scene_str) throws WxErrorException;

/** /**
* <pre> * <pre>
* 换取二维码图片文件,jpg格式 * 换取二维码图片文件,jpg格式
@@ -528,4 +542,32 @@ public interface WxMpService {
*/ */
void setMaxRetryTimes(int maxRetryTimes); void setMaxRetryTimes(int maxRetryTimes);


/**
* 统一下单(详见http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=9_1)
* 在发起微信支付前,需要调用统一下单接口,获取"预支付交易会话标识"
* @param openId 支付人openId
* @param outTradeNo 商户端对应订单号
* @param amt 金额(单位元)
* @param body 商品描述
* @param tradeType 交易类型 JSAPI,NATIVE,APP,WAP
* @param ip 发起支付的客户端IP
* @param notifyUrl 通知地址
* @return
*/
WxMpPrepayIdResult getPrepayId(String openId, String outTradeNo, double amt, String body, String tradeType, String ip, String notifyUrl);

/**
* 该接口调用“统一下单”接口,并拼装JSSDK发起支付请求需要的参数
* 详见http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E5.8F.91.E8.B5.B7.E4.B8.80.E4.B8.AA.E5.BE.AE.E4.BF.A1.E6.94.AF.E4.BB.98.E8.AF.B7.E6.B1.82
* @param openId 支付人openId
* @param outTradeNo 商户端对应订单号
* @param amt 金额(单位元)
* @param body 商品描述
* @param tradeType 交易类型 JSAPI,NATIVE,APP,WAP
* @param ip 发起支付的客户端IP
* @param notifyUrl 通知地址
* @return
*/
Map<String, String> getJSSDKPayInfo(String openId, String outTradeNo, double amt, String body, String tradeType, String ip, String notifyUrl);

} }

+ 94
- 3
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java View File

@@ -6,6 +6,7 @@ import com.google.gson.JsonObject;
import com.google.gson.internal.Streams; import com.google.gson.internal.Streams;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonReader;
import com.thoughtworks.xstream.XStream;
import me.chanjar.weixin.common.bean.WxAccessToken; import me.chanjar.weixin.common.bean.WxAccessToken;
import me.chanjar.weixin.common.bean.WxMenu; import me.chanjar.weixin.common.bean.WxMenu;
import me.chanjar.weixin.common.bean.WxJsapiSignature; import me.chanjar.weixin.common.bean.WxJsapiSignature;
@@ -17,13 +18,16 @@ import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.common.util.RandomUtils; import me.chanjar.weixin.common.util.RandomUtils;
import me.chanjar.weixin.common.util.StringUtils; import me.chanjar.weixin.common.util.StringUtils;
import me.chanjar.weixin.common.util.crypto.SHA1; import me.chanjar.weixin.common.util.crypto.SHA1;
import me.chanjar.weixin.common.util.crypto.WxCryptUtil;
import me.chanjar.weixin.common.util.fs.FileUtils; import me.chanjar.weixin.common.util.fs.FileUtils;
import me.chanjar.weixin.common.util.http.*; import me.chanjar.weixin.common.util.http.*;
import me.chanjar.weixin.common.util.json.GsonHelper; import me.chanjar.weixin.common.util.json.GsonHelper;
import me.chanjar.weixin.common.util.xml.XStreamInitializer;
import me.chanjar.weixin.mp.bean.*; import me.chanjar.weixin.mp.bean.*;
import me.chanjar.weixin.mp.bean.result.*; import me.chanjar.weixin.mp.bean.result.*;
import me.chanjar.weixin.mp.util.http.QrCodeRequestExecutor; import me.chanjar.weixin.mp.util.http.QrCodeRequestExecutor;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
import org.apache.http.Consts;
import org.apache.http.HttpHost; import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope; import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.auth.UsernamePasswordCredentials;
@@ -32,6 +36,8 @@ import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.RequestConfig; import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.BasicResponseHandler; import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpClient;
@@ -43,10 +49,9 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.StringReader; import java.io.StringReader;
import java.math.BigDecimal;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.*;


public class WxMpServiceImpl implements WxMpService { public class WxMpServiceImpl implements WxMpService {


@@ -332,6 +337,19 @@ public class WxMpServiceImpl implements WxMpService {
String responseContent = execute(new SimplePostRequestExecutor(), url, json.toString()); String responseContent = execute(new SimplePostRequestExecutor(), url, json.toString());
return WxMpQrCodeTicket.fromJson(responseContent); return WxMpQrCodeTicket.fromJson(responseContent);
} }

public WxMpQrCodeTicket qrCodeCreateLastTicket(String scene_str) throws WxErrorException {
String url = "https://api.weixin.qq.com/cgi-bin/qrcode/create";
JsonObject json = new JsonObject();
json.addProperty("action_name", "QR_LIMIT_STR_SCENE");
JsonObject actionInfo = new JsonObject();
JsonObject scene = new JsonObject();
scene.addProperty("scene_str", scene_str);
actionInfo.add("scene", scene);
json.add("action_info", actionInfo);
String responseContent = execute(new SimplePostRequestExecutor(), url, json.toString());
return WxMpQrCodeTicket.fromJson(responseContent);
}
public File qrCodePicture(WxMpQrCodeTicket ticket) throws WxErrorException { public File qrCodePicture(WxMpQrCodeTicket ticket) throws WxErrorException {
String url = "https://mp.weixin.qq.com/cgi-bin/showqrcode"; String url = "https://mp.weixin.qq.com/cgi-bin/showqrcode";
@@ -613,4 +631,77 @@ public class WxMpServiceImpl implements WxMpService {
this.maxRetryTimes = maxRetryTimes; this.maxRetryTimes = maxRetryTimes;
} }


@Override
public WxMpPrepayIdResult getPrepayId(String openId, String outTradeNo, double amt, String body, String tradeType, String ip, String callbackUrl) {
String nonce_str = System.currentTimeMillis() + "";

SortedMap<String, String> packageParams = new TreeMap<String, String>();
packageParams.put("appid", wxMpConfigStorage.getAppId());
packageParams.put("mch_id", wxMpConfigStorage.getPartnerId());
packageParams.put("nonce_str", nonce_str);
packageParams.put("body", body);
packageParams.put("out_trade_no", outTradeNo);

packageParams.put("total_fee", (int)(amt*100) + "");
packageParams.put("spbill_create_ip", ip);
packageParams.put("notify_url", callbackUrl);
packageParams.put("trade_type", tradeType);
packageParams.put("openid", openId);

String sign = WxCryptUtil.createSign(packageParams, wxMpConfigStorage.getPartnerKey());
String xml = "<xml>" +
"<appid>" + wxMpConfigStorage.getAppId() + "</appid>" +
"<mch_id>" + wxMpConfigStorage.getPartnerId() + "</mch_id>" +
"<nonce_str>" + nonce_str + "</nonce_str>" +
"<sign>" + sign + "</sign>" +
"<body><![CDATA[" + body + "]]></body>" +
"<out_trade_no>" + outTradeNo + "</out_trade_no>" +
"<total_fee>" + packageParams.get("total_fee") + "</total_fee>" +
"<spbill_create_ip>" + ip + "</spbill_create_ip>" +
"<notify_url>" + callbackUrl + "</notify_url>" +
"<trade_type>" + tradeType + "</trade_type>" +
"<openid>" + openId + "</openid>" +
"</xml>";

HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/pay/unifiedorder");
if (httpProxy != null) {
RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build();
httpPost.setConfig(config);
}

StringEntity entity = new StringEntity(xml, Consts.UTF_8);
httpPost.setEntity(entity);
try {
CloseableHttpResponse response = httpClient.execute(httpPost);
String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response);
XStream xstream = XStreamInitializer.getInstance();
xstream.alias("xml", WxMpPrepayIdResult.class);
WxMpPrepayIdResult wxMpPrepayIdResult = (WxMpPrepayIdResult) xstream.fromXML(responseContent);
return wxMpPrepayIdResult;
} catch (IOException e) {
e.printStackTrace();
}
return new WxMpPrepayIdResult();
}

@Override
public Map<String, String> getJSSDKPayInfo(String openId, String outTradeNo, double amt, String body, String tradeType, String ip, String callbackUrl) {
WxMpPrepayIdResult wxMpPrepayIdResult = getPrepayId(openId, outTradeNo, amt, body, tradeType, ip, callbackUrl);
String prepayId = wxMpPrepayIdResult.getPrepay_id();
if (prepayId == null || prepayId.equals("")) {
throw new RuntimeException("get prepayid error");
}

Map<String, String> payInfo = new HashMap<String, String>();
payInfo.put("appId", wxMpConfigStorage.getAppId());
// 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
payInfo.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));
payInfo.put("nonceStr", System.currentTimeMillis() + "");
payInfo.put("package", "prepay_id=" + prepayId);
payInfo.put("signType", "MD5");

String finalSign = WxCryptUtil.createSign(payInfo, wxMpConfigStorage.getPartnerKey());
payInfo.put("sign", finalSign);
return payInfo;
}
} }

+ 98
- 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpPrepayIdResult.java View File

@@ -0,0 +1,98 @@
package me.chanjar.weixin.mp.bean.result;

import java.io.Serializable;

/**
* <pre>
* 群发消息一发送就返回的结果
*
* 真正的群发消息是否发送成功要看
* http://mp.weixin.qq.com/wiki/index.php?title=高级群发接口#.E4.BA.8B.E4.BB.B6.E6.8E.A8.E9.80.81.E7.BE.A4.E5.8F.91.E7.BB.93.E6.9E.9C
*
* </pre>
*
* @author chanjarster
*/
public class WxMpPrepayIdResult implements Serializable {
private String return_code;
private String return_msg;
private String appid;
private String mch_id;
private String nonce_str;
private String sign;
private String result_code;
private String prepay_id;
private String trade_type;

public String getReturn_code() {
return return_code;
}

public void setReturn_code(String return_code) {
this.return_code = return_code;
}

public String getReturn_msg() {
return return_msg;
}

public void setReturn_msg(String return_msg) {
this.return_msg = return_msg;
}

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 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 String getResult_code() {
return result_code;
}

public void setResult_code(String result_code) {
this.result_code = result_code;
}

public String getPrepay_id() {
return prepay_id;
}

public void setPrepay_id(String prepay_id) {
this.prepay_id = prepay_id;
}

public String getTrade_type() {
return trade_type;
}

public void setTrade_type(String trade_type) {
this.trade_type = trade_type;
}
}

Loading…
Cancel
Save