foxycart_helpers 0.1.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5f5fd26d3b714a0c8da11768cce2851729179ca9
4
- data.tar.gz: a91e981343f2cb65ccc354c69fb92a0eb2978899
3
+ metadata.gz: 1b6e59326aa6c2092550190903c0e195bd09ba12
4
+ data.tar.gz: 786de45e35135ae337095c80303a25fc8d2733f0
5
5
  SHA512:
6
- metadata.gz: 4293fbedae46cbfe935cc72f0f27a7f53fa347b40f6e232c0635c092a39780e670a877a118cf9195d59d60f2e1dcc293f037254282be879ae9beeb2180b462ff
7
- data.tar.gz: 502e6cd100890745946a4356794d3fb78d700de7699897df63e110d5ec4c6d179c81f44f0e610f8f677348c2dd6b4a0ea7cb198bfc29170aeca649df6c826bea
6
+ metadata.gz: c29b6f02bc62fe6b80c7992f62bc000fd7c349869dfd4cd9bd6c419b5b78636c9d24103ee9e029fd9cc00012d349a89480a9290ea8de28164a5f12dcbdf6643c
7
+ data.tar.gz: 6d21663aa68e7be07ce5ee3901a36d90fee0dfb45f5f96d8c554e5f91d76efdb39b840421e1bdc920d3d104d16627f5e629b218f12f615cb8f8db21916afc234
data/.gitignore CHANGED
@@ -7,3 +7,5 @@
7
7
  /pkg/
8
8
  /spec/reports/
9
9
  /tmp/
10
+
11
+ .env
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in foxycart.gemspec
3
+ # Specify your gem's dependencies in foxycart_helpers.gemspec
4
4
  gemspec
data/README.md CHANGED
@@ -1,8 +1,11 @@
1
1
  # Foxycart Helpers
2
2
 
3
- Several helpers for working with FoxyCart:
3
+ Several helpers for working with FoxyCart in plain Ruby (several Rails helpers are included too but Rails isn't required):
4
4
 
5
5
  * Webhook endpoint for Datafeeds - https://wiki.foxycart.com/v/2.0/transaction_xml_datafeed
6
+ * HMAC Product Verification - https://wiki.foxycart.com/v/2.0/hmac_validation
7
+ * Link href builder (with support for Product Verification)
8
+ * Generation of the store `loader.js` Javascript URL and HTML.
6
9
 
7
10
  ## Installation
8
11
 
@@ -20,6 +23,28 @@ Or install it yourself as:
20
23
 
21
24
  `$ gem install foxycart_helpers`
22
25
 
26
+
27
+ ## Setup
28
+
29
+ The datafeed endpoint defaults to '/foxycart_processor'. If your app is at `https://example.com/` then you should set your datafeed URL in FoxyCart to `https://example.com/foxycart_processor`
30
+
31
+ `ENV['FOXYCART_API_KEY']` should be set to your FoxyCart API key (available from the FoxyCart Admin area).
32
+
33
+ `ENV['FOXYCART_URL']` should be set to your store URL.
34
+
35
+ Or you can override/set these in configuration:
36
+
37
+ ```ruby
38
+ # In an appropriate initializer e.g. /config/initializers/foxycart.rb
39
+ FoxycartHelpers.configure do |config|
40
+ config.mount_point = '/some/other/path'
41
+ config.api_key = 'foobarbat'
42
+ config.url = 'https://example.foxycart.com/'
43
+ config.auto_encode_hrefs = true # automatically use product verification on generated hrefs
44
+ end
45
+ ```
46
+
47
+
23
48
  ## Usage
24
49
 
25
50
  ### Transactional Datafeed Webhook
@@ -40,6 +65,8 @@ __Rack/Sinatra:__
40
65
 
41
66
  __Rails:__ This middleware is registered automatically.
42
67
 
68
+ Then:
69
+
43
70
  ```ruby
44
71
  FoxycartHelpers.subscribe do |payload|
45
72
  puts payload
@@ -50,6 +77,101 @@ end
50
77
 
51
78
  In Rails this could live at `config/initalizers/foxycart.rb`
52
79
 
80
+
81
+ ### HMAC Product Verification
82
+
83
+ This helper HMAC encodes values for use with the Product Verification feature of FoxyCart, it:
84
+
85
+ * Encodes with your API key `ENV['FOXYCART_API_KEY']`
86
+ * Can return both full string for direct replacement of existing names and values or just the hash.
87
+ * Includes Rails view helpers.
88
+
89
+ * `code` = Product code (`sku123`)
90
+ * `name` = Value of name field in the HTML (`name`)
91
+ * `value` = Value (or initial value) of the input etc (`Cool Example`)
92
+
93
+ See the [FoxyCart docs](https://wiki.foxycart.com/v/2.0/hmac_validation) for more information on `code`, `name` and `value`.
94
+
95
+ __Standalone:__
96
+
97
+ ```ruby
98
+ FoxycartHelpers::ProductVerification.encode code, name, value
99
+ # => "54a534ba0afef1b4589c2f77f9011e27089c0030a8876ec8f06fca281fedeb89"
100
+ FoxycartHelpers::ProductVerification.encoded_name code, name, value
101
+ # => "name||54a534ba0afef1b4589c2f77f9011e27089c0030a8876ec8f06fca281fedeb89"
102
+ ```
103
+
104
+ __Rails:__
105
+
106
+ In your views:
107
+
108
+ ```ruby
109
+ <%= foxycart_encode 'sku123', 'name', 'Cool Example' %>
110
+ # => "54a534ba0afef1b4589c2f77f9011e27089c0030a8876ec8f06fca281fedeb89"
111
+ <%= foxycart_encoded_name 'sku123', 'name', 'Cool Example' %>
112
+ # => "name||54a534ba0afef1b4589c2f77f9011e27089c0030a8876ec8f06fca281fedeb89"
113
+ ```
114
+
115
+ ## Link HREF builder
116
+
117
+ Creates cart HREFs (encoded or plain) given for a store URL `ENV['FOXYCART_URL']`.
118
+
119
+ Params are:
120
+
121
+ * `name` (required always)
122
+ * `price` (required always)
123
+ * `code` (required if product validation is used)
124
+ * `opts` a hash, supported values here: https://wiki.foxycart.com/v/2.0/cheat_sheet
125
+
126
+ __Standalone:__
127
+
128
+ ```ruby
129
+ # plain
130
+ FoxycartHelpers::Link.href 'Cool Example', '10', nil, { color: 'red' }
131
+ # => "https://example.foxycart.com/cart?name=Cool+Example&price=10&color=red"
132
+
133
+ # encoded (switched on in config)
134
+ FoxycartHelpers::Link.href 'Cool Example', '10', 'sku123', { color: 'red' }
135
+ => "https://example.foxycart.com/cart?name=Cool%20Example||54a534ba0afef1b4589c2f77f9011e27089c0030a8876ec8f06fca281fedeb89&price=10||a36dd6bcf3587676c9926d389c87cda3bf0033e6c40e0cc7124edc38409f16a9&code=sku123||dc2a524b987ee5e18af483c1a9e2d333f50eae7d8ed417b8b39442dff4c3ab82&color=red||a81b7a17e4f142ae99678fba7e479734785914953a07a42a0dbd44e145775ae9"
136
+ ```
137
+
138
+ __Rails:__
139
+
140
+ In your views:
141
+
142
+ ```
143
+ <%= foxycart_url_for('Cool Example', '10', 'sku123') %>
144
+ # => "https://example.foxycart.com/cart?name=Cool+Example&price=10&color=red"
145
+ <%= link_to 'Click the Link', foxycart_url_for('Cool Example', '10', 'sku123') %>
146
+ # => "<a href=\"https://example.foxycart.com/cart?name=Cool+Example&price=10&color=red\">Click the Link</a>"
147
+ ```
148
+
149
+ ## `loader.js`
150
+
151
+ FoxyCart's required Javascript. Always linked as HTTPS.
152
+ Available as just the URL and HTML element. Inferred from your configured store URL.
153
+
154
+
155
+ __Standalone:__
156
+
157
+ ```ruby
158
+ FoxycartHelpers::Javascript.url
159
+ # => "https://cdn.foxycart.com/example/loader.js"
160
+
161
+ FoxycartHelpers::Javascript.html_element
162
+ # => "<script src=\"https://cdn.foxycart.com/example/loader.js\" async defer></script>"
163
+ ```
164
+
165
+ __Rails:__
166
+
167
+ Helper for use in your layout or relevant pages:
168
+
169
+ ```ruby
170
+ <%= foxycart_loader_js %>
171
+ # => "<script src=\"https://cdn.foxycart.com/example/loader.js\" async defer></script>"
172
+ ```
173
+
174
+
53
175
  ## Development
54
176
 
55
177
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -5,3 +5,6 @@ require 'foxycart_helpers/configuration'
5
5
  require 'foxycart_helpers/listeners'
6
6
  require 'foxycart_helpers/middleware'
7
7
  require 'foxycart_helpers/railtie' if defined?(Rails::Railtie)
8
+ require 'foxycart_helpers/product_verification'
9
+ require 'foxycart_helpers/link'
10
+ require 'foxycart_helpers/javascript'
@@ -16,17 +16,22 @@ module FoxycartHelpers
16
16
  attr_accessor *[
17
17
  :logger,
18
18
  :api_key,
19
+ :url,
19
20
  :mount_point,
21
+ :auto_encode_hrefs,
20
22
  :raise_exceptions,
21
23
  ]
22
24
 
25
+ alias_method :auto_encode_hrefs?, :auto_encode_hrefs
23
26
  alias_method :raise_exceptions?, :raise_exceptions
24
27
 
25
28
  def initialize
26
- @mount_point = '/foxycart_processor'
27
- @logger = Logger.new STDOUT
28
- @api_key = ENV.fetch 'FOXYCART_API_KEY'
29
- @raise_exceptions = true unless ENV['RACK_ENV'] == 'production'
29
+ @mount_point = '/foxycart_processor'
30
+ @logger = Logger.new STDOUT
31
+ @api_key = ENV['FOXYCART_API_KEY']
32
+ @url = ENV['FOXYCART_URL']
33
+ @auto_encode_hrefs = true
34
+ @raise_exceptions = true unless ENV['RACK_ENV'] == 'production'
30
35
  end
31
36
 
32
37
  end
@@ -7,10 +7,10 @@ module FoxycartHelpers
7
7
  class Datafeed
8
8
 
9
9
  def self.from_params(params)
10
- decoded = URI.unescape params
10
+ decoded = CGI::unescape params
11
11
 
12
12
  trimmed = decoded.gsub(/FoxyData=/, '')
13
- encrypted = URI.unescape trimmed
13
+ encrypted = CGI::unescape trimmed
14
14
 
15
15
  rc4 = RC4.new FoxycartHelpers.configuration.api_key
16
16
  decrypted = rc4.decrypt encrypted
@@ -0,0 +1,32 @@
1
+ require 'foxycart_helpers/configuration'
2
+
3
+ module FoxycartHelpers
4
+ class Javascript
5
+
6
+ def self.url(*args)
7
+ new(*args).url
8
+ end
9
+
10
+ def self.html_element(*args)
11
+ new(*args).html_element
12
+ end
13
+
14
+ def url
15
+ "https://cdn.foxycart.com/#{subdomain}/loader.js"
16
+ end
17
+
18
+ def html_element
19
+ "<script src=\"#{url}\" async defer></script>"
20
+ end
21
+
22
+ def subdomain
23
+ url = URI.parse config.url
24
+ url.host.split('.').first
25
+ end
26
+
27
+ def config
28
+ FoxycartHelpers.configuration
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,52 @@
1
+ require 'uri'
2
+
3
+ require 'foxycart_helpers/configuration'
4
+
5
+ module FoxycartHelpers
6
+ class Link
7
+
8
+ def self.href(*args)
9
+ new(*args).href
10
+ end
11
+
12
+ def href
13
+ url = URI::parse config.url
14
+ url.path = '/cart'
15
+ url.query = query_string
16
+
17
+ url.to_s
18
+ end
19
+
20
+ def query_string
21
+ params = config.auto_encode_hrefs? ? encoded_query_hash : query_hash
22
+ string = URI.encode_www_form(params)
23
+
24
+ return string unless config.auto_encode_hrefs?
25
+ CGI.unescape string
26
+ end
27
+
28
+ def query_hash
29
+ Hash.new.tap do |h|
30
+ h[:name] = @name
31
+ h[:price] = @price
32
+ h[:code] = @code if @code
33
+ end.merge(@opts)
34
+ end
35
+
36
+ def encoded_query_hash
37
+ query_hash.map {|k,v| [k, FoxycartHelpers::ProductVerification.encoded_name(@code, k.to_s, v)]}.to_h
38
+ end
39
+
40
+ def initialize(name, price, code=nil, opts={})
41
+ @name = name
42
+ @price = price
43
+ @code = code
44
+ @opts = opts
45
+ end
46
+
47
+ def config
48
+ FoxycartHelpers.configuration
49
+ end
50
+
51
+ end
52
+ end
@@ -10,7 +10,7 @@ module FoxycartHelpers
10
10
  end
11
11
 
12
12
  def config
13
- Foxycart.configuration
13
+ FoxycartHelpers.configuration
14
14
  end
15
15
 
16
16
  def call(env)
@@ -0,0 +1,40 @@
1
+ require 'foxycart_helpers/configuration'
2
+
3
+ module FoxycartHelpers
4
+ class ProductVerification
5
+
6
+ def self.encode(*args)
7
+ new(*args).encode
8
+ end
9
+
10
+ def self.encoded_name(*args)
11
+ new(*args).encoded_name
12
+ end
13
+
14
+ def encode
15
+ digest = OpenSSL::Digest.new 'sha256'
16
+ key = config.api_key
17
+ data = @code + @name + @value
18
+
19
+ OpenSSL::HMAC.hexdigest digest, key, data
20
+ end
21
+
22
+ def encoded_name
23
+ @value + '||' + encode
24
+ end
25
+
26
+ def config
27
+ FoxycartHelpers.configuration
28
+ end
29
+
30
+ def initialize(code, name, value)
31
+ @code = code
32
+ @name = name
33
+ @value = value
34
+ end
35
+
36
+ # encoded_value is an alias for encoded_name
37
+ singleton_class.send :alias_method, :encoded_value, :encoded_name
38
+
39
+ end
40
+ end
@@ -0,0 +1,31 @@
1
+ require 'foxycart_helpers/product_verification'
2
+ require 'foxycart_helpers/link'
3
+ require 'foxycart_helpers/javascript'
4
+
5
+ module FoxycartHelpers
6
+ module RailsViewHelpers
7
+
8
+ def foxycart_encode(code, name, value)
9
+ FoxycartHelpers::ProductVerification.encode code, name, value
10
+ end
11
+
12
+ def foxycart_encoded_name(code, name, value)
13
+ FoxycartHelpers::ProductVerification.encoded_name code, name, value
14
+ end
15
+
16
+ def foxycart_url_for(name, price, code=nil, opts={})
17
+ FoxycartHelpers::Link.href name, price, code, opts
18
+ end
19
+
20
+ def foxycart_loader_js_url
21
+ FoxycartHelpers::Javascript.url
22
+ end
23
+
24
+ def foxycart_loader_js
25
+ FoxycartHelpers::Javascript.html_element
26
+ end
27
+
28
+ alias_method :foxycart_encoded_value, :foxycart_encoded_name
29
+
30
+ end
31
+ end
@@ -1,4 +1,5 @@
1
1
  require 'foxycart_helpers/middleware'
2
+ require 'foxycart_helpers/rails_view_helpers'
2
3
 
3
4
  module FoxycartHelpers
4
5
  class Railtie < Rails::Railtie
@@ -7,5 +8,11 @@ module FoxycartHelpers
7
8
  app.config.middleware.use 'FoxycartHelpers::Middleware'
8
9
  end
9
10
 
11
+ initializer 'foxycart_helpers.configure_view_controller' do |app|
12
+ ActiveSupport.on_load :action_view do
13
+ include FoxycartHelpers::RailsViewHelpers
14
+ end
15
+ end
16
+
10
17
  end
11
18
  end
@@ -1,3 +1,3 @@
1
1
  module FoxycartHelpers
2
- VERSION = '0.1.0'
2
+ VERSION = '1.0.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foxycart_helpers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Coleman
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-11-12 00:00:00.000000000 Z
11
+ date: 2015-11-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-rc4
@@ -115,7 +115,6 @@ executables: []
115
115
  extensions: []
116
116
  extra_rdoc_files: []
117
117
  files:
118
- - ".env"
119
118
  - ".env.example"
120
119
  - ".gitignore"
121
120
  - ".rspec"
@@ -130,8 +129,12 @@ files:
130
129
  - lib/foxycart_helpers.rb
131
130
  - lib/foxycart_helpers/configuration.rb
132
131
  - lib/foxycart_helpers/datafeed.rb
132
+ - lib/foxycart_helpers/javascript.rb
133
+ - lib/foxycart_helpers/link.rb
133
134
  - lib/foxycart_helpers/listeners.rb
134
135
  - lib/foxycart_helpers/middleware.rb
136
+ - lib/foxycart_helpers/product_verification.rb
137
+ - lib/foxycart_helpers/rails_view_helpers.rb
135
138
  - lib/foxycart_helpers/railtie.rb
136
139
  - lib/foxycart_helpers/version.rb
137
140
  homepage: https://github.com/rjocoleman/foxycart_helpers
data/.env DELETED
@@ -1 +0,0 @@
1
- FOXYCART_API_KEY='keyphrase'