美文网首页知识图谱
iOS内购-从客户端到服务器分析

iOS内购-从客户端到服务器分析

作者: Johnny_Z | 来源:发表于2021-01-18 16:33 被阅读0次

一、财务配置

image.png

登录到苹果哦itunsconnect后台后,可以到协议、税务和银行业务这里交给财务配置就行

二、itunes后台商品配置

进入到我们的iTunes后台后,在App Store 下面 有一个子栏目App 内购买项目这里点击管理我们就能看到我们进行商品配置的入口了
我们可以添加的商品类型

image.png

三、客户端集成(integration)

1、支付流程

image.png

2、iOS- swift代码

import StoreKit

class InAppPurchaseManager: NSObject,SKPaymentTransactionObserver, SKProductsRequestDelegate {
    //登录的时候调用
    func addIAPObserver() -> Void {
        SKPaymentQueue.default().remove(self)
        SKPaymentQueue.default().add(self)
    }
    //登出的时候调用,  防止发货到未知用户
    func removeIAPObserver() -> Void {
        SKPaymentQueue.default().remove(self)
    }
    
    func addPayment(_ productId:String) {
        let product = NSSet(array: [productId] as [AnyObject])
        let request = SKProductsRequest(productIdentifiers: product as! Set<String>)
        request.delegate = self
        request.start()
    }
    
    
    func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
        let avaliableProducts = response.products
        guard let product = avaliableProducts.first else {
            return
        }
        let mutablePayment = SKMutablePayment.init(product: product)
        //发起购买请求
        SKPaymentQueue.default().add(mutablePayment)
    }
    
    func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
        for transaction in transactions {
            switch transaction.transactionState {
            case .purchased:
                self.complete(transaction)
                break
            case .restored:
                self.restored(transaction)
                break
            case .failed:
                self.fail(transaction)
                break
            default:
                //其他情况
                break
            }
        }
    }
    
    //交易完成
    func complete(_ transaction: SKPaymentTransaction) -> Void {
        guard let receiptUrl = Bundle.main.appStoreReceiptURL, let receiveData:NSData = NSData(contentsOf: receiptUrl) else {
            return
        }
        let receiptString = receiveData.base64EncodedString(options: .endLineWithLineFeed)
        let transactionIdentifier = transaction.transactionIdentifier
        //将transactionIdentifier & receiptString发送给服务器,去验证票据的正确性
        //todo
    }
    //交易失败
    func fail(_ transaction: SKPaymentTransaction) {
        //todo
    }
    //交易restored
    func restored(_ transaction:SKPaymentTransaction) {
        //todo
    }
    
    //交易完成记得finish掉,不然会出现卡单,无法进行下次支付
    func finishTransactionWith(transactionId transctionId:String) {
        let transactions = SKPaymentQueue.default().transactions
        for transaction in transactions {
            if transaction.transactionIdentifier == transctionId {
                SKPaymentQueue.default().finishTransaction(transaction)
                break
            }
        }
    }
}

四、简单的服务器验票逻辑(nodejs)

整个服务逻辑牵扯太多,我用nodejs整理出单纯的验票部分,简单的校验和借鉴是没有问题的。

const https = require("https")
var postData = "客户端传过来receiptString";

var IAPVerifier = function(){};

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)) {
                // 指向沙盒测试环境再次验证
                options.host = 'sandbox.itunes.apple.com';
                return _this.verify(receiptData, options, function(err, data) {
                    return cb(err, data);
                });
            } else {
                return cb(error, data);
            }
        };
    })(this));
};


/*
  verify the receipt data
 */

IAPVerifier.verify = function(data, options, cb) {
    var post_data = JSON.stringify(data);
    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*/
    };
};


IAPVerifier.verifyWithRetry(postData, true, function (e, responseData) {
    console.log("responseData:",JSON.stringify(responseData,null,'\t'));
    //todo 验证客户端传过来的transactionIdentifier,是否存在于"in_app"中
});

参考链接:
https://www.jianshu.com/p/2f98b7937b6f

相关文章

  • iOS内购-从客户端到服务器分析

    一、财务配置 登录到苹果哦itunsconnect后台后,可以到协议、税务和银行业务这里交给财务配置就行 二、it...

  • IOS内购服务端技术方案

    IOS内购服务端技术方案 IOS购买vip流程 IOS内购服务器模式的主要流程如下所示: 服务端验证注意点 苹果A...

  • iOS内购(最新)-内含遇到的"坑"

    内购--- iOS 客户端进行虚拟商品的支付方式 官方中文内购教程文档:http://help.apple.com...

  • [直播技术实践]较为完整的开源直播框架[服务器,iOS,andr

    记录下最近搭建的基于rtmp协议的开源直播框架[服务器,iOS,android] 从服务器到客户端iOS,andr...

  • iOS 苹果内购流程

    本文参考: iOS开发之内购完全笔记 iOS开发内购全套图文教程 iOS应用程序内购/内付费(一) 代码...

  • IOS 内购掉单问题

    向服务器请求OrderID,向ios发起内购时传递给payment: SKMutablePayment *paym...

  • iOS 支付流程相关-转

    IOS 内购支付两种模式:内置模式 服务器模式 内置模式的流程:app从app store 获取产品信息 用户选择...

  • iOS内购流程文档-Lion

    iOS内购流程: iOS内购 什么时候用到呢? 虚拟产品就需要用到iOS内购;购买的商品,是在本app中...

  • iOS-内购

    前言:关于iOS内购,参考两篇博文 iOS-iOS内购流程(手把手图文教程)iOS内购你看我就够了(埋坑篇) 我自...

  • 苹果内购

    重点总结: 1.获取内购列表(从App内读取或从自己服务器读取) 2.App Store请求可用的内购列表 3.向...

网友评论

    本文标题:iOS内购-从客户端到服务器分析

    本文链接:https://www.haomeiwen.com/subject/zjtvkktx.html