mirror of
				https://gitee.com/binary/weixin-java-tools.git
				synced 2025-10-31 18:46:10 +08:00 
			
		
		
		
	公众号支付
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -19,3 +19,4 @@ target | |||||||
| sw-pom.xml | sw-pom.xml | ||||||
| *.iml | *.iml | ||||||
| test-config.xml | test-config.xml | ||||||
|  | .idea | ||||||
|  | |||||||
| @ -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()); |     return DigestUtils.sha1Hex(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); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   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(); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|  } |  } | ||||||
|  | |||||||
| @ -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.*; | ||||||
| import java.util.Random; |  | ||||||
|  |  | ||||||
| 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数组 | ||||||
|    * |    * | ||||||
|  | |||||||
| @ -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(); | ||||||
|  | |||||||
| @ -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; | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -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); | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -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.*; | ||||||
| import java.util.List; |  | ||||||
| import java.util.UUID; |  | ||||||
|  |  | ||||||
| public class WxMpServiceImpl implements WxMpService { | public class WxMpServiceImpl implements WxMpService { | ||||||
|  |  | ||||||
| @ -333,6 +338,19 @@ public class WxMpServiceImpl implements WxMpService { | |||||||
|     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"; | ||||||
|     return execute(new QrCodeRequestExecutor(), url, ticket); |     return execute(new QrCodeRequestExecutor(), url, ticket); | ||||||
| @ -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; | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -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; | ||||||
|  |     } | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user
	 oohusl
					oohusl