Android 个人开发者接入支付功能
标签:android bmob 支付宝支付 微信支付 个人开发者
如果是公司的产品,那么也就不存在问题了,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字符串,详细内容如下
效果图
后台订单查询
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:android bmob 支付宝支付 微信支付 个人开发者
原文:http://blog.csdn.net/sbsujjbcy/article/details/48781749