• 苹果内付费 IAP


    创建app内购买项目

    • 消耗型项目:对于消耗型App内购买项目,用户每次下载时都必须进行购买。一次性服务通常属于消耗型项目,例如钓鱼App 中的鱼饵。

    • 非消耗型项目:对于非消耗型App内购买项目,用户仅需要购买一次。不会过期或随使用而减少的服务通常为非消耗型项目,例如游戏App 的新跑道。

    • 自动续订订阅:通过自动续订订阅,用户可以购买指定时间期限内的更新和动态内容。除非用户取消选择,否则订阅(例如杂志订阅等)会自动续订。

    • 免费订阅:通过免费订阅,开发者可以将免费订阅内容放入“报刊杂志”。用户注册免费订阅后,该订阅内容将会出现在与该用户Apple ID 关联的所有设备上。请注意,免费订阅不会过期,并且仅在支持报刊杂志功能的 App 中提供。

    • 非续订订阅:非续订订阅允许有时限性的营销服务。对于 App 内购买项目中的限时访问内容,就需使用非续订订阅。例如,导航App 中语音导航功能的一周订阅,或者年度订阅已存档的视频或音频的在线目录。

    测试环境

    在sandbox中验证receipt:https://sandbox.itunes.apple.com/verifyReceipt

    在生产环境中验证receipt:https://buy.itunes.apple.com/verifyReceipt

    那么如何自动的识别收据是否是sandbox receipt呢?
    识别沙盒环境下收据的方法有两种:

    1. 根据收据字段 environment = sandbox。
    2. 根据收据验证接口返回的状态码。
      如果status=21007,则表示当前的收据为沙盒环境下收据, t进行验证。

    苹果反馈的状态码:

    • 21000 App Store无法读取你提供的JSON数据
    • 21002 收据数据不符合格式
    • 21003 收据无法被验证
    • 21004 你提供的共享密钥和账户的共享密钥不一致
    • 21005 收据服务器当前不可用
    • 21006 收据是有效的,但订阅服务已经过期。当收到这个信息时,解码后的收据信息也包含在返回内容中
    • 21007 收据信息是测试用(sandbox),但却被发送到产品环境中验证
    • 21008 收据信息是产品环境中使用,但却被发送到测试环境中验证

    注意:

    在verifyWithRetry方法中,首先向向真实环境验证票据,如果是21007则向沙盒环境验证;但是在消耗品类型的测试中,使用沙盒票据在真实环境中验证票据得到返回码:21002.所以下面代码在真实环境运行时,沙盒测试消耗型商品得不到正确的验证结果

    /*
        verifyWithRetry the receipt
    */
        IAPVerifier.verifyWithRetry = function(receipt, isBase64, cb) {
            var encoded = null, receiptData = {};
            if (isBase64) {
                encoded = receipt;
            } else {
                encoded = new Buffer(receipt).toString('base64');
            }
            receiptData['receipt-data'] = encoded;
            var options = this.requestOptions();
            return this.verify(receiptData, options, (function(_this) {
                return function(error, data) {
                if (error) return cb(error);
                if ((21007 === (data != null ? data.status : void 0)) && (_this.productionHost == _this.host)) {
                    var options_this.requestOptions();
                    // 指向沙盒测试环境再次验证
                    options.host = 'sandbox.itunes.apple.com/verifyReceipt';
                    return _this.verify(receiptData, options, function(err, data) {
                        return cb(err, data);
                    });
                } else {
                    return cb(err, data);
              }
            };
          })(this));
        };
    
    
        /*
          verify the receipt data
         */
    
        IAPVerifier.verify = function(data, options, cb) {
            var post_data, request;
            post_data = JSON.stringify(data);
            options.headers = {
                'Content-Type': 'application/x-www-form-urlencoded', 
                'Content-Length': post_data.length
                };
            var request = https.request(options, (function(_this) {
                return function(response) {
                    var response_chunk = [];
                    response.on('data', function(data) {
                    if (response.statusCode !== 200) {
                        return cb(new Error("response.statusCode != 200"));
                    }
                    response_chunk.push(data);
                });
                return response.on('end', function() {
                    var responseData, totalData;
                    totalData = response_chunk.join('');
                    try {
                        responseData = JSON.parse(totalData);
                    } catch (_error) {
                        return cb(_error);
                    }
                    return cb(null, responseData);
                });
            };
          })(this));
          request.write(post_data);
          request.end();
          request.on('error', function (exp) {
              console.log('problem with request: ' + exp.message);
          });
        };
        
        
        IAPVerifier.requestOptions = function() {
          return options = {
            host: 'buy.itunes.apple.com',
            port: 443,
            path: '/verifyReceipt',
            method: "POST",
            rejectUnauthorized: false/*不加:返回证书不受信任CERT_UNTRUSTED*/
          };
        };
    

    建议:

    为保证审核的通过,需要在客户端或server进行双重验证,即,先以线上交易验证地址进行验证,如果苹果正式验证服务器的返回验证码code为21007,则再一次连接沙盒测试服务器进行验证即可。在应用提审时,苹果IAP提审验证时是在沙盒环境的进行的,即:苹果在审核App时,只会在sandbox环境购买,其产生的购买凭证,也只能连接苹果的测试验证服务器,如果没有做双验证,需要特别注意此问题,否则会被拒。

  • 相关阅读:
    event.target.tagName
    Web安全之跨站伪造请求(CSRF)
    Web安全之XSS 入门与介绍
    Web安全之Web 安全介绍与基础入门知识
    设计模式之命令模式
    前端常用的库和实用技术之JavaScript多线程
    前端常用的库和实用技术之JavaScript面向切面编程
    设计模式之职责链模式
    设计模式之适配器模式
    设计模式之策略模式
  • 原文地址:https://www.cnblogs.com/Buggo/p/5503644.html
Copyright © 2020-2023  润新知