java微信公眾號支付(H5調起微信內置API)

以下信息都能從公眾號和商戶號中獲得,我是將這些信息放在properties文件中的

#公眾號appid 
APPID=xxxxx
#公眾號appsecret 
APPSECRET=xxxxx
#微信模板號
modelId=c4QSCD8K9zoGeebJp5t2QNzL-Wj8srCjlt_W5PLsap0
#商戶號
mch_id=xxxxxx
#商戶后臺配置的一個32位的key,位置:微信商戶平臺-賬戶中心-API安全
Key=xxxxxx
#交易類型
TRADE_TYPE_JSAPI=JSAPI

每個微信公眾號對應一個商戶號,當用戶關注你的公眾號后,如果在你的公眾號里面要進行支付操作,那么他支付的金額就流入到了你這個商戶號里去了

圖片.png

KEY是啥? 同理,商戶號中 賬戶中心--API安全 ↓↓↓ 長度32位哦。。。。

圖片.png

授權獲取openId(可以是用戶進你的界面就直接做,也可以用戶點擊界面中的某個按鈕再授權,主要是拿openId)

WechatPayController.java

 package com.ssm.controller;

import com.ssm.model.*;
import com.ssm.util.WXPayUtil;
import com.ssm.util.WeiXinUtil;
import com.ssm.util.WxSign;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.SortedMap;
import java.util.TreeMap;

import static com.ssm.controller.WeChatController.getUser;

/**
 * 微信支付controller
 * 1.用戶發起微信支付,初始化數據、調用統一下單接口。生成JSAPI頁面調用的支付參數并簽名(paySign,prepay_id,nonceStr,timestamp)
 * 2.js如果返回Ok,提示支付成功,實際支付結果已收到通知為主。
 * 3.在微信支付結果通知中,獲取微信提供的最終用戶支付結果信息,支付結果等信息更新用戶支付記錄中
 * 4.根據微信支付結果通知中的微信訂單號調用查詢接口,如果查詢是已經支付成功,則發送支付成功模板信息給客戶
 */
@RestController
@RequestMapping(value = "wechatpay")
public class WechatPayController{
    private static Logger log = LoggerFactory.getLogger(WechatPayController.class);

    /**
    *跳轉支付界面,將openId帶到h5頁面上去
    **/
    @RequestMapping(value = "redirectpay")
    public ModelAndView Pay(String code){
        ModelAndView modelAndView = new ModelAndView("wechatPay");
        //獲取微信用戶id
        try {
            WeixinOauth2Token weixinOauth2Token = getUser(code);
            modelAndView.addObject("openId",weixinOauth2Token.getOpenId());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return modelAndView;
    }
}

:WeixinOauth2Token實體類是網頁授權信息

WechatController.java

package com.ssm.controller;

import com.alibaba.fastjson.JSONObject;
import com.ssm.model.AccessToken;
import com.ssm.model.WeixinOauth2Token;
import com.ssm.util.WeiXinUtil;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static com.ssm.util.WeiXinUtil.APPID;
import static com.ssm.util.WeiXinUtil.APPSECRET;
import static com.ssm.util.WeiXinUtil.doGetStr;

@RestController
@RequestMapping(value = "wechat")
public class WeChatController {
    public static String url="";
    public static String wechaturl="";
    public static String modelId="";

    //獲取用戶id
    public static WeixinOauth2Token getUser(String code) throws IOException {
        System.out.println("code:"+code);
        WeixinOauth2Token weixinOauth2Token = new WeixinOauth2Token();
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="+APPID+"&secret="+APPSECRET+"&code="+code+"&grant_type=authorization_code";
        JSONObject jsonObject = doGetStr(url);
        if(jsonObject!=null){
            System.out.println(jsonObject);
            /*String access_token = jsonObject.getString("access_token");//網頁授權接口調用憑證,注意:此access_token與基礎支持的access_token不同
            String expires_in = jsonObject.getString("expires_in");//access_token接口調用憑證超時時間,單位(秒)
            String refresh_token = jsonObject.getString("refresh_token");//用戶刷新access_token*/
            String openid = jsonObject.getString("openid");//用戶唯一標識,請注意,在未關注公眾號時,用戶訪問公眾號的網頁,也會產生一個用戶和公眾號唯一的OpenID
            //String scope = jsonObject.getString("scope");//用戶授權的作用域,使用逗號(,)分隔
            if(openid!=null){
                weixinOauth2Token.setOpenId(openid);
            }
        }
        return weixinOauth2Token;
    }
}

授權做完,openId拿到,跳轉到支付界面,如下:

<%--
  Created by IntelliJ IDEA.
  User: SeaRan
  Date: 2018/6/4
  Time: 17:12
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!doctype html>
<html lang="en">
<head>
    <%
        String path = request.getContextPath();
    %>
    <meta charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="ie=edge">
    <meta name="viewport" content="width=device-width,
                                     initial-scale=1.0,
                                     maximum-scale=1.0,
                                     user-scalable=no">
    <title>支付界面</title>
    <script type="text/javascript" src="<%=path%>/resources/js/jquery-3.1.0.min.js"></script>
</head>
<body>
  <input type="button" value="支付" onclick="pay()"/>

<script>
    var prepay_id ;
    var sign ;
    var appId ;
    var timeStamp ;
    var nonceStr ;
    var packageStr ;
    var signType ;

    function pay(){
        var url = '<%=path%>/wechat/wechatpay/pay';//后臺路徑
        $.ajax({
            type:"post",
            url:url,
            dataType:"json",
            data:{openId:'${openId}'},
            success:function(data) {
                if(data.result_code == 'SUCCESS'){
                    appId = data.appid;
                    sign = data.sign;
                    timeStamp = data.timeStamp;
                    nonceStr = data.nonce_str;
                    packageStr = data.packageStr;
                    signType = data.signType;
                    //調起微信支付控件
                    callpay();
                }else{
                    alert("統一下單失敗");
                }
            }
        });
    }

    function onBridgeReady(){
        WeixinJSBridge.invoke(
            'getBrandWCPayRequest', {
                "appId":appId,     //公眾號名稱,由商戶傳入
                "paySign":sign,         //微信簽名
                "timeStamp":timeStamp, //時間戳,自1970年以來的秒數
                "nonceStr":nonceStr , //隨機串
                "package":packageStr,  //預支付交易會話標識
                "signType":signType     //微信簽名方式
            },
            function(res){
                //alert(JSON.stringify(res));
                if(res.err_msg == "get_brand_wcpay_request:ok" ) {
                    //window.location.replace("index.html");
                    alert('支付成功');
                }else if(res.err_msg == "get_brand_wcpay_request:cancel"){
                    alert('支付取消');
                }else if(res.err_msg == "get_brand_wcpay_request:fail" ){
                    alert('支付失敗');
                }
                //使用以上方式判斷前端返回,微信團隊鄭重提示:res.err_msg將在用戶支付成功后返回    ok,但并不保證它絕對可靠。
            }
        );
    }

    function callpay(){
        if (typeof WeixinJSBridge == "undefined"){
            if( document.addEventListener ){
                document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
            }else if (document.attachEvent){
                document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
                document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
            }
        }else{
            onBridgeReady();
        }
    }
</script>

</body>
</html>

如果出現錯誤,支付界面一閃而過(有調起支付控件的跡象),你看不出報什么錯,你可以打印出微信返回的res:alert(JSON.stringify(res));

點擊支付按鈕,進入下面一步

統一下單

WechatPayController.java

/**
   * 點擊支付 統一下單,獲得預付id(prepay_id)
   * @param request
   * @param response
   * @return
    */
    @ResponseBody
    @RequestMapping(value = "pay")
    public WxPaySendData prePay(HttpServletRequest request,HttpServletResponse response,String openId){
        WxPaySendData result = new WxPaySendData();
        try {
        //商戶訂單號
        String out_trade_no = WXPayUtil.getOut_trade_no();
        //產品價格,單位:分
        Integer total_fee = 1;
        //客戶端ip
        String ip = request.getRemoteAddr();
        //支付成功后回調的url地址
        String notify_url = "http://"+WeiXinUtil.getValue("wechaturl")+"wechat/wechatpay/callback";
        //統一下單
        String strResult = WXPayUtil.unifiedorder("testPay", out_trade_no, total_fee, ip, notify_url,openId);
        //解析xml
        XStream stream = new XStream(new DomDriver());
        stream.alias("xml", WxPaySendData.class);
        WxPaySendData wxReturnData = (WxPaySendData)stream.fromXML(strResult);

        //兩者都為SUCCESS才能獲取prepay_id
        if( wxReturnData.getResult_code().equals("SUCCESS") && wxReturnData.getReturn_code().equals("SUCCESS") ){
                //業務邏輯,寫入訂單日志(你自己的業務) .....
                String timeStamp = WXPayUtil.getTimeStamp();//時間戳
                String nonce_str = WXPayUtil.getNonceStr();//隨機字符串
                //注:上面這兩個參數,一定要拿出來作為后續的value,不能每步都創建新的時間戳跟隨機字符串,不然H5調支付API,會報簽名參數錯誤
                result.setResult_code(wxReturnData.getResult_code());
                result.setAppid(WeiXinUtil.getValue("APPID"));
                result.setTimeStamp(timeStamp);
                result.setNonce_str(nonce_str);
                result.setPackageStr("prepay_id="+wxReturnData.getPrepay_id());
                result.setSignType("MD5");

                //WXPayUtil.unifiedorder(.....) 下單操作中,也有簽名操作,那個只針對統一下單,要區別于下面的paySign
                //第二次簽名,將微信返回的數據再進行簽名
                SortedMap<Object,Object> signMap = new TreeMap<Object,Object>();
                signMap.put("appId", WeiXinUtil.getValue("APPID"));
                signMap.put("timeStamp", timeStamp);
                signMap.put("nonceStr", nonce_str);
                signMap.put("package", "prepay_id="+wxReturnData.getPrepay_id());  //注:看清楚,值為:prepay_id=xxx,別直接放成了wxReturnData.getPrepay_id()
                signMap.put("signType", "MD5");
                String paySign = WxSign.createSign(signMap,  WeiXinUtil.getValue("Key"));//支付簽名

                result.setSign(paySign);
            }else{
                result.setResult_code("fail");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

  /**
     * 支付回調接口
     * @param request
     * @return
     */
    @RequestMapping("/callback")
    public void callBack(HttpServletRequest request, HttpServletResponse response){
        response.setContentType("text/xml;charset=UTF-8");
        try {
            InputStream is = request.getInputStream();
            String result = IOUtils.toString(is, "UTF-8");
            if("".equals(result)){
                response.getWriter().write("<xm><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[參數錯誤!]]></return_msg></xml>");
                return ;
            }
            //解析xml
            XStream stream = new XStream(new DomDriver());
            stream.alias("xml", WxPaySendData.class);
            WxPaySendData wxPaySendData = (WxPaySendData)stream.fromXML(result);
            System.out.println(wxPaySendData.toString());

            String appid = wxPaySendData.getAppid();
            String mch_id =wxPaySendData.getMch_id();
            String nonce_str = wxPaySendData.getNonce_str();
            String out_trade_no = wxPaySendData.getOut_trade_no();
            String total_fee = wxPaySendData.getTotal_fee();
            //double money = DBUtil.getDBDouble(DBUtil.getDBInt(wxPaySendData.getTotal_fee())/100.0);
            String trade_type = wxPaySendData.getTrade_type();
            String openid =wxPaySendData.getOpenid();
            String return_code = wxPaySendData.getReturn_code();
            String result_code = wxPaySendData.getResult_code();
            String bank_type = wxPaySendData.getBank_type();
            Integer cash_fee = wxPaySendData.getCash_fee();
            String fee_type = wxPaySendData.getFee_type();
            String is_subscribe = wxPaySendData.getIs_subscribe();
            String time_end = wxPaySendData.getTime_end();
            String transaction_id = wxPaySendData.getTransaction_id();
            String sign = wxPaySendData.getSign();

            //簽名驗證
            SortedMap<Object,Object> parameters = new TreeMap<Object,Object>();
            parameters.put("appid",appid);
            parameters.put("mch_id",mch_id);
            parameters.put("nonce_str",nonce_str);
            parameters.put("out_trade_no",out_trade_no);
            parameters.put("total_fee",total_fee);
            parameters.put("trade_type",trade_type);
            parameters.put("openid",openid);
            parameters.put("return_code",return_code);
            parameters.put("result_code",result_code);
            parameters.put("bank_type",bank_type);
            parameters.put("cash_fee",cash_fee);
            parameters.put("fee_type",fee_type);
            parameters.put("is_subscribe",is_subscribe);
            parameters.put("time_end",time_end);
            parameters.put("transaction_id",transaction_id);
            //以下4個參數針對優惠券(鼓勵金之類的)這個坑真的弄了好久
            parameters.put("coupon_count",wxPaySendData.getCoupon_count());
            parameters.put("coupon_fee",wxPaySendData.getCoupon_fee());
            parameters.put("coupon_id_0",wxPaySendData.getCoupon_id_0());
            parameters.put("coupon_fee_0",wxPaySendData.getCoupon_fee_0());

            String sign2 = WxSign.createSign(parameters,WeiXinUtil.getValue("Key"));

            if(sign.equals(sign2)){//校驗簽名,兩者需要一致,防止別人繞過支付操作,不付錢直接調用你的業務,不然,哈哈,你老板會很開心的 233333.。。。
                if(return_code.equals("SUCCESS") && result_code.equals("SUCCESS")){
                    //業務邏輯(先判斷數據庫中訂單號是否存在,并且訂單狀態為未支付狀態)
                    //do something ...

                    //request.setAttribute("out_trade_no", out_trade_no);
                    //通知微信.異步確認成功.必寫.不然會一直通知后臺.八次之后就認為交易失敗了.
                    response.getWriter().write("<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>");
                }else{
                    response.getWriter().write("<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[交易失敗]]></return_msg></xml>");
                }
            }else{
                //通知微信.異步確認成功.必寫.不然會一直通知后臺.八次之后就認為交易失敗了.
                response.getWriter().write("<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[簽名校驗失敗]]></return_msg></xml>");
            }
            response.getWriter().flush();
            response.getWriter().close();
            return ;
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

統一下單封裝方法 WXPayUtil.java

package com.ssm.util;

import com.ssm.model.WXPayConstants;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.charset.Charset;
import java.util.*;

/**
 * 支付工具類
 */
public class WXPayUtil {
    private static final Logger logger = LoggerFactory.getLogger(WXPayUtil.class);

    /**
     * 統一下單
     * 獲得PrePayId
     * @param body   商品或支付單簡要描述
     * @param out_trade_no 商戶系統內部的訂單號,32個字符內、可包含字母
     * @param total_fee  訂單總金額,單位為分
     * @param ip    APP和網頁支付提交用戶端ip
     * @param notify_url 接收微信支付異步通知回調地址
     * @param openId 用戶openId
     * @throws IOException
     */
    public static String unifiedorder(String body,String out_trade_no,Integer total_fee,String ip,String notify_url,String openId)throws IOException {
        /**
         * 設置訪問路徑
         */
        HttpPost httppost = new HttpPost("https://api.mch.weixin.qq.com/pay/unifiedorder");
        String nonce_str = getNonceStr();//隨機數據
        SortedMap<Object,Object> parameters = new TreeMap<Object,Object>();
        /**
         * 組裝請求參數
         * 按照ASCII排序
         */
        parameters.put("appid",WeiXinUtil.getValue("APPID") );
        parameters.put("body", body);
        parameters.put("mch_id", WeiXinUtil.getValue("mch_id"));
        parameters.put("nonce_str", nonce_str);
        parameters.put("out_trade_no", out_trade_no);
        parameters.put("notify_url", notify_url);
        parameters.put("spbill_create_ip", ip);
        parameters.put("total_fee",total_fee.toString() );
        parameters.put("trade_type",WeiXinUtil.getValue("TRADE_TYPE_JSAPI") );
        parameters.put("openid", openId);

        String sign = WxSign.createSign(parameters, WeiXinUtil.getValue("Key"));
        System.out.println("\nsign:"+sign);

        /**
         * 組裝XML
         */
        StringBuilder sb = new StringBuilder("");
        sb.append("<xml>");
        setXmlKV(sb,"appid",WeiXinUtil.getValue("APPID"));
        setXmlKV(sb,"body",body);
        setXmlKV(sb,"mch_id",WeiXinUtil.getValue("mch_id"));
        setXmlKV(sb,"nonce_str",nonce_str);
        setXmlKV(sb,"notify_url",notify_url);
        setXmlKV(sb,"out_trade_no",out_trade_no);
        setXmlKV(sb,"spbill_create_ip",ip);
        setXmlKV(sb,"total_fee",total_fee.toString());
        setXmlKV(sb,"trade_type",WeiXinUtil.getValue("TRADE_TYPE_JSAPI"));
        setXmlKV(sb,"sign",sign);
        setXmlKV(sb,"openid",openId);
        sb.append("</xml>");

        StringEntity reqEntity = new StringEntity(new String (sb.toString().getBytes("UTF-8"),"ISO8859-1"));//這個處理是為了防止傳中文的時候出現簽名錯誤
        httppost.setEntity(reqEntity);
        DefaultHttpClient httpclient = new DefaultHttpClient();
        HttpResponse response = httpclient.execute(httppost);
        String strResult = EntityUtils.toString(response.getEntity(), Charset.forName("utf-8"));

        return strResult;

    }


    //獲得隨機字符串
    public static String getNonceStr(){
        Random random = new Random();
        return MD5Util.MD5Encode(String.valueOf(random.nextInt(10000)), "UTF-8");
    }

    //插入XML標簽
    public static StringBuilder setXmlKV(StringBuilder sb,String Key,String value){
        sb.append("<");
        sb.append(Key);
        sb.append(">");

        sb.append(value);

        sb.append("</");
        sb.append(Key);
        sb.append(">");

        return sb;
    }

    //解析XML  獲得 PrePayId
    public static String getPrePayId(String xml){
        int start = xml.indexOf("<prepay_id>");
        int end = xml.indexOf("</prepay_id>");
        if(start < 0 && end < 0){
            return null;
        }
        return xml.substring(start + "<prepay_id>".length(),end).replace("<![CDATA[","").replace("]]>","");
    }

    //商戶訂單號
    public static String getOut_trade_no(){
        /*DateFormat df = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        return df.format(new Date()) + RandomChars.getRandomNumber(7);*/
        return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
    }

    //時間戳
    public static String getTimeStamp() {
        return String.valueOf(System.currentTimeMillis() / 1000);
    }

    //隨機4位數字
    public static int buildRandom(int length) {
        int num = 1;
        double random = Math.random();
        if (random < 0.1) {
            random = random + 0.1;
        }
        for (int i = 0; i < length; i++) {
            num = num * 10;
        }
        return (int) ((random * num));
    }

    public static String inputStream2String(InputStream inStream, String encoding){
        String result = null;
        try {
            if(inStream != null){
                ByteArrayOutputStream outStream = new ByteArrayOutputStream();
                byte[] tempBytes = new byte[1024];
                int count = -1;
                while((count = inStream.read(tempBytes, 0, 1024)) != -1){
                    outStream.write(tempBytes, 0, count);
                }
                tempBytes = null;
                outStream.flush();
                result = new String(outStream.toByteArray(), encoding);
            }
        } catch (Exception e) {
            result = null;
        }
        return result;
    }

}

簽名封裝類WxSign.java

package com.ssm.util;

import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;

public class WxSign {

    /**
       * 創建簽名
       * @param parameters
       * @param key
       * @return
       */
    @SuppressWarnings("rawtypes")
    public static String createSign(SortedMap<Object,Object> parameters, String key){
        StringBuffer sb = new StringBuffer();
        Set es = parameters.entrySet();//所有參與傳參的參數按照accsii排序(升序)
        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) && !"key".equals(k)) {
                sb.append(k + "=" + v + "&");
            }
        }
        sb.append("key=" + key);
        String sign = MD5Util.MD5Encode(sb.toString(), "UTF-8").toUpperCase();
        return sign;
    }
}

支付參數封裝類WxPaySendData.java

package com.ssm.model;

/**
 * 微信支付參數
 */
public class WxPaySendData {

    //公眾賬號ID
    private String appid;
    //附加數據
    private String attach;
    //商品描述
    private String body;
    //商戶號
    private String mch_id;
    //隨機字符串
    private String nonce_str;
    //通知地址
    private String notify_url;
    //商戶訂單號
    private String out_trade_no;
    //標價金額
    private String total_fee;
    //交易類型
    private String trade_type;
    //終端IP
    private String spbill_create_ip;
    //用戶標識
    private String openid;
    //簽名
    private String sign;
    //預支付id
    private String prepay_id;
    //簽名類型:MD5
    private String signType;
    //時間戳
    private String timeStamp;
    //微信支付時用到的prepay_id
    private String packageStr;

    private String return_code;
    private String return_msg;
    private String result_code;

    private String bank_type;
    private Integer cash_fee;
    private String fee_type;
    private String is_subscribe;
    private String time_end;
    //微信支付訂單號
    private String transaction_id;
    private String ip;
    private Integer coupon_count;
    private Integer coupon_fee;
    private Integer coupon_fee_0;
    private String coupon_type_0;
    private String coupon_id_0;

    public String getAppid() {
        return appid;
    }

    public void setAppid(String appid) {
        this.appid = appid;
    }

    public String getAttach() {
        return attach;
    }

    public void setAttach(String attach) {
        this.attach = attach;
    }

    public String getBody() {
        return body;
    }

    public void setBody(String body) {
        this.body = body;
    }

    public String getMch_id() {
        return mch_id;
    }

    public void setMch_id(String mch_id) {
        this.mch_id = mch_id;
    }

    public String getNonce_str() {
        return nonce_str;
    }

    public void setNonce_str(String nonce_str) {
        this.nonce_str = nonce_str;
    }

    public String getNotify_url() {
        return notify_url;
    }

    public void setNotify_url(String notify_url) {
        this.notify_url = notify_url;
    }

    public String getOut_trade_no() {
        return out_trade_no;
    }

    public void setOut_trade_no(String out_trade_no) {
        this.out_trade_no = out_trade_no;
    }

    public String getTotal_fee() {
        return total_fee;
    }

    public void setTotal_fee(String total_fee) {
        this.total_fee = total_fee;
    }

    public String getTrade_type() {
        return trade_type;
    }

    public void setTrade_type(String trade_type) {
        this.trade_type = trade_type;
    }

    public String getSpbill_create_ip() {
        return spbill_create_ip;
    }

    public void setSpbill_create_ip(String spbill_create_ip) {
        this.spbill_create_ip = spbill_create_ip;
    }

    public String getOpenid() {
        return openid;
    }

    public void setOpenid(String openid) {
        this.openid = openid;
    }

    public String getSign() {
        return sign;
    }

    public void setSign(String sign) {
        this.sign = sign;
    }

    public String getPrepay_id() {
        return prepay_id;
    }

    public void setPrepay_id(String prepay_id) {
        this.prepay_id = prepay_id;
    }

    public String getSignType() {
        return signType;
    }

    public void setSignType(String signType) {
        this.signType = signType;
    }

    public String getTimeStamp() {
        return timeStamp;
    }

    public void setTimeStamp(String timeStamp) {
        this.timeStamp = timeStamp;
    }

    public String getPackageStr() {
        return packageStr;
    }

    public void setPackageStr(String packageStr) {
        this.packageStr = packageStr;
    }

    public String getReturn_code() {
        return return_code;
    }

    public void setReturn_code(String return_code) {
        this.return_code = return_code;
    }

    public String getReturn_msg() {
        return return_msg;
    }

    public void setReturn_msg(String return_msg) {
        this.return_msg = return_msg;
    }

    public String getResult_code() {
        return result_code;
    }

    public void setResult_code(String result_code) {
        this.result_code = result_code;
    }

    public String getBank_type() {
        return bank_type;
    }

    public void setBank_type(String bank_type) {
        this.bank_type = bank_type;
    }

    public Integer getCash_fee() {
        return cash_fee;
    }

    public void setCash_fee(Integer cash_fee) {
        this.cash_fee = cash_fee;
    }

    public String getFee_type() {
        return fee_type;
    }

    public void setFee_type(String fee_type) {
        this.fee_type = fee_type;
    }

    public String getIs_subscribe() {
        return is_subscribe;
    }

    public void setIs_subscribe(String is_subscribe) {
        this.is_subscribe = is_subscribe;
    }

    public String getTime_end() {
        return time_end;
    }

    public void setTime_end(String time_end) {
        this.time_end = time_end;
    }

    public String getTransaction_id() {
        return transaction_id;
    }

    public void setTransaction_id(String transaction_id) {
        this.transaction_id = transaction_id;
    }

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public Integer getCoupon_count() {
        return coupon_count;
    }

    public void setCoupon_count(Integer coupon_count) {
        this.coupon_count = coupon_count;
    }

    public Integer getCoupon_fee() {
        return coupon_fee;
    }

    public void setCoupon_fee(Integer coupon_fee) {
        this.coupon_fee = coupon_fee;
    }

    public Integer getCoupon_fee_0() {
        return coupon_fee_0;
    }

    public void setCoupon_fee_0(Integer coupon_fee_0) {
        this.coupon_fee_0 = coupon_fee_0;
    }

    public String getCoupon_type_0() {
        return coupon_type_0;
    }

    public void setCoupon_type_0(String coupon_type_0) {
        this.coupon_type_0 = coupon_type_0;
    }

    public String getCoupon_id_0() {
        return coupon_id_0;
    }

    public void setCoupon_id_0(String coupon_id_0) {
        this.coupon_id_0 = coupon_id_0;
    }
}

MD5加密算法

MD5Util.java

package com.ssm.util;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * MD5工具類
 */
public class MD5Util {
    private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5","6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };

    /**
     * md5加密
     *
     * @param text 需要加密的文本
     * @return
     */
    public static String encode(String text) {
        try {// aes rsa
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] result = md.digest(text.getBytes()); // 對文本進行加密
            // b
            // 000000..0000011111111
            StringBuilder sb = new StringBuilder();
            for (byte b : result) {
                int i = b & 0xff ; // 取字節的后八位有效值
                String s = Integer.toHexString(i);
                if (s.length() < 2) {
                    s = "0" + s;
                }
                sb.append(s);
            }

            // 加密的結果
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            // 找不到該算法,一般不會進入這里
            e.printStackTrace();
        }

        return "";
    }

    public static String MD5Encode(String origin, String charsetname) {
        String resultString = null;
        try {
            resultString = new String(origin);
            MessageDigest md = MessageDigest.getInstance("MD5");
            if (charsetname == null || "".equals(charsetname))
                resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
            else
                resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));
        } catch (Exception exception) {

        }
        return resultString;
    }

    private static String byteArrayToHexString(byte b[]) {
        StringBuffer resultSb = new StringBuffer();
        for (int i = 0; i < b.length; i++)
            resultSb.append(byteToHexString(b[i]));

        return resultSb.toString();
    }

    private static String byteToHexString(byte b) {
        int n = b;
        if (n < 0)
            n += 256;
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }
}

:此文章主要是實現微信公眾號支付,關于微信接入授權等沒有貼出

最后一步

你需要有將你公司的微信公眾號開通支付(審核要等個幾天),登錄后找到 微信支付-->商戶信息,你會看到如下圖所示:

圖片.png

配置支付授權目錄

圖片.png

說明一下:配置支付授權目錄,就是當你再H5界面調起支付控件進行支付時,要對你支付的post請求進行校驗

最后

如果文章有什么遺漏或不足,還望大家指教。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,619評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,155評論 3 425
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,635評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,539評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,255評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,646評論 1 326
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,655評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,838評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,399評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,146評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,338評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,893評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,565評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,983評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,257評論 1 292
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,059評論 3 397
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,296評論 2 376

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,701評論 25 708
  • 關于微信支付 生活中的微信支付 目前我們日常生活中接觸得比較多的線上電子支付方式主要有兩種,一種是支付寶,另一種就...
    積_漸閱讀 3,928評論 3 26
  • 最近感覺自己又開始浮躁了,腦袋瓜又開始想東想西,想解決那些還沒輪到解決的問題。最近工作方面提升很多,感覺穩定些又想...
    思言悟語閱讀 137評論 0 1
  • 當想肆意縱情的時候,是他,又讓我重新找回內心的平靜。
    任君雜談閱讀 200評論 0 0
  • 格桑·梅朵 /波寶兒 聽說五顏六色的我 與幸福有關 忍耐,忍耐,只要有陽光 頑強,頑強,纖細的腰肢挺拔的脊梁 雪山...
    波寶兒閱讀 266評論 0 1