foxycart_helpers 0.1.0 → 1.0.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 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'