1. 程式人生 > >MZERO微信支付流程的梳理

MZERO微信支付流程的梳理

根據專案程式碼分析微信支付的具體流程

專案中的一個包含支付邏輯的Activity

RechargeActivity(裡面包含使用微信支付完成積分充值的邏輯)

image

在具體的支付邏輯在onClick這個點選事件中,下面具體來看這個點選事件中所做的內容:
image

以上這些只需要注意下面這行程式碼:

    MyWxPayUtils.Pay(UiUtils.getContext(), Params, Url_pay);

以上是呼叫部分,下面具體看MyWxPayUtils這個工具類:

/**
 * 進行微信支付的工具類
 * 
 * @author king
 * 
 */
public class MyWxPayUtils { public static Context mContext = null; public static WXPay wxPay = null; // 呼叫該方法進行支付 public static void Pay(Context context, Map<String, String> Params, String URL) { mContext = context; String ip = getIpAddress(context); //獲取本機的Ip地址
Params.put("ip", ip); // 1.首先進行請求伺服器,上傳本次微信支付的訂單詳情,並獲取預支付Id HttpHelper httpHelper = new HttpHelper(context, URL, Params, new Handler() { @Override public void handleMessage(Message msg) { wxPay = new
WXPay(); // 封裝從伺服器獲取的用於支付的引數 String json_wx = (String) msg.obj; try { JSONObject jsonObject = new JSONObject(json_wx); wxPay.setPrepay_id(jsonObject .getString("prepay_id")); wxPay.setSign(jsonObject.getString("sign")); wxPay.setOut_trade_no(jsonObject .getString("out_trade_no")); } catch (JSONException e) { Log.i("MyWxPayUtils", "json解析異常"); e.printStackTrace(); } // 2.呼叫微信支付的邏輯 IWXAPI wxapi = WXAPIFactory.createWXAPI(mContext, WxPay.appid); wxapi.registerApp(WxPay.appid); //進行註冊 PayReq payRequest = new PayReq(); payRequest.appId = WxPay.appid; // 應用id payRequest.partnerId = WxPay.partnerid; // 商戶id payRequest.prepayId = wxPay.getPrepay_id();// 預支付訂單ID payRequest.packageValue = WxPay.packageValue;// 擴充套件欄位 payRequest.nonceStr = WxPayUtils.genNonceStr(); // 隨機字串 payRequest.timeStamp = WxPayUtils.genTimeStamp(); // 時間戳 // 二次簽名 List<NameValuePair> signParams = new LinkedList<NameValuePair>(); signParams.add(new BasicNameValuePair("appid", payRequest.appId)); signParams.add(new BasicNameValuePair("noncestr", payRequest.nonceStr)); signParams.add(new BasicNameValuePair("package", payRequest.packageValue)); /** 注意二次簽名這裡不再是mch_id,變成了prepayid; */ signParams.add(new BasicNameValuePair("partnerid", payRequest.partnerId)); signParams.add(new BasicNameValuePair("prepayid", payRequest.prepayId)); signParams.add(new BasicNameValuePair("timestamp", payRequest.timeStamp)); payRequest.sign = genAppSign(signParams); // 簽名 wxapi.sendReq(payRequest); //開始呼叫微信支付 Log.i("Test", "Sign:\n" + payRequest.sign); } }); // 2.通過handler告知要進行呼叫微信支付了 } private static String getIpAddress(Context context) { // 獲取wifi服務 WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); // 判斷wifi是否開啟 if (!wifiManager.isWifiEnabled()) { wifiManager.setWifiEnabled(true); } WifiInfo wifiInfo = wifiManager.getConnectionInfo(); int ipAddress = wifiInfo.getIpAddress(); String intToIp = intToIp(ipAddress); Log.i("Test", "本機IP:"+intToIp); return intToIp; } /** * 在app端生成簽名 * @param params * @return */ private static String genAppSign(List<NameValuePair> params) { StringBuilder str = new StringBuilder(); for (int i = 0; i < params.size(); i++) { str.append(params.get(i).getName()); str.append('='); str.append(params.get(i).getValue()); str.append('&'); } str.append("key="); str.append(WxPay.API_KEY); String appSign = MD5.getMessageDigest(str.toString().getBytes()) .toUpperCase(); Log.e("orion", appSign); return appSign; } // 將獲取到的ip轉換成字串 public static String intToIp(int i) { return (i & 0xFF) + "." + ((i >> 8) & 0xFF) + "." + ((i >> 16) & 0xFF) + "." + (i >> 24 & 0xFF); } }

WxPayRetrunServlet.Java(用於生成並返回預支付id)


/**
 * 返回給客戶端預支付id
 * @author 春水碧於天
 *
 */
public class WxPayRetrunServlet extends HttpServlet {


    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        String spbill_create_ip =request.getParameter("ip"); //獲取終端的IP地址
        System.out.println("終端ip:"+spbill_create_ip);
        String encode = TenpayUtil.getCharacterEncoding(request, response);
        System.out.println("編碼:"+encode);

        String body = request.getParameter("body"); //商品描述
        String total_fee = request.getParameter("total_fee"); //消費的金額
        //獲取當前具體的日期
        Calendar calendar=Calendar.getInstance();
        int year=calendar.get(Calendar.YEAR);
        int month=calendar.get(Calendar.MONTH)+1;
        int day=calendar.get(Calendar.DAY_OF_MONTH);
        int hour=calendar.get(Calendar.HOUR_OF_DAY);
        int minute=calendar.get(Calendar.MINUTE);
        int second=calendar.get(Calendar.SECOND);   
        String currentDateTime=year+"-"+month+"-"+day+" "+hour+":"+minute+":"+second;       

                //---------------生成訂單號 開始------------------------
                //當前時間 yyyyMMddHHmmss
                String currTime = TenpayUtil.getCurrTime();
                //8位日期
                String strTime = currTime.substring(8, currTime.length());
                //四位隨機數
                String strRandom = TenpayUtil.buildRandom(4) + "";
                //10位序列號,可以自行調整。
                String strReq = strTime + strRandom;
                //訂單號,此處用時間加隨機數生成,商戶根據自己情況調整,只要保持全域性唯一就行
                String out_trade_no = strReq;
                //---------------生成訂單號 結束------------------------
                //  
                PrepayIdRequestHandler prepayReqHandler = new PrepayIdRequestHandler(request, response);//獲取prepayid的請求類
                ClientRequestHandler clientHandler = new ClientRequestHandler(request, response);//返回客戶端支付引數的請求類
                String noncestr = WXUtil.getNonceStr();
                    String timestamp = WXUtil.getTimeStamp();
                    ////設定獲取prepayid支付引數
                    prepayReqHandler.setParameter("appid", ConstantUtil.APP_ID); //應用id
                    prepayReqHandler.setParameter("mch_id", ConstantUtil.PARTNER); //商戶號
                    prepayReqHandler.setParameter("nonce_str", noncestr);//隨機字串
                    prepayReqHandler.setParameter("body", body);//商品描述
                    prepayReqHandler.setParameter("out_trade_no", out_trade_no);//商戶訂單號
                    prepayReqHandler.setParameter("total_fee",total_fee);//總金額
                    prepayReqHandler.setParameter("spbill_create_ip", spbill_create_ip);//終端IP
                    prepayReqHandler.setParameter("notify_url", ConstantUtil.TOKENURL);//通知地址
                    prepayReqHandler.setParameter("trade_type", "APP");//指定支付方式
                    WXPay wxPay = new WXPay(); //用於封裝傳回客戶端的呼叫微信支付所需的引數
                    wxPay.setOut_trade_no(out_trade_no); //訂單號
                    //生成獲取預支付簽名
                    String sign = prepayReqHandler.createMD5Sign();
                    wxPay.setSign(sign);
                    System.out.println("簽名:"+sign);
                    prepayReqHandler.setParameter("sign",sign);
                    String gateUrl = ConstantUtil.GATEURL ;
                    prepayReqHandler.setGateUrl(gateUrl);
                    String prepayid = null;
                    try{
                    //獲取prepayId
                        prepayid = prepayReqHandler.sendPrepay();

                        wxPay.setPrepay_id(prepayid);

                        System.out.println("預支付簽名:"+prepayid);

                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                Gson gson = new Gson();
                String json_wxpay = gson.toJson(wxPay);
                response.getWriter().write(json_wxpay);
    }

}

對MyWxPayUtils和WxPayRetrunServlet之間的一個互動流程進行一個簡要的梳理:

  1. 當呼叫MyWxPayUtils.pay()方法進行支付的時候,首先攜帶由呼叫者傳遞過來的Params(提交的引數參考 https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1,需要注意的是客戶端僅需要提供body,detail,total_fell等不涉及使用者安全的引數,一些涉及到安全的引數全部在服務端進行配置 )去請求WxPayRetrunServlet,用於獲取Android客戶端呼叫起微信支付所必須的prepayId。

    Android客戶端呼叫起來微信支付所需要的必須引數如下:

    image

    注意紅框中圈出來的部分,prepayId 這個就是前面請求WxPayRetrunServlet獲取到的,也是是否能夠呼叫起來微信支付的關鍵。

    那麼sign這個引數該如何獲得?

    需要根據微信官方文件給出的簽名演算法,對欄位名為appid,partnerid,prepayid,noncestr,timestamp,package進行二次簽名得到sign這個引數。

  2. 下面關注WxPayRetrunServlet是如何獲取prepayId的,看下面的圖中的標記:

    image

  3. 以上兩個步驟完成後,下面關注Android客戶端是如何呼叫起微信支付的。

    1. 先向微信註冊APPId:

      IWXAPI wxapi = WXAPIFactory.createWXAPI(mContext,WxPay.appid);
      wxapi.registerApp(WxPay.appid); //進行註冊
      
    2. 調起支付:

      wxapi.sendReq(payRequest); //開始呼叫微信支付
      

    payRequest為第一步中封裝的那些呼叫微信支付的必要引數

    不出意外的話到這裡微信支付就可以正常被調起了

Android客戶端中支付結果的回撥

當調起微信支付的支付介面後,我們不能確定使用者一定支付成功,有可能使用者直接點選了返回不再進行支付,因此對於這種情況,需要給使用者一個介面的提示。具體的步驟如下:

  1. 建立一個名為WXPayEntryActivity的類(需要在當前專案包的根路徑下建立,而且包名必須和前面給出的包名一致,不然無法回撥!)

image

一定要注意,不要踩坑!

  1. 接著實現 IWXAPIEventHandler 這個介面,並註冊支付結果的回撥用。
api = WXAPIFactory.createWXAPI(this, WxPay.appid);  
appidapi.handleIntent(getIntent(), this);

3.支付的結果會回撥給onResp方法
“`
@Override
public void onResp(BaseResp resp){

}

“`
根據BaseResp物件中封裝的code進行判斷即可

image

相關推薦

MZERO支付流程梳理

根據專案程式碼分析微信支付的具體流程 專案中的一個包含支付邏輯的Activity RechargeActivity(裡面包含使用微信支付完成積分充值的邏輯) 在具體的支付邏輯在onClick這個點選事件中,下面具體來看這個點選事件中所做的內容:

Tp框架引入微支付類及支付流程

一、對於微信支付(引入微信支付類) 由於微信支付檔案比較多,一個檔案可能有很多類,所以使用Tp框架的時候 使用Vendor()來引入第三方的類庫 該微信支付類檔案放在ThinkPHP\Library\Vendor目錄下: 引入方法:Vendor(wxpay.wxpay)引入

支付流程指引

List<String> hashlist=new ArrayList<>();         hashlist.add("appid");         hashlist.add("mch_id");         hashlist.add("nonce_str");    

phpcms 支付流程

公司專案版本迭代,有了新需求,之前的微信支付是點選按鈕,直接生成訂單的同時請求微信授權,然後重定向在連結裡就有了code從而可以獲取使用者openid。 新需求是 下訂單的時候新增讓使用者選擇收貨地址,並且支付完成以後,訂單資訊包含使用者的收貨資訊。 上一版本的支付是點選購

支付SDK接入流程梳理

         微信SDK的支付功能接入簡單梳理。    首先說一下,你需要的官網都有,但是官網提供的東西不管新舊與否先給你放上去,部分地方提供的連結點選時還提示404,不同的頁面提示相同的下載內容

支付之掃碼支付、公眾號支付、H5支付、小程序支付相關業務流程分析總結

doc bsp 說明 引入 red 內容 bubuko url參數 數據 前言 很久以來,一直想寫一篇微信支付有關的總結文檔;一方面是總結自己的一些心得,另一方面也可以幫助別人,但是因種種原因未能完全理解透徹微信支付的幾大支付方式,今天有幸做一些總結上的文章,也趁此機會,將

支付前端流程

其實官網介紹的已經很明確了也有示例程式碼 但還是想寫一下,畢竟琢磨了一天了 首先要保證你的專案外網可以訪問到, 我的是vue專案,用nginx做的代理, 這裡是不需要jssdk的 onBridgeReady: function () { //支付 const openId = loc

全面詳細的支付思路流程以及專案程式碼分享

之前一直沒有接觸微信支付這方面的業務,現在因專案需要,需要用到此功能,開始各種百度,稍微瞭解了一下,微信支付分為: 支付寶支付、APP支付、掃碼支付,但是對於H5支付和支付寶支付現在還是沒有徹底搞明白他兩的區別,希望大佬們可以稍微提點一二,小弟先在此謝過! 大體思路如下: 1】.獲取co

一張圖瞭解支付支付流程

轉自:https://www.cnblogs.com/yang-shuai/p/6516173.html   1、微信支付 以下是微信支付互動時序圖,統一下單API、支付結果通知API和查詢訂單API等都涉及簽名過程, 呼叫都必須在商戶伺服器端完成。如圖1所示。

tp5 支付開發流程

1.使用者在選擇商品後,向APi提交包含它所選擇商品的相關資訊。 2.APi在接收到資訊後,需要檢查訂單相關商品的庫存量。 3.有庫存,把訂單資料存入資料庫中=  下單成功了,返回客戶端訊息,告訴客戶端可以支付了 4.呼叫自己的支付介面,進行支付。 5.還需要再次進行庫存量檢測 6.伺服器這邊就可以

呼叫支付wx.chooseWXPay 詳細流程

 第一步:配置微信基本配置 /* * 獲取微信配置 以下的引數後臺提供 這裡切記,經常會報錯, 因為頁面的url的問題, 我這裡是後臺寫死的,根據不同的環境配置不同url * */ initWxConfig () {

支付開發流程_清晰_易懂_有原始碼

轉自 https://blog.csdn.net/weixin_41497737/article/details/80547243      最近因為公司需求開始開始做微信支付的開發,在網上參考來了很多文章,大多都說微信支付的開發

thikphp 3.2 實現支付(jsapi支付)流程

這裡說一下微信支付(jsapi支付)流程 ,支付肯定是有訂單號的、訂單這一塊就不多說了。 第一步:點選去支付,首先你要知道你的訂單號是多少。拿著訂單號,我們來處理 ,上一下程式碼,具體看一下 //支付

ThinkPHP中實現支付(jsapi支付)流程

之前寫過一篇文章講了 PHP實現微信支付(jsapi支付)流程 ,詳見文章:。 當時的環境是沒有使用框架的,直接在一個域名指向的目錄下邊新建目錄之後訪問該目錄實現的,但應用到框架中,還是有一些問題,在ThinkPHP中,由於路由規則與支付授權目錄有出入,所以會報錯。本篇講講在TP中整合微信支付的流程。

Android支付詳細流程(包括手機端和伺服器端)

相關檔案下載地址:http://download.csdn.net/detail/s_alics/9383437點選開啟連結 **************************************************************************

iOS 支付接入最新的完整流程

前段時間,公司業務需要接入微信支付,博主就苦心鑽研了2天,終於搞通了,但最近 iOS 9 更新出來後,微信支付,又不可以使用了,具體解決方案我在後面會給出。當然,微信接入也有不少的坑啊 說多了全是淚,

java支付接入詳細流程

背景 由於專案是採用Java編寫的,微信包括微信支付大都是PHP相關,於是微信支付官方文件對java的支援就不是很友好,在網上找了很多文章,基本上沒有一篇是真正跑的通的,經過一番整理,先將java接入微信支付詳細流程總結出來以便後續使用。 步驟一 準備階段:已認證微訊號,且

Android 支付支付快速接入流程

支付寶首頁 這裡 有兩個需要注意的地方 一個是管理中心,另外一個是我的支付寶 管理中心: 管理中心 管理中心 我們需要 建立一個應用 提交給支付寶進行稽核。 我的支付寶: 在這裡我的支付寶 是一個商戶版,一會我們會需要在這裡處理一下相關的 密匙 簡單介紹完了,那麼我們開始進入程式碼接入流程 一、

支付全部詳細流程

微信文件太垃圾   先吐槽一下   搞了我三天 因為後臺沒有完成 所以我在APP的程式碼裡面實現從統一下單  到生成支付訂單  然後呼叫支付的全部過程 我從流程開始講解 第一步   通過微信支付申請支付的金額是通過統一下單形成的,不是直接賦值的這裡需要這些引數  參考文件:

支付客戶端實現流程

前期準備:                 1)註冊微信開放平臺賬號                 2)認證開發者資質                 3)建立APP並提交稽核 1)2)3)三個流程約7個工作日;         4)提交資料申請微信支付 5)啟動設計和開