微信支付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,前面
步驟四,支付程式碼部分。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接入的大概流程