React-Native之android集成支付宝

支付宝流程效果图

充值
android原生确认支付界面
付款详情

正在付款

整体思路:
1.在蚂蚁金服开放平台申请应用
2.在android原生集成支付宝
3.封装android原生
4.RN与android的通信
一.在蚂蚁金服开放平台申请应用
蚂蚁金服开放平台链接:https://openhome.alipay.com/platform/manageHome.htm
1.在注册登录成功之后选择应用

选择应用

2.选择创建应用,按照文档流程申请应用

申请应用

二、在android原生集成支付宝
1.在app目录下面新建一个libs的目录
2.把支付宝的SDK复制粘贴到libs目录下

粘贴SDK.png

3.选择SDK右键选择add as library
4.修改Manifest,在工程的AndroidManifest.xml文件里面添加声明:

<activity
            android:name="com.alipay.sdk.app.H5PayActivity"
            android:configChanges="orientation|keyboardHidden|navigation"
            android:exported="false"
            android:screenOrientation="behind" >
</activity>
<activity
            android:name="com.alipay.sdk.auth.AuthActivity"
            android:configChanges="orientation|keyboardHidden|navigation"
            android:exported="false"
            android:screenOrientation="behind" >
 </activity>

如果此时com.alipay.sdk.auth.AuthActivity报红说明未找到这个包。解决方法:
往build.gradle(有app的)中添加下面篮框的内容

00682750-1D48-4548-B851-7047C71D14D8.png

和权限声明:

<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" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

三.封装android原生
1.新建一个支付的acitivity,

新建一个新的acitivity.png
输入activity的name.png

2.进入activity_pay.xml文件点击text

activity_pay.xml文件.png

3.把activity_pay.xml的源码删除,改成我现在的布局:

activity_pay.xml的源码.png

4.PayActivity文件 添加取消按键onBack点击方法,

 public void onBack(View v){
        finish();
    }

5.根据蚂蚁金服开放平台提供的alipay_demo中的PayDemoActivity.java中添加支付接口,这里我的加签过程是在服务端配置返回的key,EnvUtils.setEnv(EnvUtils.EnvEnum.SANDBOX)(生产环境不需要调用)中如果EnvUtils报红,选中alt+enter就能引入头文件

public void payV2(View v) {
        Bundle bundle = getIntent().getExtras();
        String key = bundle.getString("key");
        final String orderInfo = key;
//支付宝沙箱android测试需要调用
        EnvUtils.setEnv(EnvUtils.EnvEnum.SANDBOX);
        Runnable payRunnable = new Runnable() {
            @Override
            public void run() {
                PayTask alipay = new PayTask(PayActivity.this);
                Map<String, String> result = alipay.payV2(orderInfo, true);
                Log.i("msp", result.toString());

                Message msg = new Message();
                msg.what = SDK_PAY_FLAG;
                msg.obj = result;
                mHandler.sendMessage(msg);
            }
        };
        Thread payThread = new Thread(payRunnable);
        payThread.start();
    }

6.此时会报SDK_PAY_FLAG,所以我们要添加进去

private static final int SDK_PAY_FLAG = 1;
    private static final int SDK_AUTH_FLAG = 2;

支付回调mHandler方法

 @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler() {
        @SuppressWarnings("unused")
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case SDK_PAY_FLAG: {
                    @SuppressWarnings("unchecked")
                    PayResult payResult = new PayResult((Map<String, String>) msg.obj);
                    String resultInfo = payResult.getResult();
                    String resultStatus = payResult.getResultStatus();
                    Toast.makeText(PayActivity.this, resultStatus, Toast.LENGTH_SHORT).show();
                    // 判断resultStatus 为9000则代表支付成功
                    if (TextUtils.equals(resultStatus, "9000")) {
                        // 该笔订单是否真实支付成功,需要依赖服务端的异步通知。
                        Toast.makeText(PayActivity.this, "支付成功", Toast.LENGTH_SHORT).show();
                    } else {
                        // 该笔订单真实的支付结果,需要依赖服务端的异步通知。
                         Toast.makeText(PayActivity.this, "支付失败", Toast.LENGTH_SHORT).show();
                    }
                    break;
                }
                case SDK_AUTH_FLAG: {
                    @SuppressWarnings("unchecked")
                    AuthResult authResult = new AuthResult((Map<String, String>) msg.obj, true);
                    String resultStatus = authResult.getResultStatus();

                    // 判断resultStatus 为“9000”且result_code
                    // 为“200”则代表授权成功,具体状态码代表含义可参考授权接口文档
                    if (TextUtils.equals(resultStatus, "9000") && TextUtils.equals(authResult.getResultCode(), "200")) {
                        // 获取alipay_open_id,调支付时作为参数extern_token 的value
                        // 传入,则支付账户为该授权账户
                        Toast.makeText(PayActivity.this,
                                "授权成功\n" + String.format("authCode:%s", authResult.getAuthCode()), Toast.LENGTH_SHORT)
                                .show();
                    } else {
                        // 其他状态值则为授权失败
                        Toast.makeText(PayActivity.this,
                                "授权失败" + String.format("authCode:%s", authResult.getAuthCode()), Toast.LENGTH_SHORT).show();

                    }
                    break;
                }
                default:
                    break;
            }
        };
    };

此时报红的PayResult,AuthResult,需要去到支付宝的alipay_demo中往工程中加入这两个文件,方法是复制这两个文件到工程的相应目录下粘贴
7.获取SDK版本号

public void getSDKVersion() {
        PayTask payTask = new PayTask(this);
        String version = payTask.getVersion();
        Toast.makeText(this, version, Toast.LENGTH_SHORT).show();
    }

PayActivity.java文件源码完成
此时支付宝的原生集成已经完成 所有调用全在PayActivity.java中
四.RN与android的通信
1.创建一个类继承ReactContextBaseJavaModule,这个类放入被RN调用的方法封装成有个原生模块

package com.cloudprocessing;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

/**
 * Created by  on 2017/3/3.
 */

public class MyNativeModule  extends ReactContextBaseJavaModule{
    private Context mContext;
    //构造方法
    public MyNativeModule(ReactApplicationContext reactContext) {
        super(reactContext);
        mContext = reactContext;
    }
    @Override
    public String getName() {
        //MyNativeModule 需要此名字来调用该类方法
        return "MyNativeModule";
    }
    //函数不能有返回值,被调用的原生代码是异步的,原生代码执行结束之后只能通过回调函数发送消息给RN

    //rnCallNative为RN需要调用的方法
    @ReactMethod
    public void rnCallNative(String msg){
        //添加意图
        Intent intent = new Intent(mContext,PayActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        //bundle为需要传给PayActivity的加密签名
        Bundle bundle = new Bundle();
        bundle.putString("key",msg);
        intent.putExtras(bundle);
        //startActivity
        mContext.startActivity(intent,bundle);
    }

}

2.创建一个类实现接口ReactPackage包管理器,把上面一步创建的类添加到原生模块(nativeModule)列表里

package com.cloudprocessing;

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

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

/**
 * Created by  on 2017/3/3.
 */

public class MyReactPackge implements ReactPackage{
    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();
        modules.add(new MyNativeModule(reactContext));
        return modules;
    }

    @Override
    public List<Class<? extends JavaScriptModule>> createJSModules() {
        return Collections.emptyList();
    }

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

3.将第二步中创建的包管理器添加到ReactPackage列表里的getPackges方法 MainApplication中加入new MyReactPackge()

package com.cloudprocessing;

import android.app.Application;
import android.util.Log;

import com.facebook.react.ReactApplication;
import com.lwansbrough.RCTCamera.RCTCameraPackage;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;

import java.util.Arrays;
import java.util.List;

public class MainApplication extends Application implements ReactApplication {

  private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
    @Override
    protected boolean getUseDeveloperSupport() {
      return BuildConfig.DEBUG;
    }

    @Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
          new MainReactPackage(),
            new RCTCameraPackage(),
              new MyReactPackge()
      );
    }
  };

  @Override
  public ReactNativeHost getReactNativeHost() {
    return mReactNativeHost;
  }

  @Override
  public void onCreate() {
    super.onCreate();
    SoLoader.init(this, /* native exopackage */ false);
  }
}

五.js调用封装的android原生组件
1.引入NativeModules

import { NativeModules} from 'react-native';

2.定义一个view,当点击的时候触发原生事件

<TouchableHighlight style={{width:width-80,height:40,alignItems:'center',marginTop:50}} underlayColor='#28780b'
                                                        onPress={()=>this.nativeAndroid()}>
                    <View style={{width:width-80,height:40,alignItems:'center',justifyContent:'center',
                        backgroundColor:'#35a40c',borderRadius:5}}>
                        <Text style={{color:'white',fontSize:17}}>确定</Text>
                    </View>
                    </TouchableHighlight>

3.点击的nativeAndroid方法,MyNativeModule是安卓原生MyNativeModule文件中的getName返回的名字,rnCallNative是rnCallNative为RN需要调用的方法,下面的触发方法中的this.state.signedString是服务器对支付宝加签返回的签名,也就是客户端调支付宝时用到的orderInfo

nativeAndroid(){
        var sign = this.state.signedString
        if(sign){
            NativeModules.MyNativeModule.rnCallNative(sign)
        }
    }

到这里RN调用安卓原生支付宝的步骤已全部完成

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,165评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,720评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,849评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,245评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,596评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,747评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,977评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,708评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,448评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,657评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,141评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,493评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,153评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,890评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,799评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,685评论 2 272

推荐阅读更多精彩内容