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



MainViewController.m中添加

- (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;
            }
        }