个人开发者使用支付

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

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

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

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

Android 个人开发者接入支付功能

声明权限<"http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwcmUgY2xhc3M9"brush:java;">

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

1 

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

1<span style="font-size: medium;"><code class="hljs"> <!-- bmob pay sdk activity begin ,please put below code into application tag -->
2 
3        <!-- bmob pay sdk activity end --></code></span>

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

1<span style="font-size: medium;"><code class="hljs">private BmobPay bmobPay = null;
2BmobPay.init(context,你的Application ID);
3bmobPay = new BmobPay(MainActivity.this);</code></span>

调用支付宝支付

1<span style="font-size: medium;"><code class="hljs">bmobPay.pay(0.01, 某商品,这里是商品描述, new PayListener() {
2    @Override
3    public void orderId(String s) {
4        orderId = s;
5        Toast.makeText(MainActivity.this, 订单号: + s, Toast.LENGTH_SHORT).show();
6    }
7 
8    @Override
9    public void succeed() {
10        Toast.makeText(MainActivity.this, 支付成功, Toast.LENGTH_SHORT).show();
11    }
12 
13    @Override
14    public void fail(int i, String s) {
15        Toast.makeText(MainActivity.this, 支付失败: + s, Toast.LENGTH_SHORT).show();
16    }
17 
18    @Override
19    public void unknow() {
20        Toast.makeText(MainActivity.this, 未知, Toast.LENGTH_SHORT).show();
21    }
22});</code></span>

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

1<span style="font-size: medium;"><code class="hljs">public class PackageUtils {
2 
3    public static String moveFileFromAssetsToSdcard(Context context, String fileName) {
4        return moveFileFromAssetsToSdcard(context,fileName,fileName);
5    }
6    public static String moveFileFromAssetsToSdcard(Context context, String fileName, String tempName) {
7        InputStream is = null;
8        FileOutputStream fos = null;
9        try {
10            is = context.getAssets().open(fileName);
11            File file = new File(Environment.getExternalStorageDirectory()
12                    .getPath() + / + tempName);
13            file.createNewFile();
14            fos = new FileOutputStream(file);
15            byte[] temp = new byte[1024];
16            int i = 0;
17            while ((i = is.read(temp)) > 0) {
18                fos.write(temp, 0, i);
19            }
20            return file.getAbsolutePath();
21        } catch (IOException e) {
22            e.printStackTrace();
23        } finally {
24            if (is != null) {
25                try {
26                    is.close();
27                } catch (IOException e) {
28                    e.printStackTrace();
29                }
30            }
31            if (fos != null) {
32                try {
33                    fos.close();
34                } catch (IOException e) {
35                    e.printStackTrace();
36                }
37            }
38        }
39        return null;
40    }
41    /**
42     * install slient
43     *
44     * @param context
45     * @param filePath
46     * @return 0 means normal, 1 means file not exist, 2 means other exception error
47     */
48    public static int installSlient(Context context, String filePath) {
49        File file = new File(filePath);
50        if (filePath == null || filePath.length() == 0 || (file = new File(filePath)) == null || file.length() <= 0
51                || !file.exists() || !file.isFile()) {
52            return 1;
53        }
54 
55        String[] args = {pm, install, -r, filePath};
56        ProcessBuilder processBuilder = new ProcessBuilder(args);
57 
58        Process process = null;
59        BufferedReader successResult = null;
60        BufferedReader errorResult = null;
61        StringBuilder successMsg = new StringBuilder();
62        StringBuilder errorMsg = new StringBuilder();
63        int result;
64        try {
65            process = processBuilder.start();
66            successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
67            errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
68            String s;
69            while ((s = successResult.readLine()) != null) {
70                successMsg.append(s);
71            }
72            while ((s = errorResult.readLine()) != null) {
73                errorMsg.append(s);
74            }
75        } catch (IOException e) {
76            e.printStackTrace();
77            result = 2;
78        } catch (Exception e) {
79            e.printStackTrace();
80            result = 2;
81        } finally {
82            try {
83                if (successResult != null) {
84                    successResult.close();
85                }
86                if (errorResult != null) {
87                    errorResult.close();
88                }
89            } catch (IOException e) {
90                e.printStackTrace();
91            }
92            if (process != null) {
93                process.destroy();
94            }
95        }
96        if (successMsg.toString().contains(Success) || successMsg.toString().contains(success)) {
97            result = 0;
98        } else {
99            result = 2;
100        }
101        Log.e(installSlient, successMsg: + successMsg + , ErrorMsg: + errorMsg);
102        return result;
103    }
104 
105    public static void installNormal(Context context, String fileName) {
106        File file = new File(fileName);
107        Intent intent = new Intent(Intent.ACTION_VIEW);
108        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
109        intent.setDataAndType(Uri.parse(file:// + file),
110                application/vnd.android.package-archive);
111        context.startActivity(intent);
112 
113    }</code></span>

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

1<span style="font-size: medium;"><code class="hljs">bmobPay.payByWX(0.01, 某商品,这里是商品描述, new PayListener() {
2    @Override
3    public void orderId(String s) {
4        orderId = s;
5        Toast.makeText(MainActivity.this, 订单号: + s, Toast.LENGTH_SHORT).show();
6    }
7 
8    @Override
9    public void succeed() {
10        Toast.makeText(MainActivity.this, 支付成功, Toast.LENGTH_SHORT).show();
11    }
12 
13    @Override
14    public void fail(int i, String s) {
15        if (i == -3) {
16            Toast.makeText(MainActivity.this, 未安装支付插件,正在准备安装 + s, Toast.LENGTH_SHORT).show();
17            String tempFile = PackageUtils.moveFileFromAssetsToSdcard(MainActivity.this, BmobPayPlugin.apk);
18            Log.e(TAG, installFile: + tempFile);
19            int installResult = PackageUtils.installSlient(MainActivity.this,tempFile);
20            Log.e(TAG, installResult: + installResult);
21            if(installResult!=0){
22                PackageUtils.installNormal(MainActivity.this,tempFile);
23            }
24            Toast.makeText(MainActivity.this, 插件安装成功! + s, Toast.LENGTH_SHORT).show();
25            return ;
26        }
27        Toast.makeText(MainActivity.this, 支付失败: + s, Toast.LENGTH_SHORT).show();
28    }
29 
30    @Override
31    public void unknow() {
32        Toast.makeText(MainActivity.this, 未知, Toast.LENGTH_SHORT).show();
33    }
34});</code></span>

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

1<span style="font-size: medium;"><code class="hljs">bmobPay.query(orderId, new OrderQueryListener() {
2    @Override
3    public void succeed(String s) {
4        Toast.makeText(MainActivity.this, 查询结果: + s, Toast.LENGTH_SHORT).show();
5    }
6 
7    @Override
8    public void fail(int i, String s) {
9        Toast.makeText(MainActivity.this, 查询失败: + s, Toast.LENGTH_SHORT).show();
10    }
11});</code></span>

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

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

Android 个人开发者接入支付功能

还有一点需要注意的就是

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

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

效果图

Android 个人开发者接入支付功能

Android 个人开发者接入支付功能

Android 个人开发者接入支付功能

后台订单查询

Android 个人开发者接入支付功能

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值