aspmarketplace 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +7 -0
- data/Manifest.txt +19 -0
- data/README.rdoc +116 -0
- data/Rakefile +25 -0
- data/aspmarketplace.gemspec +43 -0
- data/lib/aspmarketplace.rb +28 -0
- data/lib/aspmarketplace/Yml.rb +22 -0
- data/lib/aspmarketplace/helpers/form_helper.rb +29 -0
- data/lib/aspmarketplace/helpers/notification_helper.rb +49 -0
- data/lib/aspmarketplace/helpers/rails_helper.rb +44 -0
- data/lib/aspmarketplace/rails.rb +9 -0
- data/lib/aspmarketplace/service.rb +156 -0
- data/lib/aspmarketplace/services/marketplace.rb +241 -0
- data/lib/aspmarketplace/services/marketplacePolicy.rb +122 -0
- data/lib/aspmarketplace/signature_utils.rb +111 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- metadata +105 -0
data/History.txt
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
== 0.1.0 2010-1-16
|
2
|
+
|
3
|
+
* Initial release
|
4
|
+
* Amazon Simple Pay Standard Marketplace Transactions.
|
5
|
+
* Derivative Work:
|
6
|
+
* Amazon Simple Pay Gem - git://github.com/nbibler/aspmarketplace.git
|
7
|
+
* Amazon sample code - http://developer.amazonwebservices.com/connect/entry.jspa?externalID=3007&categoryID=299
|
data/Manifest.txt
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
History.txt
|
2
|
+
Manifest.txt
|
3
|
+
README.rdoc
|
4
|
+
Rakefile
|
5
|
+
lib/aspmarketplace.rb
|
6
|
+
lib/aspmarketplace/helpers/form_helper.rb
|
7
|
+
lib/aspmarketplace/helpers/notification_helper.rb
|
8
|
+
lib/aspmarketplace/helpers/rails_helper.rb
|
9
|
+
lib/aspmarketplace/rails.rb
|
10
|
+
lib/aspmarketplace/service.rb
|
11
|
+
lib/aspmarketplace/Yml.rb
|
12
|
+
lib/aspmarketplace/signature_utils.rb
|
13
|
+
lib/aspmarketplace/services/marketplace.rb
|
14
|
+
lib/aspmarketplace/services/marketplacePolicy.rb
|
15
|
+
script/console
|
16
|
+
script/destroy
|
17
|
+
script/generate
|
18
|
+
aspmarketplace.gemspec
|
19
|
+
|
data/README.rdoc
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
= aspmarketplace (Simple Marketplace Transactions)
|
2
|
+
|
3
|
+
== DESCRIPTION:
|
4
|
+
|
5
|
+
This gem provides a Rails interface to the Amazon Simple Pay marketplace service.
|
6
|
+
|
7
|
+
== SYNOPSIS:
|
8
|
+
|
9
|
+
Set up the gem requirement in your environment:
|
10
|
+
|
11
|
+
(in config/environment.rb)
|
12
|
+
|
13
|
+
config.gem "aspmarketplace"
|
14
|
+
|
15
|
+
Configure the gem with your Amazon credentials:
|
16
|
+
|
17
|
+
(in config/initializers/aspmarketplace.rb)
|
18
|
+
|
19
|
+
aspmarketplace.aws_access_key_id = 'MYAMAZONACCESSKEYID'
|
20
|
+
aspmarketplace.aws_secret_access_key = 'MYAMAZONSECRETACCESSKEY'
|
21
|
+
aspmarketplace.account_id = 'ACCOUNTIDFORAMAZONPAYMENTS'
|
22
|
+
|
23
|
+
Then, let Rails know about the aspmarketplace::Helpers:
|
24
|
+
|
25
|
+
(potentially in app/controllers/application[_controller].rb or really anywhere else)
|
26
|
+
|
27
|
+
require 'aspmarketplace/rails'
|
28
|
+
|
29
|
+
|
30
|
+
=== Generating your Simple Pay forms
|
31
|
+
|
32
|
+
Generally, this library will then be used directly from one (or more) of your
|
33
|
+
views. Depending on the type of Simple Pay service you're using (see
|
34
|
+
aspmarketplace::Services), some form values will be required, while others may be
|
35
|
+
optional. This is done like so:
|
36
|
+
|
37
|
+
<%= aspmarketplace_form_for(:standard, {
|
38
|
+
:amount => 10.95,
|
39
|
+
:description => "Profit!"
|
40
|
+
}) %>
|
41
|
+
|
42
|
+
<%= aspmarketplace_form_for(:subscription, {
|
43
|
+
:amount => 10.95,
|
44
|
+
:description => "MORE Profit!",
|
45
|
+
:recurring_frequency => "1 month"
|
46
|
+
}) %>
|
47
|
+
|
48
|
+
|
49
|
+
=== Marketplace forms
|
50
|
+
|
51
|
+
Amazon Simple Pay Marketplace makes it easy to facilitate payments between
|
52
|
+
buyers and sellers, and to charge a fee for the transaction. If you're building
|
53
|
+
a marketplace application, your sellers must first agree to the policy that you
|
54
|
+
set. You can do this by specifying the aspmarketplace::Services::MarketplacePolicy
|
55
|
+
service:
|
56
|
+
|
57
|
+
<%= aspmarketplace_form_for(:marketplacePolicy, {
|
58
|
+
:max_fixed_fee => 5.00,
|
59
|
+
:max_variable_fee => 5,
|
60
|
+
:return_url => 'http://yourservice.com',
|
61
|
+
:reference_id => '1234567890'
|
62
|
+
}) %>
|
63
|
+
|
64
|
+
The user will be prompted to login to their Amazon account and accept the policy
|
65
|
+
you propose. After they complete the process, they'll be returned to the return_url
|
66
|
+
specified. Amazon will also provide a recipientEmail parameter that will contain
|
67
|
+
the seller email here (you may want to craft your return url so that it contains the
|
68
|
+
reference_id value and use this to 'acknowledge' a sellers consent and record their
|
69
|
+
Amazon recipient email address).
|
70
|
+
|
71
|
+
Only once this is done will you be able to offer marketplace checkout options for
|
72
|
+
that sellers items:
|
73
|
+
|
74
|
+
<%= aspmarketplace_form_for(:marketplace, {
|
75
|
+
:amount => 34.95,
|
76
|
+
:description => "Mutual profit!",
|
77
|
+
:recipient_email => 'seller@gmail.com',
|
78
|
+
:fixed_marketplace_fee => 10.00,
|
79
|
+
:variable_marketplace_fee => 5
|
80
|
+
}) %>
|
81
|
+
|
82
|
+
|
83
|
+
== REQUIREMENTS:
|
84
|
+
|
85
|
+
1. You must have an Amazon Payments <b>business account</b>.
|
86
|
+
2. You must know your Amazon Payments <b>account identifier</b> [instructions to come]
|
87
|
+
3. You must know your Amazon Web Services <b>access key</b> and <b>secret access key</b>.
|
88
|
+
|
89
|
+
== INSTALL:
|
90
|
+
|
91
|
+
sudo gem install aspmarketplace
|
92
|
+
|
93
|
+
== LICENSE:
|
94
|
+
|
95
|
+
(The MIT License)
|
96
|
+
|
97
|
+
Copyright (c) 2008 Nathaniel E. Bibler
|
98
|
+
|
99
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
100
|
+
a copy of this software and associated documentation files (the
|
101
|
+
'Software'), to deal in the Software without restriction, including
|
102
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
103
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
104
|
+
permit persons to whom the Software is furnished to do so, subject to
|
105
|
+
the following conditions:
|
106
|
+
|
107
|
+
The above copyright notice and this permission notice shall be
|
108
|
+
included in all copies or substantial portions of the Software.
|
109
|
+
|
110
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
111
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
112
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
113
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
114
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
115
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
116
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
%w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
|
2
|
+
require File.dirname(__FILE__) + '/lib/aspmarketplace'
|
3
|
+
|
4
|
+
$hoe = Hoe.new('aspmarketplace', aspmarketplace::VERSION) do |p|
|
5
|
+
p.developer('Charlie White', 'charlie@fuidtickets.com')
|
6
|
+
p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
|
7
|
+
p.rubyforge_name = p.name
|
8
|
+
p.extra_deps = [
|
9
|
+
['activesupport','>= 2.0.2']
|
10
|
+
]
|
11
|
+
p.extra_dev_deps = [
|
12
|
+
['newgem', ">= #{::Newgem::VERSION}"]
|
13
|
+
]
|
14
|
+
|
15
|
+
p.clean_globs |= %w[**/.DS_Store tmp *.log]
|
16
|
+
path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
|
17
|
+
p.remote_rdoc_dir = ''
|
18
|
+
p.rsync_args = '-av --delete --ignore-errors'
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'newgem/tasks' # load /tasks/*.rake
|
22
|
+
Dir['tasks/**/*.rake'].each { |t| load t }
|
23
|
+
|
24
|
+
task :default => [:test]
|
25
|
+
task :release_and_update => [:gemspec, :release, :website, :post_news]
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{aspmarketplace}
|
5
|
+
s.version = "0.1.0"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Charlie White"]
|
9
|
+
#s.cert_chain = ["/Users/nathan/.gem/gem-public_cert.pem"]
|
10
|
+
s.date = %q{2009-06-07}
|
11
|
+
s.description = %q{Rails ready gem for Marketplace Transactions using Amazon Simple Pay.}
|
12
|
+
s.email = ["charlie@fluidtickets.com"]
|
13
|
+
s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.rdoc"]
|
14
|
+
s.files = ["History.txt", "Manifest.txt", "README.rdoc", "Rakefile", "lib/aspmarketplace.rb", "lib/aspmarketplace/helpers/form_helper.rb", "lib/aspmarketplace/helpers/notification_helper.rb", "lib/aspmarketplace/helpers/rails_helper.rb", "lib/aspmarketplace/rails.rb", "lib/aspmarketplace/service.rb", "lib/aspmarketplace/services/marketplace.rb", "lib/aspmarketplace/services/marketplacePolicy.rb", "lib/aspmarketplace/signature_utils.rb", "lib/aspmarketplace/Yml.rb", "script/console", "script/destroy", "script/generate", "aspmarketplace.gemspec"]
|
15
|
+
s.has_rdoc = true
|
16
|
+
s.homepage = %q{http://aspmarketplace.rubyforge.org}
|
17
|
+
s.rdoc_options = ["--main", "README.rdoc"]
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
s.rubyforge_project = %q{aspmarketplace}
|
20
|
+
s.rubygems_version = %q{1.3.2}
|
21
|
+
#s.signing_key = %q{/Users/nathan/.gem/gem-private_key.pem}
|
22
|
+
s.summary = %q{This gem provides a Rails interface to the Amazon Simple Pay payment service.}
|
23
|
+
|
24
|
+
|
25
|
+
if s.respond_to? :specification_version then
|
26
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
27
|
+
s.specification_version = 3
|
28
|
+
|
29
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
30
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 2.0.2"])
|
31
|
+
s.add_development_dependency(%q<newgem>, [">= 1.3.0"])
|
32
|
+
s.add_development_dependency(%q<hoe>, [">= 1.8.0"])
|
33
|
+
else
|
34
|
+
s.add_dependency(%q<activesupport>, [">= 2.0.2"])
|
35
|
+
s.add_dependency(%q<newgem>, [">= 1.3.0"])
|
36
|
+
s.add_dependency(%q<hoe>, [">= 1.8.0"])
|
37
|
+
end
|
38
|
+
else
|
39
|
+
s.add_dependency(%q<activesupport>, [">= 2.0.2"])
|
40
|
+
s.add_dependency(%q<newgem>, [">= 1.3.0"])
|
41
|
+
s.add_dependency(%q<hoe>, [">= 1.8.0"])
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__)) unless
|
2
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
|
+
|
4
|
+
require 'active_support'
|
5
|
+
require 'aspmarketplace/Yml'
|
6
|
+
|
7
|
+
module aspmarketplace
|
8
|
+
|
9
|
+
VERSION = '0.1.0' unless const_defined?(:VERSION)
|
10
|
+
|
11
|
+
mattr_accessor :aws_access_key_id
|
12
|
+
mattr_accessor :aws_secret_access_key
|
13
|
+
mattr_accessor :account_id
|
14
|
+
|
15
|
+
mattr_accessor :use_sandbox
|
16
|
+
@@use_sandbox = true
|
17
|
+
|
18
|
+
Yml.load
|
19
|
+
|
20
|
+
def self.use_sandbox?
|
21
|
+
@@use_sandbox
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
require 'aspmarketplace/service'
|
27
|
+
require 'aspmarketplace/helpers/form_helper'
|
28
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class Yml
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
require 'aspmarketplace/service'
|
5
|
+
|
6
|
+
@@yml_file = "#{RAILS_ROOT}/config/amazon_marketplace.yml"
|
7
|
+
@@yml = YAML::load(File.read(@@yml_file))
|
8
|
+
|
9
|
+
def self.load
|
10
|
+
aspmarketplace::Service.environment = @@yml['environment']
|
11
|
+
aspmarketplace::Service.access_key = @@yml['accessKey']
|
12
|
+
aspmarketplace::Service.secret_key = @@yml['secretKey']
|
13
|
+
aspmarketplace::Service.signature_method = @@yml['signatureMethod']
|
14
|
+
aspmarketplace::Services::MarketplacePolicy.return_url = @@yml['marketplace_policy']['returnUrl']
|
15
|
+
aspmarketplace::Services::Marketplace.abandon_url = @@yml['marketplace']['abandonUrl']
|
16
|
+
aspmarketplace::Services::Marketplace.return_url = @@yml['marketplace']['returnUrl']
|
17
|
+
aspmarketplace::Services::Marketplace.immediate_return = @@yml['marketplace']['immediateReturn']
|
18
|
+
aspmarketplace::Services::Marketplace.process_immediate = @@yml['marketplace']['processImmediate']
|
19
|
+
aspmarketplace::Services::Marketplace.ipn_url = @@yml['marketplace']['ipnUrl']
|
20
|
+
aspmarketplace::Services::Marketplace.collect_shipping_address = @@yml['marketplace']['collectShippingAddress']
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module aspmarketplace
|
2
|
+
module Helpers
|
3
|
+
|
4
|
+
module FormHelper
|
5
|
+
|
6
|
+
def self.tag(name, options = nil, open = false)
|
7
|
+
"<#{name}#{tag_options(options) if options}" + (open ? ">" : " />")
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.content_tag(name, content, options = nil)
|
11
|
+
"<#{name}#{tag_options(options)}>#{content}</#{name}>"
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
|
18
|
+
def self.tag_options(options)
|
19
|
+
unless options.blank?
|
20
|
+
attrs = []
|
21
|
+
attrs = options.map { |key, value| %(#{key}="#{value}") }
|
22
|
+
" #{attrs.sort * ' '}" unless attrs.empty?
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
#require 'aspmarketplace/authentication'
|
2
|
+
|
3
|
+
module aspmarketplace
|
4
|
+
module Helpers
|
5
|
+
|
6
|
+
##
|
7
|
+
# Adds a +valid_aspmarketplace_request?+ method to your ActionControllers.
|
8
|
+
#
|
9
|
+
# In order to use this, you should just directly hand your +params+ into
|
10
|
+
# the method:
|
11
|
+
#
|
12
|
+
# class FooController < ApplicationController
|
13
|
+
#
|
14
|
+
# def receive_ipn
|
15
|
+
# if valid_aspmarketplace_request?(params)
|
16
|
+
# ... record something useful ...
|
17
|
+
# else
|
18
|
+
# ... maybe log a bad request? ...
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
module NotificationHelper
|
25
|
+
|
26
|
+
protected
|
27
|
+
|
28
|
+
|
29
|
+
##
|
30
|
+
# Authenticates the incoming request by validating the +signature+
|
31
|
+
# provided.
|
32
|
+
#
|
33
|
+
# (from within your controller)
|
34
|
+
# def receive_ipn
|
35
|
+
# if valid_aspmarketplace_request?(params)
|
36
|
+
# ...
|
37
|
+
# end
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
def valid_aspmarketplace_request?(request_hash)
|
41
|
+
hash = request_hash.symbolize_keys
|
42
|
+
signature = hash.delete(:signature) || ''
|
43
|
+
aspmarketplace::SignatureUtils.authentic?(hash, signature)
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'action_view/base'
|
2
|
+
|
3
|
+
module aspmarketplace
|
4
|
+
module Helpers
|
5
|
+
|
6
|
+
##
|
7
|
+
# Adds helpers to your views for generating the correct HTML forms and
|
8
|
+
# valid signatures.
|
9
|
+
#
|
10
|
+
module RailsHelper
|
11
|
+
|
12
|
+
##
|
13
|
+
# This is the general interface for generating your Simple Pay service
|
14
|
+
# forms. See aspmarketplace::Services for available services and information
|
15
|
+
# specific to each.
|
16
|
+
#
|
17
|
+
# === Example
|
18
|
+
#
|
19
|
+
# (in your view)
|
20
|
+
#
|
21
|
+
# <%= aspmarketplace_form_for(:service_name, {:attr => 'foo'}) %>
|
22
|
+
#
|
23
|
+
def aspmarketplace_form_for(service_name, attributes = {}, submit_tag = nil)
|
24
|
+
service = get_aspmarketplace_service(service_name)
|
25
|
+
service.generate_form(attributes)
|
26
|
+
end
|
27
|
+
|
28
|
+
def aspmarketplace_url_for(service_name, attributes = {}, submit_tag = nil)
|
29
|
+
service = get_aspmarketplace_service(service_name)
|
30
|
+
service.generate_url(attributes)
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
|
37
|
+
def get_aspmarketplace_service(name) #:nodoc:
|
38
|
+
service = "aspmarketplace::Services::#{name.to_s.camelize}".constantize
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'aspmarketplace'
|
2
|
+
require 'aspmarketplace/helpers/rails_helper'
|
3
|
+
require 'aspmarketplace/helpers/notification_helper'
|
4
|
+
|
5
|
+
# Inject helper into Rails ActionView.
|
6
|
+
ActionView::Base.__send__(:include, aspmarketplace::Helpers::RailsHelper)
|
7
|
+
|
8
|
+
# Inject notification helper into ActionController
|
9
|
+
ActionController::Base.__send__(:include, aspmarketplace::Helpers::NotificationHelper)
|
@@ -0,0 +1,156 @@
|
|
1
|
+
module aspmarketplace
|
2
|
+
|
3
|
+
##
|
4
|
+
# This is a base class from which to inherit functionality for all Amazon
|
5
|
+
# Simple Pay services (Subscriptions, Marketplace Buttons, etc.)
|
6
|
+
#
|
7
|
+
# === Required Fields
|
8
|
+
#
|
9
|
+
# The following fields are required for all Simple Pay services:
|
10
|
+
#
|
11
|
+
# access_key:: Your Amazon Web Service (AWS) access key (automatically filled from aspmarketplace.aws_access_key_id).
|
12
|
+
# account_id:: Your Amazon Payments account identifier (automatically filled from aspmarketplace.account_id)
|
13
|
+
# signature:: The validation string, guaranteeing that you are the one generating the request and that the values were not tampered with enroute (automatically generated by the form generators)
|
14
|
+
#
|
15
|
+
class Service
|
16
|
+
|
17
|
+
require 'uri'
|
18
|
+
|
19
|
+
class << self
|
20
|
+
attr_accessor 'environment'
|
21
|
+
attr_accessor 'access_key'
|
22
|
+
attr_accessor 'secret_key'
|
23
|
+
attr_accessor 'signature_method'
|
24
|
+
end
|
25
|
+
|
26
|
+
@@app_name = "ASP"
|
27
|
+
@@ASPhttp_method = "POST"
|
28
|
+
@@CBUIhttp_method = "POST"
|
29
|
+
@@CBUI_REQUEST_URI = "/cobranded-ui/actions/start";
|
30
|
+
@@SANDBOX_END_POINT = "https://authorize.payments-sandbox.amazon.com/pba/paypipeline";
|
31
|
+
@@SANDBOX_IMAGE_LOCATION="https://authorize.payments-sandbox.amazon.com/pba/images/payNowButton.png";
|
32
|
+
@@SANDBOX_MP_IMAGE_LOCATION = "https://authorize.payments-sandbox.amazon.com/pba/images/MarketPlaceFeeWithLogo.png";
|
33
|
+
|
34
|
+
@@PROD_END_POINT = "https://authorize.payments.amazon.com/pba/paypipeline";
|
35
|
+
@@PROD_IMAGE_LOCATION="https://authorize.payments.amazon.com/pba/images/payNowButton.png";
|
36
|
+
@@PROD_MP_IMAGE_LOCATION = "https://authorize.payments.amazon.com/pba/images/MarketPlaceFeeWithLogo.png";
|
37
|
+
|
38
|
+
@@SIGNATURE_KEYNAME = "signature"
|
39
|
+
@@SIGNATURE_METHOD_KEYNAME = "signatureMethod"
|
40
|
+
@@SIGNATURE_VERSION_KEYNAME = "signatureVersion"
|
41
|
+
@@SIGNATURE_VERSION = "2"
|
42
|
+
@@COBRANDING_STYLE = "logo"
|
43
|
+
|
44
|
+
@@HMAC_SHA256_ALGORITHM = "HmacSHA256"
|
45
|
+
@@HMAC_SHA1_ALGORITHM = "HmacSHA1"
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
class << self
|
50
|
+
|
51
|
+
##
|
52
|
+
# Defines a field for the service.
|
53
|
+
#
|
54
|
+
# === Usage
|
55
|
+
#
|
56
|
+
# class Foo < Service
|
57
|
+
# field :access_key
|
58
|
+
# field :amount, :class => Amount, :map_to => :value
|
59
|
+
# end
|
60
|
+
#
|
61
|
+
def field(name, options = {})
|
62
|
+
field = Support::Field.new(self, name, options)
|
63
|
+
define_method("#{name.to_s.underscore}=", Proc.new { |value| self.fields.detect { |f| f.name == name }.value = value })
|
64
|
+
self.fields << field
|
65
|
+
field
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# Optional convenience method for:
|
70
|
+
#
|
71
|
+
# field :field_name, :required => true
|
72
|
+
#
|
73
|
+
# Any other +options+ given will be still be passed through.
|
74
|
+
#
|
75
|
+
def required_field(name, options = {})
|
76
|
+
field(name, options.merge(:required => true))
|
77
|
+
end
|
78
|
+
|
79
|
+
##
|
80
|
+
# Returns the collection of fields defined by the service class.
|
81
|
+
#
|
82
|
+
def fields
|
83
|
+
@fields ||= []
|
84
|
+
end
|
85
|
+
|
86
|
+
def set_submit_tag(value)
|
87
|
+
@submit_tag = value
|
88
|
+
end
|
89
|
+
|
90
|
+
def submit_tag
|
91
|
+
@submit_tag
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
##
|
98
|
+
# Returns the fields for the service instance.
|
99
|
+
#
|
100
|
+
def fields
|
101
|
+
@fields ||= self.class.fields.collect { |f| f.clone_for(self) }
|
102
|
+
end
|
103
|
+
|
104
|
+
##
|
105
|
+
# Returns the URL for the service endpoint to use. If +sandbox+ is true,
|
106
|
+
# the SANDBOX_URL will be used. Otherwise, the ENDPOINT_URL will be used.
|
107
|
+
#
|
108
|
+
def url(sandbox = aspmarketplace.use_sandbox?)
|
109
|
+
sandbox ? self.class.const_get(:SANDBOX_URL) : self.class.const_get(:ENDPOINT_URL)
|
110
|
+
end
|
111
|
+
|
112
|
+
def form(attributes = {}, submit = nil)
|
113
|
+
set_accessor_fields
|
114
|
+
set_fields(attributes)
|
115
|
+
set_signature
|
116
|
+
content = generate_input_fields + generate_submit_field(submit)
|
117
|
+
aspmarketplace::Helpers::FormHelper.content_tag(:form, content, {:method => 'post', :action => url})
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
private
|
122
|
+
|
123
|
+
|
124
|
+
def generate_input_fields
|
125
|
+
self.fields.collect { |f| f.to_input }.join
|
126
|
+
end
|
127
|
+
|
128
|
+
def generate_submit_field(submit)
|
129
|
+
options = {:type => 'submit'}
|
130
|
+
options.merge!(:value => self.class.submit_tag) if self.class.submit_tag
|
131
|
+
submit ? submit.to_s : aspmarketplace::Helpers::FormHelper.tag(:input, options)
|
132
|
+
end
|
133
|
+
|
134
|
+
def set_accessor_fields
|
135
|
+
self.access_key = aspmarketplace.aws_access_key_id if self.respond_to?(:access_key=)
|
136
|
+
self.account_id = aspmarketplace.account_id if self.respond_to?(:account_id=)
|
137
|
+
end
|
138
|
+
|
139
|
+
def set_fields(hash)
|
140
|
+
hash.each_pair do |key, value|
|
141
|
+
self.send("#{key}=", value) if self.respond_to?("#{key}=")
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def set_signature
|
146
|
+
fields = {}
|
147
|
+
self.fields.each { |f| fields[f.service_name] = f.value unless f.service_name == 'signature' }
|
148
|
+
self.signature = Authentication.generate(fields) if self.respond_to?(:signature=)
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
|
155
|
+
require 'aspmarketplace/services/marketplace'
|
156
|
+
require 'aspmarketplace/services/marketplacePolicy'
|
@@ -0,0 +1,241 @@
|
|
1
|
+
module aspmarketplace
|
2
|
+
module Services
|
3
|
+
|
4
|
+
##
|
5
|
+
# The Amazon Simple Pay Marketplace service is used to facilitate payments for others.
|
6
|
+
# Use it to charge a commission fee for brokering the exchange between buyers and sellers.
|
7
|
+
#
|
8
|
+
# Note that sellers must accept your marketplace fee policy before the payment buttons
|
9
|
+
# for their products can be generated. This can be accomplished using the +MarketplacePolicy+
|
10
|
+
# service with the form helper (see examples).
|
11
|
+
#
|
12
|
+
# === Simple Pay Marketplace Fields
|
13
|
+
#
|
14
|
+
# ==== Required Fields
|
15
|
+
#
|
16
|
+
# The following attributes are required when creating a Simple Pay
|
17
|
+
# Marketplace form (in addition to those listed in +aspmarketplace::Service+):
|
18
|
+
#
|
19
|
+
# amount:: The dollar value you'd like to collect.
|
20
|
+
# description:: A summary of the reason for the payment, this is displayed to your customer during checkout.
|
21
|
+
# recipient_email:: The e-mail address of the seller (important and must be correct).
|
22
|
+
# fixed_marketplace_fee:: The fixed marketplace fee to add to each transaction.
|
23
|
+
# variable_marketplace_fee:: The variable percentage fee to add to each transaction.
|
24
|
+
#
|
25
|
+
# ==== Optional Fields
|
26
|
+
#
|
27
|
+
# abandon_url:: The fully-qualified URL to send your custom if they cancel during payment.
|
28
|
+
# cobranding_style:: Defines the type of cobranding to use during the checkout process.
|
29
|
+
# collect_shipping_address:: Tells Amazon whether or not to ask for shipping address and contact information.
|
30
|
+
# immediate_return:: Immediately returns the customer to your +return_url+ directly after payment.
|
31
|
+
# ipn_url:: Fully-qualified URL to which Amazon will POST instant payment notifications.
|
32
|
+
# process_immediately:: Instructs Amazon to immediately process the payment.
|
33
|
+
# reference_id:: A custom string your can set to identify this transaction, it will be returned with the IPNs and other returned data.
|
34
|
+
# return_url:: Fully-qualified URL for where to send your customer following payment.
|
35
|
+
#
|
36
|
+
# === Example
|
37
|
+
#
|
38
|
+
# (in your view, sellers need to accept the marketplace fee policy using the form helper)
|
39
|
+
#
|
40
|
+
# <%= aspmarketplace_form_for(:marketplacePolicy, {
|
41
|
+
# :max_fixed_fee => 10.00,
|
42
|
+
# :max_variable_fee => 5,
|
43
|
+
# :return_url => 'http://yourservice.com'
|
44
|
+
# }) %>
|
45
|
+
#
|
46
|
+
# (in your view, payment form generated for end users using the form helper)
|
47
|
+
#
|
48
|
+
# <%= aspmarketplace_form_for(:standard, {
|
49
|
+
# :amount => 34.95,
|
50
|
+
# :description => "Mutual profit!",
|
51
|
+
# :recipient_email => 'seller@gmail.com',
|
52
|
+
# :fixed_marketplace_fee => 10.00,
|
53
|
+
# :variable_marketplace_fee => 5
|
54
|
+
# }) %>
|
55
|
+
#
|
56
|
+
class Marketplace < Service
|
57
|
+
require 'aspmarketplace/signature_utils'
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
class << self
|
62
|
+
# Loaded from YML config
|
63
|
+
attr_accessor 'amount'
|
64
|
+
attr_accessor 'description'
|
65
|
+
attr_accessor 'reference_id'
|
66
|
+
attr_accessor 'abandon_url'
|
67
|
+
attr_accessor 'return_url'
|
68
|
+
attr_accessor 'immediate_return'
|
69
|
+
attr_accessor 'process_immediate'
|
70
|
+
attr_accessor 'ipn_url'
|
71
|
+
attr_accessor 'collect_shipping_address'
|
72
|
+
attr_accessor 'recipient_email'
|
73
|
+
attr_accessor 'fixed_marketplace_fee'
|
74
|
+
attr_accessor 'variable_marketplace_fee'
|
75
|
+
attr_accessor 'environment'
|
76
|
+
end
|
77
|
+
|
78
|
+
# Function creates a Map of key-value pairs for all valid values passed to the function
|
79
|
+
# @param accessKey - Put your Access Key here
|
80
|
+
# @param amount - Enter the amount you want to collect for the item
|
81
|
+
# @param description - description - Enter a description of the item
|
82
|
+
# @param referenceId - Optionally enter an ID that uniquely identifies this transaction for your records
|
83
|
+
# @param abandonUrl - Optionally, enter the URL where senders should be redirected if they cancel their transaction
|
84
|
+
# @param returnUrl - Optionally enter the URL where buyers should be redirected after they complete the transaction
|
85
|
+
# @param immediateReturn - Optionally, enter "1" if you want to skip the final status page in Amazon Payments,
|
86
|
+
# @param processImmediate - Optionally, enter "1" if you want to settle the transaction immediately else "0". Default value is "1"
|
87
|
+
# @param ipnUrl - Optionally, type the URL of your host page to which Amazon Payments should send the IPN transaction information.
|
88
|
+
# @param collectShippingAddress - Optionally, enter "1" if you want Amazon Payments to return the buyer's shipping address as part of the transaction information.
|
89
|
+
# @param signatureMethod - Valid values are HmacSHA256 and HmacSHA1
|
90
|
+
# @param recipientEmail - Enter the e-mail address for the seller.
|
91
|
+
# @param fixedMarketplaceFee - Optionally, enter the fixed market place fee
|
92
|
+
# @param variableMarketplaceFee - Optionally, enter the variable market place fee
|
93
|
+
|
94
|
+
# @return - A map of key of key-value pair for all non null parameters
|
95
|
+
|
96
|
+
def self.get_params(attributes)
|
97
|
+
form_hidden_inputs = {}
|
98
|
+
if (Service.access_key== nil) then
|
99
|
+
raise ArgumentError, 'AccessKey is required parameter'
|
100
|
+
else
|
101
|
+
form_hidden_inputs["accessKey"] = Service.access_key
|
102
|
+
end
|
103
|
+
if (attributes[:amount] == nil) then
|
104
|
+
raise ArgumentError, 'Amount is required parameter'
|
105
|
+
else
|
106
|
+
form_hidden_inputs["amount"] = attributes[:amount].to_s
|
107
|
+
end
|
108
|
+
if (attributes[:description] == nil) then
|
109
|
+
raise ArgumentError, 'Description is required parameter'
|
110
|
+
else
|
111
|
+
form_hidden_inputs["description"] = attributes[:description].to_s
|
112
|
+
end
|
113
|
+
if (Service.signature_method == nil) then
|
114
|
+
raise ArgumentError, 'Signature Method is required parameter'
|
115
|
+
else
|
116
|
+
form_hidden_inputs[@@SIGNATURE_METHOD_KEYNAME] = Service.signature_method.to_s
|
117
|
+
end
|
118
|
+
if ( attributes[:recipient_email] == nil) then
|
119
|
+
raise ArgumentError, 'Recipient Email is required parameter'
|
120
|
+
else
|
121
|
+
form_hidden_inputs["recipientEmail"] = attributes[:recipient_email].to_s
|
122
|
+
end
|
123
|
+
form_hidden_inputs["referenceId"] = attributes[:reference_id].to_s unless attributes[:reference_id].nil?
|
124
|
+
form_hidden_inputs["immediateReturn"] = self.immediate_return.to_s unless self.immediate_return.nil?
|
125
|
+
form_hidden_inputs["returnUrl"] = self.return_url.to_s unless self.return_url.nil?
|
126
|
+
form_hidden_inputs["abandonUrl"] = self.abandon_url.to_s unless self.abandon_url.nil?
|
127
|
+
form_hidden_inputs["processImmediate"] = self.process_immediate.to_s unless self.process_immediate.nil?
|
128
|
+
form_hidden_inputs["ipnUrl"] = self.ipn_url.to_s unless self.ipn_url.nil?
|
129
|
+
form_hidden_inputs["collectShippingAddress"] = self.collect_shipping_address.to_s unless self.collect_shipping_address.nil?
|
130
|
+
|
131
|
+
form_hidden_inputs["fixedMarketplaceFee"] = attributes[:fixed_marketplace_ee].to_s unless attributes[:fixed_marketplace_fee].nil?
|
132
|
+
form_hidden_inputs["variableMarketplaceFee"] = attributes[:variable_marketplace_fee].to_s unless attributes[:variable_marketplace_fee].nil?
|
133
|
+
|
134
|
+
form_hidden_inputs["cobrandingStyle"] = @@COBRANDING_STYLE
|
135
|
+
form_hidden_inputs[@@SIGNATURE_VERSION_KEYNAME] = @@SIGNATURE_VERSION
|
136
|
+
|
137
|
+
return form_hidden_inputs
|
138
|
+
end
|
139
|
+
|
140
|
+
# Creates a form from the provided key-value pairs
|
141
|
+
# @param form_hidden_inputs
|
142
|
+
# - A map of key of key-value pair for all non null parameters
|
143
|
+
# @param service_end_point
|
144
|
+
# - The Endpoint to be used based on environment selected
|
145
|
+
# @param image_location
|
146
|
+
# - The imagelocation based on environment
|
147
|
+
# @return - An html form created using the key-value pairs
|
148
|
+
|
149
|
+
|
150
|
+
def self.get_marketplace_pay_button_form(form_hidden_inputs,service_end_point,image_location)
|
151
|
+
form = "<form target='_top' action=\"" + service_end_point + "\" method=\"" + "POST" + "\">\n"
|
152
|
+
form += "<input type=\"image\" src=\""+image_location+"\" border=\"0\">\n"
|
153
|
+
form_hidden_inputs.each { |k,v|
|
154
|
+
form += "<input type=\"hidden\" name=\"" + k + "\" value=\"" + v + "\" >\n"
|
155
|
+
}
|
156
|
+
form += "</form>\n"
|
157
|
+
end
|
158
|
+
|
159
|
+
def self.get_marketplace_pay_button_url(form_hidden_inputs,service_end_point,image_location)
|
160
|
+
|
161
|
+
|
162
|
+
url = 'https://authorize.payments-sandbox.amazon.com/cobranded-ui/actions/start?'
|
163
|
+
form_hidden_inputs.each { |k,v|
|
164
|
+
url += k + "=" + v + '&'
|
165
|
+
}
|
166
|
+
return url
|
167
|
+
|
168
|
+
# Uncomment this if you want output in a file
|
169
|
+
# File.open('out.htm', 'w') { |f| f.write x.body }
|
170
|
+
|
171
|
+
end
|
172
|
+
|
173
|
+
|
174
|
+
# @param accessKey - Put your Access Key here
|
175
|
+
# @param secretKey - Put your Secret Key here
|
176
|
+
# @param amount - Enter the amount you want to collect for the item
|
177
|
+
# @param description - description - Enter a description of the item
|
178
|
+
# @param referenceId - Optionally enter an ID that uniquely identifies this transaction for your records
|
179
|
+
# @param abandonUrl - Optionally, enter the URL where senders should be redirected if they cancel their transaction
|
180
|
+
# @param returnUrl - Optionally enter the URL where buyers should be redirected after they complete the transaction
|
181
|
+
# @param immediateReturn - Optionally, enter "1" if you want to skip the final status page in Amazon Payments,
|
182
|
+
# @param processImmediate - Optionally, enter "1" if you want to settle the transaction immediately else "0". Default value is "1"
|
183
|
+
# @param ipnUrl - Optionally, type the URL of your host page to which Amazon Payments should send the IPN transaction information.
|
184
|
+
# @param collectShippingAddress - Optionally, enter "1" if you want Amazon Payments to return the buyer's shipping address as part of the transaction information.
|
185
|
+
# @param signatureMethod - Valid values are HmacSHA256 and HmacSHA1
|
186
|
+
# @param recipientEmail - Enter the e-mail address for the seller.
|
187
|
+
# @param fixedMarketplaceFee - Optionally, enter the fixed market place fee
|
188
|
+
# @param variableMarketplaceFee - Optionally, enter the variable market place fee
|
189
|
+
# @param environment - Valid values are "sandbox" or "prod"
|
190
|
+
|
191
|
+
def self.generate_form(attributes)
|
192
|
+
if (Service.environment == "prod") then
|
193
|
+
endPoint = @@PROD_END_POINT;
|
194
|
+
imageLocation = @@PROD_IMAGE_LOCATION;
|
195
|
+
else
|
196
|
+
endPoint = @@SANDBOX_END_POINT;
|
197
|
+
imageLocation = @@SANDBOX_IMAGE_LOCATION;
|
198
|
+
end
|
199
|
+
uri = URI.parse(endPoint)
|
200
|
+
params = get_params(attributes)
|
201
|
+
|
202
|
+
|
203
|
+
signature = SignatureUtils.sign_parameters({:parameters => params,
|
204
|
+
:aws_secret_key => Service.secret_key,
|
205
|
+
:host => uri.host,
|
206
|
+
:verb => "POST",
|
207
|
+
:uri => uri.path,
|
208
|
+
:algorithm => Service.signature_method })
|
209
|
+
params[@@SIGNATURE_KEYNAME] = signature
|
210
|
+
marketplace_pay_button_form = get_marketplace_pay_button_form(params,endPoint,imageLocation)
|
211
|
+
return marketplace_pay_button_form
|
212
|
+
end
|
213
|
+
|
214
|
+
|
215
|
+
def self.generate_url(attributes)
|
216
|
+
if (Service.environment == "prod") then
|
217
|
+
endPoint = @@PROD_END_POINT;
|
218
|
+
imageLocation = @@PROD_IMAGE_LOCATION;
|
219
|
+
else
|
220
|
+
endPoint = @@SANDBOX_END_POINT;
|
221
|
+
imageLocation = @@SANDBOX_IMAGE_LOCATION;
|
222
|
+
end
|
223
|
+
uri = URI.parse(endPoint)
|
224
|
+
params = get_params(attributes)
|
225
|
+
|
226
|
+
|
227
|
+
signature = SignatureUtils.sign_parameters({:parameters => params,
|
228
|
+
:aws_secret_key => Service.secret_key,
|
229
|
+
:host => uri.host,
|
230
|
+
:verb => "POST",
|
231
|
+
:uri => uri.path,
|
232
|
+
:algorithm => Service.signature_method })
|
233
|
+
params[@@SIGNATURE_KEYNAME] = signature
|
234
|
+
return get_marketplace_pay_button_url(params,endPoint,imageLocation)
|
235
|
+
|
236
|
+
end
|
237
|
+
|
238
|
+
end
|
239
|
+
|
240
|
+
end
|
241
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
module aspmarketplace
|
2
|
+
module Services
|
3
|
+
|
4
|
+
##
|
5
|
+
# The Amazon Simple Pay Marketplace Policy service is used to allow sellers to acknowledge marketplace policy fees.
|
6
|
+
# Only once a set policy has been agreed to will marketplace transactions be able to proceed.
|
7
|
+
#
|
8
|
+
# === Simple Pay Marketplace Policy Fields
|
9
|
+
#
|
10
|
+
# ==== Required Fields
|
11
|
+
#
|
12
|
+
# The following attributes are required when creating a Simple Pay Marketplace policy fee acceptance form
|
13
|
+
# (in addition to those listed in +aspmarketplace::Service+):
|
14
|
+
#
|
15
|
+
# max_fixed_fee:: The maximum fixed fee that will be appended to transactions.
|
16
|
+
# max_variable_fee:: The maximum variable fee (%) that will be calculated and added to transactions.
|
17
|
+
# reference_id:: A custom string used to identify this transaction, it will be returned with return data.
|
18
|
+
#
|
19
|
+
# === Example
|
20
|
+
#
|
21
|
+
# (in your view, using the form helper)
|
22
|
+
#
|
23
|
+
# <%= aspmarketplace_form_for(:marketplacePolicy, {
|
24
|
+
# :max_fixed_fee => 10.00,
|
25
|
+
# :max_variable_fee => 5,
|
26
|
+
# :reference_id => '123456789'
|
27
|
+
# }) %>
|
28
|
+
#
|
29
|
+
class MarketplacePolicy < Service
|
30
|
+
require 'aspmarketplace/signature_utils'
|
31
|
+
|
32
|
+
class << self
|
33
|
+
# Loaded from YML config
|
34
|
+
attr_accessor 'return_url'
|
35
|
+
end
|
36
|
+
|
37
|
+
# Function creates a Map of key-value pairs for all valid values passed to the function
|
38
|
+
|
39
|
+
|
40
|
+
def self.get_params(attributes)
|
41
|
+
form_hidden_inputs = {}
|
42
|
+
if (Service.access_key== nil) then
|
43
|
+
raise ArgumentError, 'AccessKey is required parameter'
|
44
|
+
else
|
45
|
+
form_hidden_inputs["callerKey"] = Service.access_key.to_s
|
46
|
+
end
|
47
|
+
if (Service.signature_method == nil) then
|
48
|
+
raise ArgumentError, 'Signature Method is required parameter'
|
49
|
+
else
|
50
|
+
form_hidden_inputs[@@SIGNATURE_METHOD_KEYNAME] = Service.signature_method.to_s
|
51
|
+
end
|
52
|
+
if (self.return_url == nil) then
|
53
|
+
raise ArgumentError, 'Return_url is required parameter'
|
54
|
+
else
|
55
|
+
form_hidden_inputs["returnUrl"] = self.return_url.to_s
|
56
|
+
end
|
57
|
+
|
58
|
+
form_hidden_inputs["pipelineName"] = "Recipient"
|
59
|
+
form_hidden_inputs["recipientPaysFee"] = "True"
|
60
|
+
form_hidden_inputs["collectEmailAddress"] = "True"
|
61
|
+
|
62
|
+
form_hidden_inputs["callerReference"] = attributes[:caller_reference].to_s
|
63
|
+
|
64
|
+
form_hidden_inputs["maxFixedFee"] = attributes[:fixed_marketplace_fee].to_s unless attributes[:fixed_marketplace_fee].nil?
|
65
|
+
form_hidden_inputs["maxvariableFee"] = attributes[:variable_marketplace_fee].to_s unless attributes[:variable_marketplace_fee].nil?
|
66
|
+
|
67
|
+
form_hidden_inputs["cobrandingStyle"] = @@COBRANDING_STYLE
|
68
|
+
form_hidden_inputs[@@SIGNATURE_VERSION_KEYNAME] = @@SIGNATURE_VERSION
|
69
|
+
|
70
|
+
return form_hidden_inputs
|
71
|
+
end
|
72
|
+
|
73
|
+
# Creates a form from the provided key-value pairs
|
74
|
+
# @param form_hidden_inputs
|
75
|
+
# - A map of key of key-value pair for all non null parameters
|
76
|
+
# @param service_end_point
|
77
|
+
# - The Endpoint to be used based on environment selected
|
78
|
+
# @param image_location
|
79
|
+
# - The imagelocation based on environment
|
80
|
+
# @return - An html form created using the key-value pairs
|
81
|
+
|
82
|
+
|
83
|
+
def self.get_accept_marketplace_fee_button_form(form_hidden_inputs,service_end_point,image_location,path)
|
84
|
+
form = "<form target='_top' action=\"https://" + service_end_point + path + "\" method=\"" + @@CBUIhttp_method + "\">\n"
|
85
|
+
form += "<input type=\"image\" src=\""+image_location+"\" border=\"0\">\n"
|
86
|
+
form_hidden_inputs.each { |k,v|
|
87
|
+
form += "<input type=\"hidden\" name=\"" + k + "\" value=\"" + v + "\" >\n"
|
88
|
+
}
|
89
|
+
form += "</form>\n"
|
90
|
+
end
|
91
|
+
|
92
|
+
# Attributes Required:
|
93
|
+
# callerReference -Optionally, enter an ID that uniquely identifies this transaction for callers Record
|
94
|
+
# fixedMarketplaceFee - Optionally, enter the fixed market place fee
|
95
|
+
# variableMarketplaceFee - Optionally, enter the variable market place fee
|
96
|
+
|
97
|
+
|
98
|
+
def self.generate_form(attributes)
|
99
|
+
if (Service.environment == "prod") then
|
100
|
+
endPoint = @@PROD_END_POINT;
|
101
|
+
imageLocation = @@PROD_MP_IMAGE_LOCATION;
|
102
|
+
else
|
103
|
+
endPoint = @@SANDBOX_END_POINT;
|
104
|
+
imageLocation = @@SANDBOX_MP_IMAGE_LOCATION;
|
105
|
+
end
|
106
|
+
uri = URI.parse(endPoint)
|
107
|
+
params = get_params(attributes)
|
108
|
+
|
109
|
+
signature = SignatureUtils.sign_parameters({:parameters => params,
|
110
|
+
:aws_secret_key => Service.secret_key,
|
111
|
+
:host => uri.host,
|
112
|
+
:verb => @@CBUIhttp_method,
|
113
|
+
:uri => @@CBUI_REQUEST_URI,
|
114
|
+
:algorithm => Service.signature_method })
|
115
|
+
params[@@SIGNATURE_KEYNAME] = signature
|
116
|
+
accept_marketplace_fee_button_form = get_accept_marketplace_fee_button_form(params,uri.host,imageLocation,@@CBUI_REQUEST_URI)
|
117
|
+
return accept_marketplace_fee_button_form
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
################################################################################
|
2
|
+
# Copyright 2008 Amazon Technologies, Inc.
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
#
|
5
|
+
# You may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at: http://aws.amazon.com/apache2.0
|
7
|
+
# This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
8
|
+
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
9
|
+
# specific language governing permissions and limitations under the License.
|
10
|
+
################################################################################
|
11
|
+
class SignatureUtils
|
12
|
+
|
13
|
+
require 'base64'
|
14
|
+
require 'cgi'
|
15
|
+
require 'openssl'
|
16
|
+
require 'Amazonmarketplace/service'
|
17
|
+
|
18
|
+
|
19
|
+
#
|
20
|
+
# Copyright:: Copyright (c) 2009 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
21
|
+
#
|
22
|
+
# RFC 2104-compliant HMAC signature for request parameters
|
23
|
+
# Implements AWS Signature, as per following spec:
|
24
|
+
#
|
25
|
+
# In Signature Version 2, string to sign is based on following:
|
26
|
+
#
|
27
|
+
# 1. The HTTP Request Method followed by an ASCII newline (%0A)
|
28
|
+
# 2. The HTTP Host header in the form of lowercase host, followed by an ASCII newline.
|
29
|
+
# 3. The URL encoded HTTP absolute path component of the URI
|
30
|
+
# (up to but not including the query string parameters);
|
31
|
+
# if this is empty use a forward '/'. This parameter is followed by an ASCII newline.
|
32
|
+
# 4. The concatenation of all query string components (names and values)
|
33
|
+
# as UTF-8 characters which are URL encoded as per RFC 3986
|
34
|
+
# (hex characters MUST be uppercase), sorted using lexicographic byte ordering.
|
35
|
+
# Parameter names are separated from their values by the '=' character
|
36
|
+
# (ASCII character 61), even if the value is empty.
|
37
|
+
# Pairs of parameter and values are separated by the '&' character (ASCII code 38).
|
38
|
+
#
|
39
|
+
|
40
|
+
|
41
|
+
SIGNATURE_KEYNAME = "signature"
|
42
|
+
|
43
|
+
HMAC_SHA256_ALGORITHM = "HmacSHA256"
|
44
|
+
HMAC_SHA1_ALGORITHM = "HmacSHA1"
|
45
|
+
|
46
|
+
def authentic?(args, signature, secret_key = Service.secret_key)
|
47
|
+
string_to_sign = "";
|
48
|
+
string_to_sign = calculate_string_to_sign_v2(args)
|
49
|
+
return signature == compute_signature(string_to_sign, secret_key)
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.sign_parameters(args)
|
53
|
+
string_to_sign = "";
|
54
|
+
string_to_sign = calculate_string_to_sign_v2(args)
|
55
|
+
return compute_signature(string_to_sign, args[:aws_secret_key],get_algorithm(args[:algorithm]))
|
56
|
+
end
|
57
|
+
|
58
|
+
# Convert a string into URL encoded form.
|
59
|
+
def self.urlencode(plaintext)
|
60
|
+
CGI.escape(plaintext.to_s).gsub("+", "%20").gsub("%7E", "~")
|
61
|
+
end
|
62
|
+
|
63
|
+
private # All the methods below are private
|
64
|
+
|
65
|
+
def self.calculate_string_to_sign_v2(args)
|
66
|
+
parameters = args[:parameters]
|
67
|
+
|
68
|
+
uri = args[:uri]
|
69
|
+
uri = "/" if uri.nil? or uri.empty?
|
70
|
+
uri = urlencode(uri).gsub("%2F", "/")
|
71
|
+
|
72
|
+
verb = args[:verb]
|
73
|
+
host = args[:host].downcase
|
74
|
+
|
75
|
+
|
76
|
+
# exclude any existing Signature parameter from the canonical string
|
77
|
+
sorted = (parameters.reject { |k, v| k == SIGNATURE_KEYNAME }).sort
|
78
|
+
|
79
|
+
canonical = "#{verb}\n#{host}\n#{uri}\n"
|
80
|
+
isFirst = true
|
81
|
+
|
82
|
+
sorted.each { |v|
|
83
|
+
if(isFirst) then
|
84
|
+
isFirst = false
|
85
|
+
else
|
86
|
+
canonical << '&'
|
87
|
+
end
|
88
|
+
|
89
|
+
canonical << urlencode(v[0])
|
90
|
+
unless(v[1].nil?) then
|
91
|
+
canonical << '='
|
92
|
+
canonical << urlencode(v[1])
|
93
|
+
end
|
94
|
+
}
|
95
|
+
|
96
|
+
return canonical
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.get_algorithm(signature_method)
|
100
|
+
return 'sha256' if (signature_method == HMAC_SHA256_ALGORITHM);
|
101
|
+
return 'sha1'
|
102
|
+
end
|
103
|
+
|
104
|
+
def self.compute_signature(canonical, aws_secret_key, algorithm = 'sha256')
|
105
|
+
digest = OpenSSL::Digest::Digest.new(algorithm)
|
106
|
+
return Base64.encode64(OpenSSL::HMAC.digest(digest, aws_secret_key, canonical)).chomp
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
|
data/script/console
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# File: script/console
|
3
|
+
irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
|
4
|
+
|
5
|
+
libs = " -r irb/completion"
|
6
|
+
# Perhaps use a console_lib to store any extra methods I may want available in the cosole
|
7
|
+
# libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
|
8
|
+
libs << " -r #{File.dirname(__FILE__) + '/../lib/aspmarketplace.rb'}"
|
9
|
+
puts "Loading aspmarketplace gem"
|
10
|
+
exec "#{irb} #{libs} --simple-prompt"
|
data/script/destroy
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rubigen'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rubigen'
|
9
|
+
end
|
10
|
+
require 'rubigen/scripts/destroy'
|
11
|
+
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
14
|
+
RubiGen::Scripts::Destroy.new.run(ARGV)
|
data/script/generate
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rubigen'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rubigen'
|
9
|
+
end
|
10
|
+
require 'rubigen/scripts/generate'
|
11
|
+
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
14
|
+
RubiGen::Scripts::Generate.new.run(ARGV)
|
metadata
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: aspmarketplace
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Charlie White
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-06-07 00:00:00 -04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: activesupport
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 2.0.2
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: newgem
|
27
|
+
type: :development
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.3.0
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: hoe
|
37
|
+
type: :development
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 1.8.0
|
44
|
+
version:
|
45
|
+
description: Rails ready gem for Marketplace Transactions using Amazon Simple Pay.
|
46
|
+
email:
|
47
|
+
- charlie@fluidtickets.com
|
48
|
+
executables: []
|
49
|
+
|
50
|
+
extensions: []
|
51
|
+
|
52
|
+
extra_rdoc_files:
|
53
|
+
- History.txt
|
54
|
+
- Manifest.txt
|
55
|
+
- README.rdoc
|
56
|
+
files:
|
57
|
+
- History.txt
|
58
|
+
- Manifest.txt
|
59
|
+
- README.rdoc
|
60
|
+
- Rakefile
|
61
|
+
- lib/aspmarketplace.rb
|
62
|
+
- lib/aspmarketplace/helpers/form_helper.rb
|
63
|
+
- lib/aspmarketplace/helpers/notification_helper.rb
|
64
|
+
- lib/aspmarketplace/helpers/rails_helper.rb
|
65
|
+
- lib/aspmarketplace/rails.rb
|
66
|
+
- lib/aspmarketplace/service.rb
|
67
|
+
- lib/aspmarketplace/services/marketplace.rb
|
68
|
+
- lib/aspmarketplace/services/marketplacePolicy.rb
|
69
|
+
- lib/aspmarketplace/signature_utils.rb
|
70
|
+
- lib/aspmarketplace/Yml.rb
|
71
|
+
- script/console
|
72
|
+
- script/destroy
|
73
|
+
- script/generate
|
74
|
+
- aspmarketplace.gemspec
|
75
|
+
has_rdoc: true
|
76
|
+
homepage: http://aspmarketplace.rubyforge.org
|
77
|
+
licenses: []
|
78
|
+
|
79
|
+
post_install_message:
|
80
|
+
rdoc_options:
|
81
|
+
- --main
|
82
|
+
- README.rdoc
|
83
|
+
require_paths:
|
84
|
+
- lib
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: "0"
|
90
|
+
version:
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: "0"
|
96
|
+
version:
|
97
|
+
requirements: []
|
98
|
+
|
99
|
+
rubyforge_project: aspmarketplace
|
100
|
+
rubygems_version: 1.3.5
|
101
|
+
signing_key:
|
102
|
+
specification_version: 3
|
103
|
+
summary: This gem provides a Rails interface to the Amazon Simple Pay payment service.
|
104
|
+
test_files: []
|
105
|
+
|