微信支付操作流程


微信支付流程:
1、在頁面點擊支付發生的動作
將訂單參數傳遞后台->后台根據訂單參數以及微信相關信息->獲取支付所需要的參數->后台處理支付所需要的參數返回給前端->前端獲取到支付參數->發起支付請求->支付成功的頁面會顯示跳回商家所設置的回調路徑->后台根據回調路徑處理相關業務邏輯;

2、程序案例;從官網中下載相關API

頁面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>every thing will be will</title>
    <script type="text/javascript" src="../static/js/jquery-3.3.1.min.js"></script>
</head>
<body>
<input type="button" value="進行微信支付" id="payId">

<script type="text/javascript">

    $(function(){
        var appId,timeStamp,nonceStr,package,signType,paySign;

        $("#payId").click(function(){
            pay();
        });

        //從后台獲取參數
        function pay(){
            var url = "http://localhost:8062/wxpay/order";
            $.get(url,function(result) {
                appId = result.appId;
                timeStamp = result.timeStamp;
                nonceStr = result.nonceStr;
                package = result.package;
                signType = result.signType;
                paySign = result.paySign;

                if (typeof WeixinJSBridge == "undefined") {
                    if (document.addEventListener) {
                        document.addEventListener('WeixinJSBridgeReady',
                            onBridgeReady, false);
                    } else if (document.attachEvent) {
                        document.attachEvent('WeixinJSBridgeReady',
                            onBridgeReady);
                        document.attachEvent('onWeixinJSBridgeReady',
                            onBridgeReady);
                    }
                    alert("請在微信上進行支付操作!");
                    onBridgeReady();
                } else {
                    onBridgeReady();
                }
            });
        }
        //去微信那邊發起支付請求
        function onBridgeReady(){

            alert("appId:"+appId+" "+"timeStamp:"+timeStamp+" "+"nonceStr:"+nonceStr+" "+"package:"+package+" "+"signType:"+signType+" "+"paySign:"+paySign+" ");

            WeixinJSBridge.invoke( 'getBrandWCPayRequest', {
                    "appId":appId,     //公眾號名稱,由商戶傳入
                    "timeStamp":timeStamp,         //時間戳,自1970年以來的秒數
                    "nonceStr":nonceStr, //隨機串
                    "package":package,
                    "signType":signType,         //微信簽名方式:
                    "paySign":paySign //微信簽名
                },
                function(res){
                    if(res.err_msg == "get_brand_wcpay_request:ok" ) {
                        //alert('支付成功');
                        console.log("支付成功");
                        //支付成功后跳轉的頁面
                    }else if(res.err_msg == "get_brand_wcpay_request:cancel"){
                        alert('支付取消');
                    }else if(res.err_msg == "get_brand_wcpay_request:fail"){
                        alert('支付失敗');

                        alert(JSON.stringify(res));

                        WeixinJSBridge.call('closeWindow');
                    } //使用以上方式判斷前端返回,微信團隊鄭重提示:res.err_msg將在用戶支付成功后返回ok,但並不保證它絕對可靠。
                });
        }
    })
</script>

</body>
</html>

  后台業務邏輯

所需的參數:

public class WxParam {
    public final static String WX_APPID = "";//商家平台ID,微信平台
    public final static String WX_BODY = ""; //商品描述
    public final static String WX_MCH_ID = "";//商戶ID ,微信平台
    public final static String WX_NONCE_STR = "";//隨機字符串,UUID
    public final static String WX_OPEN_ID = "";//用戶OPENID
    public final static String WX_OUT_TRADE_NO = "";//商戶訂單號
    public final static String WX_SPBILL_CREATE_IP = "";//終端IP,從請求頭拿到
    public final static String WX_TOTAL_FEE = "";//支付金額,單位是分
    public final static String WX_TRADE_TYPE = "";//交易類型;JSAPI
    public final static String WX_NOTIFY_URL = "";//通知地址;用戶支付成功后,返回應用程序的接口;
    public final static String WX_SIGN = "";//簽名,根據上面10個參數計算獲得
    public final static String WX_PATERNERKEY = "";//商家密鑰
}

  前端所需參數的處理,以及回調路徑

@Controller
@RequestMapping("/wxpay")
public class WxPayAction {

    /**
     * 訂單采用微信支付所需的參數接口
     * @param request
     * @return
     */
    @RequestMapping("/order")
    @ResponseBody
    public Map<String,String> orders(HttpServletRequest request){
        try {
            String openId = "用戶的openid";
            //存放微信支付所需的參數
            final Map<String,String> paraMap = new HashMap<>();
            // 獲取請求ip地址
            String ip = request.getHeader("x-forwarded-for");
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
            if (ip.indexOf(",") != -1) {
                String[] ips = ip.split(",");
                ip = ips[0].trim();
            }
            String uuid = UUID.randomUUID().toString();
            //
            paraMap.put("appid",WxParam.WX_APPID);
            paraMap.put("body","微信測試商品內容" );
            paraMap.put("mch_id",WxParam.WX_MCH_ID );
            paraMap.put("nonce_str",uuid );
            paraMap.put("openid",openId );
            paraMap.put("out_trade_no",UUID.randomUUID().toString().replaceAll("-", "") );//訂單號
            paraMap.put("spbill_create_ip",ip );//終端IP,從請求頭拿到
            paraMap.put("total_fee","1" );//支付金額,1分
            paraMap.put("trade_type","JSAPI" );//支付類型
            paraMap.put("notify_url","回調url" );
            //這里的key是商家密鑰;這一步將回調路徑設置到sign參數里面了
            String sign = WXPayUtil.generateSignedXml(paraMap,WxParam.WX_PATERNERKEY);
            paraMap.put("sign",sign );
            //將map轉換為xml
            String xml = WXPayUtil.mapToXml(paraMap);
            // 統一下單 https://api.mch.weixin.qq.com/pay/unifiedorder
            String unifiedorder_url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
            System.out.println("xml為:" + xml);
            //預支付
            String xmlStr = HttpRequestUtil.httpsRequest(unifiedorder_url, "POST", xml);
            System.out.println("預支付返回的信息:"+xmlStr);
            //上面的數據主要是為了獲得預支付id;就相當於微信上提交訂單(訂單包含了回調函數),然后返回一個微信的訂單id;

            //以下內容返回前端頁面的json數據
            String prepay_id = "";//預支付id
            if(xmlStr.indexOf("SUCCESS") != -1){
                Map<String,String> map = WXPayUtil.xmlToMap(xmlStr);
                prepay_id = (String) map.get("prepay_id");
            }
            Map<String,String> payMap = new HashMap<>();
            payMap.put("appId",WxParam.WX_APPID );
            //后面為什么要加""
            payMap.put("timeStamp",WXPayUtil.getCurrentTimestamp()+"" );
            payMap.put("nonceStr",WXPayUtil.generateNonceStr() );
            payMap.put("signType","MD5" );
            payMap.put("package","prepay_id="+prepay_id);
            String paySin = WXPayUtil.generateSignature(payMap, WxParam.WX_PATERNERKEY);
            payMap.put("paySign",paySin );
            return payMap;
            
        }catch (Exception e){

        }
        return null;
    }

    /**
     * 回調函數,處理業務邏輯
    * @param request
     *      * @param response
     *      * @return
     */
    @RequestMapping("/notify")
    public String wxCallBack(HttpServletRequest request, HttpServletResponse response){
        InputStream is = null;
        try{
            is = request.getInputStream();
            InputStreamReader isr=new InputStreamReader(is,"utf-8");
            BufferedReader br=new BufferedReader(isr);
            StringBuffer buffer=new StringBuffer();
            String line=null;
            while((line=br.readLine())!=null){
                buffer.append(line);
            }
            //從流中獲取
            String xml = buffer.toString();
            Map<String,String> notifyMap = WXPayUtil.xmlToMap(xml);
            System.out.println("微信返回的回調函數信息:"+xml);
            if(notifyMap.get("result_code").equals("SUCCESS")){
                String ordersSn = notifyMap.get("out_trade_no");//商戶訂單號
                String amountpaid = notifyMap.get("total_fee"); //實際支付金額
                BigDecimal amountPay = (new BigDecimal(amountpaid).divide(new BigDecimal("100"))).setScale(2);// 將分轉換成元-實際支付金額:元

                /*
                 * 以下是自己的業務處理------僅做參考 更新order對應字段/已支付金額/狀態碼
                 */
                System.out.println("===notify===回調方法已經被調!!!");
            }
            // 告訴微信服務器收到信息了,回復微信服務器信息用流發送一個xml即可
            response.getWriter().write("<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>");
        }catch (Exception e){

        }finally {
            if(is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
    

}

  用到的工具類

public class HttpRequestUtil {

    /*
     * 處理https GET/POST請求
     * 請求地址、請求方法、參數
     * */
    public static String httpsRequest(String requestUrl,String requestMethod,String outputStr){
        StringBuffer buffer=null;
        try{
            //創建SSLContext
            SSLContext sslContext=SSLContext.getInstance("SSL");
            TrustManager[] tm={new MyX509TrustManager()};
            //初始化
            sslContext.init(null, tm, new java.security.SecureRandom());;
            //獲取SSLSocketFactory對象
            SSLSocketFactory ssf=sslContext.getSocketFactory();
            URL url=new URL(requestUrl);
            HttpsURLConnection conn=(HttpsURLConnection)url.openConnection();
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            conn.setRequestMethod(requestMethod);
            //設置當前實例使用的SSLSoctetFactory
            conn.setSSLSocketFactory(ssf);
            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);
            }
        }catch(Exception e){
            e.printStackTrace();
        }
        return buffer.toString();
    }
}

  

public class MyX509TrustManager implements X509TrustManager {

    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType)
            throws CertificateException {
        // TODO Auto-generated method stub

    }

    @Override
    public void checkServerTrusted(X509Certificate[] chain, String authType)
            throws CertificateException {
        // TODO Auto-generated method stub

    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        // TODO Auto-generated method stub
        return null;
    }

}

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM