-
Notifications
You must be signed in to change notification settings - Fork 37
/
Copy pathInAppPurchaseReceipt.swift
180 lines (144 loc) · 6 KB
/
InAppPurchaseReceipt.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
//
// InAppPurchaseReceipt.swift
// Kvitto
//
// Created by Oliver Drobnik on 07/10/15.
// Copyright © 2015 Oliver Drobnik. All rights reserved.
//
import Foundation
import DTFoundation
/**
A purchase receipt for an In-App-Purchase.
*/
@objc(DTInAppPurchaseReceipt) @objcMembers public final class InAppPurchaseReceipt: NSObject
{
/**
The number of items purchased. This value corresponds to the quantity property of the SKPayment object stored in the transaction’s payment property.
*/
fileprivate(set) public var quantity: Int?
/**
ObjectiveC support of quantity. To retrieve the value specify `quantityNumber.integerValue`.
The number of items purchased. This value corresponds to the quantity property of the SKPayment object stored in the transaction’s payment property.
*/
public var quantityNumber : NSNumber? {
get {
return quantity as NSNumber?
}
}
/**
The product identifier of the item that was purchased. This value corresponds to the productIdentifier property of the `SKPayment` object stored in the transaction’s payment property.
*/
fileprivate(set) public var productIdentifier: String?
/**
The transaction identifier of the item that was purchased. This value corresponds to the transaction’s transactionIdentifier property.
*/
fileprivate(set) public var transactionIdentifier: String?
/**
For a transaction that restores a previous transaction, the transaction identifier of the original transaction. Otherwise, identical to the transaction identifier. This value corresponds to the original transaction’s transactionIdentifier property.
All receipts in a chain of renewals for an auto-renewable subscription have the same value for this field.
*/
fileprivate(set) public var originalTransactionIdentifier: String?
/**
The date and time that the item was purchased. This value corresponds to the transaction’s transactionDate property.
For a transaction that restores a previous transaction, the purchase date is the date of the restoration. Use Original Purchase Date to get the date of the original transaction.
In an auto-renewable subscription receipt, this is always the date when the subscription was purchased or renewed, regardless of whether the transaction has been restored.
*/
fileprivate(set) public var purchaseDate: Date?
/**
For a transaction that restores a previous transaction, the date of the original transaction. This value corresponds to the original transaction’s transactionDate property.
In an auto-renewable subscription receipt, this indicates the beginning of the subscription period, even if the subscription has been renewed.
*/
fileprivate(set) public var originalPurchaseDate: Date?
/**
The expiration date for the subscription. This key is only present for auto-renewable subscription receipts.
*/
fileprivate(set) public var subscriptionExpirationDate: Date?
/**
For a transaction that was canceled by Apple customer support, the time and date of the cancellation. Treat a canceled receipt the same as if no purchase had ever been made.
*/
fileprivate(set) public var cancellationDate: Date?
/**
For an auto-renewable subscription, whether or not it is in the introductory price period.
*/
fileprivate(set) public var isSubscriptionIntroductoryPricePeriod: Bool = false
/**
The primary key for identifying subscription purchases.
*/
fileprivate(set) public var webOrderLineItemIdentifier: Int?
/**
ObjectiveC support of webOrderLineItemIdentifier. Retrieve the value with `webOrderLineItemIdentifierNumber.integerValue`.
The primary key for identifying subscription purchases.
*/
public var webOrderLineItemIdentifierNumber : NSNumber? {
get {
return webOrderLineItemIdentifier as NSNumber?
}
}
/**
The designated initializer
*/
public init?(data: Data)
{
super.init()
do
{
_ = try parseData(data)
}
catch
{
return nil
}
}
// MARK: Parsing
fileprivate func parseData(_ data: Data) throws -> Bool
{
guard let rootArray = DTASN1Serialization.object(with: data) as? [[AnyObject]]
else
{
throw ReceiptParsingError.invalidRootObject
}
for item in rootArray
{
guard item.count == 3,
let type = (item[0] as? NSNumber)?.intValue,
let version = (item[1] as? NSNumber)?.intValue,
let data = item[2] as? Data
, version > 0
else
{
throw ReceiptParsingError.invalidRootObject
}
try processItem(type, data: data)
}
return true
}
fileprivate func processItem(_ type: Int, data: Data) throws
{
switch(type)
{
case 1701:
quantity = try _intFromData(data)
case 1702:
productIdentifier = try _stringFromData(data)
case 1703:
transactionIdentifier = try _stringFromData(data)
case 1704:
purchaseDate = try _dateFromData(data)
case 1705:
originalTransactionIdentifier = try _stringFromData(data)
case 1706:
originalPurchaseDate = try _dateFromData(data)
case 1708:
subscriptionExpirationDate = try _dateFromData(data)
case 1711:
webOrderLineItemIdentifier = try _intFromData(data)
case 1712:
cancellationDate = try _dateFromData(data)
case 1719:
isSubscriptionIntroductoryPricePeriod = try _intFromData(data) != 0
default:
// all other types are private
break;
}
}
}