如果是公司的产品,那么也就不存在问题了,Ping++对所有支付做了一个集成。如果开发者个人想接入支付系统,这个申请过程几乎是不大可能的。而Bmob为广大开发人员提供的统一、正规的收费手段,让没有企业认证的个人开发者,也能通过支付宝和微信向用户收费。但是有一个缺点,支持的渠道少,只支持支付宝和微信。此外,微信支付还要安装一个插件,用户体验及其不好。

官方的文档在这里Android支付SDK

接入Bomb也很简单,首先下载BmobPay_Sdk_V1.0.2a.zip

将Lib中的四个jar文件拷到项目中的libs目录下,将plugin目录中的assets拷到项目的main目录下。如图

声明权限

    <!-- alipay sdk permission begin -->    <uses-permission android:name="android.permission.INTERNET" />    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />    <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" />    <!-- alipay sdk permission end -->

由于微信支付需要安装它的插件,所以如果在root的设备上我们希望能够静默安装,否则使用正常的安装方式,静默安装需要一个权限。

    <uses-permission android:name="android.permission.INSTALL_PACKAGES" />

在AndroidManifest.xml的Application标签下添加以下内容,声明组件

 <!-- bmob pay sdk activity begin ,please put below code into application tag -->        <activity  android:name="com.alipay.sdk.app.H5PayActivity" android:configChanges="orientation|keyboardHidden|navigation" android:exported="false" android:screenOrientation="behind" android:windowSoftInputMode="adjustResize|stateHidden" >        </activity>        <activity  android:name="com.bmob.pay.tool.PayActivity" android:screenOrientation="portrait" android:theme="@android:style/Theme.Translucent" />        <!-- bmob pay sdk activity end -->

在您的应用程序主Activity的onCreate中调用如下方法:(Application ID在后台应用管理的 数据浏览->应用信息->应用密钥->Application ID)

private BmobPay bmobPay = null;BmobPay.init(context,"你的Application ID");bmobPay = new BmobPay(MainActivity.this);

调用支付宝支付

bmobPay.pay(0.01, "某商品","这里是商品描述", new PayListener() {    @Override    public void orderId(String s) {        orderId = s;        Toast.makeText(MainActivity.this, "订单号:" + s, Toast.LENGTH_SHORT).show();    }    @Override    public void succeed() {        Toast.makeText(MainActivity.this, "支付成功", Toast.LENGTH_SHORT).show();    }    @Override    public void fail(int i, String s) {        Toast.makeText(MainActivity.this, "支付失败:" + s, Toast.LENGTH_SHORT).show();    }    @Override    public void unknow() {        Toast.makeText(MainActivity.this, "未知", Toast.LENGTH_SHORT).show();    }});

调用微信支付,微信支付需要安装插件,我们首先尝试进行静默安装,如果返回异常,则进行正常安装。我们需要编写一个工具类

public class PackageUtils {    public static String moveFileFromAssetsToSdcard(Context context, String fileName) {        return moveFileFromAssetsToSdcard(context,fileName,fileName);    }    public static String moveFileFromAssetsToSdcard(Context context, String fileName, String tempName) {        InputStream is = null;        FileOutputStream fos = null;        try {            is = context.getAssets().open(fileName);            File file = new File(Environment.getExternalStorageDirectory()                    .getPath() + "/" + tempName);            file.createNewFile();            fos = new FileOutputStream(file);            byte[] temp = new byte[1024];            int i = 0;            while ((i = is.read(temp)) > 0) {                fos.write(temp, 0, i);            }            return file.getAbsolutePath();        } catch (IOException e) {            e.printStackTrace();        } finally {            if (is != null) {                try {                    is.close();                } catch (IOException e) {                    e.printStackTrace();                }            }            if (fos != null) {                try {                    fos.close();                } catch (IOException e) {                    e.printStackTrace();                }            }        }        return null;    }    /** * install slient * * @param context * @param filePath * @return 0 means normal, 1 means file not exist, 2 means other exception error */    public static int installSlient(Context context, String filePath) {        File file = new File(filePath);        if (filePath == null || filePath.length() == 0 || (file = new File(filePath)) == null || file.length() <= 0                || !file.exists() || !file.isFile()) {            return 1;        }        String[] args = {"pm", "install", "-r", filePath};        ProcessBuilder processBuilder = new ProcessBuilder(args);        Process process = null;        BufferedReader successResult = null;        BufferedReader errorResult = null;        StringBuilder successMsg = new StringBuilder();        StringBuilder errorMsg = new StringBuilder();        int result;        try {            process = processBuilder.start();            successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));            errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));            String s;            while ((s = successResult.readLine()) != null) {                successMsg.append(s);            }            while ((s = errorResult.readLine()) != null) {                errorMsg.append(s);            }        } catch (IOException e) {            e.printStackTrace();            result = 2;        } catch (Exception e) {            e.printStackTrace();            result = 2;        } finally {            try {                if (successResult != null) {                    successResult.close();                }                if (errorResult != null) {                    errorResult.close();                }            } catch (IOException e) {                e.printStackTrace();            }            if (process != null) {                process.destroy();            }        }        if (successMsg.toString().contains("Success") || successMsg.toString().contains("success")) {            result = 0;        } else {            result = 2;        }        Log.e("installSlient", "successMsg:" + successMsg + ", ErrorMsg:" + errorMsg);        return result;    }    public static void installNormal(Context context, String fileName) {        File file = new File(fileName);        Intent intent = new Intent(Intent.ACTION_VIEW);        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);        intent.setDataAndType(Uri.parse("file://" + file),                "application/vnd.android.package-archive");        context.startActivity(intent);    }

需要将assets目录下的插件拷到文件系统中,然后调用静默安装方法,如果返回0,则安装成功,否则调用正常安装方法。我们可以在微信支付的回调函数中判断是否安装过插件。

bmobPay.payByWX(0.01, "某商品","这里是商品描述", new PayListener() {    @Override    public void orderId(String s) {        orderId = s;        Toast.makeText(MainActivity.this, "订单号:" + s, Toast.LENGTH_SHORT).show();    }    @Override    public void succeed() {        Toast.makeText(MainActivity.this, "支付成功", Toast.LENGTH_SHORT).show();    }    @Override    public void fail(int i, String s) {        if (i == -3) {            Toast.makeText(MainActivity.this, "未安装支付插件,正在准备安装" + s, Toast.LENGTH_SHORT).show();            String tempFile = PackageUtils.moveFileFromAssetsToSdcard(MainActivity.this, "BmobPayPlugin.apk");            Log.e("TAG", "installFile:" + tempFile);            int installResult = PackageUtils.installSlient(MainActivity.this,tempFile);            Log.e("TAG", "installResult:" + installResult);            if(installResult!=0){                PackageUtils.installNormal(MainActivity.this,tempFile);            }            Toast.makeText(MainActivity.this, "插件安装成功!" + s, Toast.LENGTH_SHORT).show();            return ;        }        Toast.makeText(MainActivity.this, "支付失败:" + s, Toast.LENGTH_SHORT).show();    }    @Override    public void unknow() {        Toast.makeText(MainActivity.this, "未知", Toast.LENGTH_SHORT).show();    }});

支付过程中会生成一个订单,该订单开发者需要自己进行存储,可以用该订单号进行查询支付状态

bmobPay.query(orderId, new OrderQueryListener() {    @Override    public void succeed(String s) {        Toast.makeText(MainActivity.this, "查询结果:" + s, Toast.LENGTH_SHORT).show();    }    @Override    public void fail(int i, String s) {        Toast.makeText(MainActivity.this, "查询失败:" + s, Toast.LENGTH_SHORT).show();    }});

succeed回调说明查询成功(并不是说支付成功),返回的status有NOTPAY和SUCCESS两种可能,只有返回SUCCESS才说明支付成功。

支付过程中可能会返回错误码,常见的错误码如下

还有一点需要注意的就是

当上一次支付操作尚未完成时,如果BmobPay对象发起再次请求,PayListener会回调fail方法返回并10077错误码,以免生成多个订单
如果使用过程中出现了阻塞(比如异常强制关闭支付插件页面,会导致一直不能再发起请求,这是小概率事件),则调用此方法进行BmobPay的重置
仅对下一次请求生效,而不是永久消除限制。

如果你想查询订单的详细信息,可以使用GET请求,使用Bomb的Restful API发起查询,返回结果是一个json字符串,详细内容如下

效果图

后台订单查询

源码下载
http://download.csdn.net/download/sbsujjbcy/9143253

更多相关文章

  1. 阿里ctf-2014 android 第三题——andriod模拟器安装
  2. Android(安卓)7.0解析包时出现问题 的解决方案(应用内更新)
  3. Android(安卓)RePlugin 使用及源码分析(1)
  4. Eclipse下修改Android里的apk包名
  5. Android(安卓)插件化框架DroidPlugin
  6. Android插件化开发之OpenAtlas插件的安装与卸载、更新与回滚
  7. HP TouchPad 灵魂不死,Android(安卓)附身且带 APK 应用安装
  8. 视频直播软件开发:Android客户端接入谷歌支付的实现流程
  9. 电脑怎么安装安卓系统?安卓(Android)x86 4.4安装方法图文步骤

随机推荐

  1. 分享golang实现文件传输小demo
  2. go语言中run与build命令的区别是什么?
  3. 解决GO语言安装air框架时遇到go: inconsi
  4. 分享5种文件变更时自动重载Go程序的方法
  5. go语言中普通函数与方法的区别是什么?
  6. golang中方法的receiver为指针和不为指针
  7. 分享一次腾讯Go开发岗位面试经过
  8. go是什么语言
  9. 详解Golang如何对excel进行处理
  10. 关于go值传递和地址传递的例子