调起微信支付服务器端demo页面这一步是服务器端做的吗

在 SegmentFault,解决技术问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
一线的工程师、著名开源项目的作者们,都在这里:
获取验证码
已有账号?
标签:至少1个,最多5个
最近应公司业务需求,把微信支付完成了,当然已经顺利上线。但是开发的过程是也是踩了很多坑,下面我就先说说开发流程,以及在开发中遇到的大大小小的坑。
首先,看一下微信开方平台关于支付的一个时序图,如下:
微信支付时序图
商户系统和微信支付系统主要交互说明:
步骤1:用户在商户APP中选择商品,提交订单,选择微信支付。
步骤2:商户后台收到用户支付单,调用微信支付统一下单接口。参见【统一下单API】。
步骤3:统一下单接口返回正常的prepay_id,再按签名规范重新生成签名后,将数据传输给APP。参与签名的字段名为appId,partnerId,prepayId,nonceStr,timeStamp,package。注意:package的值格式为Sign=WXPay
步骤4:商户APP调起微信支付。api参见本章节【app端开发步骤说明】
步骤5:商户后台接收支付通知。api参见【支付结果通知API】
步骤6:商户后台查询支付结果。,api参见【查询订单API】
这里我讲解的服务端的开发,那我们就看服务端需要做什么工作。
第一步 统一下单
商户系统先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易回话标识后再在APP里面调起支付。首先,准备请求的参数代码如下:
private SortedMap&String, Object& prepareOrder(String ip, String orderId,
int price) {
Map&String, Object& oparams = ImmutableMap.&String, Object& builder()
.put("appid", ConfigUtil.APPID)//应用号
.put("body", WeixinConstant.PRODUCT_BODY)// 商品描述
.put("mch_id", ConfigUtil.MCH_ID)// 商户号
.put("nonce_str", PayCommonUtil.CreateNoncestr())// 16随机字符串(大小写字母加数字)
.put("out_trade_no", orderId)// 商户订单号
.put("total_fee", "1")// 银行币种支付的钱钱啦
.put("spbill_create_ip", ip)// IP地址
.put("notify_url", ConfigUtil.NOTIFY_URL) // 微信回调地址
.put("trade_type", ConfigUtil.TRADE_TYPE)// 支付类型 APP
return MapUtils.sortMap(oparams);
接下来将这些请求参数格式化成XML格式的数据 like this
&appid&wx0ec43b&/appid&
&attach&支付测试&/attach&
&body&APP支付测试&/body&
&mch_id&&/mch_id&
&nonce_str&1add1a30ac87aa2db72f57a2375d8fec&/nonce_str&
&notify_url&http://wxpay./pub_v2/pay/notify.v2.php&/notify_url&
&out_trade_no&&/out_trade_no&
&spbill_create_ip&14.23.150.211&/spbill_create_ip&
&total_fee&1&/total_fee&
&trade_type&APP&/trade_type&
&sign&0CBEFBCA001&/sign&
请求统一下单地址 代码(部分代码,完整的代码请见我的)
String requestXML = PayCommonUtil.getRequestXml(parameters);// 生成xml格式字符串
String responseStr = HttpUtil.httpsRequest(
ConfigUtil.UNIFIED_ORDER_URL, "POST", requestXML);// 带上post
完成之后将微信返回的数据进行解析,取出APP客户端需要的数据,用于唤起微信支付。代码
* 生成订单完成,返回给android,ios唤起微信所需要的参数。
* @param resutlMap
* @throws UnsupportedEncodingException
private SortedMap&String, Object& buildClientJson(
Map&String, Object& resutlMap) throws UnsupportedEncodingException {
// 获取微信返回的签名
* backObject.put("appid", appid);
* backObject.put("noncestr", payParams.get("noncestr"));
* backObject.put("package", "Sign=WXPay");
* backObject.put("partnerid", payParams.get("partnerid"));
* backObject.put("prepayid", payParams.get("prepayid"));
* backObject.put("appkey", this.appkey);
* backObject.put("timestamp",payParams.get("timestamp"));
* backObject.put("sign",payParams.get("sign"));
Map&String, Object& params = ImmutableMap.&String, Object& builder()
.put("appid", ConfigUtil.APPID)
.put("noncestr", PayCommonUtil.CreateNoncestr())
.put("package", "Sign=WXPay")
.put("partnerid", ConfigUtil.MCH_ID)
.put("prepayid", resutlMap.get("prepay_id"))
.put("timestamp", DateUtils.getTimeStamp()).build();//取10位时间戳
// key ASCII排序
SortedMap&String, Object& sortMap = MapUtils.sortMap(params);
sortMap.put("package", "Sign=WXPay");
// paySign的生成规则和Sign的生成规则同理
String paySign = PayCommonUtil.createSign("UTF-8", sortMap);
sortMap.put("sign", paySign);
return sortM
整个统一下订单的逻辑就完成了。这里小结一下:
请求参数需要按照参数的key进行字母的ASCII码进行排序,由于我使用的是map数据结构,这里提供一个对map集合中的key元素进行排序的工具类
* 对map根据key进行排序 ASCII 顺序
* @param 无序的map
public static SortedMap&String, Object& sortMap(Map&String, Object& map) {
List&Map.Entry&String, Object&& infoIds = new ArrayList&Map.Entry&String, Object&&(
map.entrySet());
Collections.sort(infoIds, new Comparator&Map.Entry&String, Object&&() {
public int compare(Map.Entry&String, Object& o1,
Map.Entry&String, Object& o2) {
return (o1.getKey()).toString().compareTo(o2.getKey());
SortedMap&String, Object& sortmap = new TreeMap&String, Object&();
for (int i = 0; i & infoIds.size(); i++) {
String[] split = infoIds.get(i).toString().split("=");
sortmap.put(split[0], split[1]);
对排序后的数据进行MD5签名,微信服务端会进行校验,防止数据在网络传输过程中被篡改。
拿到微信响应的数据,首先要做的事,也是对获取的数据进行签名校验,理由同上。
需要注意的一点,返回给app客户端的数据的key一定是小写,这点微信的api是没有说明白的,之前和客户端联调时耽误了很多时间,这也是微信支付被很多开发者吐槽的地方api比较难用^-^
注意小细节:返回给客户端时时间戳要是10位的,太长ios那边会越界,支付不成功。
第二步 调起支付
支付成功后,微信就会调用你填写的notify_url的方法,本人微信支付的开发配置中说明了我的notify_url为http://ip:port/weixin/pay/callback/pay.action对后台通知交互时,如果微信收到商户的应答不是成功或超时,微信认为通知失败,微信会通过一定的策略(如 30 分钟共 8 次)定期重新发起通知,尽可能提高通知的成功率,但微信不保证通知最终能成功。由于存在重新収送后台通知的情况,因此同样的通知可能会多次収送给商户系统。 商户系统必须能够正确处理重复的通知。推荐的做法是,当收到通知进行处理时,首先检查对应业务数据的状态,判断该通知是否已经处理过,如果没有处理过再进行处理,如果处理过直接返回结果成功。在对业务数据进行状态检查和处理之前,要采用数据锁进行幵収控制,以避免凼数重入造成的数据混乱。判断完成后,我们需要通知微信,我们收到信息了,不然微信就会通过一定的策略定期重新发起通知。
* 微信回调告诉微信支付结果 注意:同样的通知可能会多次发送给此接口,注意处理重复的通知。
* 对于支付结果通知的内容做签名验证,防止数据泄漏导致出现“假通知”,造成资金损失。
* @param params
public String callback(HttpRequest request) {
String responseStr = parseWeixinCallback(request);
Map&String, Object& map = XMLUtil.doXMLParse(responseStr);
// 校验签名 防止数据泄漏导致出现“假通知”,造成资金损失
if (!PayCommonUtil.checkIsSignValidFromResponseString(responseStr)) {
logger.error("微信回调失败,签名可能被篡改");
return PayCommonUtil.setXML("FAIL", "invalid sign");
if (WeixinConstant.FAIL.equalsIgnoreCase(map.get("result_code")
.toString())) {
logger.error("微信回调失败");
return PayCommonUtil.setXML("FAIL", "weixin pay fail");
if (WeixinConstant.SUCCESS.equalsIgnoreCase(map.get("result_code")
.toString())) {
//获取应用服务器需要的数据进行持久化操作
String outTradeNo = (String) map.get("out_trade_no");
String transactionId = (String) map.get("transaction_id");
String totlaFee = (String) map.get("total_fee");
Integer totalPrice = Integer.valueOf(totlaFee);
if (PayApp.theApp.isDebug()) {// 测试时候支付一分钱,买入价值6块的20分钟语音
totalPrice = 6;
boolean isOk = updateDB(outTradeNo, transactionId, totalPrice,
// 告诉微信服务器,我收到信息了,不要在调用回调action了
if (isOk) {
return PayCommonUtil.setXML(WeixinConstant.SUCCESS, "OK");
return PayCommonUtil
.setXML(WeixinConstant.FAIL, "pay fail");
} catch (Exception e) {
logger.debug("支付失败" + e.getMessage());
return PayCommonUtil.setXML(WeixinConstant.FAIL,
"weixin pay server exception");
return PayCommonUtil.setXML(WeixinConstant.FAIL, "weixin pay fail");
当在本地做开发时,微信回调是不方便的,这里提供一种比较快速的方法,不过前提是有云服务器。用ssh建立反向通道。
步骤如下:
(1) ssh -R 9999:localhost:9000 ubuntu@myserver_ip_address,输入密码;
(2) server上查看一下是否监听了9999端口,netstat -anltp | grep 9999;
ubuntu@VM-39-45-ubuntu:~$ netstat -anltp | grep 9999
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
0 127.0.0.1:9999
0 ::1:9999
(3) 在本地9000上开启web服务;
(4) 当微信回调公网服务器时就会被代理到本地9000端口对应的web服务;
这样就可以在本地调试了,是不是很方便呢。
2.回调逻辑中记得,将重要数据在应用服务器进行持久化哦。
第三步 查询订单
该接口提供所有微信支付订单的查询,商户可以通过该接口主动查询订单状态,完成下一步的业务逻辑。
需要调用查询接口的情况:
◆ 当商户后台、网络、服务器等出现异常,商户系统最终未接收到支付通知;
◆ 调用支付接口后,返回系统错误或未知交易状态情况;
◆ 调用被扫支付API,返回USERPAYING的状态;
◆ 调用关单或撤销接口API之前,需确认支付状态;
需要提供两个参数outTradeNo 商户订单号transactionId 微信订单号 二选一请求接口 代码:
* 封装查询请求数据
* @param outTradeNo
* @param transactionId
private SortedMap&String, Object& prepareQueryData(String outTradeNo,
String transactionId) {
Map&String, Object& queryParams =
// 微信的订单号,优先使用
if (null == outTradeNo || outTradeNo.length() == 0) {
queryParams = ImmutableMap.&String, Object& builder()
.put("appid", ConfigUtil.APPID)
.put("mch_id", ConfigUtil.MCH_ID)
.put("transaction_id", transactionId)
.put("nonce_str", PayCommonUtil.CreateNoncestr()).build();
queryParams = ImmutableMap.&String, Object& builder()
.put("appid", ConfigUtil.APPID)
.put("mch_id", ConfigUtil.MCH_ID)
.put("out_trade_no", outTradeNo)
.put("nonce_str", PayCommonUtil.CreateNoncestr()).build();
// key ASCII 排序
SortedMap&String, Object& sortMap = MapUtils.sortMap(queryParams);
String createSign = PayCommonUtil.createSign("UTF-8", sortMap);
sortMap.put("sign", createSign);
return sortM
下一步对微信响应的数据进行解析,检查支付的状态代码如下
* 查询订单状态
* @param params
订单查询参数
public HttpResult&String& checkOrderStatus(SortedMap&String, Object& params) {
if (params == null) {
return HttpResult.error(1, "查询订单参数不能为空");
String requestXML = PayCommonUtil.getRequestXml(params);// 生成xml格式字符串
String responseStr = HttpUtil.httpsRequest(
ConfigUtil.CHECK_ORDER_URL, "POST", requestXML);// 带上post
SortedMap&String, Object& responseMap = XMLUtil
.doXMLParse(responseStr);// 解析响应xml格式字符串
// 校验响应结果return_code
if (WeixinConstant.FAIL.equalsIgnoreCase(responseMap.get(
"return_code").toString())) {
return HttpResult.error(1, responseMap.get("return_msg")
.toString());
// 校验业务结果result_code
if (WeixinConstant.FAIL.equalsIgnoreCase(responseMap.get(
"result_code").toString())) {
return HttpResult.error(2, responseMap.get("err_code")
.toString() + "=" + responseMap.get("err_code_des"));
// 校验签名
if (!PayCommonUtil.checkIsSignValidFromResponseString(responseStr)) {
logger.error("订单查询失败,签名可能被篡改");
return HttpResult.error(3, "签名错误");
// 判断支付状态
String tradeState = responseMap.get("trade_state").toString();
if (tradeState != null && tradeState.equals("SUCCESS")) {
return HttpResult.success(0, "订单支付成功");
} else if (tradeState == null) {
return HttpResult.error(4, "获取订单状态失败");
} else if (tradeState.equals("REFUND")) {
return HttpResult.error(5, "转入退款");
} else if (tradeState.equals("NOTPAY")) {
return HttpResult.error(6, "未支付");
} else if (tradeState.equals("CLOSED")) {
return HttpResult.error(7, "已关闭");
} else if (tradeState.equals("REVOKED")) {
return HttpResult.error(8, "已撤销(刷卡支付");
} else if (tradeState.equals("USERPAYING")) {
return HttpResult.error(9, "用户支付中");
} else if (tradeState.equals("PAYERROR")) {
return HttpResult.error(10, "支付失败");
return HttpResult.error(11, "未知的失败状态");
} catch (Exception e) {
logger.error("订单查询失败,查询参数 = {}", JSONObject.toJSONString(params));
return HttpResult.success(1, "订单查询失败");
整个流程就是这样的,呵呵呵...好久没写博客有点手生了。对于代码中很多工具类,这里就不一一贴出来了.
0 收藏&&|&&28
你可能感兴趣的文章
2 收藏,322
17 收藏,972
5 收藏,1.3k
本作品采用 署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可
先赞一个,写的很用心,代码也很清晰(我在你写的其中一个工具类里发现了一个很严重代码逻辑错误,不过不影响大局哈哈),学习了!不过我还有一个疑问就是,微信支付官方文档那里说的商户证书怎么用的,在代码里要使用它吗?如果要,该如何使用?在项目里是必须的吗?在线等,很急!!!先谢过兄弟了!
先赞一个,写的很用心,代码也很清晰(我在你写的其中一个工具类里发现了一个很严重代码逻辑错误,不过不影响大局哈哈),学习了!不过我还有一个疑问就是,微信支付官方文档那里说的商户证书怎么用的,在代码里要使用它吗?如果要,该如何使用?在项目里是必须的吗?在线等,很急!!!先谢过兄弟了!
企业付款那里需要证书,其实也很简单,微信支付不需要证书。 商户平台开发者文档 , 证书使用demo,希望能帮到您。(^-^)
企业付款那里需要证书,其实也很简单,微信支付不需要证书。https://pay./wiki/doc/api/tools/mch_pay.php?chapter=4_3 商户平台开发者文档 ,
https://pay./wiki/doc/api/tools/mch_pay.php?chapter=4_3 证书使用demo,希望能帮到您。(^-^)
怎么和你联系,我开发一个系统
怎么和你联系,我开发一个系统
好的,我再研究一下,不懂再私信你吧,谢谢你~
好的,我再研究一下,不懂再私信你吧,谢谢你~
* HTTP Post 获取内容
* @param url
请求的url地址 ?之前的地址
* @param params
请求的参数
* @param charset
* @return 响应结果
public static String doPost(String url, Map&String, Object& params,
String charset) {
Args.notNull(url, "请求目标url");
List&NameValuePair& pairs =
if (params != null && !params.isEmpty()) {
pairs = new ArrayList&NameValuePair&(params.size());
for (Map.Entry&String, Object& entry : params.entrySet()) {
String value = (String)entry.getValue();
if (value != null) {
pairs.add(new BasicNameValuePair(entry.getKey(), value));
HttpPost httpPost = new HttpPost(url);
if (pairs != null && pairs.size() & 0) {
httpPost.setEntity(new UrlEncodedFormEntity(pairs, CHARSET));
RequestConfig config = RequestConfig.custom().setConnectTimeout(30000)
.setSocketTimeout(60000).build();//timeunit : seconds
httpClient = createClient(config);//创建 client
CloseableHttpResponse response = httpClient.execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != 200) {
httpPost.abort();
throw new RuntimeException("HttpClient,error status code :"
+ statusCode);
HttpEntity entity = response.getEntity();
String result =
if (entity != null) {
result = EntityUtils.toString(entity, Charsets.UTF_8);
EntityUtils.consume(entity);
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
} finally{
response.close();
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
} finally {
// 关闭连接,释放资源
if (httpClient != null) {
httpClient.close();
} catch (IOException e) {
throw new RuntimeException(e.getMessage());
SSL CLIENT/**
* 获取带证书的安全client
* @param config
private static CloseableHttpClient createClient(RequestConfig config) {
CloseableHttpClient httpclient =
// 指定读取证书格式为PKCS12
KeyStore keyStore = KeyStore.getInstance(CEART_MODE);
// 读取本机存放的PKCS12证书文件
//FileInputStream instream = new FileInputStream(new File(CERT));
InputStream instream = FsClientWithCertSSL.class.getResourceAsStream(CERT);
// 指定PKCS12的密码(商户ID)
keyStore.load(instream, MCHID.toCharArray());
} catch (CertificateException e) {
e.printStackTrace();
}finally {
instream.close();
// 相信自己的CA和所有自签名的证书
//SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(keyStore, new TrustSelfSignedStrategy()).build();
// Trust own CA and all self-signed certs 加上密钥
SSLContext sslcontext = SSLContexts
.loadKeyMaterial(keyStore,MCHID.toCharArray())
// Allow TLSv1 protocol only 指定TLS版本 (IETF Internet Enginnering TaskForce )
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext,
new String[] { "TLSv1" }, // TLSv1 等于 SSLv3
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
// 设置httpclient的SSLSocketFactory
httpclient = HttpClients.custom()
.setSSLSocketFactory(sslsf)
.setDefaultRequestConfig(config)
//.setConnectionManager(connManager)
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
用到的参数
// 证书位置 某个文件下或者放在classpath下
static String CERT = "/apiclient_cert.p12"; //WeixinPayConfig.CERT_FILE;
static String MCHID = WeixinPayConfig.MCHID;
// 携带证书的client
private static
CloseableHttpClient httpC //TODO 加上httpclient 池 来管理httpclient 考虑多线程的使用情况
// 编码格式 utf-8
private static
String CHARSET = "UTF-8";
指定读取证书格式为PKCS12
private final static String CEART_MODE = "PKCS12";
* HTTP Post 获取内容
* @param url
请求的url地址 ?之前的地址
* @param params
请求的参数
* @param charset
* @return 响应结果
public static String doPost(String url, Map&String, Object& params,
String charset) {
Args.notNull(url, &请求目标url&);
List&NameValuePair& pairs =
if (params != null && !params.isEmpty()) {
pairs = new ArrayList&NameValuePair&(params.size());
for (Map.Entry&String, Object& entry : params.entrySet()) {
String value = (String)entry.getValue();
if (value != null) {
pairs.add(new BasicNameValuePair(entry.getKey(), value));
HttpPost httpPost = new HttpPost(url);
if (pairs != null && pairs.size() & 0) {
httpPost.setEntity(new UrlEncodedFormEntity(pairs, CHARSET));
RequestConfig config = RequestConfig.custom().setConnectTimeout(30000)
.setSocketTimeout(60000).build();//timeunit : seconds
httpClient = createClient(config);//创建 client
CloseableHttpResponse response = httpClient.execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != 200) {
httpPost.abort();
throw new RuntimeException(&HttpClient,error status code :&
+ statusCode);
HttpEntity entity = response.getEntity();
String result =
if (entity != null) {
result = EntityUtils.toString(entity, Charsets.UTF_8);
EntityUtils.consume(entity);
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
} finally{
response.close();
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
} finally {
// 关闭连接,释放资源
if (httpClient != null) {
httpClient.close();
} catch (IOException e) {
throw new RuntimeException(e.getMessage());
SSL CLIENT
* 获取带证书的安全client
* @param config
private static CloseableHttpClient createClient(RequestConfig config) {
CloseableHttpClient httpclient =
// 指定读取证书格式为PKCS12
KeyStore keyStore = KeyStore.getInstance(CEART_MODE);
// 读取本机存放的PKCS12证书文件
//FileInputStream instream = new FileInputStream(new File(CERT));
InputStream instream = FsClientWithCertSSL.class.getResourceAsStream(CERT);
// 指定PKCS12的密码(商户ID)
keyStore.load(instream, MCHID.toCharArray());
} catch (CertificateException e) {
e.printStackTrace();
}finally {
instream.close();
// 相信自己的CA和所有自签名的证书
//SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(keyStore, new TrustSelfSignedStrategy()).build();
// Trust own CA and all self-signed certs 加上密钥
SSLContext sslcontext = SSLContexts
.loadKeyMaterial(keyStore,MCHID.toCharArray())
// Allow TLSv1 protocol only 指定TLS版本 (IETF Internet Enginnering TaskForce )
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext,
new String[] { &TLSv1& }, // TLSv1 等于 SSLv3
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
// 设置httpclient的SSLSocketFactory
httpclient = HttpClients.custom()
.setSSLSocketFactory(sslsf)
.setDefaultRequestConfig(config)
//.setConnectionManager(connManager)
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
用到的参数
// 证书位置 某个文件下或者放在classpath下
static String CERT = &/apiclient_cert.p12&; //WeixinPayConfig.CERT_FILE;
static String MCHID = WeixinPayConfig.MCHID;
// 携带证书的client
private static
CloseableHttpClient httpC //TODO 加上httpclient 池 来管理httpclient 考虑多线程的使用情况
// 编码格式 utf-8
private static
String CHARSET = &UTF-8&;
指定读取证书格式为PKCS12
private final static String CEART_MODE = &PKCS12&;
ThreeMap 不就是按key的 ASCII 排序
ThreeMap 不就是按key的 ASCII 排序
嗯是的 自己写写如何排序也好(^-^)
嗯是的 自己写写如何排序也好(^-^)
请问能否提供jar包或者pom文件
请问能否提供jar包或者pom文件
这里 放上去了 ,由于是公司的项目 有些jar可能你用不上。(^-^)
这里 放上去了 ,由于是公司的项目 有些jar可能你用不上。(^-^)
/uniquewk/weixinpay/tree/master/weixin
正在研究您的源码,发现WeixinLogic.java类中使用到了PayApp,HttpResult,RestResult等类没有提供,影响理解,不知道能否提供一下源码?感激不尽!
正在研究您的源码,发现WeixinLogic.java类中使用到了PayApp,HttpResult,RestResult等类没有提供,影响理解,不知道能否提供一下源码?感激不尽!
/uniquewk/weixinpay
private String message = "";//返回给客户端的消息private Object result = "";//数据private int code = -1;//错误码public RestResult() {}private RestResult(Object result, int code, String msg) {this.result =this.code =this.message =}
public RestResult(int code, String msg) {this.code =this.message =} //result是 这样一个pojo类 ;PayApp是我项目的启动主函数
private String message = &&;//返回给客户端的消息private Object result = &&;//数据private int code = -1;//错误码public RestResult() {}private RestResult(Object result, int code, String msg) {this.result =this.code =this.message =}
public RestResult(int code, String msg) {this.code =this.message =} //result是 这样一个pojo类 ;PayApp是我项目的启动主函数
感觉您的pom文件.HttpResult跟RestResult是差不多的类吗?封装成两个pojo是有特殊的目的吗?求解!
感觉您的pom文件.HttpResult跟RestResult是差不多的类吗?封装成两个pojo是有特殊的目的吗?求解!
博主可以提供一下用到的jar包吗?感激不尽。感觉自己更理解微信支付一些了
博主可以提供一下用到的jar包吗?感激不尽。感觉自己更理解微信支付一些了
这里 放上去了 ,由于是公司的项目 有些jar可能你用不上。(^-^)
/uniquewk/weixinpay/tree/master/weixin 这里 放上去了 ,由于是公司的项目 有些jar可能你用不上。(^-^)
好的 中午发
好的 中午发
赶紧不尽啊,新人快被微信支付逼疯了
赶紧不尽啊,新人快被微信支付逼疯了
不难的 (^-^) 需要帮助微信联系 appleguy90
@凉宫春昊 没事
不难的 (^-^) 需要帮助微信联系 appleguy90
github 文章最下面
github 文章最下面
分享到微博?
我要该,理由是:

我要回帖

更多关于 微信支付服务器端 的文章

 

随机推荐