Apple 內(nèi)購

關(guān)于內(nèi)購所需東西:
1.測試開發(fā)證書:需要打開in-app-purchase,綁定bundleid:com.aragon.TexasPoker
2.iTunes connect 里添加內(nèi)購應(yīng)用:
1>首先需要?jiǎng)?chuàng)建一個(gè)app。套裝id 選擇證書里的創(chuàng)建好的這個(gè)項(xiàng)目app id
2>功能里添加app 內(nèi)購買項(xiàng)目:每個(gè)內(nèi)購買項(xiàng)目的id必須唯一谒养,id需要測試期間先發(fā)給我菌羽,之后發(fā)給后臺(tái)刃永,有后臺(tái)返給我(選擇消耗型的)
3>填寫協(xié)議舔清、稅務(wù)和銀行業(yè)務(wù),填寫所有的信息吩蔑,(網(wǎng)上有文檔)
4>用戶與職能里添加一個(gè)沙盒測試員,郵箱密碼發(fā)給我填抬,我需要這個(gè)做內(nèi)購買支付測試烛芬,

關(guān)于內(nèi)購

前期準(zhǔn)備任務(wù)
1>配置開發(fā)測試證書:
前往蘋果開發(fā)者網(wǎng)站(https://developer.apple.com)使用開發(fā)者賬號(hào)登入,進(jìn)入accout頁面

_1504772587009.png

選擇certifications飒责,Identitiers赘娄,&profiles

_1504772868401.png

如果你已經(jīng)有證書了,就不用創(chuàng)建證書了(證書不需要很多個(gè)宏蛉,基本上兩個(gè)證書就足夠了遣臼,一個(gè)開發(fā)證書一個(gè)測試證書),直接創(chuàng)建app ids
點(diǎn)擊app ids 點(diǎn)擊“+”拾并,按照里邊的步驟添加name揍堰, 和bundle id蚌讼,注意打開In-App-purchase,需要和應(yīng)用的bundleid 對(duì)應(yīng),很簡單
然后創(chuàng)建描述文件

_1504773116354.png

選擇dev 个榕,繼續(xù)

_1504773176808.png

選擇剛才創(chuàng)建的app id篡石,繼續(xù)
然后選擇證書,繼續(xù)
之后選擇測試的設(shè)備西采,繼續(xù)凰萨,創(chuàng)建描述文件結(jié)束,可以將這個(gè)描述文件導(dǎo)出械馆,之后用
2>配置工程

_1504773502536.png

去掉自動(dòng)配置胖眷,import剛才導(dǎo)出的描述文件,如果你安裝過證書他會(huì)自己識(shí)別霹崎,如果沒有安裝過珊搀,那么需要把證書導(dǎo)出來,雙擊安裝
3>Itunes Connect 添加應(yīng)用(這也是內(nèi)購應(yīng)用比較重要的一步):
1>創(chuàng)建內(nèi)購app尾菇,和內(nèi)購項(xiàng)目
1:到蘋果開發(fā)者網(wǎng)站accout頁面(或者直接進(jìn)入iTunes connect 網(wǎng)站登錄賬號(hào)境析,需要蘋果開發(fā)者賬號(hào))

2:
_1504775754119.png

選擇“我的app”進(jìn)入添加內(nèi)購項(xiàng)目

_1504775817311.png

點(diǎn)擊右上角新建app

_1504775927162.png

選擇平臺(tái),名稱派诬,注意套裝id選擇我們那會(huì)在創(chuàng)建證書里的App IDs劳淆,sku 隨便填,點(diǎn)擊創(chuàng)建默赂,這時(shí)候就會(huì)創(chuàng)建出一個(gè)新的app
3:點(diǎn)擊剛新創(chuàng)建的app

_1504776122233.png

選擇功能沛鸵,

_1504776175582.png

添加內(nèi)購項(xiàng)目點(diǎn)擊+

_1504776210627.png

選擇一種類型(上邊的解釋很清楚,根據(jù)需要選擇)創(chuàng)建之后填寫基本的信息

_1504776288540.png

需要注意的是產(chǎn)品id一定唯一缆八,這個(gè)id我們可以放在后臺(tái)曲掰,需要的時(shí)候返回給我們,如果你的內(nèi)購項(xiàng)目只有一個(gè)也可以放在前臺(tái)奈辰,填寫完成之后栏妖,選擇保存,創(chuàng)建內(nèi)購項(xiàng)目完成
2>創(chuàng)建沙盒測試
點(diǎn)擊“用戶和職能”

_1504776479189.png

選擇沙箱技術(shù)測試
點(diǎn)擊“+”
填寫基本信息

_1504776541872.png

注意電子郵箱隨便寫一個(gè)冯挎,但是不要求是真的底哥,選擇儲(chǔ)存,創(chuàng)建完畢房官,這個(gè)賬號(hào)是以后測試需要的apple id
3>填寫稅務(wù)和銀行卡信息
選擇“稅務(wù)”這一塊趾徽,填寫基本的信息,這塊一般是功能的產(chǎn)品填的翰守,太機(jī)密孵奶,我就沒有權(quán)限看了
所有的前奏準(zhǔn)備完成,現(xiàn)在開始代碼部分

——————————————————————————
我們用到的這個(gè)框架是:StoreKit
先說一下蜡峰,內(nèi)購的基本思路:
1>我們需要判斷是否支持內(nèi)購
2>我們需要通過產(chǎn)品id(也就是我們創(chuàng)建內(nèi)購Item的那個(gè)產(chǎn)品id)去獲取更全面的info
3>返回全面的產(chǎn)品info之后了袁,我們將這個(gè)產(chǎn)品加入到支付隊(duì)列里等待支付
4>系統(tǒng)通過通知告訴我們現(xiàn)在的狀態(tài)
5>當(dāng)支付成功之后朗恳,我們需要通過沙盒存儲(chǔ)的Url,獲取Data
6>將Data轉(zhuǎn)化base64加密的字符串载绿,提交到后臺(tái)粥诫,后臺(tái)去驗(yàn)證信息,如果驗(yàn)證成功崭庸,這時(shí)候怀浆,支付才是真正的完成了

下面直接復(fù)制上我寫的demo,代碼

//
//  ViewController.swift
//  IN_App_Purchase_Demo
//
//  Created by HaoYuhong on 2017/9/7.
//  Copyright ? 2017年 HaoYuhong. All rights reserved.
//

import UIKit
import StoreKit
import SVProgressHUD

// testting

let Diamond60 = "ACS_Diamond_60"
class ViewController: UIViewController,SKProductsRequestDelegate, SKPaymentTransactionObserver {
    /// IN-APP Purchase
    var productRequest:SKProductsRequest?
    var currentPaymentItemID:String?
    override func viewDidLoad() {
        super.viewDidLoad()
       SKPaymentQueue.default().add(self)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    @IBAction func payAction(_ sender: Any) {
        buyDiamond()
    }

}
//MARK:- In-APP Purchase
extension ViewController {

    func buyDiamond()  {
        if SKPaymentQueue.canMakePayments() {
            currentPaymentItemID = Diamond60
            self.requestProductData(id: Diamond60)
        } else {
            self.showAlert("", "您的手機(jī)未開啟允許內(nèi)購服務(wù)", "確定")
        }
        SVProgressHUD.show()
    }
    func requestProductData(id:String) {
        let productIdSet = NSSet(object: id)
        productRequest = SKProductsRequest(productIdentifiers: productIdSet as! Set<String>)
        productRequest?.delegate = self
        productRequest?.start()
    }

    //MARK:- Product Request Delegate

    func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
        let products = response.products
        if products.count == 0 {
            self.showAlert("", "未找到你所該買的產(chǎn)品", "確定")
            SVProgressHUD.dismiss()
            return
        }
        var paymentProduct:SKProduct?
        for product in products {
            print(product.localizedDescription)
            print(product.price)
            print(product.productIdentifier)
            if currentPaymentItemID! == product.productIdentifier {
                paymentProduct = product
            }
        }
        if let p = paymentProduct {
            let payment = SKPayment(product: p)
            SKPaymentQueue.default().add(payment)
        }else {
           SVProgressHUD.dismiss()
        }
    }
    func request(_ request: SKRequest, didFailWithError error: Error) {
        SVProgressHUD.dismiss()
        self.showAlert("", "購買失敗", "確定")
    }

    func requestDidFinish(_ request: SKRequest) {
        print("requestDidFinish")
    }

    //MARK:- Transition Observe

    func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
        for transaction in transactions {
            switch transaction.transactionState {
            case .purchased:
                print("交易完成")
                self.completeTransaction(transaction)
                SKPaymentQueue.default().finishTransaction(transaction)
            case .purchasing:
                print("商品添加進(jìn)列表")
            case .failed:
                print("交易失敗")
                self.failedTransaction(transaction)
            case .restored:
                print("已經(jīng)購買過此商品")
                restoredTransaction(transaction)
            default:
                break
            }
        }
    }
    func completeTransaction(_ transaction:SKPaymentTransaction)  {
        print("交易結(jié)束")
        let productId = transaction.payment.productIdentifier
        if !(productId.isEmpty) {
            // 通過存在沙盒的Url獲取Data 提交到自己服務(wù)器驗(yàn)證
            RequestManager.request((Bundle.main.appStoreReceiptURL?.absoluteString)!, method: .post).responseData(completionHandler: { (data) in
                let transactionReceiptData = data.data
                let transactionReceiptString = transactionReceiptData?.base64EncodedString(options: Data.Base64EncodingOptions.endLineWithLineFeed)
                // 提交自己服務(wù)器驗(yàn)證
                self.commitServer(transactionReceiptString)

            })

        }
    }
    func restoredTransaction(_ transaction:SKPaymentTransaction)  {

    }
    func failedTransaction(_ transaction:SKPaymentTransaction)  {
        SVProgressHUD.dismiss()
        if let nserror = transaction.error as NSError? {
            if nserror.code != SKError.Code.paymentCancelled.rawValue {
                self.showAlert("", (transaction.error?.localizedDescription)!, "確定")
            }
        }
        SKPaymentQueue.default().finishTransaction(transaction)
    }
    func commitServer(_ transactionReceiptString: String?) {
        if let string = transactionReceiptString {

        } else {
            print("未知錯(cuò)誤")
        }
    }
}

我會(huì)將此代碼上傳到我的github怕享,有需要的可以下載查看https://github.com/HaoXianSen/In_App_Purchase_Demo.git

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末执赡,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子函筋,更是在濱河造成了極大的恐慌沙合,老刑警劉巖,帶你破解...
    沈念sama閱讀 223,126評(píng)論 6 520
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件跌帐,死亡現(xiàn)場離奇詭異首懈,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)含末,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,421評(píng)論 3 400
  • 文/潘曉璐 我一進(jìn)店門猜拾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來即舌,“玉大人佣盒,你說我怎么就攤上這事⊥缒簦” “怎么了肥惭?”我有些...
    開封第一講書人閱讀 169,941評(píng)論 0 366
  • 文/不壞的土叔 我叫張陵,是天一觀的道長紊搪。 經(jīng)常有香客問我蜜葱,道長,這世上最難降的妖魔是什么耀石? 我笑而不...
    開封第一講書人閱讀 60,294評(píng)論 1 300
  • 正文 為了忘掉前任牵囤,我火速辦了婚禮,結(jié)果婚禮上滞伟,老公的妹妹穿的比我還像新娘揭鳞。我一直安慰自己,他們只是感情好梆奈,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,295評(píng)論 6 398
  • 文/花漫 我一把揭開白布野崇。 她就那樣靜靜地躺著,像睡著了一般亩钟。 火紅的嫁衣襯著肌膚如雪乓梨。 梳的紋絲不亂的頭發(fā)上鳖轰,一...
    開封第一講書人閱讀 52,874評(píng)論 1 314
  • 那天,我揣著相機(jī)與錄音扶镀,去河邊找鬼蕴侣。 笑死,一個(gè)胖子當(dāng)著我的面吹牛臭觉,可吹牛的內(nèi)容都是我干的睛蛛。 我是一名探鬼主播,決...
    沈念sama閱讀 41,285評(píng)論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼胧谈,長吁一口氣:“原來是場噩夢啊……” “哼忆肾!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起菱肖,我...
    開封第一講書人閱讀 40,249評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤客冈,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后稳强,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體场仲,經(jīng)...
    沈念sama閱讀 46,760評(píng)論 1 321
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,840評(píng)論 3 343
  • 正文 我和宋清朗相戀三年退疫,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了渠缕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,973評(píng)論 1 354
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡褒繁,死狀恐怖亦鳞,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情棒坏,我是刑警寧澤燕差,帶...
    沈念sama閱讀 36,631評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站坝冕,受9級(jí)特大地震影響徒探,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜喂窟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,315評(píng)論 3 336
  • 文/蒙蒙 一测暗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧磨澡,春花似錦碗啄、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,797評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至秩命,卻和暖如春尉共,著一層夾襖步出監(jiān)牢的瞬間褒傅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,926評(píng)論 1 275
  • 我被黑心中介騙來泰國打工袄友, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留殿托,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,431評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親冷蚂。 傳聞我的和親對(duì)象是個(gè)殘疾皇子介汹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,982評(píng)論 2 361