关于微信支付
微信支付分为很多种类型,详细可以看官方文档:https://pay.weixin.qq.com/wiki/doc/api/index.html
微信支付官方接入指引:https://pay.weixin.qq.com/static/applyment_guide/applyment_index.shtml
在了解并获得微信支付商户号后,这里以java为例,简单讲一下微信支付的代码。
首先需要在pom里引入:
<dependency> <groupId>com.github.liyiorg</groupId> <artifactId>weixin-popular</artifactId> <version>2.8.25</version> </dependency>
微信支付demo
package weixin.popular.example; import java.io.IOException; import java.util.UUID; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import weixin.popular.api.PayMchAPI; import weixin.popular.bean.paymch.Unifiedorder; import weixin.popular.bean.paymch.UnifiedorderResult; import weixin.popular.util.PayUtil; /** * 生成WEB JS 支付请求json * @author LiYi * */ public class PayMchJsServlet extends HttpServlet{ /** * */ private static final long serialVersionUID = 1L; private String appid; //appid private String mch_id; //微信支付商户号 private String key; //API密钥 @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //payPackage 的商品信息,openid 可以通过sns,或事件获取。 Unifiedorder unifiedorder = new Unifiedorder(); unifiedorder.setAppid(appid); unifiedorder.setMch_id(mch_id); unifiedorder.setNonce_str(UUID.randomUUID().toString().toString().replace("-", "")); unifiedorder.setOpenid(wx_openid); unifiedorder.setBody("商品信息"); unifiedorder.setOut_trade_no("123456"); unifiedorder.setTotal_fee("1");//单位分 unifiedorder.setSpbill_create_ip(request.getRemoteAddr());//IP unifiedorder.setNotify_url("http://mydomain.com/test/notify"); unifiedorder.setTrade_type("JSAPI");//JSAPI,NATIVE,APP,WAP //统一下单,生成预支付订单 UnifiedorderResult unifiedorderResult = PayMchAPI.payUnifiedorder(unifiedorder,key); //@since 2.8.5 API返回数据签名验证 if(unifiedorderResult.getSign_status() !=null && unifiedorderResult.getSign_status()){ String json = PayUtil.generateMchPayJsRequestJson(unifiedorderResult.getPrepay_id(), appid, key); //将json 传到jsp 页面 request.setAttribute("json", json); //示例jsp request.getRequestDispatcher("pay_example.jsp").forward(request,response); } } }
package weixin.popular.example; import java.io.IOException; import java.nio.charset.Charset; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import weixin.popular.bean.paymch.MchBaseResult; import weixin.popular.bean.paymch.MchPayNotify; import weixin.popular.support.ExpireKey; import weixin.popular.support.expirekey.DefaultExpireKey; import weixin.popular.util.SignatureUtil; import weixin.popular.util.StreamUtils; import weixin.popular.util.XMLConverUtil; /** * 支付回调通知 * @author LiYi * */ public class PayMchNotifyServlet extends HttpServlet{ /** * */ private static final long serialVersionUID = 1L; private String key; //mch key //重复通知过滤 private static ExpireKey expireKey = new DefaultExpireKey(); @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取请求数据 String xmlData = StreamUtils.copyToString(request.getInputStream(), Charset.forName("utf-8")); //将XML转为MAP,确保所有字段都参与签名验证 Map<String,String> mapData = XMLConverUtil.convertToMap(xmlData); //转换数据对象 MchPayNotify payNotify = XMLConverUtil.convertToObject(MchPayNotify.class,xmlData); //已处理 去重 if(expireKey.exists(payNotify.getTransaction_id())){ MchBaseResult baseResult = new MchBaseResult(); baseResult.setReturn_code("SUCCESS"); baseResult.setReturn_msg("OK"); response.getOutputStream().write(XMLConverUtil.convertToXML(baseResult).getBytes()); return; } //签名验证 if(SignatureUtil.validateSign(mapData,key)){ //@since 2.8.5 payNotify.buildDynamicField(mapData); expireKey.add(payNotify.getTransaction_id()); MchBaseResult baseResult = new MchBaseResult(); baseResult.setReturn_code("SUCCESS"); baseResult.setReturn_msg("OK"); response.getOutputStream().write(XMLConverUtil.convertToXML(baseResult).getBytes()); }else{ MchBaseResult baseResult = new MchBaseResult(); baseResult.setReturn_code("FAIL"); baseResult.setReturn_msg("ERROR"); response.getOutputStream().write(XMLConverUtil.convertToXML(baseResult).getBytes()); } } }