candy_check 0.1.0.pre → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.rubocop.yml +23 -0
- data/.ruby-version +1 -1
- data/.travis.yml +7 -8
- data/Guardfile +42 -0
- data/MIGRATION_GUIDE_0_2_0.md +141 -0
- data/README.md +86 -26
- data/Rakefile +1 -1
- data/candy_check.gemspec +33 -25
- data/lib/candy_check/app_store/receipt_collection.rb +5 -3
- data/lib/candy_check/app_store/subscription_verification.rb +25 -1
- data/lib/candy_check/app_store/verification.rb +1 -1
- data/lib/candy_check/app_store/verifier.rb +11 -11
- data/lib/candy_check/cli/app.rb +16 -33
- data/lib/candy_check/cli/commands/play_store.rb +12 -13
- data/lib/candy_check/play_store.rb +20 -10
- data/lib/candy_check/play_store/acknowledger.rb +19 -0
- data/lib/candy_check/play_store/android_publisher_service.rb +6 -0
- data/lib/candy_check/play_store/product_acknowledgements/acknowledgement.rb +45 -0
- data/lib/candy_check/play_store/product_acknowledgements/response.rb +24 -0
- data/lib/candy_check/play_store/product_purchases/product_purchase.rb +90 -0
- data/lib/candy_check/play_store/product_purchases/product_verification.rb +53 -0
- data/lib/candy_check/play_store/subscription_purchases/subscription_purchase.rb +154 -0
- data/lib/candy_check/play_store/subscription_purchases/subscription_verification.rb +55 -0
- data/lib/candy_check/play_store/verification_failure.rb +8 -6
- data/lib/candy_check/play_store/verifier.rb +24 -49
- data/lib/candy_check/utils/config.rb +5 -3
- data/lib/candy_check/version.rb +1 -1
- data/spec/app_store/receipt_collection_spec.rb +33 -0
- data/spec/app_store/subscription_verification_spec.rb +35 -2
- data/spec/app_store/verifier_spec.rb +24 -5
- data/spec/candy_check_spec.rb +2 -2
- data/spec/cli/commands/play_store_spec.rb +10 -43
- data/spec/fixtures/play_store/random_dummy_key.json +12 -0
- data/spec/fixtures/vcr_cassettes/play_store/product_acknowledgements/acknowledged.yml +105 -0
- data/spec/fixtures/vcr_cassettes/play_store/product_acknowledgements/already_acknowledged.yml +124 -0
- data/spec/fixtures/vcr_cassettes/play_store/product_acknowledgements/refunded.yml +122 -0
- data/spec/fixtures/vcr_cassettes/play_store/product_purchases/permission_denied.yml +196 -0
- data/spec/fixtures/vcr_cassettes/play_store/product_purchases/response_with_empty_body.yml +183 -0
- data/spec/fixtures/vcr_cassettes/play_store/product_purchases/valid_but_not_consumed.yml +122 -0
- data/spec/fixtures/vcr_cassettes/play_store/subscription_purchases/permission_denied.yml +196 -0
- data/spec/fixtures/vcr_cassettes/play_store/subscription_purchases/valid_but_expired.yml +127 -0
- data/spec/play_store/acknowledger_spec.rb +48 -0
- data/spec/play_store/product_acknowledgements/acknowledgement_spec.rb +54 -0
- data/spec/play_store/product_acknowledgements/response_spec.rb +66 -0
- data/spec/play_store/product_purchases/product_purchase_spec.rb +110 -0
- data/spec/play_store/product_purchases/product_verification_spec.rb +49 -0
- data/spec/play_store/subscription_purchases/subscription_purchase_spec.rb +237 -0
- data/spec/play_store/subscription_purchases/subscription_verification_spec.rb +65 -0
- data/spec/play_store/verification_failure_spec.rb +18 -18
- data/spec/play_store/verifier_spec.rb +32 -96
- data/spec/spec_helper.rb +32 -10
- metadata +175 -75
- data/lib/candy_check/play_store/client.rb +0 -126
- data/lib/candy_check/play_store/config.rb +0 -51
- data/lib/candy_check/play_store/discovery_repository.rb +0 -33
- data/lib/candy_check/play_store/receipt.rb +0 -81
- data/lib/candy_check/play_store/subscription.rb +0 -138
- data/lib/candy_check/play_store/subscription_verification.rb +0 -30
- data/lib/candy_check/play_store/verification.rb +0 -48
- data/spec/fixtures/api_cache.dump +0 -1
- data/spec/fixtures/play_store/api_cache.dump +0 -1
- data/spec/fixtures/play_store/auth_failure.txt +0 -18
- data/spec/fixtures/play_store/auth_success.txt +0 -20
- data/spec/fixtures/play_store/discovery.txt +0 -2841
- data/spec/fixtures/play_store/dummy.p12 +0 -0
- data/spec/fixtures/play_store/empty.txt +0 -17
- data/spec/fixtures/play_store/products_failure.txt +0 -29
- data/spec/fixtures/play_store/products_success.txt +0 -22
- data/spec/play_store/client_spec.rb +0 -125
- data/spec/play_store/config_spec.rb +0 -96
- data/spec/play_store/discovery_respository_spec.rb +0 -31
- data/spec/play_store/receipt_spec.rb +0 -88
- data/spec/play_store/subscription_spec.rb +0 -138
- data/spec/play_store/subscription_verification_spec.rb +0 -98
- data/spec/play_store/verification_spec.rb +0 -82
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 417a8850353b9726251dcae68864b46f77d30de0e73db9488c68c52282a90e70
|
4
|
+
data.tar.gz: 5dbcba7f14f6c81d73a0baa7554c01f0e53cb7167e0ff22029a6ddd8deac6b23
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6777436feed72baacb24e07634fa921f9723c37f207f8c9ab373aa68b007f326236877ecff04a32001ee046c0c5200d033218939e59b5af429e2b65d3e15504c
|
7
|
+
data.tar.gz: bc28443c9277dbad870f04fcc85a4c92705c7ce72d4a88b9a4ab9c882a5e90e7281a3ef13a77e1f12866e0c77b3896d8ea6be542184041a16d3eb15d16758917
|
data/.rubocop.yml
CHANGED
@@ -5,3 +5,26 @@ AllCops:
|
|
5
5
|
- 'vendor/**/*'
|
6
6
|
Style/Documentation:
|
7
7
|
Enabled: false
|
8
|
+
Style/FrozenStringLiteralComment:
|
9
|
+
Enabled: false
|
10
|
+
Style/NumericPredicate:
|
11
|
+
Enabled: false
|
12
|
+
Lint/UnifiedInteger:
|
13
|
+
Enabled: false
|
14
|
+
Style/PercentLiteralDelimiters:
|
15
|
+
PreferredDelimiters:
|
16
|
+
default: ()
|
17
|
+
"%i": ()
|
18
|
+
"%w": ()
|
19
|
+
Metrics/BlockLength:
|
20
|
+
Exclude:
|
21
|
+
- 'spec/**/*'
|
22
|
+
Security/MarshalLoad:
|
23
|
+
Exclude:
|
24
|
+
- 'lib/candy_check/play_store/discovery_repository.rb'
|
25
|
+
Style/DateTime:
|
26
|
+
Enabled: false
|
27
|
+
Style/Encoding:
|
28
|
+
Enabled: false
|
29
|
+
Style/ExpandPathArguments:
|
30
|
+
Enabled: false
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.7.1
|
data/.travis.yml
CHANGED
@@ -2,18 +2,17 @@ language: ruby
|
|
2
2
|
sudo: false
|
3
3
|
cache: bundler
|
4
4
|
rvm:
|
5
|
-
-
|
6
|
-
-
|
7
|
-
-
|
8
|
-
-
|
9
|
-
- '2.0'
|
5
|
+
- 2.6.5
|
6
|
+
- 2.5.7
|
7
|
+
- 2.4.9
|
8
|
+
- jruby-9.2.9.0
|
10
9
|
- ruby-head
|
11
|
-
- rbx-2
|
12
|
-
- jruby-20mode
|
13
|
-
- jruby-21mode
|
14
10
|
- jruby-head
|
15
11
|
matrix:
|
16
12
|
allow_failures:
|
17
13
|
- rvm: ruby-head
|
18
14
|
- rvm: jruby-head
|
19
15
|
fast_finish: true
|
16
|
+
before_install:
|
17
|
+
- gem update --system
|
18
|
+
- gem install bundler -v 2.0.2
|
data/Guardfile
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
## Uncomment and set this to only include directories you want to watch
|
5
|
+
directories %w(lib spec) \
|
6
|
+
.select{|d| Dir.exist?(d) ? d : UI.warning("Directory #{d} does not exist")}
|
7
|
+
|
8
|
+
## Note: if you are using the `directories` clause above and you are not
|
9
|
+
## watching the project directory ('.'), then you will want to move
|
10
|
+
## the Guardfile to a watched dir and symlink it back, e.g.
|
11
|
+
#
|
12
|
+
# $ mkdir config
|
13
|
+
# $ mv Guardfile config/
|
14
|
+
# $ ln -s config/Guardfile .
|
15
|
+
#
|
16
|
+
# and, you'll have to watch "config/Guardfile" instead of "Guardfile"
|
17
|
+
|
18
|
+
guard :minitest do
|
19
|
+
# with Minitest::Unit
|
20
|
+
# watch(%r{^test/(.*)\/?test_(.*)\.rb$})
|
21
|
+
# watch(%r{^lib/(.*/)?([^/]+)\.rb$}) { |m| "test/#{m[1]}test_#{m[2]}.rb" }
|
22
|
+
# watch(%r{^test/test_helper\.rb$}) { 'test' }
|
23
|
+
|
24
|
+
# with Minitest::Spec
|
25
|
+
watch(%r{^spec/(.*)_spec\.rb$})
|
26
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
27
|
+
watch(%r{^spec/spec_helper\.rb$}) { 'spec' }
|
28
|
+
|
29
|
+
# Rails 4
|
30
|
+
# watch(%r{^app/(.+)\.rb$}) { |m| "test/#{m[1]}_test.rb" }
|
31
|
+
# watch(%r{^app/controllers/application_controller\.rb$}) { 'test/controllers' }
|
32
|
+
# watch(%r{^app/controllers/(.+)_controller\.rb$}) { |m| "test/integration/#{m[1]}_test.rb" }
|
33
|
+
# watch(%r{^app/views/(.+)_mailer/.+}) { |m| "test/mailers/#{m[1]}_mailer_test.rb" }
|
34
|
+
# watch(%r{^lib/(.+)\.rb$}) { |m| "test/lib/#{m[1]}_test.rb" }
|
35
|
+
# watch(%r{^test/.+_test\.rb$})
|
36
|
+
# watch(%r{^test/test_helper\.rb$}) { 'test' }
|
37
|
+
|
38
|
+
# Rails < 4
|
39
|
+
# watch(%r{^app/controllers/(.*)\.rb$}) { |m| "test/functional/#{m[1]}_test.rb" }
|
40
|
+
# watch(%r{^app/helpers/(.*)\.rb$}) { |m| "test/helpers/#{m[1]}_test.rb" }
|
41
|
+
# watch(%r{^app/models/(.*)\.rb$}) { |m| "test/unit/#{m[1]}_test.rb" }
|
42
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
# Migration Guide from v0.1.x to v0.2.0
|
2
|
+
|
3
|
+
Due to changes in the PlayStore API, Candy Check needed to introduce some breaking changes in version `0.2.0`.
|
4
|
+
|
5
|
+
To adapt your old implementation to these changes, follow the steps below:
|
6
|
+
|
7
|
+
## Authorization
|
8
|
+
|
9
|
+
First we have to change, how our verifier authenticates against the Google API.
|
10
|
+
|
11
|
+
Change code like this
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
# < v0.2.0
|
15
|
+
config = CandyCheck::PlayStore::Config.new(
|
16
|
+
application_name: 'YourApplication',
|
17
|
+
application_version: '1.0',
|
18
|
+
issuer: 'abcdefg@developer.gserviceaccount.com',
|
19
|
+
key_file: 'local/google.p12',
|
20
|
+
key_secret: 'notasecret',
|
21
|
+
cache_file: 'tmp/candy_check_play_store_cache'
|
22
|
+
)
|
23
|
+
verifier = CandyCheck::PlayStore::Verifier.new(config)
|
24
|
+
verifier.boot!
|
25
|
+
```
|
26
|
+
|
27
|
+
to
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
# v0.2.0
|
31
|
+
authorization = CandyCheck::PlayStore.authorization("/path/to/key.json")
|
32
|
+
verifier = CandyCheck::PlayStore::Verifier.new(authorization: authorization)
|
33
|
+
```
|
34
|
+
|
35
|
+
If you're not sure how to get a `.json` key file, follow this part of the [`README`](/README.md#getting-the-json-key-file).
|
36
|
+
|
37
|
+
If you need other means of authentication follow this part of the [`README`](/README.md#building-an-authorization-object).
|
38
|
+
|
39
|
+
## Verifying Purchases
|
40
|
+
|
41
|
+
To be more descriptive and consistent with the PlayStore API, the verifier got a new signature and return values have been adapted accordingly.
|
42
|
+
|
43
|
+
### Verifying Product Purchases
|
44
|
+
|
45
|
+
Change all occurences of
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
# < v0.2.0
|
49
|
+
verifier.verify("my-package-name", "my product id", "my token")
|
50
|
+
# => Receipt or VerificationFailure
|
51
|
+
```
|
52
|
+
|
53
|
+
to
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
# v0.2.0
|
57
|
+
verifier.verify_product_purchase(
|
58
|
+
package_name: "my-package-name",
|
59
|
+
product_id: "my product id",
|
60
|
+
token: "my token"
|
61
|
+
)
|
62
|
+
# => ProductPurchase or VerificationFailure
|
63
|
+
```
|
64
|
+
|
65
|
+
*NOTE:* Take a closer look at the possible return values: `CandyCheck::PlayStore::Receipt` was moved to `CandyCheck::PlayStore::ProductPurchases::ProductPurchase`. In case you're matching at the class name of the result, please adapt your code accordingly.
|
66
|
+
|
67
|
+
#### Accessing Raw ProductPurchase Attributes
|
68
|
+
|
69
|
+
CandyCheck `< 0.2.0` provided the raw `ProductPurchase` attributes given by the PlayStore API like this:
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
# < v0.2.0
|
73
|
+
result = verifier.verify("my-package-name", "my product id", "my token")
|
74
|
+
result.attributes
|
75
|
+
# => Hash
|
76
|
+
```
|
77
|
+
|
78
|
+
To get the same behaviour in CandyCheck `0.2.0`, change the code above to:
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
# v0.2.0
|
82
|
+
result = verifier.verify_product_purchase(
|
83
|
+
package_name: "my-package-name",
|
84
|
+
product_id: "my product id",
|
85
|
+
token: "my token"
|
86
|
+
)
|
87
|
+
result.product_purchase.to_h
|
88
|
+
# => Hash
|
89
|
+
```
|
90
|
+
|
91
|
+
The hash key access must be changed from strings in `camelCase` to symbols in `snake_case`:
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
# < 0.2.0
|
95
|
+
result.attributes["purchaseState"]
|
96
|
+
|
97
|
+
# 0.2.0
|
98
|
+
result.product_purchase.to_h[:purchase_state]
|
99
|
+
```
|
100
|
+
|
101
|
+
## Verifying Subscription Purchases
|
102
|
+
|
103
|
+
Change all occurences of
|
104
|
+
|
105
|
+
```ruby
|
106
|
+
# < v0.2.0
|
107
|
+
verifier.verify_subscription("my-package-name", "my-subscription-id", "my-token")
|
108
|
+
# => Subscription or VerificationFailure
|
109
|
+
```
|
110
|
+
|
111
|
+
to
|
112
|
+
|
113
|
+
```ruby
|
114
|
+
# v0.2.0
|
115
|
+
verifier.verify_subscription_purchase(
|
116
|
+
package_name: "my-package-name",
|
117
|
+
subscription_id: "my-subscription-id",
|
118
|
+
token: "my-token"
|
119
|
+
)
|
120
|
+
# => SubscriptionPurchase or VerificationFailure
|
121
|
+
```
|
122
|
+
|
123
|
+
*NOTE:* Again take a closer look at the possible return values: `CandyCheck::PlayStore::Subscription` was moved to `CandyCheck::PlayStore::SubscriptionPurchases::SubscriptionPurchase`. In case you're matching at the class name of the result, please adapt your code accordingly.
|
124
|
+
|
125
|
+
## Using the CLI
|
126
|
+
|
127
|
+
The way the CandyCheck CLI gets used, needed to be changed too.
|
128
|
+
|
129
|
+
The old PlayStore command:
|
130
|
+
|
131
|
+
```bash
|
132
|
+
# < v0.2.0
|
133
|
+
$ candy_check play_store PACKAGE PRODUCT_ID TOKEN --issuer=ISSUER --key-file=KEY_FILE
|
134
|
+
```
|
135
|
+
|
136
|
+
was changed to
|
137
|
+
|
138
|
+
```bash
|
139
|
+
# v0.2.0
|
140
|
+
$ candy_check play_store PACKAGE PRODUCT_ID TOKEN --json-key-file=/path/to/key.json
|
141
|
+
```
|
data/README.md
CHANGED
@@ -4,7 +4,6 @@
|
|
4
4
|
[](https://travis-ci.org/jnbt/candy_check)
|
5
5
|
[](https://coveralls.io/r/jnbt/candy_check?branch=master)
|
6
6
|
[](https://codeclimate.com/github/jnbt/candy_check)
|
7
|
-
[](https://gemnasium.com/jnbt/candy_check)
|
8
7
|
[](http://inch-ci.org/github/jnbt/candy_check)
|
9
8
|
[](http://www.rubydoc.info/github/jnbt/candy_check/master)
|
10
9
|
|
@@ -43,12 +42,7 @@ called "[service account](https://developers.google.com/accounts/docs/OAuth2Serv
|
|
43
42
|
new account by yourself, export the generated certificate file and grant the correct permissions to the account for
|
44
43
|
your app using the [Google Developer Console](https://console.developers.google.com).
|
45
44
|
|
46
|
-
|
47
|
-
which suggest to use a locally cached service discovery. If you don't omit the `cache_file` configuration this is done
|
48
|
-
automatically.
|
49
|
-
|
50
|
-
If you have set up the Android app correctly you should get a [`purchaseToken`](http://developer.android.com/google/play/billing/billing_reference.html#getBuyIntent) per purchased item. You should use this string in combination with `packageName` and `productId`
|
51
|
-
to verify the purchase.
|
45
|
+
If you have set up the Android app correctly you should get a [`purchaseToken`](http://developer.android.com/google/play/billing/billing_reference.html#getBuyIntent) per purchased item. You should use this string in combination with `packageName` and `productId` to verify the purchase.
|
52
46
|
|
53
47
|
## Usage
|
54
48
|
|
@@ -81,42 +75,108 @@ For **subscription verification**, Apple also returns a list of the user's purch
|
|
81
75
|
verifier.verify_subscription(your_receipt_data, your_secret) # => ReceiptCollection or VerificationFailure
|
82
76
|
```
|
83
77
|
|
78
|
+
If you want to restrict the subscription verification to some specific products, pass their ids as an array:
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
# ... create your verifier as above
|
82
|
+
product_ids = ['sk_product_id_1', 'sk_product_id_2'...]
|
83
|
+
verifier.verify_subscription(your_receipt_data, your_secret, product_ids) # => ReceiptCollection or VerificationFailure
|
84
|
+
```
|
85
|
+
|
84
86
|
Please see the class documentation for [`CandyCheck::AppStore::ReceiptCollection`](http://www.rubydoc.info/github/jnbt/candy_check/master/CandyCheck/AppStore/ReceiptCollection) for further details.
|
85
87
|
|
86
88
|
### PlayStore
|
87
89
|
|
88
|
-
|
89
|
-
|
90
|
-
|
90
|
+
> :warning: Version `0.2.0` of `CandyCheck` introduced some breaking changes to the PlayStore functionality to adapt to changes in the Google API. If you're upgrading from a `CandyCheck` version `< 0.2.0` see the [migration guide](/MIGRATION_GUIDE_0_2_0.md) for more.
|
91
|
+
|
92
|
+
#### Authorization
|
93
|
+
|
94
|
+
##### Getting the JSON Key File
|
95
|
+
|
96
|
+
First we have to get a `.json` key file, that gives access to the Google API.
|
97
|
+
|
98
|
+
This `.json` key file can be generated under the following URL (make sure to adapt the `project=my-project-name` parameter accordingly):
|
99
|
+
|
100
|
+
[https://console.developers.google.com/apis/credentials/serviceaccountkey?project=my-project-name](https://console.developers.google.com/apis/credentials/serviceaccountkey?project=my-project-name)
|
101
|
+
|
102
|
+
##### Building an Authorization Object
|
103
|
+
|
104
|
+
With the `.json` key file downloaded, we can build an authorization object:
|
91
105
|
|
92
106
|
```ruby
|
93
|
-
|
94
|
-
application_name: 'YourApplication',
|
95
|
-
application_version: '1.0',
|
96
|
-
issuer: 'abcdefg@developer.gserviceaccount.com',
|
97
|
-
key_file: 'local/google.p12',
|
98
|
-
key_secret: 'notasecret',
|
99
|
-
cache_file: 'tmp/candy_check_play_store_cache'
|
100
|
-
)
|
101
|
-
verifier = CandyCheck::PlayStore::Verifier.new(config)
|
102
|
-
verifier.boot!
|
107
|
+
authorization = CandyCheck::PlayStore.authorization("/path/to/key.json")
|
103
108
|
```
|
104
109
|
|
105
|
-
|
110
|
+
> **Note:** `CandyCheck` provides the `CandyCheck::PlayStore.authorization` method as convenience to build an authorization object. In case you need more control over your authorization object, refer to the [`google-auth-library-ruby`](https://github.com/googleapis/google-auth-library-ruby) docs, which describes building authorization objects in detail.
|
111
|
+
|
112
|
+
##### Building a verifier
|
113
|
+
|
114
|
+
With the `authorization` object in place, we can build a verifier:
|
106
115
|
|
107
116
|
```ruby
|
108
|
-
verifier.
|
117
|
+
verifier = CandyCheck::PlayStore::Verifier.new(authorization: authorization)
|
109
118
|
```
|
110
119
|
|
111
|
-
|
120
|
+
> **Note:** If you need to verify against multiple Google Service Accounts, just instantiate a new verifier with another authorization object that got build with a different `.json` key file.
|
121
|
+
|
122
|
+
#### Verifying product purchases
|
123
|
+
|
124
|
+
This `verifier` can be used to verify product purchases in the PlayStore, all you need to do is to pass the `package_name`, `product_id` and `token` of the product purchase you want to verify:
|
125
|
+
|
126
|
+
```ruby
|
127
|
+
result = verifier.verify_product_purchase(
|
128
|
+
package_name: "my-package-name",
|
129
|
+
product_id: "my product id",
|
130
|
+
token: "my token"
|
131
|
+
)
|
132
|
+
# => ProductPurchase or VerificationFailure
|
133
|
+
```
|
134
|
+
|
135
|
+
On success this will return an instance of `CandyCheck::Playstore::ProductPurchases::ProductPurchase`, which is a wrapper for the raw [google-api-ruby-client](https://github.com/googleapis/google-api-ruby-client) data, but additionally provides some handy convenience methods.
|
136
|
+
Please see the class documentations [`CandyCheck::PlayStore::ProductPurchases::ProductPurchase`](http://www.rubydoc.info/github/jnbt/candy_check/master/CandyCheck/PlayStore/ProductPurchases/ProductPurchase) and [`CandyCheck::PlayStore::VerificationFailure`](http://www.rubydoc.info/github/jnbt/candy_check/master/CandyCheck/PlayStore/VerificationFailure) for further details about the responses.
|
137
|
+
|
138
|
+
#### Verifying subscriptions
|
112
139
|
|
113
140
|
In order to **verify a subscription** from the Play Store, do the following:
|
114
141
|
|
115
142
|
```ruby
|
116
|
-
verifier.
|
143
|
+
result = verifier.verify_subscription_purchase(
|
144
|
+
package_name: "my-package-name",
|
145
|
+
subscription_id: "my-subscription-id",
|
146
|
+
token: "my-token"
|
147
|
+
)
|
148
|
+
# => SubscriptionPurchase or VerificationFailure
|
117
149
|
```
|
118
150
|
|
119
|
-
Please see documenation for [`CandyCheck::PlayStore::
|
151
|
+
Please see documenation for [`CandyCheck::PlayStore::SubscriptionPurchases::SubscriptionPurchase`](http://www.rubydoc.info/github/jnbt/candy_check/master/CandyCheck/PlayStore/SubscriptionPurchases/SubscriptionPurchase) for further details.
|
152
|
+
|
153
|
+
|
154
|
+
##### Building an acknowledger
|
155
|
+
|
156
|
+
With the `authorization` object in place, we can build an acknowledger:
|
157
|
+
|
158
|
+
```ruby
|
159
|
+
acknowledger = CandyCheck::PlayStore::Acknowledger.new(authorization: authorization)
|
160
|
+
```
|
161
|
+
|
162
|
+
> **Note:** If you need to acknowledge against multiple Google Service Accounts, just instantiate a new acknowledger with another authorization object that got build with a different `.json` key file.
|
163
|
+
|
164
|
+
#### Acknowledging the purchase
|
165
|
+
Google Play purchases if not acknowledged are automatically refunded. The acknowledgement can be done client-side or server-side. If server-side validation is being used we recommend to proceed with the acknowledgement afterwards, since it is the only save way to ensure the users received what they have paid for.
|
166
|
+
|
167
|
+
```ruby
|
168
|
+
result = acknowledger.acknowledge_product_purchase(
|
169
|
+
package_name: "my-package-name",
|
170
|
+
product_id: "my-subscription-id",
|
171
|
+
token: "my-token"
|
172
|
+
)
|
173
|
+
# => ProductAcknowledgements::Response
|
174
|
+
```
|
175
|
+
|
176
|
+
The acknowledger response has 2 methods:
|
177
|
+
|
178
|
+
- `#acknowledged?` returns a boolean. It returns true only if it has been acknowledged at this moment (that's Google Play behaviour).
|
179
|
+
- `#error` returns a hash with `status_code` and `body` keys.
|
120
180
|
|
121
181
|
## CLI
|
122
182
|
|
@@ -142,7 +202,7 @@ For the PlayStore you need to specify at least the issuer, the key file, your pa
|
|
142
202
|
purchase token:
|
143
203
|
|
144
204
|
```bash
|
145
|
-
$ candy_check play_store
|
205
|
+
$ candy_check play_store PACKAGE_NAME PRODUCT_ID TOKEN --json-key-file=/path/to/key.json
|
146
206
|
```
|
147
207
|
|
148
208
|
See all options:
|
data/Rakefile
CHANGED
data/candy_check.gemspec
CHANGED
@@ -1,34 +1,42 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
|
2
|
+
|
3
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
5
|
+
require "candy_check/version"
|
5
6
|
|
6
7
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name
|
8
|
-
spec.version
|
9
|
-
spec.authors
|
10
|
-
spec.email
|
11
|
-
spec.summary
|
12
|
-
spec.homepage
|
13
|
-
spec.license
|
8
|
+
spec.name = "candy_check"
|
9
|
+
spec.version = CandyCheck::VERSION
|
10
|
+
spec.authors = ["Jonas Thiel", "Christoph Weegen"]
|
11
|
+
spec.email = ["jonas@thiel.io"]
|
12
|
+
spec.summary = "Check and verify in-app receipts"
|
13
|
+
spec.homepage = "https://github.com/jnbt/candy_check"
|
14
|
+
spec.license = "MIT"
|
14
15
|
|
15
|
-
spec.files
|
16
|
-
spec.executables
|
17
|
-
spec.test_files
|
18
|
-
spec.require_paths = [
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
19
20
|
|
20
|
-
spec.required_ruby_version = Gem::Requirement.new(
|
21
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.4")
|
21
22
|
|
22
|
-
spec.add_dependency
|
23
|
-
spec.add_dependency
|
24
|
-
spec.add_dependency
|
23
|
+
spec.add_dependency "google-api-client", "~> 0.43.0"
|
24
|
+
spec.add_dependency "multi_json", "~> 1.10"
|
25
|
+
spec.add_dependency "thor", "~> 0.19"
|
25
26
|
|
26
|
-
spec.add_development_dependency
|
27
|
-
spec.add_development_dependency
|
28
|
-
spec.add_development_dependency
|
29
|
-
spec.add_development_dependency
|
30
|
-
spec.add_development_dependency
|
31
|
-
spec.add_development_dependency
|
32
|
-
spec.add_development_dependency
|
33
|
-
spec.add_development_dependency
|
27
|
+
spec.add_development_dependency "bundler", "~> 2.0"
|
28
|
+
spec.add_development_dependency "coveralls", "~> 0.8"
|
29
|
+
spec.add_development_dependency "inch", "~> 0.7"
|
30
|
+
spec.add_development_dependency "minitest", "~> 5.10"
|
31
|
+
spec.add_development_dependency "minitest-around", "~> 0.4"
|
32
|
+
spec.add_development_dependency "minitest-focus"
|
33
|
+
spec.add_development_dependency "rake", "~> 12.0"
|
34
|
+
spec.add_development_dependency "rubocop", "~> 0.48"
|
35
|
+
spec.add_development_dependency "timecop", "~> 0.8"
|
36
|
+
spec.add_development_dependency "webmock", "~> 3.0"
|
37
|
+
spec.add_development_dependency "vcr"
|
38
|
+
spec.add_development_dependency "pry"
|
39
|
+
spec.add_development_dependency "awesome_print"
|
40
|
+
spec.add_development_dependency "guard"
|
41
|
+
spec.add_development_dependency "guard-minitest"
|
34
42
|
end
|