微信支付---統一下單

微信支付---統一下單php

身爲一個碼農,老是須要要學習一些新的知識來豐富本身的羽翼,讓本身可以在程序員的道路上走的更遠,更穩。html

最近在研究關於微信支付的接口調用:微信支付開發文檔java

接口鏈接:URL地址:https://api.mch.weixin.qq.com/pay/unifiedordernode

請求參數、返回字段、錯誤碼、請閱讀:統一下單開發文檔程序員

 請求參數格式和信息例:web

<xml>
   <return_code><![CDATA[SUCCESS]]></return_code>//返回狀態碼
   <return_msg><![CDATA[OK]]></return_msg>//返回信息
   <appid><![CDATA[wx2421b1c4370ec43b]]></appid>//公衆帳號ID
   <mch_id><![CDATA[10000100]]></mch_id>//商戶號
   <device_info><![CDATA[1000]]></device_info>//設備號
   <nonce_str><![CDATA[TN55wO9Pba5yENl8]]></nonce_str>//隨機字符串
   <sign><![CDATA[BDF0099C15FF7BC6B1585FBB110AB635]]></sign>//簽名
   <result_code><![CDATA[SUCCESS]]></result_code>//業務結果
   <openid><![CDATA[oUpF8uN95-Ptaags6E_roPHg7AG0]]></openid>//用戶標識
   <is_subscribe><![CDATA[Y]]></is_subscribe>//是否關注公衆帳號
   <trade_type><![CDATA[MICROPAY]]></trade_type>//交易類型
   <bank_type><![CDATA[CCB_DEBIT]]></bank_type>//付款銀行
   <total_fee>1</total_fee>//訂單金額——單位分
   <fee_type><![CDATA[CNY]]></fee_type>//貨幣種類
   <transaction_id><![CDATA[1008450740201411110005820873]]></transaction_id>//微信支付訂單號
   <out_trade_no><![CDATA[1415757673]]></out_trade_no>//商戶訂單號
   <attach><![CDATA[訂單額外描述]]></attach>//附加數據
   <time_end><![CDATA[20141111170043]]></time_end>//支付完成時間
   <trade_state><![CDATA[SUCCESS]]></trade_state>//交易狀態
</xml>

 

統一下訂單發起請求:json

 

package com.daat.front.pay.web.actions;

import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.daat.front.base.web.actions.BaseAction;
import com.daat.front.base.web.tools.WebUtils;
import com.daat.front.pay.sdk.common.RandomStringGenerator;
import com.daat.front.pay.sdk.common.Util;
import com.daat.front.pay.web.util.WechatURLs;
import com.daat.front.weixin.sdk.base.domain.constant.WXAppConstant;
import com.daat.front.weixin.sdk.base.exception.WXException;
import com.daat.front.weixin.sdk.util.MD5Util;
import com.daat.front.weixin.sdk.util.TenpayUtil;
import com.daat.front.weixin.sdk.util.WXHttpUtil; 

public class pay extends BaseAction {

    
    public static void main(String[] args) {
        
    }
    
    
    /**
     * 商戶發起生成預付單請求
     * @return
     */
    public String unifiedOrder(){
        Map map = WebUtils.getParameterMap();//獲取前臺數據
        String appid = WXAppConstant.APP_ID;//appid
        String mch_id = WXAppConstant.MCH_ID;//微信支付商戶號
        String nonce_str =getRandomStringByLength(8);//隨機碼
        String body = map.get("bodyName").toString();//商品描述
        String out_trade_no = map.get("outTradeNo").toString();//商品訂單號
        String product_id = map.get("productId").toString();//商品編號
        String total_fee = (int)(Float.valueOf(map.get("totalFee").toString()).floatValue()*100)+"";//總金額 分
        String time_start =getCurrTime();//交易起始時間(訂單生成時間非必須)
        String trade_type = "NATIVE";//公衆號支付
        String notify_url = "http://"+"域名"+"/"+"項目名"+"回調地址.do";//回調函數
        SortedMap<String, String> params = new TreeMap<String, String>();
        params.put("appid", appid);
        params.put("mch_id", mch_id);
        params.put("device_info", "WEB"); //設備號
        params.put("nonce_str", nonce_str);
        params.put("body", body);//商品描述
        params.put("out_trade_no", out_trade_no);
        params.put("product_id", product_id);
        params.put("total_fee", total_fee);
        params.put("time_start", time_start);
        params.put("trade_type", trade_type);
        params.put("notify_url", notify_url); 
        String sign = "";//簽名(該簽名本應使用微信商戶平臺的API證書中的密匙key,但此處使用的是微信公衆號的密匙APP_SECRET)
        sign = getSign(params);
        //參數xml化
        String xmlParams = parseString2Xml(params,sign);
        //判斷返回碼
        String jsonStr = "";
        try {
            jsonStr = WXHttpUtil.doPost(WechatURLs.prepayOrderUrl, xmlParams);// 調用支付接口
        } catch (WXException e) {
            e.printStackTrace();
        }
        if (jsonStr.indexOf("FAIL") == -1 && jsonStr.trim().length() > 0) {//成功
            model.put("result_code", "SUCCESS");
        } else {//失敗
            try {
                Map resultMap = new HashMap();
                resultMap = getMapFromXML(jsonStr);// 解析返回值
                if(resultMap!=null&&"SUCCESS".equals(resultMap.get("return_code").toString())){
                    //通訊接口二級錯誤
                    model.put("result_code", resultMap.get("result_code"));
                    model.put("error_code", resultMap.get("err_code"));
                    model.put("result_msg", resultMap.get("err_code_des"));
                }else{
                    //通訊接口一級錯誤
                    model.put("result_code", "FAIL");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return "success";
    }
    
    /**
     * 參數進行XML化
     * @param map,sign
     * @return
     */
    public static String parseString2Xml(Map<String, String> map,String sign){
        StringBuffer sb = new StringBuffer();
        sb.append("<xml>");
        Set es = map.entrySet();
        Iterator iterator = es.iterator();
        while(iterator.hasNext()){
            Map.Entry entry = (Map.Entry)iterator.next();
            String k = (String)entry.getKey();
            String v = (String)entry.getValue();
            sb.append("<"+k+">"+v+"</"+k+">");
        }
        sb.append("<sign>"+sign+"</sign>");
        sb.append("</xml>");
        return sb.toString();
    }
    /**
     * 獲取簽名 md5加密(微信支付必須用MD5加密)
     * 獲取支付簽名
     * @param params
     * @return
     */
    public static String getSign(SortedMap<String, String> params){
        String sign = null;
        StringBuffer sb = new StringBuffer();
        Set es = params.entrySet();
        Iterator iterator = es.iterator();
        while(iterator.hasNext()){
            Map.Entry entry = (Map.Entry)iterator.next();
            String k = (String)entry.getKey();
            String v = (String)entry.getValue();
            if (null != v && !"".equals(v) && !"sign".equals(k)&& !"key".equals(k)) {
                sb.append(k+"="+v+"&");
            }
        }
        sb.append("key="+WXAppConstant.APP_SECRET);
        sign = MD5Util.MD5Encode(sb.toString(), "UTF-8").toUpperCase();
        return sign;
    }
    public static Map<String,Object> getMapFromXML(String xmlString) throws ParserConfigurationException, IOException, SAXException {
        //這裏用Dom的方式解析回包的最主要目的是防止API新增回包字段
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        InputStream is =  Util.getStringStream(xmlString);
        Document document = builder.parse(is);
        //獲取到document裏面的所有結點
        NodeList allNodes = document.getFirstChild().getChildNodes();
        Node node;
        Map<String, Object> map = new HashMap<String, Object>();
        int i=0;
        while (i < allNodes.getLength()) {
            node = allNodes.item(i);
            if(node instanceof Element){
                map.put(node.getNodeName(),node.getTextContent());
            }
            i++;
        }
        return map;
    }
    /**
     * 獲取必定長度的隨機字符串
     * @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();
    }
    /**
     * 獲取當前時間 yyyyMMddHHmmss
     * @return String
     */ 
    public static String getCurrTime() {
        Date now = new Date();
        SimpleDateFormat outFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        String s = outFormat.format(now);
        return s;
    }
}

預付單成功返回信息api

測試支付返回信息:
<xml>
<return_code><![CDATA[SUCCESS]]></return_code>
<return_msg><![CDATA[OK]]></return_msg>
<appid><![CDATA[wx13842d984810c06b]]></appid>
<mch_id><![CDATA[1355962702]]></mch_id>
<device_info><![CDATA[WEB]]></device_info>
<nonce_str><![CDATA[uUaaXpCCnERVXE6R]]></nonce_str>
<sign><![CDATA[E9A1087F5A0C5F8EBCF26F3C7A842022]]></sign>
<result_code><![CDATA[SUCCESS]]></result_code>
<openid><![CDATA[oD7UhwESE3wh22Uz6PqdCXRyR-pA]]></openid>
<is_subscribe><![CDATA[Y]]></is_subscribe>
<trade_type><![CDATA[NATIVE]]></trade_type>
<bank_type><![CDATA[CFT]]></bank_type>
<total_fee>2</total_fee>
<fee_type><![CDATA[CNY]]></fee_type>
<transaction_id><![CDATA[4002722001201610247590660332]]></transaction_id>
<out_trade_no><![CDATA[1477296302523]]></out_trade_no>
<attach><![CDATA[]]></attach>
<time_end><![CDATA[20161024155820]]></time_end>
<trade_state><![CDATA[SUCCESS]]></trade_state>
<cash_fee>2</cash_fee>
</xml>
相關文章
相關標籤/搜索