如果是公司的产品,那么也就不存在问题了,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
版权声明:本文为博主原创文章,未经博主允许不得转载。