一步一步將微信支付集成到 react-native 應用

上篇文章已經介紹過 react-native 集成支付寶,本篇文章將基於微信支付官方提供的集成文檔,介紹如何將微信支付集成到 react-native 應用中。php

場景介紹

適用於商戶在移動端APP中集成微信支付功能。 商戶APP調用微信提供的SDK調用微信支付模塊,商戶APP會跳轉到微信中完成支付。 支付完後跳回到商戶APP內,最後展現支付結果。 目前微信支付支持手機系統有:IOS(蘋果)、Android(安卓)和WP(Windows Phone)。html

集成SDK

獲取APPID:商戶在微信開放平臺申請開發APP應用後,微信開放平臺會生成APP的惟一標識APPID。java

Android

  1. 後臺設置 商戶在微信開放平臺申請開發應用後,微信開放平臺會生成APP的惟一標識APPID。因爲須要保證支付安全,須要在開放平臺綁定商戶應用包名和應用簽名,設置好後才能正常發起支付。設置界面在【開放平臺】中的欄目【管理中心 / 修改應用 / 修改開發信息】裏面,以下圖紅框內所示。
    應用簽名獲取可使用:應用簽名獲取工具,將安裝包安裝到手機裏,輸入應用包名便可獲取到簽名。
    這裏有個調試技巧,能夠將應用的簽名改成 debug 版本的簽名,等支付調試完成後再改成生產環境的簽名。
  2. 導入微信SDK,修改android/app/build.gradle添加以下代碼:
dependencies {
    ......
    compile "com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+"
    ......
}
複製代碼
  1. com.xx.xx建立包名wxapi注意此處包名必定要爲wxapi,不然後續將沒法處理回調
  2. 編寫 Module,在com.xx.xx.wxapi包下建立WxpayModule.java,代碼以下:
package com.xx.xx.wxapi;

import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.tencent.mm.opensdk.modelpay.PayReq;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;

class WxpayModule extends ReactContextBaseJavaModule {

  private IWXAPI api;
  static String APP_ID = "";
  static Promise promise = null;

  WxpayModule(ReactApplicationContext reactContext) {
    super(reactContext);
    api = WXAPIFactory.createWXAPI(reactContext, null);
  }

  @Override
  public String getName() {
    return "Wxpay";
  }

  @ReactMethod
  public void registerApp(String APP_ID) { // 向微信註冊
    WxpayModule.APP_ID = APP_ID;
    api.registerApp(APP_ID);
  }

  @ReactMethod
  public void pay(final ReadableMap order, Promise promise) {
    WxpayModule.promise = promise;
    PayReq request = new PayReq();
    request.appId = order.getString("appid");
    request.partnerId = order.getString("partnerid");
    request.prepayId= order.getString("prepayid");
    request.packageValue = order.getString("package");
    request.nonceStr= order.getString("noncestr");
    request.timeStamp= order.getInt("timestamp")+"";
    request.sign= order.getString("sign");
    api.sendReq(request);
  }

  @ReactMethod
  public void isSupported(Promise promise) { // 判斷是否支持調用微信SDK
    boolean isSupported = api.isWXAppInstalled();
    promise.resolve(isSupported);
  }

}
複製代碼
  1. 編寫 Package,在com.xx.xx.wxapi包下建立WxpayPackage.java,代碼以下:
package com.xx.xx.wxapi;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class WxpayPackage implements ReactPackage {

  @Override
  public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
    return Collections.emptyList();
  }

  @Override
  public List<NativeModule> createNativeModules( ReactApplicationContext reactContext) {
    List<NativeModule> modules = new ArrayList<>();
    modules.add(new WxpayModule(reactContext));
    return modules;
  }

}
複製代碼
  1. 編寫 WXPayEntryActivity 處理微信支付回調,在com.xx.xx.wxapi包下建立WXPayEntryActivity.java注意包名或類名不一致會形成沒法回調,代碼以下:
package com.xx.xx.wxapi;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableMap;
import com.tencent.mm.opensdk.constants.ConstantsAPI;
import com.tencent.mm.opensdk.modelbase.BaseReq;
import com.tencent.mm.opensdk.modelbase.BaseResp;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;

public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {
	
    private static final String TAG = "WXPayEntryActivity";
    private IWXAPI api;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    	api = WXAPIFactory.createWXAPI(this, WxpayModule.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) {
		Log.d(TAG, "onPayFinish, errCode = " + resp.errCode);
		if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
			WritableMap map = Arguments.createMap();
			map.putInt("errCode", resp.errCode);
			WxpayModule.promise.resolve(map);
			finish();
		}
	}
}
複製代碼
  1. 最後在 Android 這邊要作的最後一件事就是註冊這個模塊,在com.xx.xx.MainApplication中註冊模塊:
@Override
protected List<ReactPackage> getPackages() {
    return Arrays.<ReactPackage>asList(
        new MainReactPackage(),
        // ...other packages
        new WxpayPackage() // <-- 註冊模塊
    );
}
複製代碼

iOS

  1. 項目設置APPID,在Xcode中打開項目,設置項目屬性中的URL Schemes爲你的APPID。如圖標紅位置所示:
  2. 添加微信白名單 info.plist --> 右擊 --> open as --> source Code --> 添加白名單,以下圖所示:
    2017-12-11-14-28-10
    代碼以下:
<key>LSApplicationQueriesSchemes</key>
    <array>
        <string>wechat</string>
        <string>weixin</string>
    </array>
</key>
複製代碼
  1. 導入必要的庫文件,以下圖所示:
    2017-12-11-14-30-54
  2. 在項目目錄下建立Group Wxapi,並建立WxpayModule模塊
  3. 下載開發工具包(SDK),導入Wxapi中,最終以下圖所示:
    2017-12-11-15-05-34
  4. 編寫WxpayModule.h代碼以下:
#import <React/RCTBridgeModule.h>
#import <React/RCTLog.h>
#import "WXApiObject.h"
#import "WXApi.h"

@interface WxpayModule : NSObject <RCTBridgeModule, WXApiDelegate>
@end
複製代碼
  1. 編寫WxpayModule.m代碼以下:
#import "WxpayModule.h"

@implementation WxpayModule

RCTPromiseResolveBlock resolveBlock = nil;

- (instancetype)init
{
  self = [super init];
  if (self) {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleWXPay:) name:@"WXPay" object:nil];
  }
  return self;
}

- (void)dealloc
{
  [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)handleWXPay:(NSNotification *)aNotification
{
  NSString * errCode =  [aNotification userInfo][@"errCode"];
  resolveBlock(@{@"errCode": errCode});
}

RCT_EXPORT_METHOD(registerApp:(NSString *)APP_ID){
  [WXApi registerApp: APP_ID];//向微信註冊
}

RCT_EXPORT_METHOD(pay:(NSDictionary *)order
                  resolver:(RCTPromiseResolveBlock)resolve
                  rejecter:(RCTPromiseRejectBlock)reject){
  resolveBlock = resolve;
  //調起微信支付
  PayReq *req = [[PayReq alloc] init];
  req.partnerId = [order objectForKey:@"partnerid"];
  req.prepayId = [order objectForKey:@"prepayid"];
  req.nonceStr = [order objectForKey:@"noncestr"];
  req.timeStamp = [[order objectForKey:@"timestamp"] intValue];
  req.package = [order objectForKey:@"package"];
  req.sign = [order objectForKey:@"sign"];
  [WXApi sendReq:req];
}

RCT_REMAP_METHOD(isSupported, // 判斷是否支持調用微信SDK
                  resolver:(RCTPromiseResolveBlock)resolve
                  rejecter:(RCTPromiseRejectBlock)reject){
  if (![WXApi isWXAppInstalled]) resolve(@NO);
  else resolve(@YES);
}

RCT_EXPORT_MODULE(Wxpay);

@end
複製代碼
  1. 處理微信支付回調,在AppDelegate.m中添加以下代碼:
//支付回調9之後
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary*)options {
  return  [WXApi handleOpenURL:url delegate:self];
}
//支付回調9之前
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
  return  [WXApi handleOpenURL:url delegate:self];
}
//ios9之後的方法
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
  return [WXApi handleOpenURL:url delegate:self];
}

#pragma mark - wx callback

- (void) onReq:(BaseReq*)req
{
  // TODO Something
}

- (void)onResp:(BaseResp *)resp
{
  //判斷是不是微信支付回調 (注意是PayResp 而不是PayReq)
  if ([resp isKindOfClass:[PayResp class]])
  {
    //發出通知 從微信回調回來以後,發一個通知,讓請求支付的頁面接收消息,而且展現出來,或者進行一些自定義的展現或者跳轉
    NSNotification * notification = [NSNotification notificationWithName:@"WXPay" object:nil userInfo:@{@"errCode":@(resp.errCode)}];
    [[NSNotificationCenter defaultCenter] postNotification:notification];
  }
}
複製代碼
  1. 至此,iOS端微信SDK集成成功

React-Native

  1. 修改原生代碼後,須要從新打包運行程序:
react-native run-android # 運行Android端
react-native run-ios # 運行iOS端
複製代碼
  1. 編寫Wxpay.js工具類
import { NativeModules } from 'react-native';
export default NativeModules.Wxpay;
複製代碼
  1. 在入口文件index.js向微信註冊應用
import Wxpay from './your/path/to/Wxpay';
Wxpay.registerApp(APPID); //向微信註冊
複製代碼
  1. 調用Wxpay模塊發起微信支付:
import Wxpay from './your/path/to/Wxpay';
async pay(params){ // params 爲後端提供的參數
    let isSupported = await call(Payway.isSupported);
    if (!isSupported) { // 判斷是否支持微信支付
        message.show('找不到微信應用,請安裝最新版微信');
        return;
    }
    let res = await call(getOrderInfo, params); // 從後端獲取簽名對象,參考支付接口調用
    let ret = await call(Wxpay.pay, res.data); // 調起微信客戶端,發起支付
    if (ret.errCode === 0) {
        // 支付成功回調
    } else {
        // 支付失敗回調
    }
}    
複製代碼
  1. 支付接口調用參考調起支付接口統一下單,本篇將不作贅述。

參考文檔

原文章地址:react-native 集成微信支付react

做者:ZevenFangandroid

轉載請註明出處~ios

相關文章
相關標籤/搜索