上节我们实现了简单的插件编写。那么这一节,我们开始真正的实现支付宝插件的编写。
一、下载支付宝接口文档及DEMO
具体怎么下载,请自行度娘解决。下载完毕如下所以。
二、解压后如下:
请自行根据openssl中“生成命令.txt”的指导,生成商户公钥,私钥及转换pkcs8格式
若根据指导无法完成,请自行度娘,有超详细的介绍。
生成完毕,上传用户公钥到支付宝用户私钥管理。如下图:
点击查看PID|Key,查看自己的商户ID,以及上传商户公钥。
好了,到此支付宝的服务器配置方面已经完毕!
下面开始代码的编写。
一、复制DEMO中的类库文件到我们的项目中。即复制到我们的插件包中(com.demo.plugs)
项目结构如下:
新建PlugAlipay.java文件,并打开DEMO中PayDemoActivity.java文件,复制代码到我们的文件中
// 商户PID
public static final String PARTNER = "";
// 商户收款账号
public static final String SELLER = "";
// 商户私钥,pkcs8格式
public static final String RSA_PRIVATE = "";
我们只需要这几个参数,其他的不考虑。不影响集成。
public boolean execute(String action , JSONArray args, CallbackContext callbackContext ){
PARTNER = "2088xxxxxxxxxx";
SELLER = "你的支付宝收款账户 xxx@xxx.com";
这个地方的私钥是pkcs8格式的。
RSA_PRIVATE = "MIICdgIBADANBgkqhkiG9xxxxxxxxxxx.....";
try {
//从传递的参数中获取以下参数
//subject:商品名称
//body:商品详情
//price:付款金额
//fromUrlScheme:支付完毕后,跳转到用户应用的页面地址。
//notifyUrl:服务器异步通知接收文件
//整理参数
JSONObject arguments = args.getJSONObject(0);
//System.out.println("参数传递:"+arguments.toString());
String subject = arguments.getString("subject");
String body = arguments.getString("body");
String price = arguments.getString("price");
String fromUrlScheme = arguments.getString("fromUrlScheme");
String notifyUrl = arguments.getString("notifyUrl");
//执行方法
this.pay( subject, body, price, fromUrlScheme, notifyUrl);
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(
this.cordova.getActivity().getApplicationContext(),
"参数传递错误",
Toast.LENGTH_LONG
).show();
return false;
}
return true;
}
添加pay方法,这里基本是从demo中copy过来的,可根据自己的需求变更。
public void pay(String subject, String body, String price, final String fromUrlScheme, String notifyUrl) {
// 订单
String orderInfo = getOrderInfo(subject, body, price, notifyUrl);
System.out.println("封装订单信息:"+orderInfo);
// 对订单做RSA 签名
String sign = sign(orderInfo);
System.out.println("封装签名信息:"+sign);
try {
// 仅需对sign 做URL编码
sign = URLEncoder.encode(sign, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
// 完整的符合支付宝参数规范的订单信息
final String payInfo = orderInfo + "&sign=\"" + sign + "\"&"
+ getSignType();
System.out.println("封装完整订单信息:"+payInfo);
cordova.getThreadPool().execute(new Runnable() {
@Override
public void run() {
// 构造PayTask 对象
PayTask alipay = new PayTask(cordova.getActivity());
// 调用支付接口,获取支付结果
String result = alipay.pay(payInfo);
System.out.println("支付结果:"+result);
//对支付宝返回的消息进行处理
PayResult payResult = new PayResult(result);
// 支付宝返回此次支付结果及加签,建议对支付宝签名信息拿签约时支付宝提供的公钥做验签
String resultInfo = payResult.getResult();
String resultStatus = payResult.getResultStatus();
// 判断resultStatus 为“9000”则代表支付成功,具体状态码代表含义可参考接口文档
if (TextUtils.equals(resultStatus, "9000")) {
toastMsg("支付成功");//这个方式是自定义的toast方法
} else {
// 判断resultStatus 为非“9000”则代表可能支付失败
// “8000”代表支付结果因为支付渠道原因或者系统原因还在等待支付结果确认,最终交易是否成功以服务端异步通知为准(小概率状态)
if (TextUtils.equals(resultStatus, "8000")) {
toastMsg("支付结果确认中");
} else {
// 其他值就可以判断为支付失败,包括用户主动取消支付,或者系统返回的错误
toastMsg("支付失败");
}
}
//不管执行是否成功,显示Toast信息后,返回商户界面
Intent backUrl = new Intent(Intent.ACTION_VIEW,
Uri.parse(fromUrlScheme + result));
cordova.getActivity().startActivity(backUrl);
}
});
}
自定义Toast方法
/**
* 自定义显示Toast消息方法。
* @param toamsg
*/
private void toastMsg(String toamsg) {
Toast.makeText(this.cordova.getActivity().getApplicationContext(), toamsg, Toast.LENGTH_LONG).show();
}
这里基本的编写就完毕了。
现在来js文件中调用测试。
function a1(){
var sstr = {
subject:1,
body:"缴费第三",
price:"0.01",
fromUrlScheme:"file:///android_assets/www/index.html",//这里是支付完成后,返回到用户app
notifyUrl:"http://www.xxx.com:9121/" //这里的地址支持花生壳解析的,随便什么地址都可以,只要通过外网可以访问到就行。
};
cordova.exec(null,null,"PlugAlipay",null,[sstr]);
}
因为这里我们是新建了一个java文件来执行支付宝的操作,所以,在res\xml\config.xml中要更改配置,不然会访问不到。
<feature name="PlugAlipay">
<param name="android-package" value="com.demo.plugs.PlugAlipay" />
</feature>
这里就可以了。。
我在做这个的时候,出现了一个问题,就是提示 系统繁忙 请稍后再试(ALI64) ,网上找了好多,都是说私钥,公钥,什么的,上传不对应之类的。
其实是我在传递json参数的时候,fromUrlScheme 和 notifyUrl 的值传递的是空值所造成的。
这2个值不允许为空。否则就是那个错误,一直提示!
到这里,基本就结束了插件的代码编写,,下一节,我们把做好的插件进行优化并遵从开源精神发布一下!