相親原始碼中移動支付的實現,沒有想象中那麼難
前言
在相親原始碼中實現移動支付其實是非常簡單的,因為只要按照第三方的文件來就行了,做過支付的人都知道支付的難點其實是在第三方文件和demo上(集中體現文件陳舊、demo容易誤導人、槽點太多),那就不得不先來吐槽下WX的開發文件和示例,我相信大部分人都被坑過,沒有對比就沒有傷害,相對而言,支付寶好很多,下面我先說重點再談支付流程。
開發優化要點
-
微信回撥返回相親原始碼當前頁面部分機型會產生一閃而過的黑屏現象,測試機型三星S8,解決方案為在微信回撥頁面增加透明主題,如下:
<!--解決微信支付回撥部分機型黑屏閃爍的問題--> <style name="wxPayTheme" parent="Theme.AppCompat.Light.NoActionBar"> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:windowIsTranslucent">true</item> <item name="android:windowNoTitle">true</item> </style> <!--回撥頁面WXPayEntryActivity關閉finish的時候增加--> overridePendingTransition(0, 0); <!--回撥頁面WXPayEntryActivity配置--> <activity android:name=".wxapi.WXPayEntryActivity" android:configChanges="orientation|screenSize" android:exported="true" android:launchMode="singleTop" android:theme="@style/wxPayTheme" android:windowSoftInputMode="adjustPan|stateAlwaysHidden" /> <!--另外一種解決方案--> android:launchMode="singleTop"改為android:launchMode="singleInstance" 建議優先採取第一種方案,該方案作為備選,畢竟微信推薦使用"singleTop"啟動模式。
-
DialogFragment記憶體洩漏問題,google雖然推薦使用DialogFragment替代Dialog,但是記憶體洩漏問題並未解決,試過很多方案,並未完美解決洩漏問題,故更改使用Activity結合動畫實現相親原始碼底部支付彈窗的效果。
<!--底部彈框支付Activity主題樣式--> <style name="PayTranslucentTheme" parent="Theme.AppCompat.Light.NoActionBar"> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:windowAnimationStyle">@null</item> <item name="android:windowIsTranslucent">true</item> <item name="android:windowNoTitle">true</item> <!-- 無標題 --> <item name="android:windowContentOverlay">@null</item> <item name="android:backgroundDimEnabled">true</item><!-- 半透明 --> </style> <!-- R.anim.push_bottom_in 進入動畫--><?xml version="1.0" encoding="utf-8"?><set xmlns:android=" <translate android:duration="300" android:fromYDelta="100%p" android:toYDelta="0" /></set><!-- R.anim.push_bottom_out 淡出動畫--><?xml version="1.0" encoding="utf-8"?><set xmlns:android=" <translate android:duration="300" android:fromYDelta="0" android:toYDelta="100%p" /></set><!-- R.anim.push_bottom_silent 原點--><?xml version="1.0" encoding="utf-8"?><translate xmlns:android=" android:duration="300" android:fromYDelta="0" android:toYDelta="0" /> <!-- 底部彈框-->startActivity(intent);overridePendingTransition(R.anim.push_bottom_in,R.anim.push_bottom_silent);<!-- 關閉底部彈框-->finish();overridePendingTransition(R.anim.push_bottom_silent,R.anim.push_bottom_out);<!-- 實現透明狀態列-->setContentView(R.layout.activity_dialog_pay_custom);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { getWindow().setStatusBarColor(Color.TRANSPARENT); }
微信支付
流程
沒錯,這就是官方的業務流程圖,有點糊的感覺,下面我以相親原始碼客戶端開發為主,簡化一下流程:
-
相親原始碼客戶端選擇購買的商品後,選擇微信支付,介面請求伺服器,伺服器此時需要生成預支付訂單(呼叫微信統一下單介面),其中返回的引數便是我們調起微信支付所需要的引數。(統一下單)
-
相親原始碼客戶端拿到伺服器返回的預支付訂單引數,通過微信SDK調起微信支付頁面
-
客戶端收到微信支付的狀態回撥
-
通過相親原始碼伺服器查詢支付訂單的狀態,注意:以伺服器查詢的結果為準,不要使用微信返回給客戶端的支付狀態作為支付依據。(訂單查詢)
整合
-
微信開放平臺註冊及配置
1.申請相親原始碼獲取微信平臺生成的唯一APPID(管理中心-建立應用)
2.配置簽名,獲取相親原始碼的簽名(簽名工具)
3.配置相親原始碼包名,此處文件太老舊,應該為buile.gradle中的applicationId
-
註冊APPID
IWXAPI api = WXAPIFactory.createWXAPI(this, APP_ID);
-
呼叫SDK發起支付
/** * 微信支付 * * @param payInfo 預支付資訊 */ private void wechatPay(final String payInfo) { try { JSONObject json = new JSONObject(payInfo); if (!json.has("retcode")) { PayReq req = new PayReq(); // 測試用appId req.appId = APP_ID;// req.appId = json.getString("appid"); req.partnerId = json.getString("partnerid"); req.prepayId = json.getString("prepayid"); req.nonceStr = json.getString("noncestr"); req.timeStamp = json.getString("timestamp"); req.packageValue = json.getString("package"); req.sign = json.getString("sign"); req.extData = "app data"; Toast.makeText(PayDialogActivity.this, "正常調起支付", Toast.LENGTH_SHORT).show(); // 在支付之前,如果應用沒有註冊到微信,應該先呼叫IWXMsg.registerApp將應用註冊到微信 api.sendReq(req); } } catch (JSONException e) { e.printStackTrace(); showToast(this, "異常:" + e.getMessage()); } }
-
微信回撥介面
1.目錄結構配置,需要在包名下新建wxapi目錄,並增加回撥介面WXPayEntryActivity,如下圖:
2.回撥介面示例
/** * @author hule * @date 2019/7/29 15:58 * description: 微信支付回撥 */ public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler { private IWXAPI api; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //此處如果需要顯示介面需要設定setContentView(); //一般情況下會都不會去設定介面,拿到回撥後直接關閉介面,傳送通知處理 api = WXAPIFactory.createWXAPI(this, PayDialogActivity.APP_ID); api.handleIntent(getIntent(), this); } @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) { //通知我們回撥,我們拿來查詢訂單的狀態 EventBus.getDefault().post(new WXPayEntryEntity(resp.errCode)); } // 清除動畫,有助於防止黑屏閃爍 overridePendingTransition(0, 0); finish(); } }
3.回撥頁面配置
<!--解決微信支付回撥部分機型黑屏閃爍的問題--> <style name="wxPayTheme" parent="Theme.AppCompat.Light.NoActionBar"> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:windowIsTranslucent">true</item> <item name="android:windowNoTitle">true</item> </style> <!--回撥頁面WXPayEntryActivity關閉finish的時候增加--> overridePendingTransition(0, 0); <activity android:name=".wxapi.WXPayEntryActivity" android:configChanges="orientation|screenSize" android:exported="true" android:launchMode="singleTop" android:theme="@style/wxPayTheme" android:windowSoftInputMode="adjustPan|stateAlwaysHidden" />
-
查詢訂單支付結果,並提示給使用者
@Subscribe(threadMode = ThreadMode.MAIN) public void payment(WXPayEntryEntity wxPayEntryEntity) { //TODO 當客戶端收到微信支付成功的回撥後,繼續向後臺伺服器進行驗證為最終的結果 // .......此處省略呼叫伺服器介面,查詢結果邏輯...... // 此處以下程式碼只是作為測試使用,這裡需要去伺服器非同步查詢結果 switch (wxPayEntryEntity.getPayStatus()) { case BaseResp.ErrCode.ERR_OK: showToast(this, "支付成功"); break; case BaseResp.ErrCode.ERR_AUTH_DENIED: showToast(this, "微信授權失敗"); break; case BaseResp.ErrCode.ERR_COMM: showToast(this, "訂單支付失敗!"); break; case BaseResp.ErrCode.ERR_SENT_FAILED: showToast(this, "微信傳送失敗"); break; case BaseResp.ErrCode.ERR_UNSUPPORT: showToast(this, "微信不支援"); break; case BaseResp.ErrCode.ERR_USER_CANCEL: showToast(this, "使用者點選取消並返回"); break; default: showToast(this, "訂單支付失敗!"); break; } }
-
混淆配置
# 微信混淆 -keep class com.tencent.mm.opensdk.** { *; } -keep class com.tencent.wxop.** { *; } -keep class com.tencent.mm.sdk.** { *; }
支付寶支付
流程
其實流程和微信差不多,對於相親原始碼只需要簡單的幾個流程就能完成支付寶支付
-
下單後,選擇支付寶支付,相親原始碼客戶端向伺服器傳送請求,伺服器產生預支付訂單,並返回給客戶端
-
客戶端拿到預支付訂單的相關引數,通過支付寶SDK喚起支付
-
相親原始碼客戶端拿到支付寶返回的支付結果,向商戶後臺伺服器查詢最終的訂單完成資訊。
整合
-
相親原始碼接入支付寶SDK
1.下載SDK
2.將alipaySdk-15.6.5-20190718211148.aar複製到libs目錄下
3.工程目錄的build.gradle新增
allprojects { repositories { // 支付寶 SDK AAR 包所需的配置 flatDir { dirs 'libs' } google() jcenter() }}
4.Module專案的build.gradle增加依賴
// 支付寶 SDK AAR 包所需的配置 implementation (name: 'alipaySdk-15.6.5-20190718211148', ext: 'aar')
-
新增許可權
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
-
呼叫支付
/** * 支付寶支付 * * @param payInfo 預支付資訊 */ private void aliPay(final String payInfo) { // 1.去伺服器拿支付訂單 final Runnable payRunnable = new Runnable() { @Override public void run() { PayTask aliPay = new PayTask(PayDialogActivity.this); Map<String, String> result = aliPay.payV2(payInfo, true); Log.d(TAG, result.toString()); Message msg = new Message(); msg.what = SDK_PAY_FLAG; msg.obj = result; payHandler.sendMessage(msg); } }; // 必須非同步呼叫 Thread payThread = new Thread(payRunnable); payThread.start(); }
-
支付寶回撥
/** * 支付寶回撥 */ static class PayHandler extends Handler { private final WeakReference<PayDialogActivity> payDialogActivityWrf; private PayHandler(PayDialogActivity payDialogActivityWrf) { this.payDialogActivityWrf = new WeakReference<>(payDialogActivityWrf); } @Override public void handleMessage(Message msg) { if (SDK_PAY_FLAG == msg.what) { @SuppressWarnings("unchecked") PayResult payResult = new PayResult((Map<String, String>) msg.obj); //對於支付結果,請商戶依賴服務端的非同步通知結果。同步通知結果,僅作為支付結束的通知。 String resultStatus = payResult.getResultStatus(); // 判斷resultStatus 為9000則代表支付成功 if (TextUtils.equals(resultStatus, CODE_9000)) { // TODO 該筆訂單是否真實支付成功,需要依賴[服務端的非同步通知]。 // 該筆訂單是否真實支付成功,需要依賴服務端的非同步通知。 if (payDialogActivityWrf.get() != null) { payDialogActivityWrf.get().showAlert(payDialogActivityWrf.get(), "支付成功!"); } } else { // TODO 該筆訂單是否真實支付成功,需要依賴[服務端的非同步通知]。 if (payDialogActivityWrf.get() != null) { payDialogActivityWrf.get().showAlert(payDialogActivityWrf.get(), "支付失敗!"); } } } } }
-
關於混淆
由於新版的支付寶SDK採用的是aar替換了原來舊版的jar包,預設aar中已經幫你做出了混淆,故新版的支付寶無需手動混淆
,以下是aar中解壓出來的混淆說明
# 這個 ProGuard 檔案被指定為 consumerProguardFiles。 # 如此一來,AAR 包的使用者在其應用進行 ProGuard 混淆時,將自動附加下列規則, # 省去了接入 JAR 時手動在 ProGuard 規則檔案中加入支付寶 SDK 規則的步驟。 -keep class com.alipay.android.app.IAlixPay{*;} -keep class com.alipay.android.app.IAlixPay$Stub{*;} -keep class com.alipay.android.app.IRemoteServiceCallback{*;} -keep class com.alipay.android.app.IRemoteServiceCallback$Stub{*;} -keep class com.alipay.sdk.app.PayTask{ public *;} -keep class com.alipay.sdk.app.AuthTask{ public *;} -keep class com.alipay.sdk.app.H5PayCallback { <fields>; <methods>; } -keep class com.alipay.android.phone.mrpc.core.** { *; } -keep class com.alipay.apmobilesecuritysdk.** { *; } -keep class com.alipay.mobile.framework.service.annotation.** { *; } -keep class com.alipay.mobilesecuritysdk.face.** { *; } -keep class com.alipay.tscenter.biz.rpc.** { *; } -keep class org.json.alipay.** { *; } -keep class com.alipay.tscenter.** { *; } -keep class com.ta.utdid2.** { *;} -keep class com.ut.device.** { *;} # SDK 包可能不包含 utdid -dontwarn com.ta.utdid2.** -dontwarn com.ut.device.** # SDK 包可能不包含 securitysdk -dontwarn com.alipay.mobilesecuritysdk.**
總結
關於相親原始碼實現移動支付大概就是這麼多了,總而言之,對於移動支付,相親原始碼客戶端流程只需要做到以下幾點就能完成支付:
-
商戶伺服器產生預支付訂單
-
相親原始碼客戶端通過預訂單引數呼叫支付SDK客戶端
-
拿到支付客戶端返回的訂單資訊並以商戶後臺伺服器查詢的訂單為最終結果
本文轉載自網路,轉載僅為分享乾貨知識,如有侵權歡迎聯絡雲豹科技進行刪除處理
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69996194/viewspace-2841355/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 想拿到BAT的前端開發崗offer,並沒有想象中的那麼難!BAT前端
- [譯] 為 Django Framework 貢獻你的力量並沒有想象中的那麼難DjangoFramework
- 相親交友原始碼實現相親直播間,移動終端的優化方案原始碼優化
- Netty快速上手:Netty沒有你想象的那麼難Netty
- 全球“萬人迷”MySQL或許並沒有想象中的那麼“香”MySql
- 在遊戲裡新增簡單模式,沒有想象中那麼簡單遊戲模式
- 相親交友原始碼中,音訊AAC解碼的實現程式碼原始碼音訊
- 基本型號 14 英寸 MacBook Pro 可能沒有您想象中那麼快Mac
- block沒那麼難(一):block的實現BloC
- 復刻或重製老遊戲,可能並沒有想象中那麼簡單遊戲
- Excel 中的 VLOOKUP 函式,沒你想的那麼難Excel函式
- 【IT生活】成長,沒有想象的那麼迫切 ——葉紹琛
- 自己實現JSON、XML的解析 沒那麼難JSONXML
- API 與 Webhook,其實並沒有那麼難懂APIWebHook
- 在相親原始碼的多人音視訊聊天中插入現場直播的實現方式原始碼
- Python創始人訪談:Python沒想象中的那麼慢Python
- Java轉python機器學習,並沒有大家想象的那麼美好!JavaPython機器學習
- 如何在相親交友原始碼中實現正方形驗證碼輸入框?原始碼
- 在相親原始碼開發中,如何實現圓角及特殊圓角的使用?原始碼
- 相親交友原始碼中語音連麥的實現方式,值得一看原始碼
- 軟體人才並沒有那麼難找
- Masonry實現原理並沒有那麼可怕
- 在相親交友原始碼中實現視訊連麥直播需要哪些步驟?原始碼
- 聊聊Spring的FactoryBean其實沒那麼難SpringBean
- iOS遊戲開發沒有你想的那麼難–HardestiOS遊戲開發
- 相親交友原始碼開發中,Redis的三種限流方式原始碼Redis
- 相親交友原始碼中的事件循壞,你瞭解多少?原始碼事件
- 相親原始碼的效能為何這麼重要,該怎樣實現優化?原始碼優化
- 解讀 App Store 稽核黑箱政策 —— 遠沒有你想象的那麼邪惡APP
- Javascript之其實我覺得原型鏈沒有難的那麼誇張!JavaScript原型
- 相親交友原始碼開發,前端如何實現水印功能?原始碼前端
- Spring Security,沒有看起來那麼複雜(附原始碼)Spring原始碼
- 開源:比想象中大,也沒想象中重要
- CSS 滾屏效果,要比想象中的難CSS
- 相親交友原始碼開發中會用到的幾種日期處理方法原始碼
- 世嘉的霧遊戲有沒有那麼奇葩?遊戲
- 親愛的商界精英們,開發一個iOS應用沒有那麼容易iOS
- 如何實現相親交友原始碼的CPU效能優化?解決方案梳理原始碼優化