标签:
appstore 中审核中,如果你app内卖的东西是个虚拟的产品,那么你有可能被要求不能使用第三方支付工具,只能使用 IAP 应用内支付功能。
使用这个功能需要在apple 开发者后台签合同,设置银行账号,设置价格,这个就不讲了,本篇主要讲phonegap中整合IAP的代码
/** * 苹果应用内支付 */ (function (cordova) { var define = cordova.define; define("cordova/plugin/applepay", function (require, exports, module) { var argscheck = require('cordova/argscheck'), exec = require('cordova/exec'); exports.pay = function (productID,quantity, successCB, failCB) { exec(successCB, failCB, "ApplePay", "pay", [productID,quantity]); }; }); cordova.addConstructor(function () { if (!window.plugins) { window.plugins = {}; } console.log("将插件注入cordovaapplepay..."); window.plugins.applepay = cordova.require("cordova/plugin/applepay"); console.log("applepay注入结果:" + typeof (window.plugins.applepay)); }); })(cordova);
<feature name="ApplePay"> <param name="ios-package" value="CDVApplePay" /> </feature>
#import <Cordova/CDV.h> @interface CDVApplePay : CDVPlugin @property (nonatomic,copy) NSString*callbackID; //Instance Method - (void)pay:(CDVInvokedUrlCommand*)command; @end
#import "CDVApplePay.h" #import "AppDelegate.h" #import <StoreKit/StoreKit.h> #import "MainViewController.h" #import "Conts.h" @implementation CDVApplePay @synthesize callbackID; - (void)pay:(CDVInvokedUrlCommand*)command { if ([SKPaymentQueue canMakePayments]) { NSString *produtid = [command.arguments objectAtIndex:0]; NSString* strQuantity =[command.arguments objectAtIndex:1]; buyQuantity = [strQuantity intValue]; MainViewController* view = [[MainViewController alloc] init]; [view getProductInfo:produtid]; // [[AppDelegate appDelegate] getProductInfo:produtid]; } else { NSLog(@"失败,用户禁止应用内付费购买."); NSString *js = [[NSString alloc]initWithFormat:@"yooshow.alert('%@')", @"您已禁止应用内购买,请先开启" ]; [[AppDelegate appDelegate] runJS:js]; } CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@""]; [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } @end
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view from its nib. // 监听购买结果 [[SKPaymentQueue defaultQueue] addTransactionObserver:self];} - (void)viewDidUnload { [super viewDidUnload]; // Release any retained subviews of the main view. // e.g. self.myOutlet = nil; [[SKPaymentQueue defaultQueue] removeTransactionObserver:self]; } - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions { for (SKPaymentTransaction *transaction in transactions) { switch (transaction.transactionState) { case SKPaymentTransactionStatePurchased://交易完成 NSLog(@"transactionIdentifier = %@", transaction.transactionIdentifier); [self completeTransaction:transaction]; break; case SKPaymentTransactionStateFailed://交易失败 [self failedTransaction:transaction]; break; case SKPaymentTransactionStateRestored://已经购买过该商品 [self restoreTransaction:transaction]; break; case SKPaymentTransactionStatePurchasing: //商品添加进列表 NSLog(@"苹果交易流水号开始交易transactionIdentifier = %@", transaction.transactionIdentifier); NSLog(@"商品添加进列表此处我方服务器应创建订单"); break; default: break; } } } - (void)completeTransaction:(SKPaymentTransaction *)transaction { // Your application should implement these two methods. NSString * productIdentifier = transaction.payment.productIdentifier; NSString * receipt = [transaction.transactionReceipt base64Encoding]; NSLog(@"苹果交易流水号完成交易transactionIdentifier = %@", transaction.transactionIdentifier); if ([productIdentifier length] > 0) { // 向自己的服务器验证购买凭证 NSLog(@"购买成功应将修改我方服务器用户数据凭证为%@,产品信息%@",receipt,productIdentifier); NSString *js = [[NSString alloc]initWithFormat:@"pay.applePayResult('%@','%@')", transaction.transactionIdentifier,receipt]; [[AppDelegate appDelegate] runJS:js]; } // Remove the transaction from the payment queue. [[SKPaymentQueue defaultQueue] finishTransaction: transaction]; } - (void)failedTransaction:(SKPaymentTransaction *)transaction { if(transaction.error.code != SKErrorPaymentCancelled) { NSLog(@"购买失败"); } else { NSLog(@"用户取消交易"); } NSString *js = [[NSString alloc]initWithFormat:@"$.ui.hideMask();" ]; [[AppDelegate appDelegate] runJS:js]; [[SKPaymentQueue defaultQueue] finishTransaction: transaction]; } - (void)restoreTransaction:(SKPaymentTransaction *)transaction { NSLog(@"恢复购买"); NSString * productIdentifier = transaction.payment.productIdentifier; NSString * receipt = [transaction.transactionReceipt base64Encoding]; if ([productIdentifier length] > 0) { // 向自己的服务器验证购买凭证 NSLog(@"恢复购买成功应将修改我方服务器用户数据凭证为%@,产品信息%@",receipt,productIdentifier); } // 对于已购商品,处理恢复购买的逻辑 [[SKPaymentQueue defaultQueue] finishTransaction: transaction]; } // 下面的ProductId应该是事先在itunesConnect中添加好的,已存在的付费项目。否则查询会失败。 - (void)getProductInfo:(NSString*) productID { NSSet * set = [NSSet setWithArray:@[productID]]; SKProductsRequest * request = [[SKProductsRequest alloc] initWithProductIdentifiers:set]; request.delegate = self; [request start]; } // 以上查询的回调函数 - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response { NSArray *myProduct = response.products; if (myProduct.count == 0) { NSLog(@"无法获取产品信息,购买失败。"); NSString *js = [[NSString alloc]initWithFormat:@"$.ui.hideMask();" ]; [[AppDelegate appDelegate] runJS:js]; return; } // SKPayment * payment = [SKPayment paymentWithProduct:myProduct[0]]; // payment.quantity =buyQuantity; SKMutablePayment * payment = [SKMutablePayment paymentWithProduct:myProduct[0]]; payment.quantity = buyQuantity; [[SKPaymentQueue defaultQueue] addPayment:payment]; }
最后服务端的验证,服务端我用的是 C#
public bool ApplePayNotifyVerify(ApplePayParam param) { //验证支付凭证 // 初始化通信处理类 try { //支付凭证不能被重复使用,检查支付凭证是否已经被计入流水账,如果被使用过,直接返回false, 未被使用过的才可以验证,并处理相关业务 var payment = PaymentService.Instance.GetList(p => p.AppleReceipt == param.AppleReceipt).FirstOrDefault(); if (payment == null) { var config = AppService.Instance.GetThirdPartyConfig(); System.Net.Http.HttpClient httpClient = new System.Net.Http.HttpClient(); httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var receipt = "{\"receipt-data\":\"" + param.AppleReceipt + "\"}"; HttpContent content = new StringContent(receipt, Encoding.UTF8); content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); HttpResponseMessage response = httpClient.PostAsync(new Uri(config.ApplePayVerify), content).Result; string result = response.Content.ReadAsStringAsync().Result.Replace(Environment.NewLine, string.Empty).Replace("\n", string.Empty); var entity= JObject.Parse(result); //AppleVerifyEntity entity = JsonConvert.DeserializeObject<AppleVerifyEntity>(result); if (entity.Value<int>("status") == 0) { //成功之后修改订单状态,记帐,加花 OrderPaySuccessParam payParam = new OrderPaySuccessParam(); //订单号 payParam.OrderNO = param.OrderNO; //交易号 payParam.TradeNO = param.TradeNO; //支付方式 payParam.PayMethod = PaymentMethodKind.Online; //卖家收款账户 payParam.Account = config.ApplePayBankAccount; //卖家收款账户银行 payParam.Bank = config.ApplePayBankName; //买家账户 payParam.PayAccount = ""; //买家收款账户银行 payParam.PayBank = ""; //实际支付金额 var order = OrderService.Instance.GetList(o => o.OrderNO == param.OrderNO).FirstOrDefault(); //苹果支付没有返回支付金额,为了避免后期验证不通过,设置总金额为实际订单金额 payParam.TotalAmount = order.TotalAmount; //支付时间 payParam.PayDate = DateTime.Now; //支付工具类型 payParam.PayType = PayTypeKind.ApplePay; //记录支付凭证到流水账 payParam.AppleReceipt = param.AppleReceipt; OrderService.Instance.OrderPaySuccess(payParam); return true; } else { return false; } } else { throw new Exception("此支付凭证已被使用,请勿重复使用"); } } catch { return false; } }
phonegap(cordova) 自定义插件代码篇(一)----IAP 应用内支付
标签:
原文地址:http://blog.csdn.net/lorinzhang/article/details/50441704