1. 程式人生 > >常用微信整合(第三方sdk整合套路)-- 微信支付

常用微信整合(第三方sdk整合套路)-- 微信支付

支付

微信支付,官方給出的時序圖如下:
微信支付時序圖
支付流程總體還是遵循SDK的基本整合流程的。因此,也分為:

包裝請求(req)--> 傳送請求 --> 處理請求 

三個步驟。但從時序圖上,我們不難看出整個流程其實應該分為兩大部分:
1. 訂單支付流程
2. 訂單查詢流程
先後順序上,支付流程在前,查詢流程在後。即:

訂單支付流程 --> 訂單查詢流程

這兩大塊分別完成了相互可獨立劃分,但資料上存在關聯,存在因果關係的表目的不同的過程。一起組成了整個支付流程。所以,我們分別從這兩部分入手。

訂單支付流程

訂單支付流程是包裝訂單請求和傳送請求建立支付的這樣的一個過程的封裝。支付請求的本質目的是為了將本次交易的具體資訊,封裝成微信可識別的訂單啟動資訊(即預支付資訊)。然後交予伺服器,伺服器收到App的資料後會和微信支付伺服器做“溝通”,開啟支付流,並將本次訂單的預支付資訊返回給客戶端。客戶端通過服務端返回的資料生成預支付資訊,就可以通知本地的微信客戶端來連線並支付了。
需要注意的是:微信支付的返回值處理是在WXPayEntryActivity當中進行的,同樣實現了 IWXAPIEventHandler,並在onResp當中處理了交易狀態返回值。因此,我們demo中的支付頁面(Vip中心),使用的就是WXPayEntryActivity。
所以我們可以將這個過程放在同一個非同步執行緒當中,避免主執行緒負載(存在資料蒐集、載入過程),同時在時序上有個限定:

 /** 1.發起交易 */
    public void doPayDebtAction(final VipPackInfo data) {
        new AsyncTask<Integer, Void, Boolean>() {

            @Override
            protected Boolean doInBackground(Integer... params) {
                MessageManager.showProgressDialog((Activity) context, "蒐集資料中...");
                VipDebtPayInfo myPackDebt = sendReqToServer();
                if
(myPackDebt == null) return false; return doWechatPayAction(myPackDebt); } @Override protected void onPostExecute(Boolean isSuccess) { super.onPostExecute(isSuccess); MessageManager.closeProgressDialog(); if
(!isSuccess) { MessageManager.showMessage((Activity) context, "交易失敗"); } } /***************************************具體流程*****************************************/ /** (1).請求服務端,發起交易會話 */ private VipDebtPayInfo sendReqToServer() { return // TODO 這裡放置你的資料蒐集結果,這是和伺服器端約定的,每個App間有所不同。 } /** (2).根據會話返回結果,發起本地交易 */ public boolean doWechatPayAction(final VipDebtPayInfo debt) { orderNumber = debt.getOrderNumber(); // 構造微信請求 PayReq req = new PayReq(); req.appId = debt.getAppId(); req.partnerId = debt.getPartnerId(); req.prepayId = debt.getPrepayId(); req.nonceStr = debt.getNonceStr(); req.timeStamp = debt.getTimeStamp(); req.packageValue = debt.getPackage(); req.sign = debt.getSign(); // 呼叫API介面傳送到微信 IWXAPI wxApi = WXAPIFactory.createWXAPI(context, FirstPageConstants.WX.APP_ID); wxApi.registerApp(FirstPageConstants.WX.APP_ID); return wxApi.sendReq(req); } }.execute(); }

程式碼demo模擬的情況是一個Vip的購買流程,其中VipDebtPayInfo即是服務端在接受了客戶端資料後返回的資料了。如要使用查詢功能,則VipDebtPayInfo的資料在包含預支付所需資訊外,還需要攜帶一個唯一的C-S約定的“訂單號”欄位,用於客戶端後續連線伺服器查詢訂單資訊。

訂單查詢流程

因為涉及到錢,且微信本身只管支付過程,並不會(並且也沒辦法)幫你處理支付後的本地資料更新。所以,我們需要必須得訂單查詢流程,以確保:
1. 訂單支付成功,服務端更新了資料。
2. 客戶端能夠確認服務端資料更新。
因此,查詢流程的目的有兩個:
1. 通知並確認服務端資料得到了更新。
2. 客戶端資料同步更新。
所以我們有:

 /** 2.交易結束(提交檢查支付是否成功) */
    public void checkWhenPayFinish() {
        new AsyncTask<Integer, Void, Boolean>() {

            @Override
            protected Boolean doInBackground(Integer... params) {
                MessageManager.showProgressDialog((Activity) context, "訂單檢測中...");
                return checkFinalResult();
            }

            @Override
            protected void onPostExecute(Boolean isSuccess) {
                super.onPostExecute(isSuccess);
                if (!isSuccess && !timerInfo.isDone()) {    // 重新檢測(未成功且小於3次)
                    debtTripleCheck();
                } else {                                    // 結果處理(成功或3次失敗後)
                    resultDeal(isSuccess);
                }
            }


            /***************************************具體流程*****************************************/
            /** (1).最終結果校驗(當前採用的是簡單的本地線上比對,最好由服務端提交微信安全查詢) */
            private Boolean checkFinalResult() {
                VipPayCheckInfo checkResult = mVipsRepository.checkPackDebt(orderNumber);
                if (checkResult != null && checkResult.isSuccess()) {
                    VipProfilesInfo mProfilesOld = mVipsRepository.doLoadUserProfileByCache();
                    VipProfilesInfo mProfilesNew = mVipsRepository.doLoadVipsProfile();

                    // 更新個人資料
                    UserInfo usersInfo = mUserRepository.getUserInfo();
                    if (usersInfo != null && usersInfo.getChuyeUser() != null) {
                        UserSocial basicInfos = usersInfo.getChuyeUser();
                        basicInfos.setVipData(mProfilesNew.getVipData());
                        mUserRepository.saveBasicUserInfo(basicInfos);
                        mUserRepository.saveUserInfo(usersInfo);
                    }

                    return (mProfilesNew != null && !mProfilesNew.equals(mProfilesOld));
                } else {
                    return false;
                }
            }

            /** (2).網路訂單三重校驗(伺服器特性,保證可靠性) */
            @NonNull
            private void debtTripleCheck() {
                final Timer timer = new Timer();
                timer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        int count = timerInfo.getCount();
                        if (count >= 2) {
                            timerInfo.setIsDone(true);
                        } else {
                            timerInfo.setCount(count + 1);
                            checkWhenPayFinish();
                        }
                    }
                }, 1000);
            }

            /** (3).結果處理 */
            private void resultDeal(Boolean isSuccess) {
                timerInfo.reset();
                MessageManager.closeProgressDialog();
                if (isSuccess) {
                    doUpdateProfile();
                    MessageManager.showMessage((Activity) context, "支付成功");
                } else {
                    MessageManager.showMessage((Activity) context, "支付處理中,請等待微信通知");
                }
            }

            /** (4).交易成功,更新Vip中心 */
            private void doUpdateProfile() {
                if (mOnDoNetFinishListener != null) {
                    VipCenterReunionInfo result = new VipCenterReunionInfo(
                            mVipsRepository.doLoadPackListByCache(),
                            mVipsRepository.doLoadUserProfileByCache()
                    );
                    mOnDoNetFinishListener.onLoadFinish(result);
                }
            }

        }.execute();
    }

因為模擬的是Vip的支付流,所以更新資料後,需要更新使用者的Vip資訊,同時更新Vip支付中心的資訊(即交易發起介面的資訊)。同時,為了保證避免檢測過程中的資料延遲導致獲取不正確的資料,我們需要進行三次重複校驗,以保證交易準確性。

總結

前面我們討論了SDK通用整合方法,並通過微信的登入、分享、支付展示了一下具體的使用過程,相信大家對SDK的使用已經有了一定的瞭解。其實,不論是聊天開發、天氣資訊、還是bug反饋,當使用第三方類庫.jar檔案時,基本是依照這個流程來的,只不過聊天需要你本地自定義的細節比較多,具體註冊過程也會在隨後的初始化流程中存在大量監聽和細節(看具體SDK),訊息推送根據不同的SDK在初始化上也存在大量的自定義及細節。可以看出,基本流程存在較大變數的位置就在於初始化流程當中了,這時會根據具體情況多處少至幾行程式碼,多至幾個模組的程式碼量了。具體情況還需要在使用中體會了。

相關推薦

常用整合第三方sdk整合套路-- 支付

支付 微信支付,官方給出的時序圖如下: 支付流程總體還是遵循SDK的基本整合流程的。因此,也分為: 包裝請求(req)--> 傳送請求 --> 處理請求 三個步驟。但從時序圖上,我們不難看出整個流程其實應該分為兩大部分: 1.

常用整合第三方sdk整合套路-- 登入

序言 程式開發過程中,總歸是會用到第三方sdk的,這裡就常用的登入、分享、支付做一個整合方法上的綜述,以備引申至通用的sdk使用方法。 一般的,sdk在登入、分享、支付上,都會按照如下的流程進行: 包裝請求(req)--> 傳送請求 -->

----分享第三方平臺的授權分享待完善

參考SDK-----詳情百度網盤 連結:https://pan.baidu.com/s/1ejSw4A5Vi6knL8T9qVQnCQ 提取碼:h8wl 微信文件 :https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115

開發準備工作簡版

scale tro ima acc client XML 帳號 red wid 1.準備工作 1.1 首先需要一個url地址,用來接收相關的數據 1.2 註冊開發者賬號進行開發(可用公眾平臺測試賬號) 1.3 appid,第三方用戶唯一憑證(你的AppID) 1.4 sec

WebService--CXF與Spring的整合jaxws:endpoint形式配置

tid archetype 全路徑 systems hide onf -o hot conf 一、CXF與Spring整合(jaxws:endpoint形式配置) 工具要點:idea、maven 1.新建一個maven項目 <?xml version="1.0"

SSM整合實現全部使用者查詢

準備 1、建立工程(我建立了一個maven工程) 2、pom檔案匯入依賴: https://blog.csdn.net/qq_43154385/article/details/84308826 3、工程結構 程式碼 mybatis-config.xml(SqlMapCo

springboot2.x簡單詳細教程--搜尋框架ElasticSearch介紹和整合第十二章

一、搜尋引擎知識和搜尋框架elasticsearch(es)基本介紹    1. 簡介:通過京東電商 介紹什麼是搜尋引擎,和開源搜尋框架ElasticSearch6.x新特性介紹         前言

原創分享C# MVC支付之公眾號支付教程

前段時間在公司實習做了公眾號的微信支付及退款,期間參考了網上一大推資料,自己也遇到了一些坑,所以把這個教程寫下來方便後來人。 首先做微信支付你得先把微信官網的開發文件看一邊,網址:https://pay.weixin.qq.com/wiki/doc/api/j

Arduino+W5100+新浪雲SAE開發語言:Python+公眾平臺實現LED控制

閱讀本部落格之前,建議先參考部落格:微信客戶端+微信公眾平臺+新浪雲SAE+Arduino+WS100(控制LED) 不同之處:主要是伺服器使用的語言,本部落格使用的是Python 一、硬體部分 1) Arduino、W5100 連線圖如下: 硬體

SpringMVC與Shiro的最簡單整合不包含許可權管理

1.Maven 引入依賴 <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifa

訊息佇列--與spring整合採用註解消費佇列

一、簡介 這裡採用註解方式使用kafka。 二、新增maven依賴 <dependency> <groupId>org.springframework.kafka&l

Flume+Kakfa+Spark Streaming整合執行WordCount小例子

環境版本:Scala 2.10.5; Spark 1.6.0; Kafka 0.10.0.1; Flume 1.6.0 Flume/Kafka的安裝配置請看我之前的部落格: http://blog.c

授權前後端分離授權

微信授權分為以下四步: 我認為我們前端需要的步驟是  1、判斷收否授權。 2、如果沒有,跳轉到微信提供的第三方授權連結。 3、使用者點選授權,微信自動會跳轉一個重定向頁

一步一步完成SSM框架整合Spring+Spring MVC + Mybatis

新建maven工程 eclipse中選擇new Maven Project項,制定archetype為webapp,填寫好groupId之類的,然後finish,這時可能工程有一些錯誤,通過修改Java Build Path,修復錯誤: 然後new一個s

spring-boot+mybatis+mysql+maven整合附帶自己整合的專案

最近在學習springboot,整合了一個spring-boot+mybatis,看了很多教程,都沒成功,具體的整合流程,大家 看這篇基本就行了,再down下我自己的專案,大家參照著看,希望能幫到大家。LZ今天自己搭建了下Spring boot+Mybatis,比原來的Spr

SSH框架整合實現分頁查詢

SSH框架整合、分頁查詢案例之前已經寫過了SSM框架的分頁查詢案例,剛翻筆記時看到了以前寫過的SSH分頁查詢的功能的筆記,這裡就也再整理一下嘍,送給那些在學習SSH框架的同學,SSH框架因為用的Hibernate,所以與SSM有所不同,希望這個小案例能對大家有所幫助。<

linux腳本獲取系統選自實驗樓實驗

可用 led all .sh sys info 腳本 cpu process 執行getinfo.sh腳本後,不需要任何參數,輸出內容如下:$ bash getinfo.shcpu num: 2memory total: 2.8Gmemory free: 329Mdisk

統計學生使用鏈表完成

雙向鏈表 rcm math cstring true 個學生 分鐘 其中 oid 【描述】 利用動態鏈表記錄從標準輸入輸入的學生信息(學號、姓名、性別、年齡、得分、地址) 其中,學號長度不超過20, 姓名長度不超過40, 性別長度為1, 地址長度不超過40 【輸入】 輸入包

[0301]統計圖書銷售運算符重載

pad logs line end tps HR close names cccccc Description: Code: #include<iostream> #include<cstring> #include<fstre

Python收集LinuxUbuntu環境測試過系統息——CPU、內存、磁盤、網卡

python收集linux系統信息#!/usr/bin/python # coding:utf-8 import os import json import socket import psutil class Host: _hostname = socket.getfqdn(socket.get