| | |
| | | |
| | | import com.hx.exception.ServiceException; |
| | | import com.hx.util.SimpleTool; |
| | | import com.hx.util.StringUtils; |
| | | import net.sf.json.JSONObject; |
| | | import org.apache.commons.io.IOUtils; |
| | | import org.apache.http.HttpEntity; |
| | | import org.apache.http.client.methods.CloseableHttpResponse; |
| | | import org.apache.http.client.methods.HttpPost; |
| | |
| | | return returnObj; |
| | | } |
| | | |
| | | /**统一支付(分账) |
| | | * @param request 方法获取 |
| | | * @param appId 小程序号 |
| | | * @param partner 商户号 |
| | | * @param key 秘钥 |
| | | * @param notifyUrl 回调链接 |
| | | * @param out_trade_no 订单号 |
| | | * @param body 商品描述 |
| | | * @param total_fee 支付金额 |
| | | * @param openid 用户openId |
| | | * @param attach 附带数据包 |
| | | * @param notifyUrl 回调通知地址 |
| | | * @param trade_type 交易类型 |
| | | * @param profit_sharing 是否分账:N不,Y是 |
| | | * @return JSON status = "SUC"为成功 |
| | | */ |
| | | public static JSONObject unifiedPay(HttpServletRequest request,String appId,String partner,String key,String notifyUrl,String out_trade_no, String body, String total_fee, String openid, |
| | | String attach,String trade_type,String profit_sharing) throws Exception { |
| | | |
| | | if (!SimpleTool.checkNotNull(notifyUrl)) { |
| | | throw new ServiceException("支付功能故障!"); |
| | | } |
| | | |
| | | // 创建查询请求对象 |
| | | RequestHandler reqHandler = new RequestHandler(null, null); |
| | | // 通信对象 |
| | | TenpayHttpClient httpClient = new TenpayHttpClient(); |
| | | // 应答对象 |
| | | ClientResponseHandler resHandler = new ClientResponseHandler(); |
| | | |
| | | // ----------------------------- |
| | | // 设置请求参数 |
| | | // ----------------------------- |
| | | // reqHandler.init(); |
| | | reqHandler.setKey(key); |
| | | reqHandler.setGateUrl(FIRST_ORDER_URL);// 请求URL |
| | | |
| | | // ----------------------------- |
| | | // 设置接口参数(sign后台自动生成) |
| | | // ----------------------------- |
| | | |
| | | reqHandler.setParameter("appid", appId); // 公众号/小程序 |
| | | reqHandler.setParameter("mch_id", partner); // 商户号 |
| | | reqHandler.setParameter("nonce_str", SimpleTool.getUUIDName().substring(0, 30));// 随机乱码 |
| | | reqHandler.setParameter("body", body);// 商品描述 |
| | | reqHandler.setParameter("out_trade_no", out_trade_no);// 商户订单号 |
| | | reqHandler.setParameter("total_fee", total_fee);// 总金额 |
| | | reqHandler.setParameter("spbill_create_ip", "8.8.8.8");// 终端IP |
| | | reqHandler.setParameter("notify_url",notifyUrl);// 通知地址 |
| | | reqHandler.setParameter("trade_type", trade_type);// 交易类型 |
| | | //JSAPI,NATIVE,APP |
| | | reqHandler.setParameter("openid", openid);// openId |
| | | reqHandler.setParameter("attach", attach);// 附带数据包 |
| | | reqHandler.setParameter("profit_sharing", profit_sharing);// 附带数据包 |
| | | |
| | | // ----------------------------- |
| | | // 设置通信参数 |
| | | // ----------------------------- |
| | | // 设置请求返回的等待时间 |
| | | httpClient.setTimeOut(5); |
| | | |
| | | // 设置ca证书 |
| | | // httpClient.setCaInfo(new File(CA_PATH)); |
| | | |
| | | // 设置个人(商户)证书 |
| | | // httpClient.setCertInfo(new File(CERT_PATH), CERT_PWD); |
| | | |
| | | // 设置发送类型POST |
| | | httpClient.setMethod("POST"); |
| | | |
| | | // 设置请求内容(生成sign) |
| | | String requestUrl = reqHandler.getRequestURL();// 组拼https://www.baidu.com?a=x&b=xx |
| | | |
| | | httpClient.setReqContent(requestUrl);// https://www.baidu.com?a=x&b=xx |
| | | String rescontent = "null"; |
| | | |
| | | httpClient.setRequestHandler(reqHandler);// 把处理对象,像是参数各种东西都设置进去方便获取(quan) |
| | | |
| | | // 返回出去的对象(状态,错误原因,该操作相关信息(参数,返回值)) |
| | | JSONObject returnObj = new JSONObject(); |
| | | |
| | | // 后台调用 |
| | | if (httpClient.call()) { |
| | | System.out.println("统一下单,成功cll了::"); |
| | | |
| | | // 设置结果参数 |
| | | rescontent = httpClient.getResContent(); |
| | | System.out.println("统一下单返回结果:" + rescontent); |
| | | resHandler.setContent(rescontent);// 解析xml |
| | | resHandler.setKey(key); |
| | | |
| | | // 获取返回参数 |
| | | String return_code = resHandler.getParameter("return_code"); |
| | | String return_msg = resHandler.getParameter("return_msg"); |
| | | |
| | | // 判断签名及结果 |
| | | if (resHandler.isTenpaySign() && "SUCCESS".equals(return_code)) { |
| | | String prepay_id = resHandler.getParameter("prepay_id");// 预支付交易会话标识 |
| | | String code_url = resHandler.getParameter("code_url");// 二维码链接 |
| | | |
| | | String result_code = resHandler.getParameter("result_code");// 业务结果 |
| | | String appid = resHandler.getParameter("appid");// 公众账号ID |
| | | String mch_id = resHandler.getParameter("mch_id");// 商户号 |
| | | String nonce_str = resHandler.getParameter("nonce_str");// 随机码 |
| | | String sign = resHandler.getParameter("sign");// 签名 |
| | | |
| | | if (result_code.equals("SUCCESS")) { |
| | | returnObj.put("status", "suc"); |
| | | returnObj.put("sign", sign); |
| | | returnObj.put("nonce_str", nonce_str); |
| | | returnObj.put("mch_id", mch_id); |
| | | returnObj.put("appid", appid); |
| | | returnObj.put("prepay_id", prepay_id); |
| | | returnObj.put("code_url", code_url); |
| | | returnObj.put("out_trade_no", out_trade_no); |
| | | } else { |
| | | String errMsg = "[ERROR]result_code:" + resHandler.getParameter("result_code") + " err_code:" |
| | | + resHandler.getParameter("err_code") + "err_code_des:" |
| | | + resHandler.getParameter("err_code_des"); |
| | | |
| | | // 错误时,返回结果未签名,记录retcode、retmsg看失败详情。 |
| | | returnObj.put("status", "ERROR-C"); |
| | | returnObj.put("errMsg", errMsg); |
| | | } |
| | | } else { |
| | | String errMsg = "return_code:" + return_code + "err_code:" + resHandler.getParameter("err_code") |
| | | + " return_msg:" + return_msg; |
| | | // 错误时,返回结果未签名,记录retcode、retmsg看失败详情。 |
| | | returnObj.put("status", "ERROR-B"); |
| | | returnObj.put("errMsg", errMsg); |
| | | } |
| | | } else { |
| | | // 有可能因为网络原因,请求已经处理,但未收到应答。 |
| | | returnObj.put("status", "ERROR-A"); |
| | | returnObj.put("errMsg", httpClient.getResponseCode() + ":" + httpClient.getErrInfo()); |
| | | } |
| | | |
| | | // 获取debug信息,建议把请求、应答内容、debug信息,通信返回码写入日志,方便定位问题 |
| | | String detail = "http res:" + httpClient.getResponseCode() + "," + httpClient.getErrInfo() + ";" + "req url:" |
| | | + requestUrl + ";" + ";" + "req debug:" + reqHandler.getDebugInfo() + ";" + "res content:" + rescontent |
| | | + ";" + "res debug:" + resHandler.getDebugInfo() + ";"; |
| | | |
| | | returnObj.put("detail", detail); |
| | | |
| | | |
| | | return returnObj; |
| | | } |
| | | |
| | | /**处理信息 |
| | | */ |
| | | public static JSONObject paymentData(JSONObject payObj,String key){ |
| | |
| | | CloseableHttpClient httpclient = HttpClients.custom() |
| | | .setSSLSocketFactory(sslsf).build(); |
| | | HttpPost httppost = new HttpPost(REFUND_URL); |
| | | String xml = wxPayRefundData(appId,partner,key,out_trade_no, transaction_id, total_fee, out_refund_no, refund_fee); |
| | | try { |
| | | String xml = wxPayRefundData(appId, partner, key, out_trade_no, transaction_id, out_refund_no, total_fee, refund_fee); |
| | | try { |
| | | StringEntity se = new StringEntity(xml); |
| | | httppost.setEntity(se); |
| | | System.out.println("executing request" + httppost.getRequestLine()); |
| | | |
| | | CloseableHttpResponse responseEntry = httpclient.execute(httppost); |
| | | try { |
| | | HttpEntity entity = responseEntry.getEntity(); |
| | | System.out.println(responseEntry.getStatusLine()); |
| | | if (entity != null) { |
| | | |
| | | SAXReader saxReader = new SAXReader(); |
| | | Document document = saxReader.read(entity.getContent()); |
| | | Element rootElt = document.getRootElement(); |
| | | String resultCode = rootElt.elementText("result_code"); |
| | | JSONObject result = new JSONObject(); |
| | | String returnCode = rootElt.elementText("return_code"); |
| | | JSONObject result = new JSONObject(); |
| | | |
| | | if(resultCode.equals("SUCCESS")){ |
| | | result.put("weixinPayUrl", rootElt.elementText("code_url")); |
| | | result.put("prepayId", rootElt.elementText("prepay_id")); |
| | | result.put("msg","success"); |
| | | |
| | | String refund_id = rootElt.elementText("refund_id");//微信退款单号 |
| | | String r_out_refund_no=rootElt.elementText("out_refund_no"); |
| | | String errMsg = "商户号"+r_out_refund_no+"的退款流水号是:"+refund_id; |
| | | result.put("status", "SUCCESS"); |
| | | result.put("errMsg", errMsg); |
| | | result.put("refund_id", refund_id); |
| | | if(returnCode.equals("SUCCESS")){ |
| | | String resultCode = rootElt.elementText("result_code"); |
| | | if(resultCode.equals("SUCCESS")) { |
| | | result.put("weixinPayUrl", rootElt.elementText("code_url")); |
| | | result.put("prepayId", rootElt.elementText("prepay_id")); |
| | | result.put("msg", "success"); |
| | | |
| | | String refund_id = rootElt.elementText("refund_id");//微信退款单号 |
| | | String r_out_refund_no = rootElt.elementText("out_refund_no"); |
| | | String errMsg = "商户号" + r_out_refund_no + "的退款流水号是:" + refund_id; |
| | | result.put("status", "SUCCESS"); |
| | | result.put("errMsg", errMsg); |
| | | result.put("refund_id", refund_id); |
| | | }else{ |
| | | String errMsg = "[ERROR]result_code:" + rootElt.elementText("result_code")+ |
| | | " err_code:" + rootElt.elementText("err_code"); |
| | | |
| | | //错误时,返回结果未签名,记录retcode、retmsg看失败详情。 |
| | | result.put("errMsg", errMsg); |
| | | result.put("status","false"); |
| | | result.put("msg",rootElt.elementText("err_code_des")); |
| | | } |
| | | }else{ |
| | | String errMsg = "[ERROR]result_code:" + rootElt.elementText("result_code")+ |
| | | " err_code:" + rootElt.elementText("err_code"); |
| | | String errMsg = "[ERROR]return_code:" + rootElt.elementText("return_code"); |
| | | |
| | | //错误时,返回结果未签名,记录retcode、retmsg看失败详情。 |
| | | result.put("errMsg", errMsg); |
| | | result.put("status","false"); |
| | | result.put("msg",rootElt.elementText("err_code_des")); |
| | | result.put("msg",rootElt.elementText("return_msg")); |
| | | } |
| | | return result; |
| | | } |
| | |
| | | parameters.put("appid",appId); |
| | | parameters.put("mch_id",partner); |
| | | parameters.put("nonce_str", nonceStr); |
| | | parameters.put("out_trade_no", out_trade_no); |
| | | parameters.put("transaction_id", transaction_id); |
| | | if(!StringUtils.isEmpty(out_trade_no)) { |
| | | parameters.put("out_trade_no", out_trade_no); |
| | | } |
| | | if(!StringUtils.isEmpty(transaction_id)) { |
| | | parameters.put("transaction_id", transaction_id); |
| | | } |
| | | parameters.put("out_refund_no", out_refund_no); |
| | | parameters.put("fee_type", "CNY"); |
| | | parameters.put("total_fee", total_fee);//总金额 |