react-native集成微信支付

前言

之前一篇介紹了react-native支付寶支付,微信這篇偷懶借鑒他人的react-native微信支付的例子,并對他的文章進行優化。

在集成之前獲取APPID:商戶在微信開放平臺申請開發APP應用后,微信開放平臺會生成APP的唯一標識APPID。

Android

1.微信開發平臺配置
商戶在微信開放平臺申請開發應用后,微信開放平臺會生成APP的唯一標識APPID。由于需要保證支付安全,需要在開放平臺綁定商戶應用包名和應用簽名,設置好后才能正常發起支付。設置界面在【開放平臺】中的欄目【管理中心 / 修改應用 / 修改開發信息】里面,如下圖紅框內所示。


chapter8_5_2.png

應用簽名獲取可以使用:應用簽名獲取工具,將安裝包安裝到手機里,輸入應用包名即可獲取到簽名。

chapter8_5_3.png

注:安卓調用微信支付在調試模式使用開發簽名只能調起微信客戶端一次且無法回調,相信這個做安卓開發的朋友都遇到過,不多贅述。這里有個調試技巧,可以將應用的簽名改為 debug 版本的簽名,等支付調試完成后再改為生產環境的簽名。

2.在android/app/build.gradle中增加微信sdk從jCenter的引用(如下代碼塊最后一行):

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation "com.android.support:appcompat-v7:23.0.1"
    implementation "com.facebook.react:react-native:+"  // From node_modules
    implementation "com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+" //微信支付,jCenter獲取sdk
}

3.在android/app/src/main/java/com.xx下創建包名wxapi,注意此處包名一定要為wxapi,否則后續將無法處理回調

wxAnd1.jpg

4.編寫 Module,在com.xx.wxapi包下創建WxpayModule.java,代碼如下:

package com.xxx.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();
        //注意此處order.getString中的key對應自己服務器返回的支付參數key
        request.appId = order.getString("appid");
        request.partnerId = order.getString("partnerId");
        request.prepayId= order.getString("prepayid");
        request.packageValue = "Sign=WXPay";
        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();
       // boolean isSupported = api.isWXAppInstalled()&& api.isWXAppSupportAPI();
        promise.resolve(isSupported);
    }

}

5.編寫 Package,在com.xx.wxapi包下創建WxpayPackage.java,代碼如下:

package com.xxx.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;
    }

}

6.編寫 WXPayEntryActivity 處理微信支付回調,在com.xx.wxapi包下創建WXPayEntryActivity.java,注意包名或類名不一致會造成無法回調,代碼如下:

package com.xxx.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();
      }
  }
}

7.最后在 Android 這邊要做的最后一件事就是注冊這個模塊,在com.xx.MainApplication中注冊模塊:

 @Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
          new MainReactPackage(),
              // ...other packages
            new WxpayPackage()// <-- 注冊模塊
      );
    }

iOS

1.項目設置APPID,在Xcode中打開項目,設置項目屬性中的URL Schemes為你的APPID。如圖標紅位置所示:


無效4444.jpeg

2.添加微信白名單
info.plist –> 右擊 –> open as –> source Code –> 添加白名單:

<key>LSApplicationQueriesSchemes</key>
  <array>
    <string>weixin</string>
  </array>

3.導入必要的庫文件,如下圖所示:

2017-12-11-14-30-54.jpg

4.在項目目錄下創建Group Wxpay,并創建WxpayModule模塊
5.下載開發工具包(SDK),導入Wxpay中,最終如下圖所示:
wx2.jpg

6.編寫WxpayModule.h代碼如下

#import <React/RCTBridgeModule.h>
#import <React/RCTLog.h>
#import "WXApiObject.h"
#import "WXApi.h"

@interface WxpayModule : NSObject <RCTBridgeModule, WXApiDelegate>
@end

7.編寫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;
  //調起微信支付
  //注意order取的值對應的key要和自己服務器提供的一致
  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

8.處理微信支付回調,在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];
 }
}

9.至此,iOS端微信支付SDK集成成功

react-native

1.編寫Wxpay.js工具類

import { NativeModules } from 'react-native';
export default NativeModules.Wxpay;

2.在入口文件(如index.js)中向微信注冊應用

import Wxpay from './your/path/to/Wxpay';
Wxpay.registerApp(APPID); //向微信注冊

3.調用Wxpay模塊發起微信支付:

async wxPayAction(wxDic){
        //wxDic為從服務器獲取的支付信息
        Wxpay.isSupported().then((isSupported)=>{
            if (isSupported) {
                Wxpay.pay(wxDic).then((data) =>{
                    console.log('data='+JSON.stringify(data));
                    //data = {"errCode":0}//支付成功
                    //data={"errCode":-2} //取消支付
                    if (data.errCode == 0){
                       //支付成功
                        });
                    } else {
                       //支付失敗
                    }
                });
            }else {
                //未安裝微信或當前微信版本較低
            }
        }).catch((err) => {
            console.log('err='+err);
            this.refs.toast.show('支付失敗');
        });
    }
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容