phonegap(cordova) 自己定义插件代码篇(三)----支付宝支付工具整合
建议读者,先阅读官方文档,知晓其支付流程之后再来使用此代码,比方客户须要做什么,服务端须要做什么(非常重要!非常重要!
非常重要!),由于这几个篇幅都是纯代码篇,由于阅读前面的入门篇之后看这些应该毫无问题才对,否则就是没入门。上代码
公用js
(function (cordova) {
var define = cordova.define; define("cordova/plugin/alipay", function (require, exports, module) {
var argscheck = require('cordova/argscheck'),
exec = require('cordova/exec');
exports.pay = function (orderInfo, successCB, failCB) {
argscheck.checkArgs('AFF', 'alipay.pay', arguments);
if (!orderInfo) {
failCB && failCB("请输入订单信息.");
} else {
exec(successCB, failCB, "Alipay", "pay", orderInfo);
}
}; });
cordova.addConstructor(function () {
if (!window.plugins) {
window.plugins = {};
}
//console.log("将插件注入cordovaAlipay...");
window.plugins.alipay = cordova.require("cordova/plugin/alipay");
//console.log("alipay注入结果:" + typeof (window.plugins.alipay));
});
})(cordova);
android版
public class AlipayPlugin extends CordovaPlugin {
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case Constants.Alipay.SDK_PAY_FLAG: {
PayResult payResult = new PayResult((String) msg.obj); // 支付宝返回此次支付结果及加签,建议对支付宝签名信息拿签约时支付宝提供的公钥做验签
String resultInfo = payResult.getResult(); String resultStatus = payResult.getResultStatus();
String out_trade_no = payResult.getOut_trade_no();
// 推断resultStatus 为“9000”则代表支付成功。详细状态码代表含义可參考接口文档
if (TextUtils.equals(resultStatus, "9000")) {
// 通知到页面 支付工具 0--微信 1--支付宝 2--银联
String jsCode = "pay.result('1','" + out_trade_no + "','true')";
yooshow.instance.ToJS(jsCode);
} else {
// 推断resultStatus 为非“9000”则代表可能支付失败
// “8000”代表支付结果由于支付渠道原因或者系统原因还在等待支付结果确认,终于交易是否成功以服务端异步通知为准(小概率状态)
if (TextUtils.equals(resultStatus, "8000")) {
// 通知到页面
String jsCode = "pay.result('1','" + out_trade_no
+ "','true')";
yooshow.instance.ToJS(jsCode);
} else {
// 其它值就能够推断为支付失败。包括用户主动取消支付。或者系统返回的错误
// 通知到页面
String jsCode = "pay.result('1','" + out_trade_no
+ "','false')";
yooshow.instance.ToJS(jsCode); }
}
break;
}
case Constants.Alipay.SDK_CHECK_FLAG: {
// Toast.makeText(currentActivity, "检查结果为:" + msg.obj,
// Toast.LENGTH_SHORT).show();
break;
}
default:
break;
}
};
}; @Override
public boolean execute(String action, JSONArray args,
CallbackContext callbackContext) throws JSONException {
final Activity currentActivity = this.cordova.getActivity();
// // 构造订单信息
// // 订单编号
// String orderNo = args.getString(0);
// // 商品名称
// String productName = args.getString(1);
// // 商品描写叙述
// String productDesc = args.getString(2);
// // 商品总价
// String productTotal_fee = args.getString(3);
//
// // 订单
// String orderInfo = getOrderInfo(orderNo, productName, productDesc,
// productTotal_fee);
//
// // 对订单做RSA 签名
// String sign = sign(orderInfo);
//
// try {
// // 仅需对sign 做URL编码
// sign = URLEncoder.encode(sign, "UTF-8");
// } catch (UnsupportedEncodingException e) {
// e.printStackTrace();
// }
//
// // 完整的符合支付宝參数规范的订单信息
// final String payInfo = orderInfo + "&sign=\"" + sign + "\"&"
// + getSignType(); // 改动为直接传递服务端签名(已经包括订单信息和签名信息)
final String payInfo = args.getString(0);
// Log.i("alipay", payInfo);
if ("pay".equals(action)) { Runnable payRunnable = new Runnable() {
@Override
public void run() {
// 构造PayTask 对象
PayTask alipay = new PayTask(currentActivity);
// 调用支付接口,获取支付结果
String result = alipay.pay(payInfo); Message msg = new Message();
msg.what = Constants.Alipay.SDK_PAY_FLAG;
msg.obj = result;
mHandler.sendMessage(msg);
}
}; // 必须异步调用
Thread payThread = new Thread(payRunnable);
payThread.start(); callbackContext.success();
return true; } else {
return false;
}
} }
iOS
#import <Cordova/CDV.h> @interface CDVAlipay : CDVPlugin @property (nonatomic,copy) NSString*callbackID;
//Instance Method
-(void) pay:(CDVInvokedUrlCommand*)command ; @end
#import "CDVAlipay.h"
#import "Order.h"
#import "Conts.h"
#import "DataSigner.h"
#import <AlipaySDK/AlipaySDK.h>
#import "AppDelegate.h"
@implementation CDVAlipay
@synthesize callbackID;
-(void)pay:(CDVInvokedUrlCommand *)command
{ //应用注冊scheme,在AlixPayDemo-Info.plist定义URL types
NSString *appScheme = @"yooshow";
//将签名成功字符串格式化为订单字符串,请严格依照该格式
NSString *orderString = nil;
orderString = [command.arguments objectAtIndex:0]; [[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) { //状态
NSString* resultStatus = [resultDic objectForKey:@"resultStatus"];
NSString* msg = @"false";
if([resultStatus isEqualToString:@"9000"] || [resultStatus isEqualToString:@"8000"] ){
msg = @"true";
}
//获取订单号
NSString * result = [resultDic objectForKey:@"result"];
NSString* out_trade_no = [self getOut_trade_no:result];
//通知到界面 //0--微信 1--支付宝 2--银联
NSString *js = [[NSString alloc]initWithFormat:@"pay.result('1','%@','%@')", out_trade_no,msg ];
[[AppDelegate appDelegate] runJS:js]; }]; CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@""];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
-(NSString*) getOut_trade_no:(NSString*) result
{
NSString* out_trade_no = @"";
NSArray *parames = [result componentsSeparatedByString:@"&"];
for (NSUInteger i = 0; i < parames.count; i++)
{
NSString* p = parames[i];
NSRange range = [p rangeOfString:@"out_trade_no"]; if(range.location==0){
NSArray *keyValue = [p componentsSeparatedByString:@"="];
if(keyValue!=nil && keyValue.count>1){
@try{
out_trade_no = keyValue[1];
NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:@"\""];
out_trade_no= [out_trade_no stringByTrimmingCharactersInSet:set];
// NSLog(@"终于的订单号>>>>>>>>>>%@", out_trade_no);
}@catch (NSException * e) {
// NSLog(@"Exception: %@", e);
}
}
}
}
return out_trade_no; } @end
服务端的通知页面安装官方的要求做,验证之后做业务处理。比方添加账号剩余金额,我还是上一段代码吧,我使用的c#
/// <summary>
/// 支付宝签名(包括订单信息+签名)
/// </summary>
/// <param name="param"></param>
/// <returns></returns>
public string AlipaySign(AlipayParam param)
{
//获取第三方(alipay) 配置信息
ThirdPartyConfig config = AppService.Instance.GetThirdPartyConfig();
//构造须要签名的内容
string orderInfo = AlipayCore.GetOrderInfo(param.OrderNO, param.Subject, param.Body, param.Price, config.AlipayPartner, config.AlipaySeller, config.AlipayServer_Notify);
//签名
var signed = RSAFromPkcs8.Sign(orderInfo, config.AlipayPrivate_Key, "UTF-8");
//编码签名后的值。而且构造返回结果
var result = orderInfo + "&sign=\"" + HttpUtility.UrlEncode(signed, Encoding.UTF8) + "\"&sign_type=\"" + config.AlipaySignType + "\""; return result;
}
/// <summary>
/// 验证阿里支付回调。假设通过则处理订单。并返回true ,假设验证失败则直接返回false
/// </summary>
/// <param name="sPara"></param>
/// <returns></returns> public bool AlipayNotifyVerify(SortedDictionary<string, string> sPara)
{
var config = AppService.Instance.GetThirdPartyConfig();
Notify aliNotify = new Notify(config.AlipayPartner, "utf-8", "RSA");
bool verifyResult = aliNotify.Verify(sPara, sPara["notify_id"], sPara["sign"]);
if (verifyResult)//验证成功
{
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//请在这里加上商户的业务逻辑程序代码 //——请依据您的业务逻辑来编敲代码(下面代码仅作參考)——
//获取支付宝的通知返回參数。可參考技术文档中server异步通知參数列表 //商户订单号 string out_trade_no = sPara["out_trade_no"]; //支付宝交易号 string trade_no = sPara["trade_no"]; //交易状态
string trade_status = sPara["trade_status"]; string seller_email = sPara["seller_email"]; string buyer_email = sPara["buyer_email"]; string total_fee = sPara["total_fee"];
//买家付款时间
string gmt_payment = sPara["gmt_payment"];
if (sPara["trade_status"] == "TRADE_SUCCESS" || sPara["trade_status"] == "TRADE_FINISHED")
{
//推断该笔订单是否在商户站点中已经做过处理
//假设没有做过处理。依据订单号(out_trade_no)在商户站点的订单系统中查到该笔订单的具体,并运行商户的业务程序
//假设有做过处理,不运行商户的业务程序 //注意:
//该种交易状态仅仅在两种情况下出现
//1、开通了普通即时到账,买家付款成功后。
//2、开通了高级即时到账。从该笔交易成功时间算起,过了签约时的可退款时限(如:三个月以内可退款、一年以内可退款等)后。 //成功之后改动订单状态,记帐,加花
OrderPaySuccessParam param = new OrderPaySuccessParam();
//订单号
param.OrderNO = out_trade_no;
//支付宝交易号
param.TradeNO = trade_no;
//支付方式
param.PayMethod = PaymentMethodKind.Online;
//卖家收款账户
param.Account = seller_email;
//卖家收款账户银行
param.Bank = PayTypeKind.AliPay.ToString();
//买家账户
param.PayAccount = buyer_email;
//买家收款账户银行
param.PayBank = PayTypeKind.AliPay.ToString();
//实际支付金额
param.TotalAmount = Convert.ToDouble(total_fee);
//支付时间
param.PayDate = Convert.ToDateTime(gmt_payment);
//支付工具类型
param.PayType = PayTypeKind.AliPay; OrderService.Instance.OrderPaySuccess(param);
}
else
{ }
return true;
}
else
{
return false;
}
}
phonegap(cordova) 自己定义插件代码篇(三)----支付宝支付工具整合的更多相关文章
- phonegap(cordova) 自己定义插件代码篇(六)----android ,iOS 微信支付工具整合
还是那句话,在使用插件代码篇的时候,请先了解插件机制(如整合原生插件先阅读原生插件文档.非常重要.非常重要!非常重要!),如未了解,请先阅读入门篇.这里就专贴关键代码 必须先把官方sdk 依照要求一步 ...
- phonegap(cordova) 自己定义插件代码篇(五)----android ,iOS 集成微信登陆
统一登陆还是非常有必要的,安全,放心.代码 /*cordov 微信自己定义插件*/ (function (cordova) { var define = cordova.define; define( ...
- phonegap(cordova) 自己定义插件代码篇(四)----读取本地图片
有时候确实知道本地图片地址,要获取到base64 /** * 获取本地图片,包括路径和压缩后的 base64 */ (function (cordova) { var define = cordov ...
- Android移动APP开发笔记——Cordova(PhoneGap)通过CordovaPlugin插件调用 Activity 实例
引言 Cordova(PhoneGap)采用的是HTML5+JavaScript混合模式来开发移动手机APP,因此当页面需要获取手机内部某些信息时(例如:联系人信息,坐标定位,短信等),程序就需要调用 ...
- Cordova应用的JavaScript代码和自定义插件代码的调试
我之前写过三篇Cordova相关的技术文章.当我们使用Cordova将自己开发的前端应用打包安装到手机上后,可能会遇到需要调试Cordova应用的时候. 本文就介绍Cordova应用的调试步骤. 如果 ...
- Android Cordova 插件开发之编写自己定义插件
前言 本文适合Android+web的复合型人才,由于cordova本身就是混合开发,所以在Android开发的基础上,还要懂web相关技术(HTML+CSS+JS).可是也有例外,比方我.仅仅需负责 ...
- YbSoftwareFactory 代码生成插件【二十五】:Razor视图中以全局方式调用后台方法输出页面代码的三种方法
上一篇介绍了 MVC中实现动态自定义路由 的实现,本篇将介绍Razor视图中以全局方式调用后台方法输出页面代码的三种方法. 框架最新的升级实现了一个页面部件功能,其实就是通过后台方法查询数据库内容,把 ...
- Cordova - 与iOS原生代码交互2(使用Swift开发Cordova的自定义插件)
在前一篇文章中我介绍了如何通过 js 与原生代码进行交互(Cordova - 与iOS原生代码交互1(通过JS调用Swift方法)),当时是直接对Cordova生成的iOS工程项目进行编辑操作的(添加 ...
- 【SSRS】入门篇(三) -- 为报表定义数据集
原文:[SSRS]入门篇(三) -- 为报表定义数据集 通过前两篇文件 [SSRS]入门篇(一) -- 创建SSRS项目 和 [SSRS]入门篇(二) -- 建立数据源 后, 我们建立了一个SSRS项 ...
随机推荐
- HDU——2089 不要62
不要62 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- BZOJ-1043 [HAOI2008]下落的圆盘
几何题... 先把所有圆储存起来,然后对于每个圆我们求得之后放下的圆挡住了的部分,求个并集,并把没被挡到的周长加进答案. #include <cstdlib> #include <c ...
- 分布式存储ceph集群实践
1.环境规划,三台主机 10.213.14.51/24 10.213.14.52/24 10.213.14.53/24 集群网络 172.140.140.11. ...
- HDOJ 2222: Keywords Search
Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
- .NET返回上一页
原文发布时间为:2010-05-25 -- 来源于本人的百度文章 [由搬家工具导入] if (Request.UrlReferrer != null) { ...
- The C programming language [book]
1 A12.3 Macro Definition and Expansion A control line of the form #define identifier token-sequence ...
- Selenium2+python自动化(学习笔记2)
from selenium import webdriverdriver = webdriver.Ie()driver.get=("http://www.baidu.com")dr ...
- Scrapy笔记:CrawSpider中rules中的使用
scrapy.spiders.crawl.CrawlSpider类的使用 这个类比较适用于对网站爬取批量网页,相比于Spider类,CrawlSpider主要使用规则(rules)来提取链接 rule ...
- javascript 省市二级联动
通过遍历二维数组 获取到 二级列表的 每个option 然后onchange事件 获取到省,然后循环遍历该省具有的市并将遍历到的市添加到id为city的选择器中. 获取完需要清空二级列表的内容,不然不 ...
- AC日记——[Sdoi2010]星际竞速 bzoj 1927
1927 思路: 连边,拆点: 每个点拆成i,i+n,都向t连边: i到t表示高速模式,i+n到t表示跳跃模式: 然后读入路径,如果u>v,则交换u,v: u向v+n连边: spfa跑最小费用: ...