1. 程式人生 > >微信支付SDK接入流程梳理

微信支付SDK接入流程梳理

         微信SDK的支付功能接入簡單梳理。

   首先說一下,你需要的官網都有,但是官網提供的東西不管新舊與否先給你放上去,部分地方提供的連結點選時還提示404,不同的頁面提示相同的下載內容(demo)還不一樣,表示很無奈(lai)。

    這裡把幾個主要點羅列出來,給大家節省點寶貴的時間,有什麼錯誤希望大家指正(預設微信支付平臺商戶申請及應用建立略去,商務小夥伴已經把AppID祕鑰給到你了,這裡只說一下客戶端需要處理的相關事宜)。

微信支付有兩個平臺分別是開發者平臺商戶平臺

      開發者平臺:主要是針對開發者,比如:建立應用,獲取appid
    商戶平臺:主要是商戶上面的一些管理,比如:可以檢視流水,訂單呀

    步驟一:下載官方示例,示例下載地址


點選下載Android平臺所需的APP支付檔案。

點選“Android標頭檔案和庫下載”下載後會跳轉到該頁面:


接著點選Android開發工具包,下載對應的lib庫。

解壓以後的檔案目錄裡有兩個jar。

細節1:這兩個jar不是都得用,不知道的把兩個jar都考到專案工程下,肯定會給你個jar重複的錯誤提示。這裡依據需求進行選擇,這兩個依賴包的區別是前者包含統計功能,後者沒有。

自己這裡選擇的是第二個,沒有統計功能且包體小一點的。
      步驟二,新建公共lib庫,將對應jar包放入專案工程中待用.(lib公共庫的建立)

    步驟三,從Demo示例的工程目錄下拷入WXEntryActivity.java檔案到你的專案目錄下,一定要保證:
該檔案存放的目錄格式是這樣的:com.package.name.wxapi,前面

com.package.name是你真正的包名,wxapi是同級包。編輯修改對應檔案,其他無用部分都不使用。以下是整個檔案剩下內容。

public class WXEntryActivity extends Activity implements IWXAPIEventHandler{
	// IWXAPI 是第三方app和微信通訊的openapi介面
    private IWXAPI api;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.entry);這一行不需要,直接註釋。
        
        // 通過WXAPIFactory工廠,獲取IWXAPI的例項
    	api = WXAPIFactory.createWXAPI(this, Constants.APP_ID, false);
		// 將該app註冊到微信
		api.registerApp(APP_ID);//你的AppID,最好寫在Lua端或者服務端。    	
        
		//注意:
		//第三方開發者如果使用透明介面來實現WXEntryActivity,需要判斷handleIntent的返回值,如果返回值為false,則說明入參不合法未被SDK處理,應finish當前透明介面,避免外部通過傳遞非法引數的Intent導致停留在透明介面,引起使用者的疑惑
        try {
        	api.handleIntent(getIntent(), this);
        } catch (Exception e) {
        	e.printStackTrace();
        }
    }
	@Override
	protected void onNewIntent(Intent intent) {
		super.onNewIntent(intent);
		setIntent(intent);
        api.handleIntent(intent, this);
	}

	// 微信傳送請求到第三方應用時,會回撥到該方法
	@Override
	public void onReq(BaseReq req) {
	}

	// 第三方應用傳送到微信的請求處理後的響應結果,會回撥到該方法
	@Override
	public void onResp(BaseResp resp) {
		if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX){
			if (resp.errCode == 0){
				Toast.makeText(this, "支付成功!", Toast.LENGTH_SHORT).show();
			}else{
				Toast.makeText(this, "支付失敗!", Toast.LENGTH_SHORT).show();
			}
		}
		finish();
	}
}
        步驟四,支付程式碼部分

          支付部分也是最主要的部分,基於cocos2d-lua的專案,這裡涉及到Lua呼叫Java的需求,簡單說一下:

     1,你可以直接使用cocos封裝好的

       luaj.callStaticMethod(param1, param2, param3, param4)

       param1:"com.game.mainactivity",回撥到java的對應類的完整路徑(字串型別

       param2:"on_pay",回撥到java的對應方法名稱(字串型別)

       param3:{...},呼叫java方法時需要傳入的引數資訊(table型別)

       param4:"(Ljava/lang/String;)V",方法的簽名。具體可參考:JNI方法簽名

               2,直接在C++裡寫一個專門處理支付的方法,匯出給lua使用,然後在C++裡使用JNI回撥到java。

  2種方法本質基本一樣,這樣在java端對應的方法裡解析傳入的引數,取到對應所需的數值:商品ID,商品價格等等即可。

     ------------------------------重點線-------------------------------------------

             一,目前微信最新的支付接入,需要四個引數:

         APP_ID:應用唯一標示

                          PARTNER_ID:應用商戶ID號

        PAY_KEY:應用私鑰

        PRE_PAY_ID:預支付交易訂單號(商戶系統先呼叫該介面在微信支付服務後臺生成預支付交易單,返回正確的預支付交易回話標識後再在APP裡面調起支付,用於後續介面呼叫中使用,該值有效期為2小時)

     上面四個變數的命名無特殊要求,自己清楚對應數值含義就好,個人建議這些東西最好放在服務端,由客戶端請求後傳入支付呼叫介面處,自己是寫在lua層的,出包時對lua檔案做了加密。這裡的預支付訂單是有伺服器請求微信支付後臺取到,發給客戶端的,這個數值在後面的呼叫支付介面時會用到。

     二,客戶端調起支付介面時所需的引數(注意相應的欄位型別)

    

     從應用ID到預支付ID都是已有的,擴充套件欄位填入給到的示例值即可。

     隨機字串:一定要和伺服器採用相同的演算法生成,統一使用如下方法:

private static String genNonceStr() {
		Random r = new Random(System.currentTimeMillis());
		return MD5.getMessageDigest((WXPayConfig.APP_ID + r.nextInt(10000) + System.currentTimeMillis()).getBytes());
	}
     時間戳:
String timestamp = "" + System.currentTimeMillis();
             

              這裡直接給出方法邏輯

List<NameValuePair> signParams = new LinkedList<NameValuePair>();
		signParams.add(new BasicNameValuePair("appid", payReq.appId));
		signParams.add(new BasicNameValuePair("noncestr", payReq.nonceStr));
		signParams.add(new BasicNameValuePair("package", payReq.packageValue));
		signParams.add(new BasicNameValuePair("partnerid", payReq.partnerId));
		signParams.add(new BasicNameValuePair("prepayid", payReq.prepayId));
		signParams.add(new BasicNameValuePair("timestamp", payReq.timeStamp));

		StringBuilder sb = new StringBuilder();

		for (int i = 0; i < signParams.size(); i++) {
			sb.append(signParams.get(i).getName());
			sb.append('=');
			sb.append(signParams.get(i).getValue());
			sb.append('&');
		}
		sb.append("key=");
		sb.append(WXPayConfig.PAY_KEY);//該欄位很重要

		String appSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();
		return appSign;
      整個支付方法的核心程式碼:
        //支付方法,引數prePayId由客戶端請求伺服器獲得的預支付ID通過JNI回傳到客戶端的數值
	public static void wxPay(String prePayId) {
		IWXAPI msgApi = WXAPIFactory.createWXAPI(mContext, WXPayConfig.APP_ID);
		msgApi.registerApp(WXPayConfig.APP_ID);
		if (!msgApi.isWXAppInstalled() || !msgApi.isWXAppSupportAPI()) {
			Toast.makeText(mContext, "您沒有安裝微信,或者微信版本過低,請要先安裝或者升級", Toast.LENGTH_SHORT).show();
			return;
		}
		
		PayReq payRequest = new PayReq();
		payRequest.appId = WXPayConfig.APP_ID;
		payRequest.partnerId = WXPayConfig.PARTNER_ID;
		payRequest.prepayId = prePayId;
		payRequest.nonceStr = genNonceStr();
		payRequest.timeStamp = "" + System.currentTimeMillis();
		payRequest.packageValue = "Sign=WXPay";
		payRequest.sign = genAppSign(payRequest);
		msgApi.sendReq(payRequest);
	}
     這樣微信支付的整個流程基本就走通了,支付以後會回撥你在WXEntryActivity裡的如下方法提示你支付結果
@Override
	public void onResp(BaseResp resp) {
		if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
			if (resp.errCode == 0) {
				Toast.makeText(this, "支付成功 ", Toast.LENGTH_SHORT).show();
			} else {
				Toast.makeText(this, "支付失敗,請重試 ", Toast.LENGTH_SHORT).show();
			}
		}
	}

細節:

   1,AndroidManifest.xml裡新增一下activity標籤定義:

<activity android:name="專案包名.wxapi.WXEntryActivity" android:exported="true" />
   2,接入微信SDK關於分享,登入,支付的等功能,為了確保能正常使用及安全支付,都需要在開放平臺繫結商戶應用包名和應用簽名,設定好後才能正常發起支付。

   

應用簽名的生成方式:

    1,確保app使用包名和開放平臺中填入的包名一直,然後下載對應的簽名工具
       
      即可生成對應的簽名,填入應用開放平臺即可。

      這就是微信支付SDK接入的大概流程