boutique 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +4 -3
- data/config.ru +1 -0
- data/lib/boutique.rb +12 -6
- data/test/app_test.rb +8 -8
- data/test/config_test.rb +1 -0
- data/test/helper.rb +1 -0
- metadata +12 -12
data/README.md
CHANGED
@@ -25,6 +25,7 @@ can configure what products you sell here:
|
|
25
25
|
|
26
26
|
Boutique.configure do |c|
|
27
27
|
c.dev_email 'dev@mailinator.com'
|
28
|
+
c.pem_cert_id 'LONGCERTID'
|
28
29
|
c.pem_private '/path/to/private.pem'
|
29
30
|
c.pem_public '/path/to/public.pem'
|
30
31
|
c.pem_paypal '/path/to/paypal.pem'
|
@@ -36,7 +37,7 @@ can configure what products you sell here:
|
|
36
37
|
c.db_password 'secret'
|
37
38
|
c.db_database 'boutique'
|
38
39
|
c.pp_email 'paypal_biz@mailinator.com'
|
39
|
-
c.pp_url '
|
40
|
+
c.pp_url 'https://www.sandbox.paypal.com/cgi-bin/webscr'
|
40
41
|
end
|
41
42
|
|
42
43
|
Boutique.product('icon-set') do |p|
|
@@ -59,11 +60,11 @@ credentials):
|
|
59
60
|
|
60
61
|
With the settings above, a normal flow would look like:
|
61
62
|
|
62
|
-
1. On your site, link the user to `/
|
63
|
+
1. On your site, link the user to `/buy/icon-set/` to purchase
|
63
64
|
2. User is redirected to paypal
|
64
65
|
3. After completing paypal, user is redirected to
|
65
66
|
`http://zincmade.com/thankyou?b=order-id`
|
66
|
-
4. On this page, issue an AJAX request to `/
|
67
|
+
4. On this page, issue an AJAX request to `/purchases/order-id`.
|
67
68
|
The `downloads` field of the JSON will include the download URLs.
|
68
69
|
|
69
70
|
Usage
|
data/config.ru
CHANGED
@@ -2,6 +2,7 @@ require File.expand_path('lib/boutique', File.dirname(__FILE__))
|
|
2
2
|
|
3
3
|
Boutique.configure(!ENV['BOUTIQUE_CMD'].nil?) do |c|
|
4
4
|
c.dev_email 'dev@localhost'
|
5
|
+
c.pem_cert_id 'LONGCERTID'
|
5
6
|
c.pem_private File.expand_path('certs/private.pem', File.dirname(__FILE__))
|
6
7
|
c.pem_public File.expand_path('certs/public.pem', File.dirname(__FILE__))
|
7
8
|
c.pem_paypal File.expand_path('certs/paypal.pem', File.dirname(__FILE__))
|
data/lib/boutique.rb
CHANGED
@@ -11,7 +11,7 @@ require 'openssl'
|
|
11
11
|
require 'pony'
|
12
12
|
|
13
13
|
module Boutique
|
14
|
-
VERSION = '0.0.
|
14
|
+
VERSION = '0.0.6'
|
15
15
|
|
16
16
|
class << self
|
17
17
|
def configure(setup_db=true)
|
@@ -45,6 +45,11 @@ module Boutique
|
|
45
45
|
@dev_email
|
46
46
|
end
|
47
47
|
|
48
|
+
def self.pem_cert_id(value=nil)
|
49
|
+
@pem_cert_id = value if !value.nil?
|
50
|
+
@pem_cert_id
|
51
|
+
end
|
52
|
+
|
48
53
|
def self.pem_private(value=nil)
|
49
54
|
@pem_private = value if !value.nil?
|
50
55
|
@pem_private
|
@@ -258,7 +263,8 @@ module Boutique
|
|
258
263
|
:amount => product.price,
|
259
264
|
:currency_code => 'USD',
|
260
265
|
:notify_url => "#{notify_url}/#{boutique_id}",
|
261
|
-
:return => "#{product.return_url}?b=#{boutique_id}"
|
266
|
+
:return => "#{product.return_url}?b=#{boutique_id}",
|
267
|
+
:cert_id => Boutique.config.pem_cert_id
|
262
268
|
}
|
263
269
|
{'action' => Boutique.config.pp_url,
|
264
270
|
'cmd' => '_s-xclick',
|
@@ -296,7 +302,7 @@ module Boutique
|
|
296
302
|
) if Boutique.config.dev_email
|
297
303
|
end
|
298
304
|
|
299
|
-
post '/
|
305
|
+
post '/buy/:code' do
|
300
306
|
product = Boutique::Product.first(:code => params[:code])
|
301
307
|
if product.nil?
|
302
308
|
halt(404, "product #{params[:code]} not found")
|
@@ -314,7 +320,7 @@ module Boutique
|
|
314
320
|
"</form><script>document.paypal.submit();</script></body></html>"
|
315
321
|
end
|
316
322
|
|
317
|
-
post '/
|
323
|
+
post '/notify/:boutique_id' do
|
318
324
|
purchase = get_purchase(params[:boutique_id])
|
319
325
|
if !purchase.completed? &&
|
320
326
|
params['txn_id'] &&
|
@@ -327,7 +333,7 @@ module Boutique
|
|
327
333
|
''
|
328
334
|
end
|
329
335
|
|
330
|
-
post '/
|
336
|
+
post '/recover/:code' do
|
331
337
|
product = Boutique::Product.first(:code => params[:code])
|
332
338
|
purchase = product.purchases.first(:email => params['email']) if product
|
333
339
|
if product.nil? || purchase.nil? || !purchase.completed?
|
@@ -337,7 +343,7 @@ module Boutique
|
|
337
343
|
purchase.boutique_id
|
338
344
|
end
|
339
345
|
|
340
|
-
get '/
|
346
|
+
get '/record/:boutique_id' do
|
341
347
|
purchase = get_purchase(params[:boutique_id])
|
342
348
|
purchase.maybe_refresh_downloads!
|
343
349
|
params['jsonp'].nil? ?
|
data/test/app_test.rb
CHANGED
@@ -5,7 +5,7 @@ class AppTest < BoutiqueTest
|
|
5
5
|
|
6
6
|
def test_redirect_to_paypal
|
7
7
|
ebook_product.save
|
8
|
-
post '/
|
8
|
+
post '/buy/ebook'
|
9
9
|
|
10
10
|
purchase = Boutique::Purchase.first
|
11
11
|
refute(purchase.nil?)
|
@@ -13,7 +13,7 @@ class AppTest < BoutiqueTest
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def test_purchase_non_existing_product
|
16
|
-
post '/
|
16
|
+
post '/buy/non-existing-product'
|
17
17
|
assert(last_response.not_found?)
|
18
18
|
end
|
19
19
|
|
@@ -25,7 +25,7 @@ class AppTest < BoutiqueTest
|
|
25
25
|
refute(purchase.completed?)
|
26
26
|
assert_nil(Pony.last_mail)
|
27
27
|
|
28
|
-
post "/
|
28
|
+
post "/notify/#{purchase.boutique_id}?payment_status=Completed&txn_id=1337&receiver_email=#{Boutique.config.pp_email}"
|
29
29
|
assert(last_response.ok?)
|
30
30
|
|
31
31
|
purchase.reload
|
@@ -35,7 +35,7 @@ class AppTest < BoutiqueTest
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def test_notify_not_found
|
38
|
-
post "/
|
38
|
+
post "/notify/99-notfound"
|
39
39
|
assert(last_response.not_found?)
|
40
40
|
end
|
41
41
|
|
@@ -45,20 +45,20 @@ class AppTest < BoutiqueTest
|
|
45
45
|
purchase.save
|
46
46
|
assert_nil(Pony.last_mail)
|
47
47
|
|
48
|
-
post "/
|
48
|
+
post "/recover/ebook", 'email' => 'john@mailinator.com'
|
49
49
|
assert(last_response.ok?)
|
50
50
|
assert_equal(purchase.boutique_id, last_response.body)
|
51
51
|
refute_nil(Pony.last_mail)
|
52
52
|
end
|
53
53
|
|
54
54
|
def test_recover_not_found
|
55
|
-
post "/
|
55
|
+
post "/recover/99-notfound"
|
56
56
|
assert(last_response.not_found?)
|
57
57
|
end
|
58
58
|
|
59
59
|
def test_record
|
60
60
|
purchase = ebook_purchase
|
61
|
-
get "/
|
61
|
+
get "/record/#{purchase.boutique_id}"
|
62
62
|
assert(last_response.ok?)
|
63
63
|
|
64
64
|
json = JSON.parse(last_response.body)
|
@@ -70,7 +70,7 @@ class AppTest < BoutiqueTest
|
|
70
70
|
end
|
71
71
|
|
72
72
|
def test_record_not_found
|
73
|
-
get "/
|
73
|
+
get "/record/99-notfound"
|
74
74
|
assert(last_response.not_found?)
|
75
75
|
end
|
76
76
|
|
data/test/config_test.rb
CHANGED
@@ -3,6 +3,7 @@ require File.expand_path('helper', File.dirname(__FILE__))
|
|
3
3
|
class ConfigTest < BoutiqueTest
|
4
4
|
def test_db
|
5
5
|
assert_equal('dev@localhost', Boutique.config.dev_email)
|
6
|
+
assert_equal('LONGCERTID', Boutique.config.pem_cert_id)
|
6
7
|
assert_equal(File.expand_path('../certs/private.pem', File.dirname(__FILE__)), Boutique.config.pem_private)
|
7
8
|
assert_equal(File.expand_path('../certs/public.pem', File.dirname(__FILE__)), Boutique.config.pem_public)
|
8
9
|
assert_equal(File.expand_path('../certs/private.pem', File.dirname(__FILE__)), Boutique.config.pem_private)
|
data/test/helper.rb
CHANGED
@@ -25,6 +25,7 @@ class BoutiqueTest < MiniTest::Unit::TestCase
|
|
25
25
|
Boutique::Product.all.destroy
|
26
26
|
Boutique.configure(false) do |c|
|
27
27
|
c.dev_email 'dev@localhost'
|
28
|
+
c.pem_cert_id 'LONGCERTID'
|
28
29
|
c.pem_private File.expand_path('../certs/private.pem', File.dirname(__FILE__))
|
29
30
|
c.pem_public File.expand_path('../certs/public.pem', File.dirname(__FILE__))
|
30
31
|
c.pem_paypal File.expand_path('../certs/paypal.pem', File.dirname(__FILE__))
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: boutique
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: .
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-01-
|
12
|
+
date: 2012-01-31 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: sinatra
|
16
|
-
requirement: &
|
16
|
+
requirement: &70290588702720 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70290588702720
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: data_mapper
|
27
|
-
requirement: &
|
27
|
+
requirement: &70290588702180 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70290588702180
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: pony
|
38
|
-
requirement: &
|
38
|
+
requirement: &70290588743100 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70290588743100
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: minitest
|
49
|
-
requirement: &
|
49
|
+
requirement: &70290588742600 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70290588742600
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: shotgun
|
60
|
-
requirement: &
|
60
|
+
requirement: &70290588742140 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,7 +65,7 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70290588742140
|
69
69
|
description: A Sinatra module which accepts payments via PayPal and gives customers
|
70
70
|
a secret URL to download your product.
|
71
71
|
email:
|