微信APP支付
来源:互联网 发布:编程入门教学视频 编辑:程序博客网 时间:2024/04/30 13:14
微信APP支付
说明:此微信支付前端使用的是Angularjs,ionic ,
支付插件是cordova-plugin-wechat(插件下载地址:https://github.com/xu-li/cordova-plugin-wechat);
一、微信APP支付步骤
1.进入微信开放平台https://open.weixin.qq.com/注册;
2.登录进去创建移动应用,填写应用签名和应用包名(很重要包名的填写规则及签名,详见https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_5微信开发文档),并申请微信支付功能;
3.获得微信商户平台账号,获得微信商户号及应用APPID
4.微信APP支付开发文档地址https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=1_2 (不看这微信开发文档,我就不说啥了)
好了废话不说了,下面贴APP支付代码
二、微信APP支付代码
1、微信的支付工具类
package com.huaxia.traffic.app.util;import java.io.BufferedReader;import java.io.ByteArrayInputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.UnsupportedEncodingException;import java.net.MalformedURLException;import java.net.URL;import java.util.Date;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;import java.util.SortedMap;import javax.net.ssl.HttpsURLConnection;import org.jdom.Document;import org.jdom.Element;import org.jdom.input.SAXBuilder;import org.springframework.util.DigestUtils;public class WxPayUtil { //发送https POST 请求 public static String httpsPost(String httpsUrl, String xmlStr) { BufferedReader in = null; InputStreamReader inputStreamReader = null; InputStream inputStream = null; HttpsURLConnection urlCon = null; try { urlCon = (HttpsURLConnection) (new URL(httpsUrl)).openConnection(); urlCon.setDoInput(true); urlCon.setDoOutput(true); urlCon.setRequestMethod("POST"); urlCon.setRequestProperty("Content-Length", String.valueOf(xmlStr.getBytes().length)); urlCon.setUseCaches(false); urlCon.getOutputStream().write(xmlStr.getBytes("utf-8")); urlCon.getOutputStream().flush(); inputStream = urlCon.getInputStream(); inputStreamReader = new InputStreamReader(inputStream,"utf-8"); in = new BufferedReader(inputStreamReader); String line; StringBuffer sb = new StringBuffer(); while ((line = in.readLine()) != null) { sb.append(line); } System.out.println(sb.toString()); return sb.toString(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); }finally{ try {in.close();inputStreamReader.close();inputStream.close();inputStream = null; urlCon.disconnect();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} } return null; } //将SortedMap转换成xml格式的String @SuppressWarnings({ "rawtypes" })public static String getReqXml(SortedMap<Object, Object> map){ StringBuffer sb =new StringBuffer(); sb.append("<xml>"); Set<?> es = map.entrySet(); Iterator<?> it = es.iterator(); while(it.hasNext()){ Map.Entry entry = (Map.Entry)it.next(); String k = (String) entry.getKey(); Object v = entry.getValue(); if("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k) || "sign".equalsIgnoreCase(k)){ sb.append("<"+k+">"+"<![CDATA["+v+"]]>"+"</"+k+">"); }else{ sb.append("<"+k+">"+v+"</"+k+">"); } } sb.append("</xml>"); return sb.toString(); }//微信签名 @SuppressWarnings("rawtypes")public static String createSign(SortedMap<Object, Object> map,String key){StringBuffer sb =new StringBuffer();Set<?> es = map.entrySet();Iterator<?> it = es.iterator(); while(it.hasNext()){ Map.Entry entry = (Map.Entry)it.next(); String k = (String) entry.getKey(); Object v = entry.getValue(); if(null != v && !"".equals(v)&& !"sign".equals(k)){ sb.append(k + "=" + v + "&"); } } sb.append("key="+key); String md5Val = DigestUtils.md5DigestAsHex(getContentBytes(sb.toString(), "UTF-8")).toUpperCase(); return md5Val;} private static byte[] getContentBytes(String content, String charset) { if (charset == null || "".equals(charset)) { return content.getBytes(); } try { return content.getBytes(charset); } catch (UnsupportedEncodingException e) { throw new RuntimeException("MD5签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:" + charset); } } //将XML格式的String转换成MAP @SuppressWarnings({ "rawtypes" })public static Map<String,String> doXmlParse(String xmlStr){ if(xmlStr == null || "".equals(xmlStr)){ return null; } xmlStr = xmlStr.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\""); Map<String,String> m = new HashMap<String,String>(); InputStream in = null; try {in = new ByteArrayInputStream(xmlStr.getBytes("UTF-8"));SAXBuilder builder = new SAXBuilder();Document doc = builder.build(in);Element root = doc.getRootElement();List list = root.getChildren();Iterator it = list.iterator();while(it.hasNext()){Element e = (Element)it.next();String k = e.getName();String v = "";List children = e.getChildren();if(children.isEmpty()){v = e.getTextNormalize();}else{v = getChildrenText(children);}m.put(k, v);} } catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();} finally{try {in.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}} return m; } @SuppressWarnings("rawtypes")public static String getChildrenText(List children){ StringBuffer sb =new StringBuffer(); if(!children.isEmpty()){ Iterator it = children.iterator(); while(it.hasNext()){ Element e = (Element)it.next();String name = e.getName();String value = e.getTextNormalize();List list = e.getChildren();sb.append("<"+name+">");if(!list.isEmpty()){sb.append(getChildrenText(list));}sb.append(value);sb.append("</"+name+">"); } } return sb.toString(); }}2.微信统一下单
package com.huaxia.traffic.app.selfservice.service.impl;import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.InputStreamReader;import java.security.KeyStore;import java.util.Date;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.Map.Entry;import java.util.Set;import java.util.SortedMap;import java.util.TreeMap;import java.util.UUID;import javax.net.ssl.SSLContext;import javax.servlet.http.HttpServletRequest;import org.apache.http.HttpEntity;import org.apache.http.client.methods.CloseableHttpResponse;import org.apache.http.client.methods.HttpPost;import org.apache.http.conn.ssl.SSLConnectionSocketFactory;import org.apache.http.conn.ssl.SSLContexts;import org.apache.http.entity.StringEntity;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.HttpClients;import org.apache.http.util.EntityUtils;import org.apache.log4j.Logger;import org.springframework.beans.factory.annotation.Value;import org.springframework.scheduling.annotation.Async;import org.springframework.stereotype.Service;import com.huaxia.traffic.app.selfservice.bean.OrderRequestBean;import com.huaxia.traffic.app.selfservice.domain.PayLog;import com.huaxia.traffic.app.selfservice.service.WxPayService;import com.huaxia.traffic.app.util.WxPayUtil;@Servicepublic class WxPayServiceImpl implements WxPayService{/** * Logger for this class */ private static final Logger logger = Logger.getLogger(PayServiceImpl.class); @Value("${wxpay.appid}") private String appid; @Value("${wxpay.attach}") private String attach; @Value("${wxpay.mchid}") private String mchid; @Value("${wxpay.notifyUrl}") private String notifyUrl;//调起支付后的回调地址 里面有响应信息 @Value("${wxpay.tradeType}") private String tradeType; @Value("${wxpay.key}")//微信商户平台API安全里面自己设置 签名要用 private String key; @Value("${wxpay.unifiedorderUrl}") private String unifiedorderUrl;//统一下单地址 @Value("${wxpay.refundUrl}") private String refundUrl;//退款地址 @Value("${wxpay.certCatalog}") private String certCatalog;//微信证书地址,退单要用;微信商户平台里面自己去下载 /** * 统一下单 */@Overridepublic Map<String,String> uniformOrder(OrderRequestBean orderRequestBean,HttpServletRequest request) {// TODO Auto-generated method stubString ip = request.getRemoteAddr();SortedMap<Object, Object> map = new TreeMap<Object, Object>();map.put("appid", appid);map.put("attach", attach);map.put("body", "APP——流量加油站-手机流量充值");map.put("mch_id", mchid);map.put("nonce_str", UUID.randomUUID().toString().replace("-", ""));map.put("notify_url", notifyUrl);map.put("out_trade_no", orderRequestBean.getOutTradeNo());map.put("spbill_create_ip", ip);map.put("total_fee", (int)(orderRequestBean.getFee()*100));map.put("trade_type", tradeType);String sign = WxPayUtil.createSign(map,key);map.put("sign", sign);String xmlStr = WxPayUtil.getReqXml(map);logger.info(xmlStr);String backInfo = WxPayUtil.httpsPost(unifiedorderUrl, xmlStr);Map<String,String> m = WxPayUtil.doXmlParse(backInfo);return m;}/** * 生成支付订单 */public Map<String,String> payOrder(Map<String,String> m){SortedMap<Object, Object> map = new TreeMap<Object, Object>();String prepayid = m.get("prepay_id");String timestamp = Long.toString((new Date().getTime())/1000);Map<String,String> returnMap = new HashMap<String, String>();map.put("appid", appid);map.put("partnerid",mchid);map.put("prepayid",prepayid);map.put("package","Sign=WXPay");map.put("noncestr",UUID.randomUUID().toString().replace("-", ""));map.put("timestamp",timestamp);String sign = WxPayUtil.createSign(map,key);map.put("sign", sign);Set<Entry<Object, Object>> entry = map.entrySet();Iterator<Entry<Object, Object>> it = entry.iterator();while (it.hasNext()) {Entry<Object, Object> e = it.next();returnMap.put(e.getKey().toString(), e.getValue().toString());} String xmlStr = WxPayUtil.getReqXml(map);logger.info(xmlStr);return returnMap;}/** * 生成退单 */public String refundOrder(PayLog payLog) {// TODO Auto-generated method stubSortedMap<Object, Object> map = new TreeMap<Object, Object>();map.put("appid", appid);map.put("mch_id", mchid);map.put("nonce_str", UUID.randomUUID().toString().replace("-", ""));map.put("op_user_id", mchid);map.put("out_trade_no", payLog.getSerialNumber());map.put("out_refund_no", UUID.randomUUID().toString().replace("-", ""));map.put("total_fee", (int)(payLog.getFee()*100));map.put("refund_fee", (int)(payLog.getFee()*100));String sign = WxPayUtil.createSign(map,key);map.put("sign", sign);String xmlStr = WxPayUtil.getReqXml(map);logger.info(xmlStr);return xmlStr;}/** * 退单 */@Async@Overridepublic String refund(String strXml){// TODO Auto-generated method stubString text = "";try {KeyStore keyStore = KeyStore.getInstance("PKCS12");FileInputStream instream = new FileInputStream(new File(certCatalog));try {keyStore.load(instream, mchid.toCharArray());} finally {instream.close();}SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, mchid.toCharArray()).build();SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null,SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();try {HttpPost httppost = new HttpPost(refundUrl);StringEntity se = new StringEntity(strXml);httppost.setEntity(se);System.out.println("executing request" + httppost.getRequestLine());CloseableHttpResponse response = httpclient.execute(httppost);try {HttpEntity entity = response.getEntity();logger.info("----------------------------------------");logger.info(response.getStatusLine());if (entity != null) {logger.info("Response content length: "+ entity.getContentLength());BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent()));while ((text = bufferedReader.readLine()) != null) {logger.info(text);}}EntityUtils.consume(entity);} finally {response.close();}} finally {httpclient.close();}return text;} catch (Exception e) {e.printStackTrace();}return null;}}3.页面调起支付
4.支付成功后获取微信返回的支付信息var params = { partnerid: '10000100', // merchant id prepayid: 'wx201411101639507cbf6ffd8b0779950874', // prepay id noncestr: '1add1a30ac87aa2db72f57a2375d8fec', // nonce timestamp: '1439531364', // timestamp sign: '0CB01533B8C1EF103065174F50BCA001', // signed string};Wechat.sendPaymentRequest(params, function () { alert("Success");}, function (reason) { alert("Failed: " + reason);});
@Override @ResponseBody @RequestMapping("/wxNotify") public ReturnBean wxNotify(HttpServletRequest request){ System.out.println("---success--"); InputStream is;try {is = request.getInputStream();String xml = this.inputStream2String(is, "UTF-8");logger.info(xml);System.out.println(xml);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} /** * 后面把xml转成Map根据数据作逻辑处理 */ return null; }
0 0
- 支付--微信APP支付
- 微信支付app
- 微信支付app
- 微信APP支付
- app微信支付
- APP微信支付
- app微信支付
- 微信APP支付
- 支付--微信APP
- 微信APP支付
- 微信app支付
- 微信APP支付
- 微信APP支付
- APP微信支付集成
- 微信app支付问题
- 微信APP支付填坑记
- 微信支付 app 服务器
- 微信APP支付 C#
- Hdu2524
- 透彻 Linux (Unix) 五种 IO 模型
- hdu ACM steps 1.2.6 hdu3361
- QT5 样式表无效问题
- C#滚动条的使用
- 微信APP支付
- sql游标
- 堆和栈的区别(转过无数次的文章)
- 【转】2017年,电视内容将如何发展?
- 邮件正则表达式
- OPC 统一架构的优势
- shimmer让你的view闪烁起来
- 安卓自定义theme以及attrs,styles资源文件详解(一)
- Bind event to element using pure Javascript