APP 微信支付java后台代码(解决支付失败返回-1)

开发之前的准备工作:

APP支付申请条件

申请成为APP支付商户需要满足以下条件:

1、APP支付商户,须拥有微信开放平台(http://open.weixin.qq.com)的APPID;

2、APP应用必须通过开发者认证。

APP支付申请方法

1、 登陆开放平台(open.weixin.qq.com),选择"管理中心"=》"移动应用",选择需要申请支付的应用,点击"查看"=》 "微信支付"=》 "申请开通",申请流程与公众号支付申请流程一致。如下图:
进入管理中心,点击移动应用
APP 微信支付java后台代码(解决支付失败返回-1)_第1张图片
选择需申请支付功能的应用,点击申请开通;
APP 微信支付java后台代码(解决支付失败返回-1)_第2张图片
进入申请页面,开始填写资料。再依次根据页面指引操作;
APP 微信支付java后台代码(解决支付失败返回-1)_第3张图片
温馨提示:商户申请微信认证的主体与申请开通微信支付的主体需保持一致。

全部完成后可确认提交审核,将在1-5个工作日内审核完成。

2、开户成功,登录商户平台进行金额验证

     提交资料审核通过之后,微信平台会发送商户平台的帐号密码到你填写的邮箱中,并且还会打入一笔验证款项(随机金额)到你的结算银行账户中。

     接下来你所需要做的就是查看银行账户的转账流水(转账方的名义是财付通),然后登录微信商户平台进行金额验证。

     输入你在邮箱中得到的帐号密码

   【!!!注意!!!】:

     在输入密码的时候需要安装一个安全插件,按要求安装插件之后,关闭浏览器然后重新打开,再次输入密码的时候如果还提示需要安装插件,那么请查看一下浏览器的地址栏是什么模式。文主用的是360极速浏览器,所以必须是要在【兼容模式】下才能够正常输入密码,注意啦!是!!!兼容模式!!!

    ②接下来就是激动人心的时刻了

    选择验证账户,输入微信支付给公司对公账户打的款项金额

  【注意!!!】:只有三次验证机会哦,所以要慎重!

    验证成功

    签署微信支付协议,完成微信支付申请

    整个申请过程就这样完成啦,后面对应用的设计和开发,支付接口的调试就属于后台技术人员的活了。如果有什么还不清楚的地方的话,可以艾特文主,看到后能回答的都会帮你们解答。

     APP 微信支付java后台代码(解决支付失败返回-1)_第4张图片

     APP 微信支付java后台代码(解决支付失败返回-1)_第5张图片

     APP 微信支付java后台代码(解决支付失败返回-1)_第6张图片

     APP 微信支付java后台代码(解决支付失败返回-1)_第7张图片


这个时候就该技术人员上场了。

正式开发工作。

1.首先我们先来看一下微信支付的流程。


https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_3


APP 微信支付java后台代码(解决支付失败返回-1)_第8张图片


2.看完支付流程,我们就应该去调微信[统一下单]生成预付单


发送一个支付请求


@RequestMapping("/toGetWxPay")
@ResponseBody
	public JSONObject toGetWxPay(HttpServletRequest request) {
		String oid = request.getParameter("oid");
		String type = request.getParameter("type");
		String string = request.getRequestURL().toString();
		String calBack_url = string.substring(0,string.lastIndexOf("/"));
		calBack_url+="/appPayNotify";
		return wechatService.getWxPayAPP(oid, type, request.getRemoteAddr(), calBack_url);
	}


public JSONObject getWxPayAPP(String oid, String type,
	String spbill_create_ip, String calBack_url) 
		{
		// 支付map
		Map order = null;
		if ("single".equals(type)) {
			// 单个订单
			order = orderBillService.toPayOrder(oid, false);
			order.put("TYPE", "single");
		} else {
			// 多个订单
			order = orderBillService.toPayOrder(oid, true);
			order.put("TYPE", "many");
		}
		order.put("OID", oid);
		Double ormoney = Double.valueOf(order.get("ormoney").toString());
		order.put("ORMONEY", ormoney);
		logger.info("订单:" + order);
		// 调用第三方支付方法发送支付请求
		return wechatInterface.getWxPayAPP(
				propertyUtil.getProperty("wechat.app.appid"),
				propertyUtil.getProperty("wechat.app.mch_id"),
				propertyUtil.getProperty("wechat.app.mch_key"), 
						    spbill_create_ip, order, calBack_url); 
		}


发起预支付请求


public JSONObject getWxPayAPP(String appId, String mchId, String mchKey,
	String spbill_create_ip, Map order, String calBack_url) 
	{
		// 支付map
		Map resmap = new HashMap();
		resmap.put("appid", appId);
		resmap.put("mch_id", mchId);
		resmap.put("device_info", "WEB");
		String nonceStr = UUID.randomUUID().toString().replaceAll("-", "");
		resmap.put("nonce_str", nonceStr);
		resmap.put("body", "集团名称");
		// 签名
		resmap.put("attach", order.get("TYPE"));
		// 商户订单号
		resmap.put("out_trade_no", order.get("OID"));
		// 货币类型
		resmap.put("fee_type", "CNY");
		// 总金额分
		int order_amount = 0;
		try {
			double money = Double.parseDouble(String.valueOf(order
					.get("ORMONEY"))) * 100;
			order_amount = (int) money;
		} catch (Exception e) {
			e.printStackTrace();
		}
		resmap.put("total_fee", order_amount);
		// 终端IP APP和网页支付提交用户端ip
		resmap.put("spbill_create_ip", spbill_create_ip);
		// 起始时间
		resmap.put("time_start", ToolUtil.getFormatedNowDateTime());
		// 结束时间
		resmap.put("time_expire", ToolUtil.getFormatedTenDaysDateTime());
		// 通知地址
		resmap.put("notify_url", calBack_url);
		// 交易类型取值如下:JSAPI,NATIVE,APP
		resmap.put("trade_type", "APP");
		// 支付签名采用md5加密2次
		String sign = SignUtil.createMd5Sign(resmap, mchKey);
		logger.info("加密前map:" + resmap);
		// 生成加密签名
		resmap.put("sign", sign);
		logger.info("sign:" + sign);
		return toPayAPP(resmap, appId, mchKey);
	}
发送支付请求并返回支付数据



private JSONObject toPayAPP(Map resmap, String appId, String mchKey) 
	{
		String payInfoToXml = MessageUtil.mapToXml(resmap);
		logger.info("统一订单xml:" + payInfoToXml);
		Map pay = WeixinUtil.toPay(payInfoToXml);
		logger.info("支付返回map:" + pay);
		// 交易成功返回信息处理
		if (pay != null && pay.containsKey("result_code")
				&& "SUCCESS".equals(pay.get("result_code"))) {
			Map map = new HashMap();
			map.put("appid", appId);
			map.put("noncestr", UUID.randomUUID().toString()
					.replaceAll("-", ""));
			map.put("package", "Sign=WXPay");
			map.put("partnerid", pay.get("mch_id"));
			map.put("prepayid", pay.get("prepay_id"));
			map.put("timestamp", System.currentTimeMillis()/1000);
			String paySign = SignUtil.createMd5Sign(map, mchKey);
			map.put("sign", paySign);
			logger.info("返回给页面的map:" + map);
			return JSONObject.fromObject(map);
		}
		return null;
	}

3.接下来我们来看看支付成功后的回调。

@RequestMapping("/appPayNotify")
	public void appPayNotify(HttpServletRequest request, HttpServletResponse response)
	{
		try {
			// 将请求、响应的编码均设置为UTF-8(防止中文乱码)
			request.setCharacterEncoding("UTF-8");
			String respMessage = wechatService.appPayNotify(MessageUtil
					.parseXml(request.getInputStream()));
			logger.info("回复内容:" + respMessage);
			response.setContentType("application/xml;charset=utf-8");
			// 调用核心业务类接收消息、处理消息
			if (respMessage != null) {
				// 响应消息
				response.getWriter().print(respMessage);
//				out.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}


@Override
	public String appPayNotify(Map requestMap) {
	 try {
		// 是否是微信发来的
		if (wechatInterface.isWechatSign(requestMap, propertyUtil.getProperty
			("wechat.app.mch_key"))==false) {
			return null;
		}
		//处理多次回调
		Map callBack = transactionPayRecordService.findCallBack
			(requestMap.get("transaction_id"));
		if(callBack!=null){
			return "
				";
		}
		Map tMap = new HashMap();
		tMap.put("is_success", "失败");
		tMap.put("verifyStatus", "false");
		tMap.put("transaction_type", "1");
		tMap.put("notify_time", requestMap.get("time_end"));
		if ("SUCCESS".equals(requestMap.get("return_code"))) {
			if ("SUCCESS".equals(requestMap.get("result_code"))) {
				logger.info("验证成功!");
				// 订单号
				String oid = requestMap.get("out_trade_no");
				String type = requestMap.get("attach");
				String transaction_id = requestMap
							.get("transaction_id");
				Map param = new HashMap();
				param.put("transaction_id", transaction_id);
				param.put("payment_method", "3");
				if ("single".equals(type)) {
					param.put("oid", oid);
					// 单个订单
					tMap.put("body", "单个支付");
				} else {
					// 多个订单oid是支付宝号
					param.put("opayid", oid);
					tMap.put("body", "批量支付");
				}
				// 修改订单支付时间
				Integer state = orderBillService.setOrderSuccess(param);
				ogger.info("微信支付成功!");
					
				//订单支付成功,
					
					处理业务逻辑
				
					
					// 记录日志
				tMap.put("callback_payid", transaction_id);// 微信支付交易号
				tMap.put("total_fee", requestMap.get("total_fee"));// 交易金额
				tMap.put("title", "微信支付");
				if (state != null && state > 0) {
					tMap.put("is_success", "成功");
					tMap.put("trade_status", "支付成功");// 支付状态
				} else {
					tMap.put("trade_status", "支付失败");// 支付状态
				}
				tMap.put("verifyStatus", "true");
				tMap.put("payid", requestMap.get("out_trade_no"));
				tMap.put("payment_method", "3");
				tMap.put("remarks", JSONObject.fromObject(requestMap)
							.toString());// 备注
				transactionPayRecordService.save(tMap);
				return "
					";
				} else {
					logger.info("result_code不存在");
					logger.info(requestMap);
				}
				transactionPayRecordService.save(tMap);
			} else {
				logger.info("return_code不存在");
				logger.info(requestMap);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

到这里差不多这个流程就算完了!!!!

说一下在开发过程当中本人遇到的问题:

1.每个微信号只能支付一次,之后就一直是error:{"code":-100,"message":"[payment微信:-1]General errors"}

解决办法是,清理了一下微信缓存。

2.微信支付成功后的回调,(支付成功后,微信会回调好几次)

解决办法,这个时候我们应该在后台做逻辑判断,回调成功修改订单状态,保存支付信息,给微信返回信息,告诉微信已经成功回调,

response.setContentType("application/xml;charset=utf-8");

我开始写的是text,微信一直回调,后来改成application,微信只调了一次。


最后给大家总结一下

1.微信支付必须apk包,本地调试支付不能成功,因为Huilder上的包名和密钥和你app申请的微信支付的包名和密钥是不一样的。所以支付失败。
2.调用微信app统一支付,生成预付订单,这时候微信会返回来success,和微信预支付唯一标示,(prepay_id)
3.注意预支付成功之后参数的顺序
{
appid=wx123......
noncestr=不长于32位的随机字符串
package=Sign=WXPay,
partnerid=商户ID,
prepayid=预支付成功返回的预支付单号,
sign=MD5签名(记得按顺序
toUpperCase转换为大写),
timestamp=时间戳10位,
}
4.注意签名和密钥
5.切记记得清理微信缓存,不是微信聊天记录,是微信缓存。
6,查看appid是否配置(离线打包在AndroidManifest.xml配置,云打包在manifest.json配置)
7,申请appid时所用证书签名与apk的签名证书必须一致
8,申请appid时填写包名与打包时候所填写包名必须一致 开发平台配置的包名与签名跟apk的签名文件是否一致
9,服务生成订单时设置的appid、appkey等参数是否正确

10,调统一下单是参数变量名必是小写,total_fee以分为单位,时间时间戳10位。





你可能感兴趣的:(APP 微信支付java后台代码(解决支付失败返回-1))