itunes_receipt_validator 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 38e317636d5e42242456b34d6210cb329441ca5b
4
+ data.tar.gz: 0f98438cbc20775e4e04cc33f1064506e62b6950
5
+ SHA512:
6
+ metadata.gz: 0eb6b796ef6302d5cf953da5f4bb9640738ef0dfac5bc0953eb6847c263f34c9d9c10be325314fbd686d906aad7e4c47d4b5231ad327f3a335c2da232baedef9
7
+ data.tar.gz: dff34a3e35e7e68fe59eed49f54d46346c5a2f49178e5a8feb44009331a8949f40a1a44e2af685ff46ded97da8353eaa18166471133a1426ad349a2ebeac8f80
@@ -0,0 +1,73 @@
1
+ ##
2
+ # ItunesReceiptValidator
3
+ module ItunesReceiptValidator
4
+ ##
5
+ # ItunesReceiptValidator::Receipt
6
+ class Receipt
7
+ attr_reader :receipt, :options
8
+
9
+ def initialize(receipt, options = {})
10
+ @receipt = receipt
11
+ @options = options
12
+ local
13
+ end
14
+
15
+ def sandbox?
16
+ local.sandbox?
17
+ end
18
+
19
+ def production?
20
+ !sandbox?
21
+ end
22
+
23
+ def bundle_id
24
+ @bundle_id = local.receipt
25
+ .fetch(local.style == :unified ? :bundle_id : :bid)
26
+ end
27
+
28
+ def transactions
29
+ @transactions = TransactionsProxy.import(
30
+ local_transactions_source, self
31
+ )
32
+ end
33
+
34
+ def latest_transactions
35
+ @latest_transactions = TransactionsProxy.import(
36
+ remote_transactions_source, self
37
+ )
38
+ end
39
+
40
+ def latest_receipt
41
+ @latest_receipt = remote.json.fetch(:latest_receipt)
42
+ end
43
+
44
+ def local
45
+ @local ||= ItunesReceiptDecoder.new(receipt, expand_timestamps: true)
46
+ end
47
+
48
+ def remote
49
+ @remote ||= Remote.new(
50
+ receipt,
51
+ { sandbox: local.sandbox? }.merge(options)
52
+ )
53
+ end
54
+
55
+ private
56
+
57
+ def local_transactions_source
58
+ if local.style == :unified
59
+ local.receipt.fetch(:in_app)
60
+ else
61
+ [local.receipt]
62
+ end
63
+ end
64
+
65
+ def remote_transactions_source
66
+ if local.style == :unified
67
+ remote.json.fetch(:latest_receipt_info)
68
+ else
69
+ [remote.json.fetch(:latest_receipt_info)]
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,57 @@
1
+ ##
2
+ # ItunesReceiptValidator
3
+ module ItunesReceiptValidator
4
+ ##
5
+ # ItunesReceiptValidator::Receipt
6
+ class Remote
7
+ PRODUCTION_ENDPOINT = 'https://buy.itunes.apple.com/verifyReceipt'
8
+ SANDBOX_ENDPOINT = 'https://sandbox.itunes.apple.com/verifyReceipt'
9
+
10
+ attr_reader :receipt, :sandbox, :shared_secret, :options
11
+
12
+ def initialize(receipt, options = {})
13
+ @receipt = receipt
14
+ @sandbox = options.fetch(:sandbox)
15
+ @shared_secret = options.fetch(:shared_secret)
16
+ @options = options
17
+ end
18
+
19
+ def status
20
+ json[:status].to_i
21
+ end
22
+
23
+ def valid?
24
+ status == 0
25
+ end
26
+
27
+ def expired?
28
+ status == 21_006
29
+ end
30
+
31
+ def json
32
+ @json ||= JSON.parse(response.body, symbolize_names: true)
33
+ end
34
+
35
+ private
36
+
37
+ def response
38
+ @response ||= HTTParty.post(
39
+ sandbox ? SANDBOX_ENDPOINT : PRODUCTION_ENDPOINT,
40
+ options.merge(payload)
41
+ )
42
+ end
43
+
44
+ def payload
45
+ {
46
+ headers: {
47
+ 'Accept' => 'application/json',
48
+ 'Content-Type' => 'application/json'
49
+ },
50
+ body: {
51
+ 'password' => shared_secret,
52
+ 'receipt-data' => receipt
53
+ }.to_json
54
+ }
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,60 @@
1
+ ##
2
+ # ItunesReceiptValidator
3
+ module ItunesReceiptValidator
4
+ ##
5
+ # ItunesReceiptValidator::Transaction
6
+ class Transaction
7
+ attr_reader :id, :original_id, :product_id, :quantity, :first_purchased_at,
8
+ :purchased_at, :expires_at, :cancelled_at,
9
+ :web_order_line_item_id, :trial_period, :receipt
10
+
11
+ def initialize(hash, receipt)
12
+ normalize(hash)
13
+ @receipt = receipt
14
+ end
15
+
16
+ def expired?
17
+ receipt.remote.expired? || expires_at < Time.now.utc
18
+ end
19
+
20
+ def cancelled?
21
+ !cancelled_at.nil?
22
+ end
23
+
24
+ def auto_renewing?
25
+ !web_order_line_item_id.nil?
26
+ end
27
+
28
+ def trial_period?
29
+ trial_period
30
+ end
31
+
32
+ def latest
33
+ receipt.latest_transactions.where(original_id: original_id).last
34
+ end
35
+
36
+ private
37
+
38
+ def convert_ms(ms)
39
+ return nil if ms.nil?
40
+ Time.at(ms.to_f / 1000).utc
41
+ end
42
+
43
+ def normalize(hash)
44
+ @id = hash.fetch(:transaction_id)
45
+ @original_id = hash.fetch(:original_transaction_id)
46
+ @product_id = hash.fetch(:product_id)
47
+ @quantity = hash.fetch(:quantity)
48
+ @purchased_at = convert_ms hash.fetch(:purchase_date_ms)
49
+ @first_purchased_at = convert_ms hash.fetch(:original_purchase_date_ms)
50
+ @cancelled_at = convert_ms hash.fetch(:cancelled_date_ms, nil)
51
+ @web_order_line_item_id = hash.fetch(:web_order_line_item_id, nil)
52
+ @trial_period = hash.fetch(:is_trial_period, nil) == 'true'
53
+ if hash[:bid]
54
+ @expires_at = convert_ms hash.fetch(:expires_date, nil)
55
+ else
56
+ @expires_at = convert_ms hash.fetch(:expires_date_ms, nil)
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,20 @@
1
+ ##
2
+ # ItunesReceiptValidator
3
+ module ItunesReceiptValidator
4
+ ##
5
+ # ItunesReceiptValidator::TransactionsProxy
6
+ class TransactionsProxy < Array
7
+ include Enumerable
8
+
9
+ def self.import(array, receipt)
10
+ new array.map { |t| Transaction.new(t, receipt) }
11
+ .sort { |a, b| a.purchased_at <=> b.purchased_at }
12
+ end
13
+
14
+ def where(props)
15
+ select do |t|
16
+ !props.map { |key, val| t.send(key.to_sym) == val }.include?(false)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,7 @@
1
+ ##
2
+ # ItunesReceiptValidator
3
+ module ItunesReceiptValidator
4
+ ##
5
+ # Gem version
6
+ VERSION = '0.0.1'
7
+ end
@@ -0,0 +1,15 @@
1
+ require 'pp'
2
+ require 'httparty'
3
+ require 'itunes_receipt_decoder'
4
+ require 'itunes_receipt_validator/receipt'
5
+ require 'itunes_receipt_validator/remote'
6
+ require 'itunes_receipt_validator/transaction'
7
+ require 'itunes_receipt_validator/transactions_proxy'
8
+
9
+ ##
10
+ # ItunesReceiptValidator
11
+ module ItunesReceiptValidator
12
+ def self.new(receipt, options = {})
13
+ Receipt.new(receipt, options)
14
+ end
15
+ end
metadata ADDED
@@ -0,0 +1,177 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: itunes_receipt_validator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - mbaasy.com
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-11-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: httparty
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.13'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.13'
27
+ - !ruby/object:Gem::Dependency
28
+ name: itunes_receipt_decoder
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.4'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.4'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.3'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.3'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubygems-tasks
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.2'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.2'
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.10'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.10'
97
+ - !ruby/object:Gem::Dependency
98
+ name: codeclimate-test-reporter
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.4'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.4'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rubocop
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '0.33'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '0.33'
125
+ - !ruby/object:Gem::Dependency
126
+ name: webmock
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '1.22'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '1.22'
139
+ description: |2
140
+ Validate iTunes Transaction and Unified receipts
141
+ email: hello@mbaasy.com
142
+ executables: []
143
+ extensions: []
144
+ extra_rdoc_files: []
145
+ files:
146
+ - lib/itunes_receipt_validator.rb
147
+ - lib/itunes_receipt_validator/receipt.rb
148
+ - lib/itunes_receipt_validator/remote.rb
149
+ - lib/itunes_receipt_validator/transaction.rb
150
+ - lib/itunes_receipt_validator/transactions_proxy.rb
151
+ - lib/itunes_receipt_validator/version.rb
152
+ homepage: https://github.com/mbaasy/itunes_receipt_validator
153
+ licenses:
154
+ - MIT
155
+ metadata: {}
156
+ post_install_message:
157
+ rdoc_options: []
158
+ require_paths:
159
+ - lib
160
+ required_ruby_version: !ruby/object:Gem::Requirement
161
+ requirements:
162
+ - - ">="
163
+ - !ruby/object:Gem::Version
164
+ version: 2.0.0
165
+ required_rubygems_version: !ruby/object:Gem::Requirement
166
+ requirements:
167
+ - - ">="
168
+ - !ruby/object:Gem::Version
169
+ version: '0'
170
+ requirements: []
171
+ rubyforge_project:
172
+ rubygems_version: 2.4.6
173
+ signing_key:
174
+ specification_version: 4
175
+ summary: Validate iTunes OS X and iOS receipts
176
+ test_files: []
177
+ has_rdoc: