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 +4 -4
- data/.gitignore +2 -0
- data/Gemfile +1 -1
- data/README.md +123 -1
- data/lib/foxycart_helpers.rb +3 -0
- data/lib/foxycart_helpers/configuration.rb +9 -4
- data/lib/foxycart_helpers/datafeed.rb +2 -2
- data/lib/foxycart_helpers/javascript.rb +32 -0
- data/lib/foxycart_helpers/link.rb +52 -0
- data/lib/foxycart_helpers/middleware.rb +1 -1
- data/lib/foxycart_helpers/product_verification.rb +40 -0
- data/lib/foxycart_helpers/rails_view_helpers.rb +31 -0
- data/lib/foxycart_helpers/railtie.rb +7 -0
- data/lib/foxycart_helpers/version.rb +1 -1
- metadata +6 -3
- data/.env +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1b6e59326aa6c2092550190903c0e195bd09ba12
|
4
|
+
data.tar.gz: 786de45e35135ae337095c80303a25fc8d2733f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c29b6f02bc62fe6b80c7992f62bc000fd7c349869dfd4cd9bd6c419b5b78636c9d24103ee9e029fd9cc00012d349a89480a9290ea8de28164a5f12dcbdf6643c
|
7
|
+
data.tar.gz: 6d21663aa68e7be07ce5ee3901a36d90fee0dfb45f5f96d8c554e5f91d76efdb39b840421e1bdc920d3d104d16627f5e629b218f12f615cb8f8db21916afc234
|
data/Gemfile
CHANGED
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.
|
data/lib/foxycart_helpers.rb
CHANGED
@@ -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
|
27
|
-
@logger
|
28
|
-
@api_key
|
29
|
-
@
|
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 =
|
10
|
+
decoded = CGI::unescape params
|
11
11
|
|
12
12
|
trimmed = decoded.gsub(/FoxyData=/, '')
|
13
|
-
encrypted =
|
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
|
@@ -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
|
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:
|
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-
|
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
|