rm_vendor 0.2 → 0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/README.md +14 -16
- data/lib/Vendor.rb +1 -1
- data/lib/project/buy.rb +10 -9
- data/lib/project/info.rb +14 -8
- data/lib/project/product.rb +7 -19
- data/lib/project/products.rb +43 -0
- data/lib/project/receipt.rb +6 -22
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YjUyYzdhMWQ5OTY1OTdmOGEyYmJlODQzYjk5ZmRhNDlhN2I4OWIzOQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
YjFlNDA4NTkyMjA3ZDAxYThmZmZiNTBhNDlhOTk2ODZlOGJiOTkxZQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MjlkYWJiMDNmNjIwODVhYWIxM2ZlNjdhYWVkZWY4MjczZmJkNTUzOTZhMWMz
|
10
|
+
NGNkYzBhMWU5ZmRmYzVlZDI3MTQxODE2YjVhODY1NTNjNWExYThhZThmOThj
|
11
|
+
NTdkOTczY2U4ZWMxZTNmODhkMWYwNzY3OGNjYTMxMWZiMTg4NDQ=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NWJiY2EwZGMwNjJhYTI5NGM2MjIzZDIwNDE1NzY3ZjExNjZhNGEyNWRjOGZj
|
14
|
+
ZjQ5NjBmYTVkN2ZiMWJhNmE5NjM3ZTM2ZTczYmMxMTk0MjlkN2I5Y2I3ZDI5
|
15
|
+
Yjk1NzA3OGQ2NDkyOGE1Nzc3OTEzMTk1Mjc5NjkzYzVjNTI3MDY=
|
data/README.md
CHANGED
@@ -14,19 +14,18 @@ And then execute:
|
|
14
14
|
|
15
15
|
#### Initialize.
|
16
16
|
|
17
|
-
Initialize your
|
17
|
+
Initialize your products with your In App Purchase ID. Vendor will check if the product exists and return it's attributes:
|
18
18
|
|
19
19
|
```Ruby
|
20
|
-
@
|
21
|
-
|
22
|
-
p "Product response: #{product.response}"
|
20
|
+
@products = Vendor::Products.new([{:name => "first_item", :id => "com.your.first_item.id"}, {:name => "second_item", :id => "com.your.second_item.id"}]) do |products|
|
21
|
+
products.map{ |product| NSLog "Product exists?: #{product.success}" }
|
23
22
|
end
|
24
23
|
```
|
25
24
|
|
26
25
|
You don't need to pass along a block though. If you're sure your product exists, then you can just do this:
|
27
26
|
|
28
27
|
```Ruby
|
29
|
-
@
|
28
|
+
@products = Vendor::Products.new([{:name => "first_item", :id => "com.your.first_item.id"}, {:name => "second_item", :id => "com.your.second_item.id"}])
|
30
29
|
```
|
31
30
|
|
32
31
|
#### Get product info.
|
@@ -34,10 +33,10 @@ You don't need to pass along a block though. If you're sure your product exists,
|
|
34
33
|
After you've initialized your product, you get its information:
|
35
34
|
|
36
35
|
```Ruby
|
37
|
-
@product.price
|
38
|
-
@product.title
|
39
|
-
@product.description
|
40
|
-
@product.bought?
|
36
|
+
@product[:first_item].price
|
37
|
+
@product[:first_item].title
|
38
|
+
@product[:first_item].description
|
39
|
+
@product[:first_item].bought?
|
41
40
|
```
|
42
41
|
|
43
42
|
#### Purchase product.
|
@@ -45,7 +44,7 @@ After you've initialized your product, you get its information:
|
|
45
44
|
To purchase a product, simply do:
|
46
45
|
|
47
46
|
```Ruby
|
48
|
-
@product.purchase do |product|
|
47
|
+
@product[:first_item].purchase do |product|
|
49
48
|
p "Purchase successful: #{product.success}"
|
50
49
|
p "Purchase transaction: #{product.transaction}"
|
51
50
|
end
|
@@ -56,16 +55,15 @@ end
|
|
56
55
|
Vendor also works with subscriptions. To initialize a subscription:
|
57
56
|
|
58
57
|
```Ruby
|
59
|
-
@
|
60
|
-
|
61
|
-
p "Subscription response: #{subscription.response}"
|
58
|
+
@subscription_products = Vendor::Products.new([{:name => "subscription", :id => "com.your.subscription.id", :secret => "abcdefg12345", :subscription => true}]) do |subscriptions|
|
59
|
+
subscriptions.map{ |subscription| NSLog "Subscription exists?: #{subscription.success}" }
|
62
60
|
end
|
63
61
|
```
|
64
62
|
|
65
63
|
To purchase a subscription:
|
66
64
|
|
67
65
|
```Ruby
|
68
|
-
@subscription.purchase do |subscription|
|
66
|
+
@subscription_products[:subscription].purchase do |subscription|
|
69
67
|
p "Subscription successful: #{subscription.success}"
|
70
68
|
p "Subscription transaction: #{subscription.transaction}"
|
71
69
|
end
|
@@ -74,8 +72,8 @@ end
|
|
74
72
|
To see wether product is registered as a subscription and if user is currently subscribed:
|
75
73
|
|
76
74
|
```Ruby
|
77
|
-
@subscription.subscribed?
|
78
|
-
@subscription.subscription?
|
75
|
+
@subscription_products[:subscription].subscribed?
|
76
|
+
@subscription_products[:subscription].subscription?
|
79
77
|
```
|
80
78
|
|
81
79
|
## Example App.
|
data/lib/Vendor.rb
CHANGED
data/lib/project/buy.rb
CHANGED
@@ -2,8 +2,7 @@ module Vendor
|
|
2
2
|
class Buy
|
3
3
|
attr_accessor :params, :block, :request_operation_queue
|
4
4
|
|
5
|
-
def initialize
|
6
|
-
@params = params
|
5
|
+
def initialize
|
7
6
|
SKPaymentQueue.defaultQueue.addTransactionObserver(self)
|
8
7
|
end
|
9
8
|
|
@@ -14,12 +13,14 @@ module Vendor
|
|
14
13
|
|
15
14
|
|
16
15
|
# PUBLIC METHODS
|
17
|
-
def purchase(&block)
|
16
|
+
def purchase(params, &block)
|
17
|
+
@params = params
|
18
18
|
@block = block
|
19
19
|
SKPaymentQueue.defaultQueue.addPayment(SKPayment.paymentWithProductIdentifier(@params.id))
|
20
20
|
end
|
21
21
|
|
22
|
-
def restore(&block)
|
22
|
+
def restore(params, &block)
|
23
|
+
@params = params
|
23
24
|
@block = block
|
24
25
|
SKPaymentQueue.defaultQueue.restoreCompletedTransactions
|
25
26
|
end
|
@@ -29,13 +30,13 @@ module Vendor
|
|
29
30
|
# DELEGATE METHODS
|
30
31
|
def finishTransaction(transaction, success:success)
|
31
32
|
SKPaymentQueue.defaultQueue.finishTransaction(transaction)
|
32
|
-
|
33
|
-
|
33
|
+
return if @params.nil?
|
34
|
+
password = @params.secret=="no_secret" ? nil : @params.secret
|
35
|
+
|
34
36
|
if success
|
37
|
+
# Verify transaction receipt
|
35
38
|
Vendor::Receipt.new(transaction.transactionReceipt, @params) do |block|
|
36
|
-
|
37
|
-
valid_receipt = block.success && result_object.status.to_i == 0
|
38
|
-
|
39
|
+
valid_receipt = block[:success] && block[:object][:status]==0
|
39
40
|
@block.call({success: valid_receipt, transaction: transaction}.to_object) unless @block.blank?
|
40
41
|
end
|
41
42
|
else
|
data/lib/project/info.rb
CHANGED
@@ -12,7 +12,10 @@ module Vendor
|
|
12
12
|
productsRequest.start
|
13
13
|
|
14
14
|
# Update receipt if bought and subscription
|
15
|
-
|
15
|
+
receipt = NSUserDefaults["#{@params.id}.receipt"]
|
16
|
+
decoder = CocoaSecurityDecoder.new
|
17
|
+
latest_receipt_data = decoder.base64(receipt[:latest_receipt])
|
18
|
+
Vendor::Receipt.new(latest_receipt_data, @params) if bought? && subscription?
|
16
19
|
end
|
17
20
|
|
18
21
|
|
@@ -40,22 +43,26 @@ module Vendor
|
|
40
43
|
end
|
41
44
|
|
42
45
|
def subscribed?
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
+
# Return false if product is not a subscription or not bought
|
47
|
+
return false if !subscription? || !bought?
|
48
|
+
receipt = NSUserDefaults["#{@params.id}.receipt"]
|
49
|
+
return false if receipt[:status].to_i!=0
|
46
50
|
|
51
|
+
# Get the latest receipt
|
52
|
+
receipt = NSUserDefaults["#{@params.id}.receipt"]
|
47
53
|
decoder = CocoaSecurityDecoder.new
|
48
|
-
latest_receipt_data = decoder.base64(
|
54
|
+
latest_receipt_data = decoder.base64(receipt[:latest_receipt])
|
49
55
|
latest_receipt_plist = NSPropertyListSerialization.propertyListWithData(latest_receipt_data, options:NSPropertyListImmutable, format:nil, error:nil)
|
50
56
|
|
57
|
+
# Get the time for the latest receipt
|
51
58
|
purchase_info_data = decoder.base64(latest_receipt_plist.objectForKey("purchase-info"))
|
52
59
|
purchase_info_plist = NSPropertyListSerialization.propertyListWithData(purchase_info_data, options:NSPropertyListImmutable, format:nil, error:nil)
|
53
|
-
purchase_info_plist = NSPropertyListSerialization.propertyListWithData(purchase_info_data, options:NSPropertyListImmutable, format:nil, error:nil)
|
54
60
|
|
61
|
+
# Manipulate the time for the latest receipt
|
55
62
|
expires_date = purchase_info_plist.objectForKey("expires-date")
|
56
|
-
# ap "expires_date: #{expires_date}"
|
57
63
|
expires_calc = expires_date.to_i/1000
|
58
64
|
|
65
|
+
# Check if the latest receipt is too old
|
59
66
|
return expires_calc > NSDate.date.timeIntervalSince1970
|
60
67
|
end
|
61
68
|
|
@@ -79,6 +86,5 @@ module Vendor
|
|
79
86
|
def request(request, didFailWithError:error)
|
80
87
|
@block.call({success: false, error: error}.to_object)
|
81
88
|
end
|
82
|
-
|
83
89
|
end
|
84
90
|
end
|
data/lib/project/product.rb
CHANGED
@@ -2,20 +2,11 @@ module Vendor
|
|
2
2
|
class Product
|
3
3
|
attr_reader :params, :block, :exists, :info, :buy
|
4
4
|
|
5
|
-
def initialize(options
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
:subscription => false,
|
11
|
-
:price => "0.99",
|
12
|
-
:title => "No Title",
|
13
|
-
:desc => "No Description."
|
14
|
-
}
|
15
|
-
|
16
|
-
# Set global params and block
|
17
|
-
options = default_options.merge(options)
|
18
|
-
@params = options.to_object
|
5
|
+
def initialize(options, buy_class, &block)
|
6
|
+
|
7
|
+
# Set params and block
|
8
|
+
@buy = buy_class
|
9
|
+
@params = options
|
19
10
|
@block = block
|
20
11
|
|
21
12
|
# Raise argument error if id is not included
|
@@ -27,20 +18,17 @@ module Vendor
|
|
27
18
|
@exists = block.success
|
28
19
|
@block.call(block) unless @block.nil?
|
29
20
|
end
|
30
|
-
|
31
|
-
# Initialize purchase
|
32
|
-
@buy = Vendor::Buy.new(@params)
|
33
21
|
end
|
34
22
|
|
35
23
|
|
36
24
|
|
37
25
|
# PURCHASE METHODS
|
38
26
|
def purchase(&block)
|
39
|
-
@buy.purchase { |result| block.call(result)}
|
27
|
+
@buy.purchase(@params) { |result| block.call(result)}
|
40
28
|
end
|
41
29
|
|
42
30
|
def restore(&block)
|
43
|
-
@buy.restore { |result| block.call(result)}
|
31
|
+
@buy.restore(@params) { |result| block.call(result)}
|
44
32
|
end
|
45
33
|
|
46
34
|
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Vendor
|
2
|
+
class Products
|
3
|
+
attr_reader :block, :products
|
4
|
+
|
5
|
+
def [](key)
|
6
|
+
return @products.select{ |p| p.params[:name]==key.to_s }.first
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(products=[], &block)
|
10
|
+
# Set up products array
|
11
|
+
@products = []
|
12
|
+
|
13
|
+
# Set up block
|
14
|
+
@block = block
|
15
|
+
|
16
|
+
# Set up blocks for giving a callback
|
17
|
+
@blocks = []
|
18
|
+
|
19
|
+
# Initialize buy block
|
20
|
+
@buy = Vendor::Buy.new
|
21
|
+
|
22
|
+
# Set up info for products
|
23
|
+
products.each do |product|
|
24
|
+
# Set default options
|
25
|
+
default_options = {
|
26
|
+
:id => "no_id",
|
27
|
+
:secret => "no_secret",
|
28
|
+
:subscription => false,
|
29
|
+
:price => "0.99",
|
30
|
+
:title => "No Title",
|
31
|
+
:desc => "No Description."
|
32
|
+
}
|
33
|
+
options = default_options.merge(product)
|
34
|
+
|
35
|
+
# Update product and set exists variable
|
36
|
+
@products << Vendor::Product.new(options.to_object, @buy) do |block|
|
37
|
+
@blocks << block
|
38
|
+
@block.call(@blocks) unless @block.nil? || @blocks.count!=@products.count
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/project/receipt.rb
CHANGED
@@ -1,41 +1,25 @@
|
|
1
1
|
module Vendor
|
2
2
|
class Receipt
|
3
3
|
|
4
|
-
attr_reader :receipt_data, :params, :
|
4
|
+
attr_reader :receipt_data, :params, :block
|
5
5
|
|
6
6
|
def initialize(receipt_data, params, &block)
|
7
7
|
@receipt_data = receipt_data
|
8
8
|
@params = params
|
9
9
|
@block = block
|
10
|
-
@request_operation_queue = NSOperationQueue.alloc.init
|
11
10
|
|
12
11
|
check_receipt(receipt_data)
|
13
12
|
end
|
14
13
|
|
15
14
|
def check_receipt(receipt_data)
|
16
|
-
|
17
|
-
json_data = {"receipt-data" => encoder.base64(receipt_data)}
|
18
|
-
json_data[:password] = @params.secret if @params.secret != "no_secret"
|
19
|
-
server = App.development? ? "sandbox" : "buy"
|
20
|
-
base_url = NSURL.URLWithString("https://#{server}.itunes.apple.com")
|
15
|
+
password = @params.secret != "no_secret" ? @params.secret : nil
|
21
16
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
client.setParameterEncoding(AFJSONParameterEncoding)
|
27
|
-
AFJSONRequestOperation.addAcceptableContentTypes(NSSet.setWithObject("text/plain"))
|
28
|
-
|
29
|
-
request = client.requestWithMethod("POST", path:"verifyReceipt", parameters:json_data)
|
30
|
-
request_operation = client.HTTPRequestOperationWithRequest(request, success: lambda { |operation, response_object|
|
31
|
-
NSUserDefaults["#{@params.id}.receipt_data"] = receipt_data
|
32
|
-
NSUserDefaults["#{@params.id}.receipt"] = response_object
|
33
|
-
@block.call({success: true, object: response_object}.to_object) unless @block.blank?
|
34
|
-
}, failure: lambda {|operation, error|
|
17
|
+
CargoBay.sharedManager.verifyTransactionReceipt(receipt_data, password:password, success:lambda { |receipt|
|
18
|
+
NSUserDefaults["#{@params.id}.receipt"] = receipt
|
19
|
+
@block.call({success: true, object: receipt}.to_object) unless @block.blank?
|
20
|
+
}, failure: lambda { |error|
|
35
21
|
@block.call({success: false, error: error}.to_object) unless @block.blank?
|
36
22
|
})
|
37
|
-
|
38
|
-
@request_operation_queue.addOperation(request_operation)
|
39
23
|
end
|
40
24
|
|
41
25
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rm_vendor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.3'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Holger Sindbaek
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-01-
|
11
|
+
date: 2014-01-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -78,6 +78,7 @@ files:
|
|
78
78
|
- lib/project/buy.rb
|
79
79
|
- lib/project/info.rb
|
80
80
|
- lib/project/product.rb
|
81
|
+
- lib/project/products.rb
|
81
82
|
- lib/project/receipt.rb
|
82
83
|
- lib/Vendor.rb
|
83
84
|
homepage: https://github.com/holgersindbaek/Vendor
|