monza 1.1.3 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +0 -1
- data/README.md +2 -2
- data/lib/monza.rb +2 -0
- data/lib/monza/receipt.rb +8 -6
- data/lib/monza/renewal_info.rb +46 -0
- data/lib/monza/status_response.rb +141 -0
- data/lib/monza/transaction_receipt.rb +9 -1
- data/lib/monza/verification_response.rb +22 -2
- data/lib/monza/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9964737ff15c89dbd259e27531882476fefef34d
|
4
|
+
data.tar.gz: ac1a4b1288efd6afc7a00a0628e94307b0d3d67b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 71770d975dd49fbdbd779fe7ffea8e15eacba18b597fff750dc94b3bdb634de5d836a33d65139e924de7fcad9f8563e5faabe16736fb621ed4965bec34f690c3
|
7
|
+
data.tar.gz: 90fb4fd6e051f3a5d4feb8a49205e1a0a8eb98b39e30d8508e4c171f89f7ded633fa332708e4ad9357d7ed9fe9cefefd11898d56fb4b8d3b14a9104bf6e36e19
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
[![Build Status](https://travis-ci.org/gabrielgarza/monza.svg?branch=master)](https://travis-ci.org/gabrielgarza/monza)
|
2
2
|
|
3
|
-
![monza_asset](https://
|
3
|
+
![monza_asset](https://user-images.githubusercontent.com/1076706/30770801-8dc83b60-9fee-11e7-8532-c486dacaea07.png)
|
4
4
|
|
5
5
|
#### Monza is a ruby gem that makes In-App Purchase receipt and Auto-Renewable subscription validation easy.
|
6
6
|
|
@@ -33,7 +33,7 @@ options = { shared_secret: "your shared secret" }
|
|
33
33
|
response = Monza::Receipt.verify(data, options)
|
34
34
|
|
35
35
|
```
|
36
|
-
You can also pass in `
|
36
|
+
You can also pass in `exclude_old_transactions` with value `true` as an option in the options hash for [iOS7 style app receipts](https://developer.apple.com/library/content/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html#//apple_ref/doc/uid/TP40010573-CH104-SW3).
|
37
37
|
|
38
38
|
##### Useful Methods
|
39
39
|
```ruby
|
data/lib/monza.rb
CHANGED
data/lib/monza/receipt.rb
CHANGED
@@ -38,12 +38,14 @@ module Monza
|
|
38
38
|
@bundle_id = attributes['bundle_id']
|
39
39
|
@application_version = attributes['application_version']
|
40
40
|
@download_id = attributes['download_id']
|
41
|
-
|
42
|
-
@
|
43
|
-
@
|
44
|
-
@
|
45
|
-
@
|
46
|
-
@
|
41
|
+
|
42
|
+
@receipt_creation_date = DateTime.parse(attributes['receipt_creation_date']) rescue nil
|
43
|
+
@receipt_creation_date_ms = Time.zone.at(attributes['receipt_creation_date_ms'].to_i / 1000) rescue nil
|
44
|
+
@receipt_creation_date_pst = DateTime.parse(attributes['receipt_creation_date_pst'].gsub("America/Los_Angeles","PST")) rescue nil
|
45
|
+
@request_date = DateTime.parse(attributes['request_date']) rescue nil
|
46
|
+
@request_date_ms = Time.zone.at(attributes['request_date_ms'].to_i / 1000) rescue nil
|
47
|
+
@request_date_pst = DateTime.parse(attributes['request_date_pst'].gsub("America/Los_Angeles","PST")) rescue nil
|
48
|
+
|
47
49
|
@original_purchase_date = DateTime.parse(attributes['original_purchase_date'])
|
48
50
|
@original_purchase_date_ms = Time.zone.at(attributes['original_purchase_date_ms'].to_i / 1000)
|
49
51
|
@original_purchase_date_pst = DateTime.parse(attributes['original_purchase_date_pst'].gsub("America/Los_Angeles","PST"))
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Monza
|
2
|
+
class RenewalInfo
|
3
|
+
# Receipt Fields Documentation
|
4
|
+
# https://developer.apple.com/library/ios/releasenotes/General/ValidateAppStoreReceipt/Chapters/ReceiptFields.html#//apple_ref/doc/uid/TP40010573-CH106-SW1
|
5
|
+
|
6
|
+
attr_reader :expiration_intent
|
7
|
+
attr_reader :product_id
|
8
|
+
attr_reader :auto_renew_product_id
|
9
|
+
attr_reader :original_transaction_id
|
10
|
+
attr_reader :is_in_billing_retry_period
|
11
|
+
attr_reader :will_renew
|
12
|
+
|
13
|
+
def initialize(attributes)
|
14
|
+
|
15
|
+
@product_id = attributes['product_id']
|
16
|
+
@auto_renew_product_id = attributes['auto_renew_product_id']
|
17
|
+
@original_transaction_id = attributes['original_transaction_id']
|
18
|
+
|
19
|
+
if attributes['expiration_intent']
|
20
|
+
@expiration_intent = attributes['expiration_intent']
|
21
|
+
end
|
22
|
+
|
23
|
+
if attributes['is_in_billing_retry_period']
|
24
|
+
@is_in_billing_retry_period = attributes['is_in_billing_retry_period'].to_bool
|
25
|
+
end
|
26
|
+
|
27
|
+
if attributes['auto_renew_status']
|
28
|
+
@will_renew = attributes['auto_renew_status'].to_bool
|
29
|
+
end
|
30
|
+
end # end initialize
|
31
|
+
|
32
|
+
end # end class
|
33
|
+
end # end module
|
34
|
+
|
35
|
+
#
|
36
|
+
# Sample JSON Object
|
37
|
+
# "pending_renewal_info": [
|
38
|
+
# {
|
39
|
+
# "expiration_intent": "1",
|
40
|
+
# "auto_renew_product_id": "renew_product_id",
|
41
|
+
# "original_transaction_id": "1000000218147500",
|
42
|
+
# "is_in_billing_retry_period": "0",
|
43
|
+
# "product_id": "product_id",
|
44
|
+
# "auto_renew_status": "0"
|
45
|
+
# }
|
46
|
+
# ]
|
@@ -0,0 +1,141 @@
|
|
1
|
+
require 'time'
|
2
|
+
|
3
|
+
module Monza
|
4
|
+
class StatusResponse
|
5
|
+
# https://developer.apple.com/library/ios/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html
|
6
|
+
|
7
|
+
attr_reader :auto_renew_product_id
|
8
|
+
attr_reader :auto_renew_status
|
9
|
+
attr_reader :environment
|
10
|
+
attr_reader :latest_receipt
|
11
|
+
|
12
|
+
attr_reader :notification_type
|
13
|
+
attr_reader :password
|
14
|
+
|
15
|
+
attr_reader :bundle_id
|
16
|
+
attr_reader :bvrs
|
17
|
+
attr_reader :item_id
|
18
|
+
attr_reader :product_id
|
19
|
+
attr_reader :transaction_id
|
20
|
+
attr_reader :original_transaction_id
|
21
|
+
attr_reader :purchase_date
|
22
|
+
attr_reader :purchase_date_ms
|
23
|
+
attr_reader :purchase_date_pst
|
24
|
+
attr_reader :original_purchase_date
|
25
|
+
attr_reader :original_purchase_date_ms
|
26
|
+
attr_reader :original_purchase_date_pst
|
27
|
+
attr_reader :web_order_line_item_id
|
28
|
+
attr_reader :quantity
|
29
|
+
attr_reader :unique_identifier
|
30
|
+
attr_reader :unique_vendor_identifier
|
31
|
+
attr_reader :expires_date
|
32
|
+
attr_reader :expires_date_ms
|
33
|
+
attr_reader :expires_date_pst
|
34
|
+
attr_reader :is_in_intro_offer_period
|
35
|
+
attr_reader :is_trial_period
|
36
|
+
attr_reader :cancellation_date
|
37
|
+
|
38
|
+
attr_reader :original_json_response
|
39
|
+
|
40
|
+
def initialize(attributes)
|
41
|
+
@original_json_response = attributes
|
42
|
+
|
43
|
+
@auto_renew_product_id = attributes['auto_renew_product_id']
|
44
|
+
@auto_renew_status = attributes['auto_renew_status'].to_bool
|
45
|
+
@environment = attributes['environment']
|
46
|
+
@latest_receipt = attributes['latest_receipt']
|
47
|
+
@notification_type = attributes['notification_type']
|
48
|
+
|
49
|
+
if attributes['password']
|
50
|
+
@password = attributes['password']
|
51
|
+
end
|
52
|
+
|
53
|
+
# There'll only be one latest receipt info, so lets just flatten it out here
|
54
|
+
latest_receipt_info = attributes['latest_receipt_info']
|
55
|
+
|
56
|
+
# If the receipt is cancelled / expired, we'll get this instead
|
57
|
+
if latest_receipt_info.nil?
|
58
|
+
latest_receipt_info = attributes['latest_expired_receipt_info']
|
59
|
+
end
|
60
|
+
|
61
|
+
@bundle_id = latest_receipt_info['bid']
|
62
|
+
@bvrs = latest_receipt_info['bvrs'].to_i
|
63
|
+
@item_id = latest_receipt_info['item_id'].to_i
|
64
|
+
@product_id = latest_receipt_info['product_id']
|
65
|
+
@transaction_id = latest_receipt_info['transaction_id']
|
66
|
+
@original_transaction_id = latest_receipt_info['original_transaction_id']
|
67
|
+
@purchase_date = DateTime.parse(latest_receipt_info['purchase_date']) if latest_receipt_info['purchase_date']
|
68
|
+
@purchase_date_ms = Time.zone.at(latest_receipt_info['purchase_date_ms'].to_i / 1000)
|
69
|
+
@purchase_date_pst = date_for_pacific_time(latest_receipt_info['purchase_date_pst']) if latest_receipt_info['purchase_date_pst']
|
70
|
+
@original_purchase_date = DateTime.parse(latest_receipt_info['original_purchase_date']) if latest_receipt_info['original_purchase_date']
|
71
|
+
@original_purchase_date_ms = Time.zone.at(latest_receipt_info['original_purchase_date_ms'].to_i / 1000)
|
72
|
+
@original_purchase_date_pst = date_for_pacific_time(latest_receipt_info['original_purchase_date_pst']) if latest_receipt_info['original_purchase_date_pst']
|
73
|
+
@web_order_line_item_id = latest_receipt_info['web_order_line_item_id']
|
74
|
+
@quantity = latest_receipt_info['quantity'].to_i
|
75
|
+
|
76
|
+
@unique_identifier = latest_receipt_info['unique_identifier']
|
77
|
+
@unique_vendor_identifier = latest_receipt_info['unique_vendor_identifier']
|
78
|
+
|
79
|
+
# Here we coerce the field names to match what the receipt verify response returns
|
80
|
+
if latest_receipt_info['expires_date_formatted']
|
81
|
+
@expires_date = DateTime.parse(latest_receipt_info['expires_date_formatted'])
|
82
|
+
end
|
83
|
+
if latest_receipt_info['expires_date']
|
84
|
+
@expires_date_ms = Time.zone.at(latest_receipt_info['expires_date'].to_i / 1000)
|
85
|
+
end
|
86
|
+
if latest_receipt_info['expires_date_formatted_pst']
|
87
|
+
@expires_date_pst = date_for_pacific_time(latest_receipt_info['expires_date_formatted_pst'])
|
88
|
+
end
|
89
|
+
if latest_receipt_info['is_in_intro_offer_period']
|
90
|
+
@is_in_intro_offer_period = latest_receipt_info['is_in_intro_offer_period'].to_bool
|
91
|
+
end
|
92
|
+
if latest_receipt_info['is_trial_period']
|
93
|
+
@is_trial_period = latest_receipt_info['is_trial_period'].to_bool
|
94
|
+
end
|
95
|
+
if latest_receipt_info['cancellation_date']
|
96
|
+
@cancellation_date = DateTime.parse(latest_receipt_info['cancellation_date'])
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def date_for_pacific_time pt
|
101
|
+
# The field is labelled "PST" by apple, but the "America/Los_Angelus" time zone is actually Pacific Time,
|
102
|
+
# which is different, because it observes DST.
|
103
|
+
ActiveSupport::TimeZone["Pacific Time (US & Canada)"].parse(pt).to_datetime
|
104
|
+
end
|
105
|
+
|
106
|
+
end # class
|
107
|
+
end # module
|
108
|
+
|
109
|
+
# Sample JSON Response
|
110
|
+
#
|
111
|
+
# {
|
112
|
+
# "auto_renew_product_id": "product_id.quarterly",
|
113
|
+
# "auto_renew_status": "true",
|
114
|
+
# "environment": "Sandbox",
|
115
|
+
# "latest_receipt": "<base 64>",
|
116
|
+
# "latest_receipt_info": {
|
117
|
+
# "bid": "co.bundle.id",
|
118
|
+
# "bvrs": "1004",
|
119
|
+
# "expires_date": "1521161603000",
|
120
|
+
# "expires_date_formatted": "2018-03-16 00:53:23 Etc/GMT",
|
121
|
+
# "expires_date_formatted_pst": "2018-03-15 17:53:23 America/Los_Angeles",
|
122
|
+
# "is_in_intro_offer_period": "false",
|
123
|
+
# "is_trial_period": "false",
|
124
|
+
# "item_id": "1359908036",
|
125
|
+
# "original_purchase_date": "2018-03-15 23:23:05 Etc/GMT",
|
126
|
+
# "original_purchase_date_ms": "1521156185000",
|
127
|
+
# "original_purchase_date_pst": "2018-03-15 16:23:05 America/Los_Angeles",
|
128
|
+
# "original_transaction_id": "1000000383185294",
|
129
|
+
# "product_id": "product_id.quarterly",
|
130
|
+
# "purchase_date": "2018-03-16 00:38:23 Etc/GMT",
|
131
|
+
# "purchase_date_ms": "1521160703000",
|
132
|
+
# "purchase_date_pst": "2018-03-15 17:38:23 America/Los_Angeles",
|
133
|
+
# "quantity": "1",
|
134
|
+
# "transaction_id": "1000000383189543",
|
135
|
+
# "unique_identifier": "3a142176fee52ba64ddc3ba3b685786bd58cb4fe",
|
136
|
+
# "unique_vendor_identifier": "D8E8B1EB-7A35-4E88-A21C-584E4FEB6543",
|
137
|
+
# "web_order_line_item_id": "1000000038128465"
|
138
|
+
# },
|
139
|
+
# "notification_type": "RENEWAL",
|
140
|
+
# "password": "password"
|
141
|
+
# }
|
@@ -38,10 +38,18 @@ module Monza
|
|
38
38
|
@web_order_line_item_id = attributes['web_order_line_item_id']
|
39
39
|
|
40
40
|
if attributes['expires_date']
|
41
|
-
|
41
|
+
begin
|
42
|
+
# Attempt to parse as RFC 3339 timestamp (new-style receipt)
|
43
|
+
@expires_date = DateTime.parse(attributes['expires_date'])
|
44
|
+
rescue
|
45
|
+
# Attempt to parse as integer ms epoch (old-style receipt)
|
46
|
+
@expires_date = Time.at(attributes['expires_date'].to_i / 1000).to_datetime
|
47
|
+
end
|
42
48
|
end
|
43
49
|
if attributes['expires_date_ms']
|
44
50
|
@expires_date_ms = Time.zone.at(attributes['expires_date_ms'].to_i / 1000)
|
51
|
+
elsif attributes['expires_date']
|
52
|
+
@expires_date_ms = Time.zone.at(attributes['expires_date'].to_i / 1000)
|
45
53
|
end
|
46
54
|
if attributes['expires_date_pst']
|
47
55
|
@expires_date_pst = DateTime.parse(attributes['expires_date_pst'].gsub("America/Los_Angeles","PST"))
|
@@ -8,6 +8,7 @@ module Monza
|
|
8
8
|
attr_reader :environment
|
9
9
|
attr_reader :receipt
|
10
10
|
attr_reader :latest_receipt_info
|
11
|
+
attr_reader :renewal_info
|
11
12
|
attr_reader :latest_receipt
|
12
13
|
attr_reader :original_json_response
|
13
14
|
|
@@ -18,10 +19,19 @@ module Monza
|
|
18
19
|
@environment = attributes['environment']
|
19
20
|
@receipt = Receipt.new(attributes['receipt'])
|
20
21
|
@latest_receipt_info = []
|
21
|
-
|
22
|
+
case attributes['latest_receipt_info']
|
23
|
+
when Array
|
22
24
|
attributes['latest_receipt_info'].each do |transaction_receipt_attributes|
|
23
25
|
@latest_receipt_info << TransactionReceipt.new(transaction_receipt_attributes)
|
24
26
|
end
|
27
|
+
when Hash
|
28
|
+
@latest_receipt_info << TransactionReceipt.new(attributes['latest_receipt_info'])
|
29
|
+
end
|
30
|
+
@renewal_info = []
|
31
|
+
if attributes['pending_renewal_info']
|
32
|
+
attributes['pending_renewal_info'].each do |renewal_info_attributes|
|
33
|
+
@renewal_info << RenewalInfo.new(renewal_info_attributes)
|
34
|
+
end
|
25
35
|
end
|
26
36
|
@latest_receipt = attributes['latest_receipt']
|
27
37
|
end
|
@@ -133,5 +143,15 @@ end # module
|
|
133
143
|
# "is_trial_period": "true"
|
134
144
|
# }
|
135
145
|
# ],
|
136
|
-
# "latest_receipt": "base 64"
|
146
|
+
# "latest_receipt": "base 64",
|
147
|
+
# "pending_renewal_info": [
|
148
|
+
# {
|
149
|
+
# "expiration_intent": "1",
|
150
|
+
# "auto_renew_product_id": "renew_product_id",
|
151
|
+
# "original_transaction_id": "1000000218147500",
|
152
|
+
# "is_in_billing_retry_period": "0",
|
153
|
+
# "product_id": "product_id",
|
154
|
+
# "auto_renew_status": "0"
|
155
|
+
# }
|
156
|
+
# ]
|
137
157
|
# }
|
data/lib/monza/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: monza
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gabriel Garza
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-06-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
@@ -103,6 +103,8 @@ files:
|
|
103
103
|
- lib/monza/client.rb
|
104
104
|
- lib/monza/config.rb
|
105
105
|
- lib/monza/receipt.rb
|
106
|
+
- lib/monza/renewal_info.rb
|
107
|
+
- lib/monza/status_response.rb
|
106
108
|
- lib/monza/transaction_receipt.rb
|
107
109
|
- lib/monza/verification_response.rb
|
108
110
|
- lib/monza/version.rb
|