itunes_receipt_encoder 0.0.1
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 +7 -0
- data/lib/itunes_receipt_encoder/asn1/sequence.rb +42 -0
- data/lib/itunes_receipt_encoder/asn1.rb +24 -0
- data/lib/itunes_receipt_encoder/in_app.rb +96 -0
- data/lib/itunes_receipt_encoder/payload.rb +86 -0
- data/lib/itunes_receipt_encoder/receipt.rb +91 -0
- data/lib/itunes_receipt_encoder/utils.rb +20 -0
- data/lib/itunes_receipt_encoder/version.rb +5 -0
- data/lib/itunes_receipt_encoder.rb +9 -0
- metadata +208 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 389838e63604ad8eca54e6ffce19a8f846a2a159
|
4
|
+
data.tar.gz: 5717db2e0eef76637858030ff38a30de9f82fd6e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2e098be05c5b76611439a75836814c02c179024945d683bffb9f9d019964108ebc18dfbb19fc591d80386e396bb45e650b6919d006efde253c6383ac538cb4b6
|
7
|
+
data.tar.gz: 3d5a71c47406936b24507df03b18acc5ca5ff71fba3bd2a026fe4e77fcc6188029e742b85d59afb50253d0dc7b7b4a7dcd8c4467eff98806ce2f228ba209258c
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
|
3
|
+
##
|
4
|
+
# ItunesReceiptEncoder
|
5
|
+
module ItunesReceiptEncoder
|
6
|
+
##
|
7
|
+
# ItunesReceiptEncoder::ASN1
|
8
|
+
module ASN1
|
9
|
+
##
|
10
|
+
# ItunesReceiptEncoder::ASN1::Sequence
|
11
|
+
class Sequence
|
12
|
+
attr_reader :encoding, :type
|
13
|
+
|
14
|
+
def initialize(value, type, encoding = nil)
|
15
|
+
@value = value
|
16
|
+
@encoding = encoding
|
17
|
+
@type = type
|
18
|
+
end
|
19
|
+
|
20
|
+
def value
|
21
|
+
case encoding
|
22
|
+
when :utf8_string
|
23
|
+
OpenSSL::ASN1::UTF8String.new(@value.to_s).to_der
|
24
|
+
when :ia5_string
|
25
|
+
OpenSSL::ASN1::IA5String.new(@value.to_s).to_der
|
26
|
+
when :integer
|
27
|
+
OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(@value.to_s)).to_der
|
28
|
+
else
|
29
|
+
@value
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_seq
|
34
|
+
OpenSSL::ASN1::Sequence.new([
|
35
|
+
OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(type.to_s)),
|
36
|
+
OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(ASN1_VERSION.to_s)),
|
37
|
+
OpenSSL::ASN1::OctetString.new(value.to_s)
|
38
|
+
])
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'itunes_receipt_encoder/asn1/sequence'
|
3
|
+
|
4
|
+
##
|
5
|
+
# ItunesReceiptEncoder
|
6
|
+
module ItunesReceiptEncoder
|
7
|
+
##
|
8
|
+
# ItunesReceiptEncoder::ASN1
|
9
|
+
module ASN1
|
10
|
+
ASN1_VERSION = 1
|
11
|
+
|
12
|
+
def self.sequence(value, encoding, type = nil)
|
13
|
+
Sequence.new(value, encoding, type).to_seq
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.set(array)
|
17
|
+
OpenSSL::ASN1::Set.new(array.compact)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.time(time)
|
21
|
+
time && time.utc.strftime('%FT%TZ')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'itunes_receipt_encoder/utils'
|
2
|
+
require 'itunes_receipt_encoder/asn1'
|
3
|
+
|
4
|
+
##
|
5
|
+
# ItunesReceiptEncoder
|
6
|
+
module ItunesReceiptEncoder
|
7
|
+
##
|
8
|
+
# ItunesReceiptEncoder::InApp
|
9
|
+
class InApp
|
10
|
+
include Utils
|
11
|
+
|
12
|
+
attr_accessor :quantity, :product_id, :transaction_id,
|
13
|
+
:original_transaction_id, :purchase_date,
|
14
|
+
:original_purchase_date, :expires_date, :cancellation_date,
|
15
|
+
:web_order_line_item_id, :item_id
|
16
|
+
|
17
|
+
def initialize(attrs = {})
|
18
|
+
attrs.each { |key, val| send("#{key}=", val) }
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_asn1_set
|
22
|
+
ASN1.set [
|
23
|
+
asn1_quantity,
|
24
|
+
asn1_product_id,
|
25
|
+
asn1_transaction_id,
|
26
|
+
asn1_original_transaction_id,
|
27
|
+
asn1_purchase_date,
|
28
|
+
asn1_original_purchase_date,
|
29
|
+
asn1_web_order_line_item_id,
|
30
|
+
(asn1_expires_date if expires_date),
|
31
|
+
(asn1_cancellation_date if cancellation_date)
|
32
|
+
]
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_plist_hash(options = {})
|
36
|
+
hash = {
|
37
|
+
'quantity' => quantity,
|
38
|
+
'product-id' => product_id,
|
39
|
+
'transaction-id' => transaction_id,
|
40
|
+
'original_transaction-id' => original_transaction_id,
|
41
|
+
'purchase-date' => gmt_time(purchase_date),
|
42
|
+
'original-purchase-date' => gmt_time(original_purchase_date),
|
43
|
+
'expires-date-formatted' => gmt_time(expires_date)
|
44
|
+
}
|
45
|
+
hash.merge!(
|
46
|
+
'purchase-date-ms' => ms_time(purchase_date),
|
47
|
+
'original-purchase_date_ms' => ms_time(original_purchase_date),
|
48
|
+
'expires-date' => gmt_time(expires_date)
|
49
|
+
) unless options[:no_ms_dates]
|
50
|
+
hash.merge!(
|
51
|
+
'purchase-date-pst' => pst_time(purchase_date),
|
52
|
+
'original-purchase-date-pst' => pst_time(original_purchase_date),
|
53
|
+
'expires-date-pst' => pst_time(expires_date)
|
54
|
+
) unless options[:no_pst_dates]
|
55
|
+
hash
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def asn1_quantity
|
61
|
+
ASN1.sequence quantity, 1701, :integer
|
62
|
+
end
|
63
|
+
|
64
|
+
def asn1_product_id
|
65
|
+
ASN1.sequence product_id, 1702, :utf8_string
|
66
|
+
end
|
67
|
+
|
68
|
+
def asn1_transaction_id
|
69
|
+
ASN1.sequence transaction_id, 1703, :utf8_string
|
70
|
+
end
|
71
|
+
|
72
|
+
def asn1_original_transaction_id
|
73
|
+
ASN1.sequence original_transaction_id, 1705, :utf8_string
|
74
|
+
end
|
75
|
+
|
76
|
+
def asn1_web_order_line_item_id
|
77
|
+
ASN1.sequence web_order_line_item_id, 1711, :integer
|
78
|
+
end
|
79
|
+
|
80
|
+
def asn1_purchase_date
|
81
|
+
ASN1.sequence ASN1.time(purchase_date), 1704, :ia5_string
|
82
|
+
end
|
83
|
+
|
84
|
+
def asn1_original_purchase_date
|
85
|
+
ASN1.sequence ASN1.time(original_purchase_date), 1706, :ia5_string
|
86
|
+
end
|
87
|
+
|
88
|
+
def asn1_expires_date
|
89
|
+
ASN1.sequence ASN1.time(expires_date), 1708, :ia5_string
|
90
|
+
end
|
91
|
+
|
92
|
+
def asn1_cancellation_date
|
93
|
+
ASN1.sequence ASN1.time(cancellation_date), 1712, :ia5_string
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'itunes_receipt_encoder/utils'
|
2
|
+
require 'itunes_receipt_encoder/in_app'
|
3
|
+
require 'itunes_receipt_encoder/asn1'
|
4
|
+
|
5
|
+
##
|
6
|
+
# ItunesReceiptEncoder
|
7
|
+
module ItunesReceiptEncoder
|
8
|
+
##
|
9
|
+
# ItunesReceiptEncoder::Payload
|
10
|
+
class Payload
|
11
|
+
include Utils
|
12
|
+
|
13
|
+
attr_accessor :environment, :bundle_id, :application_version,
|
14
|
+
:original_application_version, :creation_date,
|
15
|
+
:expiration_date, :opaque_value, :sha1_hash, :in_app,
|
16
|
+
:unique_vendor_identifier
|
17
|
+
|
18
|
+
def initialize(attrs = {})
|
19
|
+
attrs.each { |key, val| send("#{key}=", val) }
|
20
|
+
@in_app ||= []
|
21
|
+
yield self if block_given?
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_asn1_set
|
25
|
+
ASN1.set [
|
26
|
+
asn1_environment,
|
27
|
+
asn1_bundle_id,
|
28
|
+
asn1_application_version,
|
29
|
+
asn1_original_application_version,
|
30
|
+
asn1_creation_date,
|
31
|
+
(asn1_opaque_value if opaque_value),
|
32
|
+
(asn1_sha1_hash if sha1_hash),
|
33
|
+
(asn1_expiration_date if expiration_date)
|
34
|
+
].concat(asn1_in_app)
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_plist_hash(options = {})
|
38
|
+
transaction = InApp.new(in_app[options.fetch(:index, 0)])
|
39
|
+
{
|
40
|
+
'bid' => bundle_id.to_s,
|
41
|
+
'bvrs' => application_version.to_s,
|
42
|
+
'unique-vendor-identifier' => unique_vendor_identifier.to_s
|
43
|
+
}.merge(transaction.to_plist_hash(options))
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def asn1_environment
|
49
|
+
ASN1.sequence environment, 0, :utf8_string
|
50
|
+
end
|
51
|
+
|
52
|
+
def asn1_bundle_id
|
53
|
+
ASN1.sequence bundle_id, 2, :utf8_string
|
54
|
+
end
|
55
|
+
|
56
|
+
def asn1_application_version
|
57
|
+
ASN1.sequence application_version, 3, :utf8_string
|
58
|
+
end
|
59
|
+
|
60
|
+
def asn1_opaque_value
|
61
|
+
ASN1.sequence opaque_value, 4
|
62
|
+
end
|
63
|
+
|
64
|
+
def asn1_sha1_hash
|
65
|
+
ASN1.sequence sha1_hash, 5
|
66
|
+
end
|
67
|
+
|
68
|
+
def asn1_original_application_version
|
69
|
+
ASN1.sequence original_application_version, 19, :utf8_string
|
70
|
+
end
|
71
|
+
|
72
|
+
def asn1_creation_date
|
73
|
+
ASN1.sequence ASN1.time(creation_date), 12, :ia5_string
|
74
|
+
end
|
75
|
+
|
76
|
+
def asn1_expiration_date
|
77
|
+
ASN1.sequence ASN1.time(expiration_date), 21, :ia5_string
|
78
|
+
end
|
79
|
+
|
80
|
+
def asn1_in_app
|
81
|
+
in_app.map do |in_app|
|
82
|
+
ASN1.sequence InApp.new(in_app).to_asn1_set.to_der, 17
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'cfpropertylist'
|
3
|
+
require 'itunes_receipt_encoder/payload'
|
4
|
+
|
5
|
+
##
|
6
|
+
# ItunesReceiptEncoder
|
7
|
+
module ItunesReceiptEncoder
|
8
|
+
##
|
9
|
+
# ItunesReceiptEncoder::Receipt
|
10
|
+
class Receipt
|
11
|
+
PRIVATE_KEY = <<-EOF
|
12
|
+
-----BEGIN RSA PRIVATE KEY-----
|
13
|
+
MIICXgIBAAKBgQCwFAFtL0PVWIAhkZGvOieoG+FYbSxGsQZ+oj8p71kSIPj4zo1/
|
14
|
+
tNAB4hZZkhNUcys1WXb1AK5dXlMs4AwK6zIANvlwJxu4fBIW+sENc4yHaJWfcZJR
|
15
|
+
tgX35aWzAPTSjy/ChsYGwV9eVHNN1iG47E5vwLYH7B8xmagK8ame5cNIhwIDAQAB
|
16
|
+
AoGBAK8VhYGbYRkw4l/+zt1tt2c7Ke1yyXcVqj6beLFrNaeIL+nAAgW9tqRYux6f
|
17
|
+
2Sa9SnbHGjlvTvK6y3ww4OiujEzxRO/0ERUk49bkKt/wmEgBpp76mNcoosBu21Gq
|
18
|
+
p/C9NGkqqvV31nDhcgqYBAqI7Yc2d0vsUV4pPBw8tGl4yjKpAkEA4lTYxtXn7y2j
|
19
|
+
TFOQvmQkctqwC1zi2OtvP4uo3llnLsE1ffIQYk8c1jBXChiGgT7v2frZIv+fIUk/
|
20
|
+
DSxUEkDG7QJBAMcoxq91664GOZSsmZJK6R8uDbOrQ/PGTSrBfvwPP/CtUSJotaP2
|
21
|
+
qOFl8CttDs7DJbS6mY5oplNjN8s0MknwisMCQA13FMqHkVvmcC+rTRI2rQB0SEL0
|
22
|
+
zL4xC5ZRPcO0t/HNJtyOWTEwGbwYdiUwnlf0IZrrVJ3DbXkyfWDQQVQwrGUCQQCT
|
23
|
+
7T+Wd/n0Kn9+ZK00shtxo11eBGnWmYYbqdlOE22ksLdA3ZF9FerecD7xonGLNfu9
|
24
|
+
v5Pq6OQRr/JzJnPr45TNAkEAkqll2DUKWTKiva4MPvda30vZFbraRkW0WUWNIara
|
25
|
+
RDUtoqjlu22PZhexNT4aulrb7OVBxq4yjqdGq5Kgo1z8mw==
|
26
|
+
-----END RSA PRIVATE KEY-----
|
27
|
+
EOF
|
28
|
+
CERTIFICATE = <<-EOF
|
29
|
+
-----BEGIN CERTIFICATE-----
|
30
|
+
MIIC3jCCAkegAwIBAgIJAN0obOgx+IbBMA0GCSqGSIb3DQEBBQUAMFQxCzAJBgNV
|
31
|
+
BAYTAkRFMQ8wDQYDVQQIEwZCZXJsaW4xDzANBgNVBAcTBkJlcmxpbjEjMCEGA1UE
|
32
|
+
ChMabWJhYXN5IG1vYmlsZSBzb2x1dGlvbnMgVUcwHhcNMTUxMjExMTczNjU3WhcN
|
33
|
+
MTYxMjEwMTczNjU3WjBUMQswCQYDVQQGEwJERTEPMA0GA1UECBMGQmVybGluMQ8w
|
34
|
+
DQYDVQQHEwZCZXJsaW4xIzAhBgNVBAoTGm1iYWFzeSBtb2JpbGUgc29sdXRpb25z
|
35
|
+
IFVHMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwFAFtL0PVWIAhkZGvOieo
|
36
|
+
G+FYbSxGsQZ+oj8p71kSIPj4zo1/tNAB4hZZkhNUcys1WXb1AK5dXlMs4AwK6zIA
|
37
|
+
NvlwJxu4fBIW+sENc4yHaJWfcZJRtgX35aWzAPTSjy/ChsYGwV9eVHNN1iG47E5v
|
38
|
+
wLYH7B8xmagK8ame5cNIhwIDAQABo4G3MIG0MB0GA1UdDgQWBBRWJ8qIehJu60Jt
|
39
|
+
8QDfEjx/BZIFqTCBhAYDVR0jBH0we4AUVifKiHoSbutCbfEA3xI8fwWSBamhWKRW
|
40
|
+
MFQxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIEwZCZXJsaW4xDzANBgNVBAcTBkJlcmxp
|
41
|
+
bjEjMCEGA1UEChMabWJhYXN5IG1vYmlsZSBzb2x1dGlvbnMgVUeCCQDdKGzoMfiG
|
42
|
+
wTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBABBYeC04N2OMT5pPEeC2
|
43
|
+
Ckl6J9RkVghCz/LurxcqWXzZvt4SbBhKTGRxoIGKIbtkz8Kk3MoCH2/HwSNd56+W
|
44
|
+
LRZiVl2m9xTwOjNmZI2hqe8Ps3oY5IJyPp/9A6OQqVCB59zW2Br547Su+5hhxRcX
|
45
|
+
iZxrB9LI1CXppp9/9b8D0vYf
|
46
|
+
-----END CERTIFICATE-----
|
47
|
+
EOF
|
48
|
+
|
49
|
+
attr_reader :payload
|
50
|
+
|
51
|
+
def initialize(attrs = {})
|
52
|
+
@payload = Payload.new(attrs)
|
53
|
+
yield self if block_given?
|
54
|
+
end
|
55
|
+
|
56
|
+
def to_unified(options = {})
|
57
|
+
receipt = OpenSSL::PKCS7.sign(
|
58
|
+
OpenSSL::X509::Certificate.new(options.fetch(:cert, CERTIFICATE)),
|
59
|
+
OpenSSL::PKey::RSA.new(options.fetch(:key, PRIVATE_KEY)),
|
60
|
+
payload.to_asn1_set.to_der,
|
61
|
+
[],
|
62
|
+
OpenSSL::PKCS7::BINARY
|
63
|
+
).to_der
|
64
|
+
options[:raw] ? receipt : [receipt].pack('m0')
|
65
|
+
end
|
66
|
+
|
67
|
+
def to_transaction(options = {})
|
68
|
+
data = {
|
69
|
+
'purchase-info' => purchase_info_plist(options),
|
70
|
+
'signature' => options.fetch(:signature, 'unsigned'),
|
71
|
+
'pod' => options.fetch(:pod, 100),
|
72
|
+
'signing-status' => options.fetch(:signing_status, 0)
|
73
|
+
}
|
74
|
+
data.merge!('environment' => payload.environment) unless
|
75
|
+
payload.environment == 'Production'
|
76
|
+
plist = CFPropertyList::List.new
|
77
|
+
plist.value = CFPropertyList.guess data
|
78
|
+
receipt = plist.to_str(CFPropertyList::List::FORMAT_PLAIN)
|
79
|
+
options[:raw] ? receipt : [receipt].pack('m0')
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def purchase_info_plist(options)
|
85
|
+
plist = CFPropertyList::List.new
|
86
|
+
plist.value = CFPropertyList.guess payload.to_plist_hash(options)
|
87
|
+
purchase_info = plist.to_str(CFPropertyList::List::FORMAT_PLAIN)
|
88
|
+
[purchase_info].pack('m0')
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
##
|
2
|
+
# ItunesReceiptEncoder
|
3
|
+
module ItunesReceiptEncoder
|
4
|
+
##
|
5
|
+
# ItunesReceiptEncoder::Receipt
|
6
|
+
module Utils
|
7
|
+
def gmt_time(time)
|
8
|
+
time.utc.strftime('%F %T') + ' Etc/GMT'
|
9
|
+
end
|
10
|
+
|
11
|
+
def pst_time(time)
|
12
|
+
(time + Time.zone_offset('PST'))
|
13
|
+
.strftime('%F %T') + ' America/Los_Angeles'
|
14
|
+
end
|
15
|
+
|
16
|
+
def ms_time(time)
|
17
|
+
(time.to_i * 1000).to_s
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,208 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: itunes_receipt_encoder
|
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-12-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: CFPropertyList
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.3'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.4'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.4'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.3'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.3'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubygems-tasks
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.2'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.2'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: simplecov
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.10'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.10'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: codeclimate-test-reporter
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.4'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.4'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rubocop
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0.33'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0.33'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: webmock
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '1.22'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '1.22'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: byebug
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '8.2'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '8.2'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: ffaker
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '2.1'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '2.1'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: itunes_receipt_decoder
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - '='
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: 0.2.3
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - '='
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: 0.2.3
|
167
|
+
description: |2
|
168
|
+
Encodes receipt data into iTunes encoded receipts and exports as
|
169
|
+
appStoreReceiptURL or transactionReceipt formats.
|
170
|
+
email: hello@mbaasy.com
|
171
|
+
executables: []
|
172
|
+
extensions: []
|
173
|
+
extra_rdoc_files: []
|
174
|
+
files:
|
175
|
+
- lib/itunes_receipt_encoder.rb
|
176
|
+
- lib/itunes_receipt_encoder/asn1.rb
|
177
|
+
- lib/itunes_receipt_encoder/asn1/sequence.rb
|
178
|
+
- lib/itunes_receipt_encoder/in_app.rb
|
179
|
+
- lib/itunes_receipt_encoder/payload.rb
|
180
|
+
- lib/itunes_receipt_encoder/receipt.rb
|
181
|
+
- lib/itunes_receipt_encoder/utils.rb
|
182
|
+
- lib/itunes_receipt_encoder/version.rb
|
183
|
+
homepage: https://github.com/mbaasy/itunes_receipt_encoder
|
184
|
+
licenses:
|
185
|
+
- MIT
|
186
|
+
metadata: {}
|
187
|
+
post_install_message:
|
188
|
+
rdoc_options: []
|
189
|
+
require_paths:
|
190
|
+
- lib
|
191
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
192
|
+
requirements:
|
193
|
+
- - ">="
|
194
|
+
- !ruby/object:Gem::Version
|
195
|
+
version: 2.0.0
|
196
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
197
|
+
requirements:
|
198
|
+
- - ">="
|
199
|
+
- !ruby/object:Gem::Version
|
200
|
+
version: '0'
|
201
|
+
requirements: []
|
202
|
+
rubyforge_project:
|
203
|
+
rubygems_version: 2.4.6
|
204
|
+
signing_key:
|
205
|
+
specification_version: 4
|
206
|
+
summary: Encodes receipt data into iTunes encoded receipts
|
207
|
+
test_files: []
|
208
|
+
has_rdoc:
|