网上关于RN的支付宝支付组件大部分都是IOS的,Android要实现支付宝支付只剩下走原生这一步了。

整体思路:

1、在蚂蚁金服开放平台申请应用

2、在android原生集成支付宝

3、封装android原生

4、RN与android的通信

一、准备工作

1、在蚂蚁金服开放平台https://docs.open.alipay.com/204/105051/ 按照官方提示创建应用,添加app支付的功能。

2、在审核通过后可以拿到调用支付所需要的参数。

3、下载官方的Demo和SDKhttps://docs.open.alipay.com/54/104509



解压项目,用Android Studio打开alipay_demo项目,核心代码都在这个文件夹中。

二、项目操作

1、初始化zfbDemo的RN项目。并用Android Studio打开android部分。

2、在zfbDemo/android/app/目录下新建libs文件夹,将官网下载的alipay_demo中的libs下的sdk复制到新建的libs文件夹下。并右键 Add as  Library添加到项目中。


3、在AndroidManifest.xml文件中加入注册声明:

                                        

和权限声明:

                

4、我们直接实现点击RN中的按钮调出支付宝支付页面。

创建一个类继承ReactContextBaseJavaModule,这个类放入被RN调用的方法封装成有个原生模块

新建一个MyNativeModule的类,内容:

package com.zfbdemo;import android.content.Context;import android.content.Intent;import com.facebook.react.bridge.ReactApplicationContext;import com.facebook.react.bridge.ReactContextBaseJavaModule;import com.facebook.react.bridge.ReactMethod;/** * Created by admin on 2017/11/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(){    }}

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

新建一个MyReactPackge的类,内容:

package com.zfbdemo;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.ArrayList;import java.util.Collections;import java.util.List;/** * Created by admin on 2017/11/3. */public class MyReactPackge implements ReactPackage {    @Override    public List createNativeModules(ReactApplicationContext reactContext) {        List modules = new ArrayList<>();        modules.add(new MyNativeModule(reactContext));        return modules;    }    @Override    public List> createJSModules() {        return Collections.emptyList();    }    @Override    public List createViewManagers(ReactApplicationContext reactContext) {        return Collections.emptyList();    }}

在MainApplication中加入new MyReactPackge()

@Override    protected List getPackages() {      return Arrays.asList(          new MainReactPackage(),              new MyReactPackge()//添加这一句      );    }

到现在,RN调用的原生Android方法就封装好了,下一步就需要在方法里面调用支付了,不再一一叙述,直接贴代码:

tip:这一块只是为了实现支付功能的演示,真正的项目是需要后台加密返回orderInfo的。

先引入一些文件:


将官方demo中的这些文件复制过来,然后逐个打开,有包名之类的错误的改正。

将MyNativeModule.Java文件改为以下内容:

package com.zfbdemo;import android.annotation.SuppressLint;import android.app.AlertDialog;import android.content.Context;import android.content.DialogInterface;import android.content.Intent;import android.os.Handler;import android.os.Looper;import android.os.Message;import android.text.TextUtils;import android.util.Log;import android.view.View;import android.widget.Toast;import com.alipay.sdk.app.PayTask;import com.facebook.react.bridge.ReactApplicationContext;import com.facebook.react.bridge.ReactContextBaseJavaModule;import com.facebook.react.bridge.ReactMethod;import com.zfbdemo.util.OrderInfoUtil2_0;import java.util.Map;/** * Created by admin on 2017/11/3. */public class MyNativeModule  extends ReactContextBaseJavaModule {    /** 支付宝支付业务:入参app_id */    public static final String APPID = "申请的appid";    /** 支付宝账户登录授权业务:入参pid值 */    public static final String PID = "申请的pid";    /** 支付宝账户登录授权业务:入参target_id值 */    public static final String TARGET_ID = "";    /** 商户私钥,pkcs8格式 */    /** 如下私钥,RSA2_PRIVATE 或者 RSA_PRIVATE 只需要填入一个 */    /** 如果商户两个都设置了,优先使用 RSA2_PRIVATE */    /** RSA2_PRIVATE 可以保证商户交易在更加安全的环境下进行,建议使用 RSA2_PRIVATE */    /** 获取 RSA2_PRIVATE,建议使用支付宝提供的公私钥生成工具生成, */    /** 工具地址:https://doc.open.alipay.com/docs/doc.htm?treeId=291&articleId=106097&docType=1 */    public static final String RSA2_PRIVATE = "申请应用中的私钥";    public static final String RSA_PRIVATE = "";    private static final int SDK_PAY_FLAG = 1;    private static final int SDK_AUTH_FLAG = 2;    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(){        payV2();    }    @SuppressLint("HandlerLeak")    private Handler mHandler = new Handler(Looper.getMainLooper()) {        @SuppressWarnings("unused")        public void handleMessage(Message msg) {            switch (msg.what) {                case SDK_PAY_FLAG: {                    @SuppressWarnings("unchecked")                    PayResult payResult = new PayResult((Map) msg.obj);                    /**                     对于支付结果,请商户依赖服务端的异步通知结果。同步通知结果,仅作为支付结束的通知。                     */                    String resultInfo = payResult.getResult();// 同步返回需要验证的信息                    String resultStatus = payResult.getResultStatus();                    // 判断resultStatus 为9000则代表支付成功                    if (TextUtils.equals(resultStatus, "9000")) {                        // 该笔订单是否真实支付成功,需要依赖服务端的异步通知。                        Toast.makeText(mContext, "支付成功", Toast.LENGTH_SHORT).show();                    } else {                        // 该笔订单真实的支付结果,需要依赖服务端的异步通知。                        Toast.makeText(mContext, "支付失败", Toast.LENGTH_SHORT).show();                    }                    break;                }                case SDK_AUTH_FLAG: {                    @SuppressWarnings("unchecked")                    AuthResult authResult = new AuthResult((Map) 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(mContext,                                "授权成功\n" + String.format("authCode:%s", authResult.getAuthCode()), Toast.LENGTH_SHORT)                                .show();                    } else {                        // 其他状态值则为授权失败                        Toast.makeText(mContext,                                "授权失败" + String.format("authCode:%s", authResult.getAuthCode()), Toast.LENGTH_SHORT).show();                    }                    break;                }                default:                    break;            }        };    };    public void payV2() {        /**         * 这里只是为了方便直接向商户展示支付宝的整个支付流程;所以Demo中加签过程直接放在客户端完成;         * 真实App里,privateKey等数据严禁放在客户端,加签过程务必要放在服务端完成;         * 防止商户私密数据泄露,造成不必要的资金损失,及面临各种安全风险;         *         * orderInfo的获取必须来自服务端;         */        boolean rsa2 = (RSA2_PRIVATE.length() > 0);        Map params = OrderInfoUtil2_0.buildOrderParamMap(APPID, rsa2);        String orderParam = OrderInfoUtil2_0.buildOrderParam(params);        String privateKey = rsa2 ? RSA2_PRIVATE : RSA_PRIVATE;        String sign = OrderInfoUtil2_0.getSign(params, privateKey, rsa2);        final String orderInfo = orderParam + "&" + sign;        Runnable payRunnable = new Runnable() {            @Override            public void run() {                PayTask alipay = new PayTask(getCurrentActivity());                Map 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();    }}

在JS中:

import {    AppRegistry,    StyleSheet,    Text,    View,    NativeModules,    TouchableOpacity} from 'react-native';

{            NativeModules.MyNativeModule.rnCallNative()        }}>          调用支付        

此时点击RN中的按钮会直接调出支付宝支付。

再次提醒orderInfo必须从后台获得(防止信息泄密)


当手机安装了支付宝会调用支付宝支付,如果没有支付宝会登录网页版的支付宝。

需要注意一点,当应用设置了状态栏沉浸模式,网页版的支付宝的activity会被提上来影响美观,需要在AndroidManifest.xml中加一句:

android:theme="@android:style/Theme"
















更多相关文章

  1. 应用phprpc协议实现Android客户端的一些总结
  2. 使用React Native开发Android手持机
  3. android应用程序基本原理
  4. Android调用系统自带的文件管理器进行文件选择并获得路径,android
  5. 编写android对google地图的调用
  6. 精通android体系架构、mvc、常见的设计模式、控制反转(ioc)
  7. Android(安卓)技术-- 图形系统详解
  8. Android数据库ORMlite框架翻译系列(第一章)
  9. QCom Camera Development

随机推荐

  1. 我的Android学习笔记1(Android开发环境配
  2. Android(安卓)NDK常见错误解决方案
  3. android开发环境配置
  4. Android(安卓)Bitmap详细介绍
  5. android 4中新增的日历处理相关API
  6. Android(安卓)build system note
  7. 2012 年最佳 Android(安卓)应用
  8. Android无法真正睡眠:服务广播插件等仍激
  9. Android(安卓)安全 —— 本地拒绝服务漏
  10. Android动画之ViewAnimation和DrawableAn