1. 程式人生 > >JAVA實現微信支付

JAVA實現微信支付

1.微信支付官方文件微信官網連結
2.可以看到這些支付方式。
可以看到微信這些支付方式
3.在此介紹公眾號支付和app支付。後面的開發基本看下文件就沒什麼問題了。
4.開發之前需要準備前期公眾。
5.首先需要申請公眾號並且開通支付等設定一些配置東西,這裡就不廢話了。
6.程式碼如下:
一、公眾號網頁支付(H5調起支付)

package com.common.action;
import java.io.BufferedOutputStream;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts2.ServletActionContext
; import org.apache.struts2.convention.annotation.Namespace; import org.apache.struts2.convention.annotation.ParentPackage; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import com.common.util.PoUtil; import com.common.util
.RequestUtil; import com.common.util.ResponseResultUtil; import com.common.util.ResultBeanUtil; import com.common.util.TokenUtil; import com.common.util.wx.WeixinPayUtil; import com.common.util.wx.XMLUtil; import com.frame.base.dto.Query; import com.frame.enums.DeletedStatus; import com.frame.enums.PlatformType; import com.opensymphony.xwork2.ActionSupport; import com.sfc.service.interfaces.ISfcFormOrderServiceCustom; @ParentPackage("struts-framework") @Namespace("/wxPayTools") @SuppressWarnings("all") public class WxPayToolsAction extends ActionSupport{ private static final long serialVersionUID = 4809391090975348475L; private static final Log logger = LogFactory.getLog(WxPayToolsAction.class); protected HttpServletRequest request = ServletActionContext.getRequest(); protected HttpServletResponse response = ServletActionContext.getResponse(); @Autowired @Qualifier("tSysWxPayConfigCustomService") private ITSysWxPayConfigServiceCustom tSysWxPayConfigCustomService; @Autowired @Qualifier("terminalUserService") private ITerminalUserService terminalUserService; /** * 獲取action類名 * @return */ private String getActionName(){ return this.getClass().getSimpleName(); } /** * 微信公眾號支付 */ public void wxPay(){ String methodName = "wxPay"; String message = ""; try{ String ecid = RequestUtil.getParameter(request, "ecid"); String orderNum = RequestUtil.getParameter(request, "orderNum"); String orderMoney = RequestUtil.getParameter(request, "orderMoney"); String userId = RequestUtil.getParameter(request, "userId"); String notifyUrl = RequestUtil.getParameter(request, "notifyUrl"); String body = RequestUtil.getParameter(request, "body"); String detail = RequestUtil.getParameter(request, "detail"); TSysWxPayConfigCustom wxPayConfigCustom = tSysWxPayConfigCustomService.getTSysWxPayConfigCustom(ecid); if(wxPayConfigCustom == null){ ResponseUtils.renderJsonObject(response, ResponseResultUtil.returnFailResult(ResultBeanUtil.MSG_FAIL, "查詢配置資訊為空"); return; } // 獲取 prepayId String prepayId= ""; Map<String, Object> mrsInfo = new HashMap<String, Object>(); SortedMap<String, String> wxInfo = new TreeMap<>(); wxInfo.put("orderNum",orderNum); wxInfo.put("orderMoney",orderMoney); wxInfo.put("body",body); wxInfo.put("detail",detail); Map<String, String> data = new HashMap<String,String>(); //微信公眾號手機網頁支付 TerminalUser terminalUser = terminalUserService.findObjById(userId); if(terminalUser == null){ message = "查詢資料為空terminalUser="+terminalUser ; ResponseUtils.renderJsonObject(response, ResponseResultUtil.returnFailResult(ResultBeanUtil.MSG_FAIL, message)); return; } String openId = terminalUser.getOpenId(); if(StringUtil.isEmptyOrNullStr(openId)){ ResponseUtils.renderJsonObject(response, ResponseResultUtil.returnFailResult(ResultBeanUtil.MSG_FAIL, "使用者openid為空openId="+openId)); return; } wxInfo.put("openId", openId); // 根據prepayId簽名 prepayId = WeixinPayUtil.getWxJsPrepayId(request, response, wxInfo, wxPayConfigCustom,notifyUrl); data = weixiPayUtil.createWxJsSignByPrepayId(request, response, prepayId, wxPayConfigCustom); if (StringUtil.isEmptyOrNullStr(prepayId) || "-1".equals(prepayId)) { message = methodName + " 方法 微信支付 ,微信公眾號手機網頁支付獲取預支付 prepayId " + prepayId + " 有誤!"; logger.error(message); ResponseUtils.renderJsonObject(response,ResponseResultUtil.returnExceptionResult(ResultBeanUtil.MSG_EXCEPTION, message)); return; } mrsInfo.put("wxJsApi", data); ResponseUtils.renderJsonObject(response, ResponseResultUtil.returnSuccResult(mrsInfo)); }catch(Exception e){ logger.error(getActionName() + "類的" + methodName + " 方法異常了exception=" + e.getMessage(), e); e.printStackTrace(); ResponseUtils.renderJsonObject(response, ResponseResultUtil.returnExceptionResult( ResultBeanUtil.MSG_EXCEPTION, getActionName() + "類的" + methodName + " 方法異常了!")); } } } package com.common.util.wx; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.ServletActionContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.xcx.util.Sign; /** * 微信支付工具類 * @ClassName: WeixiPayUtil * @Description: 微信支付工具 * @author Administrator * @date 2017年4月28日 下午12:02:12 * */ public class WeixinPayUtil { private static Logger logger = LoggerFactory.getLogger(WeixinPayUtil.class); public static final String RETURN_CODE_SUCC = "SUCCESS"; public static final String RETURN_CODE_FAIL = "FAIL"; public static final String JSAPI_PREPAY_ID = "jsapi_prepayId_"; public static final String APP_PREPAY_ID = "app_prepayId_"; protected static HttpServletRequest request = ServletActionContext.getRequest(); protected static HttpServletResponse response = ServletActionContext.getResponse(); public static SortedMap<String,String> getOrderInfoMap(Map<String, Object> mrsInfo, List<Map<String, Object>> productList){ SortedMap<String,String> orderInfo = new TreeMap<String, String>(); orderInfo.put("userId", mrsInfo.get("userId").toString()); orderInfo.put("orderNum", mrsInfo.get("orderNum").toString()); orderInfo.put("orderMoney", mrsInfo.get("allMoney").toString()); String subject = "",body=""; int bookCount = 0; if(productList!=null && productList.size()>0){ for (Map<String, Object> shopOrderDetail : productList) { subject = subject + shopOrderDetail.get("productName") + " , "; bookCount = bookCount + StrUtil.getIntValue(shopOrderDetail.get("productCount").toString()); } } if(subject.contains(",")){ if(subject.length()>25){ subject = subject.substring(0,25)+"......"; } subject = subject.substring(0,subject.length()-3);// 去掉最後一個,號或者最後一個.號 } body = "訂單:"+mrsInfo.get("orderNum")+" 共包含"+bookCount+"件商品。"; orderInfo.put("body", body); orderInfo.put("detail", subject); return orderInfo; } /** * 獲取JSAPI預支付ID * @param request * @param response * @param orderInfo 包括欄位orderNum,orderMoney(單位:分),myNotifyUrl(自定義回撥地址時,可空),openId,detail(可空),body * @param wxPayConfigCustom * @param selfNotifyUrl 自定義通知連結 * @return */ public static String getWxJsPrepayId(HttpServletRequest request, HttpServletResponse response, Map<String,String> orderInfo, TSysWxPayConfigCustom wxPayConfigCustom, String selfNotifyUrl){ String methodName = "getWxJsPrepayId"; // 微信配置資訊 String wxappId = wxPayConfigCustom.getPublicAppId(); // 公眾號的唯一標識 String wxappSecret = wxPayConfigCustom.getPublicSecret(); // 微信公眾平臺應用APPSECRET // 訂單資訊 String out_trade_no = orderInfo.get("orderNum");//訂單號 logger.info("out_trade_no="+out_trade_no); String prepayId = getJsapiPrepayIdRedis(out_trade_no); if(!StringUtil.isEmpty(prepayId)){ return prepayId; } String orderMoney = orderInfo.get("orderMoney"); logger.info("orderMoney="+orderMoney); // 呼叫公共支付介面傳的自定義業務回撥通知地址 String myNotifyUrl = orderInfo.get("myNotifyUrl"); // 金額轉化為分為單位 float sessionmoney = Float.parseFloat(orderMoney); String finalmoney = String.format("%.2f", sessionmoney); String total_fee = Integer.parseInt(finalmoney.replace(".", "")) + ""; String detail = orderInfo.get("detail"); String openId = orderInfo.get("openId"); logger.info("openId="+openId); // 商品描述 String body = orderInfo.get("body"); logger.info("body="+body); if(StringUtil.isEmptyAnyOf(out_trade_no, orderMoney, body, openId)){ logger.info(getClassName()+"類 "+ methodName +"方法,orderNum,orderMoney,body,openId引數必須都不為空!"); return "-1"; } // 商戶相關資料 String wxpartner = wxPayConfigCustom.getPublicMchId(); String wxpartnerkey = wxPayConfigCustom.getPublicKey(); // 商戶號 String mch_id = wxpartner; // 隨機數 String nonce_str = Sha1Util.getNonceStr(); //附加資料 String attach = getAttachKey(out_trade_no, myNotifyUrl); // 訂單生成的機器 IP String spbill_create_ip = request.getRemoteAddr(); // 這裡notify_url是 支付完成後微信發給該連結資訊,可以判斷會員是否支付成功,改變訂單狀態等。 String url = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath(); String notify_url = url; if (StringUtil.isEmpty(selfNotifyUrl)) { notify_url += WeixinConfig.notify_url;//支付調起的連結/weiXinPay/wei_xin_pay!payNotify.action } else { notify_url += selfNotifyUrl; } String trade_type = WeixinConfig.trade_type_jsapi;//填寫JSAPI SortedMap<String, String> packageParams = new TreeMap<String, String>(); packageParams.put("appid", wxappId); packageParams.put("mch_id", mch_id); packageParams.put("nonce_str", nonce_str); packageParams.put("body", body); if (StringUtil.isNotEmpty(detail)) { packageParams.put("detail", detail); } packageParams.put("attach", attach); packageParams.put("out_trade_no", out_trade_no); packageParams.put("total_fee", total_fee); packageParams.put("spbill_create_ip", spbill_create_ip); packageParams.put("notify_url", notify_url); packageParams.put("trade_type", trade_type); packageParams.put("openid", openId); RequestHandler reqHandler = new RequestHandler(request, response); reqHandler.init(wxappId, wxappSecret, wxpartnerkey); String sign = reqHandler.createSign(packageParams); String xml="<xml>"+ "<appid>"+wxappId+"</appid>"+ "<mch_id>"+mch_id+"</mch_id>"+ "<nonce_str>"+nonce_str+"</nonce_str>"+ "<sign>"+sign+"</sign>"+ "<body><![CDATA["+body+"]]></body>"; if(StringUtil.isNotEmpty(detail)){ xml += "<detail><![CDATA["+detail+"]]></detail>"; } xml += "<attach>"+attach+"</attach>"+ "<out_trade_no>"+out_trade_no+"</out_trade_no>"+ "<total_fee>"+total_fee+"</total_fee>"+ "<spbill_create_ip>"+spbill_create_ip+"</spbill_create_ip>"+ "<notify_url>"+notify_url+"</notify_url>"+ "<trade_type>"+trade_type+"</trade_type>"+ "<openid>"+openId+"</openid>"+ "</xml>"; logger.info(getClassName()+"類 "+ methodName +"方法,xml="+ xml); String createOrderURL = WeixinConfig.prepay_url; try { prepayId = GetWxOrderno.getPayNo(createOrderURL, xml); setJsapiPrepayIdRedis(out_trade_no, prepayId); logger.info(getClassName()+"類 "+ methodName +"方法,生成 prepayId="+prepayId+"||orderNum="+out_trade_no); } catch (Exception e) { logger.error(getClassName()+"類 "+ methodName +"方法,生成 prepayId 出錯了", e); e.printStackTrace(); } return prepayId; } package com.shopn.util; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.HttpProtocolParams; import org.apache.http.util.EntityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.common.model.TSysWxPayConfigCustom; import net.sf.json.JSONObject; public class weixiPayUtil { private static Logger logger = LoggerFactory.getLogger(weixiPayUtil.class); //封裝H5請求的引數 public static Map<String,String> createWxJsSignByPrepayId(HttpServletRequest request, HttpServletResponse response, String prepayId,TSysWxPayConfigCustom wxPayConfigCustom){ String wxappid = WeixinpayConfig.wxappid; String wxappsecret = WeixinpayConfig.wxappsecret; String partnerkey = WeixinpayConfig.wxpartnerkey; if(wxPayConfigCustom!=null){ if(!StringUtil.isEmptyOrNullStr(wxPayConfigCustom.getPublicAppId())){ wxappid = wxPayConfigCustom.getPublicAppId(); wxappsecret = wxPayConfigCustom.getPublicSecret(); partnerkey = wxPayConfigCustom.getPublicKey(); } } String noncestr = Sha1Util.getNonceStr(); String timeStamp = Sha1Util.getTimeStamp(); String signType = WeixinpayConfig.sign_type_md5; String packageStr = "prepay_id="+prepayId; SortedMap<String,String> params = new TreeMap<String,String>(); params.put("appId", wxappid); params.put("timeStamp",timeStamp); params.put("nonceStr", noncestr); params.put("package", packageStr); params.put("signType", signType); //生成支付簽名,這個簽名 給 微信支付的呼叫使用 RequestHandler reqHandler = new RequestHandler(request, response); reqHandler.init(wxappid, wxappsecret, partnerkey); String paySign = reqHandler.createSign(params); Map<String,String> map = new HashMap<String, String>(); map.put("appId", wxappid); map.put("nonceStr", noncestr); map.put("timeStamp", timeStamp); map.put("signType", signType); map.put("packageStr", packageStr); map.put("paySign", paySign); logger.info("createWxJsSignByPrepayId方法中生成 finalSign "+paySign); return map; } } }

生成微信公眾號H5發起的支付引數,然後通前端H5調起支付就可以了。H5發起支付微信公眾號連結