中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

微信小程序調用微信支付接口的實現

發布時間:2021-06-03 16:28:05 來源:億速云 閱讀:693 作者:Leah 欄目:web開發

本篇文章為大家展示了微信小程序調用微信支付接口的實現,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

1.開發工具:

Eclipse+Tomcat+微信web開發工具

2.開發環境:

java+maven

3.開發前準備:

3.1 所需材料

小程序的appid,APPsecret,支付商戶號(mch_id),商戶密鑰(key),付款用戶的openid。

申請接入微信商戶地址:https://pay.weixin.qq.com/static/applyment_guide/applyment_detail_miniapp.shtml

3.2 開發模式

本次開發采用的開發模式是:普通模式,適用于有自己開發團隊或外包開發商的直連商戶收款。開發者申請自己的appid和mch_id,兩者需具備綁定關系,以此來使用微信支付提供的開放接口,對用戶提供服務。

微信小程序調用微信支付接口的實現

4 開發

wx.request({
 
  url: address + 'wxPay',
 
  data: {
 
    openId: openId
  
    // amount: amount,
 
    // openId: openId
 
  },
 
  header: {
 
    'content-type': 'application/x-www-form-urlencoded' // 默認值
  
  },
 
  method: "POST",
 
  success: function (res) {
 
    console.log(res);
 
    that.doWxPay(res.data);
  },
 
  fail: function (err) {
 
    wx.showToast({
 
      icon: "none",
 
      title: '服務器異常,清稍候再試'
 
    })
 
  },
 
});
 
 
 
doWxPay(param) {
 
//小程序發起微信支付
 
wx.requestPayment({
 
timeStamp: param.data.timeStamp,//記住,這邊的timeStamp一定要是字符串類型的,不然會報錯
 
nonceStr: param.data.nonceStr,
 
package: param.data.package,
 
signType: 'MD5',
 
paySign: param.data.paySign,
 
success: function (event) {
 
// success
 
console.log(event);
 
 
 
wx.showToast({
 
title: '支付成功',
 
icon: 'success',
 
duration: 2000
 
});
 
},
 
fail: function (error) {
 
// fail
 
console.log("支付失敗")
 
console.log(error)
 
},
 
complete: function () {
 
// complete
 
console.log("pay complete")
 
}
 
});
 
},

4.2 java后臺

4.2.1 PayUtil.java

private static Logger logger = Logger.getLogger(PayUtil.class);
public static JSONObject wxPay(String openid,HttpServletRequest request){
JSONObject json = new JSONObject();
        try{
            //生成的隨機字符串
            String nonce_str = Util.getRandomStringByLength(32);
            //商品名稱 
            String body = new String(WXConst.title.getBytes("ISO-8859-1"),"UTF-8");
            //獲取本機的ip地址
            String spbill_create_ip = Util.getIpAddr(request);
            String orderNo = WXConst.orderNo;
            String money = "1";//支付金額,單位:分,這邊需要轉成字符串類型,否則后面的簽名會失敗
 
            Map<String, String> packageParams = new HashMap<String, String>();
            packageParams.put("appid", WXConst.appId);
            packageParams.put("mch_id", WXConst.mch_id);
            packageParams.put("nonce_str", nonce_str);
            packageParams.put("body", body);
            packageParams.put("out_trade_no", orderNo);//商戶訂單號
            packageParams.put("total_fee", money);
            packageParams.put("spbill_create_ip", spbill_create_ip);
            packageParams.put("notify_url", WXConst.notify_url);
            packageParams.put("trade_type", WXConst.TRADETYPE);
            packageParams.put("openid", openid);
 
 
            // 除去數組中的空值和簽名參數
            packageParams = PayUtil.paraFilter(packageParams);
            String prestr = PayUtil.createLinkString(packageParams); // 把數組所有元素,按照“參數=參數值”的模式用“&”字符拼接成字符串
 
 
            //MD5運算生成簽名,這里是第一次簽名,用于調用統一下單接口
            String mysign = PayUtil.sign(prestr, WXConst.key, "utf-8").toUpperCase();
            logger.info("=======================第一次簽名:" + mysign + "=====================");
 
 
            //拼接統一下單接口使用的xml數據,要將上一步生成的簽名一起拼接進去
            String xml = "<xml version='1.0' encoding='gbk'>" + "<appid>" + WXConst.appId + "</appid>"
                    + "<body><![CDATA[" + body + "]]></body>"
                    + "<mch_id>" + WXConst.mch_id + "</mch_id>"
                    + "<nonce_str>" + nonce_str + "</nonce_str>"
                    + "<notify_url>" + WXConst.notify_url + "</notify_url>"
                    + "<openid>" + openid + "</openid>"
                    + "<out_trade_no>" + orderNo + "</out_trade_no>"
                    + "<spbill_create_ip>" + spbill_create_ip + "</spbill_create_ip>"
                    + "<total_fee>" + money + "</total_fee>"
                    + "<trade_type>" + WXConst.TRADETYPE + "</trade_type>"
                    + "<sign>" + mysign + "</sign>"
                    + "</xml>";
 
 
            System.out.println("調試模式_統一下單接口 請求XML數據:" + xml);
 
 
            //調用統一下單接口,并接受返回的結果
            String result = PayUtil.httpRequest(WXConst.pay_url, "POST", xml);
 
 
            System.out.println("調試模式_統一下單接口 返回XML數據:" + result);
 
 
            // 將解析結果存儲在HashMap中
            Map map = PayUtil.doXMLParse(result);
 
 
            String return_code = (String) map.get("return_code");//返回狀態碼
 
 
            //返回給移動端需要的參數
            Map<String, Object> response = new HashMap<String, Object>();
            if(return_code == "SUCCESS" || return_code.equals(return_code)){
                // 業務結果
                String prepay_id = (String) map.get("prepay_id");//返回的預付單信息
                response.put("nonceStr", nonce_str);
                response.put("package", "prepay_id=" + prepay_id);
                Long timeStamp = System.currentTimeMillis() / 1000;
                response.put("timeStamp", timeStamp + "");//這邊要將返回的時間戳轉化成字符串,不然小程序端調用wx.requestPayment方法會報簽名錯誤
 
 
                String stringSignTemp = "appId=" + WXConst.appId + "&nonceStr=" + nonce_str + "&package=prepay_id=" + prepay_id+ "&signType=" + WXConst.SIGNTYPE + "&timeStamp=" + timeStamp;
                //再次簽名,這個簽名用于小程序端調用wx.requesetPayment方法
                String paySign = PayUtil.sign(stringSignTemp, WXConst.key, "utf-8").toUpperCase();
                logger.info("=======================第二次簽名:" + paySign + "=====================");
 
 
                response.put("paySign", paySign);
 
 
                //更新訂單信息
                //業務邏輯代碼
            }
 
 
            response.put("appid", WXConst.appId);
            json.put("errMsg", "OK");
            //json.setSuccess(true);
            json.put("data", response);
            //json.setData(response);
        }catch(Exception e){
            e.printStackTrace();
            json.put("errMsg", "Failed");
            //json.setSuccess(false);
            //json.setMsg("發起失敗");
        }
        return json;
    }
 
 
 
/**  
     * 簽名字符串  
     * @param text需要簽名的字符串  
     * @param key 密鑰  
     * @param input_charset編碼格式  
     * @return 簽名結果  
     */   
    public static String sign(String text, String key, String input_charset) {   
        text = text + "&key=" + key;   
        return DigestUtils.md5Hex(getContentBytes(text, input_charset));   
    }   
    /**  
     * 簽名字符串  
     * @param text需要簽名的字符串  
     * @param sign 簽名結果  
     * @param key密鑰  
     * @param input_charset 編碼格式  
     * @return 簽名結果  
     */   
    public static boolean verify(String text, String sign, String key, String input_charset) {   
        text = text + key;   
        String mysign = DigestUtils.md5Hex(getContentBytes(text, input_charset));   
        if (mysign.equals(sign)) {   
            return true;   
        } else {   
            return false;   
        }   
    }   
    /**  
     * @param content  
     * @param charset  
     * @return  
     * @throws SignatureException  
     * @throws UnsupportedEncodingException  
     */   
    public 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);   
        }   
    }   
    /**  
     * 生成6位或10位隨機數 param codeLength(多少位)  
     * @return  
     */   
    public static String createCode(int codeLength) {   
        String code = "";   
        for (int i = 0; i < codeLength; i++) {   
            code += (int) (Math.random() * 9);   
        }   
        return code;   
    }   
    @SuppressWarnings("unused")
private static boolean isValidChar(char ch) {   
        if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'))   
            return true;   
        if ((ch >= 0x4e00 && ch <= 0x7fff) || (ch >= 0x8000 && ch <= 0x952f))   
            return true;// 簡體中文漢字編碼   
        return false;   
    }   
    /**  
     * 除去數組中的空值和簽名參數  
     * @param sArray 簽名參數組  
     * @return 去掉空值與簽名參數后的新簽名參數組  
     */   
    public static Map<String, String> paraFilter(Map<String, String> sArray) {   
        Map<String, String> result = new HashMap<String, String>();   
        if (sArray == null || sArray.size() <= 0) {   
            return result;   
        }   
        for (String key : sArray.keySet()) {   
            String value = sArray.get(key);   
            if (value == null || value.equals("") || key.equalsIgnoreCase("sign")   
                    || key.equalsIgnoreCase("sign_type")) {   
                continue;   
            }   
            result.put(key, value);   
        }   
        return result;   
    }   
    /**  
     * 把數組所有元素排序,并按照“參數=參數值”的模式用“&”字符拼接成字符串  
     * @param params 需要排序并參與字符拼接的參數組  
     * @return 拼接后字符串  
     */   
    public static String createLinkString(Map<String, String> params) {   
        List<String> keys = new ArrayList<String>(params.keySet());   
        Collections.sort(keys);   
        String prestr = "";   
        for (int i = 0; i < keys.size(); i++) {   
            String key = keys.get(i);   
            String value = params.get(key);   
            if (i == keys.size() - 1) {// 拼接時,不包括最后一個&字符   
                prestr = prestr + key + "=" + value;   
            } else {   
                prestr = prestr + key + "=" + value + "&";   
            }   
        }   
        return prestr;   
    }   
    /**  
     *  
     * @param requestUrl請求地址  
     * @param requestMethod請求方法  
     * @param outputStr參數  
     */   
    public static String httpRequest(String requestUrl,String requestMethod,String outputStr){   
        // 創建SSLContext   
        StringBuffer buffer = null;   
        try{   
        URL url = new URL(requestUrl);   
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();   
        conn.setRequestMethod(requestMethod);   
        conn.setDoOutput(true);   
        conn.setDoInput(true);   
        conn.connect();   
        //往服務器端寫內容   
        if(null !=outputStr){   
            OutputStream os=conn.getOutputStream();   
            os.write(outputStr.getBytes("utf-8"));   
            os.close();   
        }   
        // 讀取服務器端返回的內容   
        InputStream is = conn.getInputStream();   
        InputStreamReader isr = new InputStreamReader(is, "utf-8");   
        BufferedReader br = new BufferedReader(isr);   
        buffer = new StringBuffer();   
        String line = null;   
        while ((line = br.readLine()) != null) {   
        buffer.append(line);   
        }   
        br.close();
        }catch(Exception e){   
            e.printStackTrace();   
        }
        return buffer.toString();
    }     
    public static String urlEncodeUTF8(String source){   
        String result=source;   
        try {   
            result=java.net.URLEncoder.encode(source, "UTF-8");   
        } catch (UnsupportedEncodingException e) {   
            // TODO Auto-generated catch block   
            e.printStackTrace();   
        }   
        return result;   
    } 
    /**
* 解析xml,返回第一級元素鍵值對。如果第一級元素有子節點,則此節點的值是子節點的xml數據。
* @param strxml
* @return
* @throws JDOMException
* @throws IOException
*/
public static Map doXMLParse(String strxml) throws Exception {
  if(null == strxml || "".equals(strxml)) {
    return null;
    }
 
  Map m = new HashMap();
  InputStream in = String2Inputstream(strxml);
  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);
}
 
//關閉流
in.close();
 
return m;
}
/**
* 獲取子結點的xml
* @param children
* @return String
*/
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();
}
public static InputStream String2Inputstream(String str) {
  return new ByteArrayInputStream(str.getBytes());
}
 
 
 
 
 
public static void wxNotify(HttpServletRequest request,HttpServletResponse response) throws Exception{  
BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream)request.getInputStream()));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while((line = br.readLine())!=null){
            sb.append(line);
        }
        br.close();
        //sb為微信返回的xml
        String notityXml = sb.toString();
        String resXml = "";
        System.out.println("接收到的報文:" + notityXml);
 
 
        Map map = PayUtil.doXMLParse(notityXml);
 
 
        String returnCode = (String) map.get("return_code");
        if("SUCCESS".equals(returnCode)){
            //驗證簽名是否正確
            if(PayUtil.verify(PayUtil.createLinkString(map), (String)map.get("sign"), WXConst.key, "utf-8")){
                /**此處添加自己的業務邏輯代碼start**/
 
 
 
 
                /**此處添加自己的業務邏輯代碼end**/
 
 
                //通知微信服務器已經支付成功
                resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                        + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
            }
        }else{
            resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                    + "<return_msg><![CDATA[報文為空]]></return_msg>" + "</xml> ";
        }
        System.out.println(resXml);
        System.out.println("微信支付回調數據結束");
 
 
        BufferedOutputStream out = new BufferedOutputStream(
                response.getOutputStream());
        out.write(resXml.getBytes());
        out.flush();
        out.close();  
    }

4.2.2 Util.java

/**
     * Util工具類方法
     * 獲取一定長度的隨機字符串,范圍0-9,a-z
     * @param length:指定字符串長度
     * @return 一定長度的隨機字符串
     */
    public static String getRandomStringByLength(int length) {
        String base = "abcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }
    
    
    /**
     * Util工具類方法
     * 獲取真實的ip地址
     * @param request
     * @return
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if(StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)){
            //多次反向代理后會有多個ip值,第一個ip才是真實ip
            int index = ip.indexOf(",");
            if(index != -1){
                return ip.substring(0,index);
            }else{
                return ip;
            }
        }
        ip = request.getHeader("X-Real-IP");
        if(StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)){
            return ip;
        }
        return request.getRemoteAddr();
 
    }

4.2.3 WXConst.java

//微信小程序appid
public static String appId = "";
//微信小程序appsecret
public static String appSecret = "";
//微信支付主體
public static String title = "";
public static String orderNo = "";
//微信商戶號
public static String mch_id="";
//微信支付的商戶密鑰
public static final String key = "";
//獲取微信Openid的請求地址
public static String WxGetOpenIdUrl = "";
//支付成功后的服務器回調url
public static final String notify_url="https://api.weixin.qq.com/sns/jscode2session";
//簽名方式
public static final String SIGNTYPE = "MD5";
//交易類型
public static final String TRADETYPE = "JSAPI";
//微信統一下單接口地址
public static final String pay_url = "https://api.mch.weixin.qq.com/pay/unifiedorder";

上述內容就是微信小程序調用微信支付接口的實現,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

普兰县| 德阳市| 西昌市| 福泉市| 沧源| 保山市| 阳东县| 景德镇市| 涪陵区| 平南县| 禹城市| 北京市| 太和县| 广饶县| 长治市| 信丰县| 马关县| 九江县| 平阴县| 台北市| 铜陵市| 会泽县| 日喀则市| 阳高县| 临沭县| 五指山市| 瑞金市| 云和县| 嫩江县| 瓦房店市| 宜章县| 莒南县| 章丘市| 长子县| 玉山县| 崇明县| 通榆县| 巴马| 平邑县| 贡嘎县| 汪清县|