建議讀者,先閱讀官方文檔,知曉其支付流程之後再來使用此代碼,比如客戶需要做什麼,服務端需要做什麼(很重要!很重要!很重要!),因爲這幾個篇幅都是純代碼篇,因爲閱讀前面的入門篇之後看這些應該毫無問題纔對,否則就是沒入門,上代碼
公用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)//驗證成功
{
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//請在這裏加上商戶的業務邏輯程序代碼
//——請根據您的業務邏輯來編寫程序(以下代碼僅作參考)——
//獲取支付寶的通知返回參數,可參考技術文檔中服務器異步通知參數列表
//商戶訂單號
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;
}
}