wepay-rails 2.2.9 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +4 -0
- data/Gemfile +17 -14
- data/Gemfile.lock +116 -24
- data/README.rdoc +4 -2
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/app/controllers/wepay/checkout_controller.rb +5 -1
- data/app/controllers/wepay/ipn_controller.rb +4 -0
- data/build +1 -0
- data/lib/api/account_methods.rb +4 -4
- data/lib/api/checkout_methods.rb +98 -88
- data/lib/generators/wepay_rails/install/install_generator.rb +4 -0
- data/lib/generators/wepay_rails/install/templates/wepay.yml +10 -8
- data/lib/helpers/controller_helpers.rb +2 -0
- data/lib/wepay-rails.rb +158 -124
- data/test/helper.rb +102 -18
- data/test/test_wepay_rails_account_methods.rb +105 -0
- data/test/test_wepay_rails_authorize.rb +31 -0
- data/test/test_wepay_rails_checkout_methods.rb +33 -0
- data/test/test_wepay_rails_initialize.rb +39 -0
- data/wepay-rails.gemspec +29 -16
- metadata +96 -21
- data/config/routes.rb +0 -7
- data/test/test_wepay-rails.rb +0 -7
@@ -2,11 +2,12 @@ production:
|
|
2
2
|
client_id: <your client id from wepay>
|
3
3
|
client_secret: <your client secret from wepay>
|
4
4
|
account_id: <your account id from wepay>
|
5
|
-
access_token: <your access token that you
|
5
|
+
access_token: <your access token that you received when you went to http://your.domain.com/wepay/authorize>
|
6
6
|
root_callback_uri: "http://www.example.com"
|
7
7
|
after_checkout_redirect_uri: "http://www.example.com/purchase/finalize"
|
8
8
|
scope: [refund_payments,collect_payments,view_balance,view_user]
|
9
|
-
|
9
|
+
wepay_ui_endpoint: "https://www.wepay.com/v2"
|
10
|
+
wepay_api_endpoint: "https://wepayapi.com/v2"
|
10
11
|
fee_payer: Payee
|
11
12
|
checkout_type: GOODS
|
12
13
|
charge_tax: false
|
@@ -19,11 +20,12 @@ development:
|
|
19
20
|
client_id: <your client id from wepay>
|
20
21
|
client_secret: <your client secret from wepay>
|
21
22
|
account_id: <your account id from wepay>
|
22
|
-
access_token: <your access token that you
|
23
|
+
access_token: <your access token that you received when you went to http://your.domain.com/wepay/authorize>
|
23
24
|
root_callback_uri: "http://www.example.com"
|
24
25
|
after_checkout_redirect_uri: "http://www.example.com/purchase/finalize"
|
25
26
|
scope: [refund_payments,collect_payments,view_balance,view_user]
|
26
|
-
|
27
|
+
wepay_ui_endpoint: "https://stage.wepay.com/v2"
|
28
|
+
wepay_api_endpoint: "https://stage.wepayapi.com/v2"
|
27
29
|
fee_payer: Payee
|
28
30
|
checkout_type: GOODS
|
29
31
|
charge_tax: false
|
@@ -36,11 +38,12 @@ test:
|
|
36
38
|
client_id: <your client id from wepay>
|
37
39
|
client_secret: <your client secret from wepay>
|
38
40
|
account_id: <your account id from wepay>
|
39
|
-
access_token: <your access token that you
|
41
|
+
access_token: <your access token that you received when you went to http://your.domain.com/wepay/authorize>
|
40
42
|
root_callback_uri: "http://www.example.com"
|
41
43
|
after_checkout_redirect_uri: "http://www.example.com/purchase/finalize"
|
42
44
|
scope: [refund_payments,collect_payments,view_balance,view_user]
|
43
|
-
|
45
|
+
wepay_ui_endpoint: "https://stage.wepay.com/v2"
|
46
|
+
wepay_api_endpoint: "https://stage.wepayapi.com/v2"
|
44
47
|
fee_payer: Payee
|
45
48
|
checkout_type: GOODS
|
46
49
|
charge_tax: false
|
@@ -48,5 +51,4 @@ test:
|
|
48
51
|
auto_capture: true
|
49
52
|
require_shipping: false
|
50
53
|
shipping_fee: 0
|
51
|
-
charge_tax: false
|
52
|
-
|
54
|
+
charge_tax: false
|
data/lib/wepay-rails.rb
CHANGED
@@ -1,124 +1,158 @@
|
|
1
|
-
require 'active_record'
|
2
|
-
require 'helpers/controller_helpers'
|
3
|
-
require 'api/account_methods'
|
4
|
-
require 'api/checkout_methods'
|
5
|
-
require 'httparty'
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
end
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
end
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
1
|
+
require 'active_record'
|
2
|
+
require 'helpers/controller_helpers'
|
3
|
+
require 'api/account_methods'
|
4
|
+
require 'api/checkout_methods'
|
5
|
+
require 'httparty'
|
6
|
+
|
7
|
+
module WepayRails
|
8
|
+
class Configuration
|
9
|
+
@@settings = nil
|
10
|
+
|
11
|
+
def self.init_conf(settings)
|
12
|
+
@@settings = settings
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.settings
|
16
|
+
@@settings
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Engine < Rails::Engine
|
21
|
+
# Initializers
|
22
|
+
initializer "WepayRails.initialize_wepay_rails" do |app|
|
23
|
+
yml = Rails.root.join('config', 'wepay.yml').to_s
|
24
|
+
if File.exists?(yml)
|
25
|
+
settings = YAML.load_file(yml)[Rails.env].symbolize_keys
|
26
|
+
elsif File.exists?(yml+".erb")
|
27
|
+
settings = YAML::load(ERB.new(IO.read(yml+".erb")).result)[Rails.env].symbolize_keys
|
28
|
+
end
|
29
|
+
Configuration.init_conf(settings)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class << self
|
34
|
+
def routes(rails_router)
|
35
|
+
rails_router.instance_exec do
|
36
|
+
namespace :wepay do
|
37
|
+
resources :ipn
|
38
|
+
resources :authorize
|
39
|
+
resources :checkout
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
module Exceptions
|
46
|
+
class AccessTokenError < StandardError; end
|
47
|
+
class ExpiredTokenError < StandardError; end
|
48
|
+
class InitializeCheckoutError < StandardError; end
|
49
|
+
class AuthorizationError < StandardError; end
|
50
|
+
class WepayCheckoutError < StandardError; end
|
51
|
+
class WepayApiError < StandardError; end
|
52
|
+
end
|
53
|
+
|
54
|
+
module Payments
|
55
|
+
class Gateway
|
56
|
+
include HTTParty
|
57
|
+
base_uri @base_uri
|
58
|
+
default_timeout 30000
|
59
|
+
|
60
|
+
attr_accessor :access_token
|
61
|
+
attr_accessor :account_id
|
62
|
+
|
63
|
+
# Pass in the wepay access token that we got after the oauth handshake
|
64
|
+
# and use it for ongoing communique with Wepay.
|
65
|
+
# This also relies heavily on there being a wepay.yml file in your
|
66
|
+
# rails config directory - it must look like this:
|
67
|
+
def initialize(*args)
|
68
|
+
@wepay_config = WepayRails::Configuration.settings || {:scope => []}
|
69
|
+
@access_token = args.first || @wepay_config[:access_token]
|
70
|
+
@account_id = args.first || @wepay_config[:account_id]
|
71
|
+
@ui_endpoint = @wepay_config[:wepay_ui_endpoint] || "https://www.wepay.com/v2"
|
72
|
+
@api_endpoint = @wepay_config[:wepay_api_endpoint] || "https://wepayapi.com/v2"
|
73
|
+
end
|
74
|
+
|
75
|
+
# Get the auth code url that will be used to fetch the auth code for the customer
|
76
|
+
# arguments are the redirect_uri and an array of permissions that your application needs
|
77
|
+
# ex. ['manage_accounts','collect_payments','view_balance','view_user']
|
78
|
+
def auth_code_url(redirect_uri, params = {})
|
79
|
+
params[:client_id] ||= @wepay_config[:client_id]
|
80
|
+
params[:scope] ||= @wepay_config[:scope].join(',')
|
81
|
+
params[:redirect_uri] = redirect_uri
|
82
|
+
query = params.map { |k, v| "#{k.to_s}=#{v}" }.join('&')
|
83
|
+
|
84
|
+
"#{@ui_endpoint}/oauth2/authorize?#{query}"
|
85
|
+
end
|
86
|
+
|
87
|
+
def wepay_auth_header
|
88
|
+
@access_token.blank? ? {'User-Agent' => "WepayRails"}
|
89
|
+
: {'User-Agent' => "WepayRails", 'Authorization' => "Bearer: #{@access_token}"}
|
90
|
+
end
|
91
|
+
|
92
|
+
def configuration
|
93
|
+
@wepay_config
|
94
|
+
end
|
95
|
+
|
96
|
+
def raise_if_response_error(json)
|
97
|
+
if json.has_key?(:error) && json.has_key?(:error_description)
|
98
|
+
if ['invalid code parameter','the code has expired','this access_token has been revoked', 'a valid access_token is required'].include?(json[:error_description])
|
99
|
+
raise WepayRails::Exceptions::ExpiredTokenError.new("Token either expired, revoked or invalid: #{json[:error_description]}")
|
100
|
+
else
|
101
|
+
raise WepayRails::Exceptions::WepayApiError.new(json[:error_description])
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def symbolize_response(response)
|
107
|
+
json = JSON.parse(response)
|
108
|
+
if json.kind_of? Hash
|
109
|
+
json.symbolize_keys! and raise_if_response_error(json)
|
110
|
+
elsif json.kind_of? Array
|
111
|
+
json.each{|h| h.symbolize_keys!}
|
112
|
+
end
|
113
|
+
json
|
114
|
+
end
|
115
|
+
|
116
|
+
def call_api(api_path, params={}, timeout=30000)
|
117
|
+
begin
|
118
|
+
self.class.default_timeout(timeout)
|
119
|
+
response = self.class.post("#{@api_endpoint}#{api_path}", {:headers => wepay_auth_header, :body => params})
|
120
|
+
json = symbolize_response(response.body)
|
121
|
+
rescue Errno, JSON::ParserError => e
|
122
|
+
raise WepayRails::Exceptions::WepayApiError.new("The request to WePay timed out. This might mean you sent an invalid request or WePay is having issues.")
|
123
|
+
rescue => e
|
124
|
+
raise e if e.class.to_s =~ /WepayRails/
|
125
|
+
raise WepayRails::Exceptions::WepayApiError.new("There was an error while trying to connect with WePay - #{e.inspect}")
|
126
|
+
end
|
127
|
+
if response.success?
|
128
|
+
return json
|
129
|
+
elsif response.code == 401
|
130
|
+
raise WepayRails::Exceptions::ExpiredTokenError.new("Token either expired, revoked or invalid: #{json.inspect}.")
|
131
|
+
else
|
132
|
+
raise WepayRails::Exceptions::WepayApiError.new("The API request failed with error code ##{response.code}: #{json.inspect}.")
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
# Fetch the access token from wepay for the auth code
|
137
|
+
def get_access_token(auth_code, redirect_uri)
|
138
|
+
params = {
|
139
|
+
:client_id => @wepay_config[:client_id],
|
140
|
+
:client_secret => @wepay_config[:client_secret],
|
141
|
+
:redirect_uri => redirect_uri,
|
142
|
+
:code => auth_code
|
143
|
+
}
|
144
|
+
json = call_api("/oauth2/token", params)
|
145
|
+
raise WepayRails::Exceptions::AccessTokenError.new("A problem occurred trying to get the access token: #{json.inspect}") unless json.has_key?(:access_token)
|
146
|
+
@account_id = json[:user_id]
|
147
|
+
@access_token = json[:access_token]
|
148
|
+
end
|
149
|
+
|
150
|
+
include WepayRails::Api::AccountMethods
|
151
|
+
include WepayRails::Api::CheckoutMethods
|
152
|
+
end
|
153
|
+
|
154
|
+
include WepayRails::Exceptions
|
155
|
+
include WepayRails::Helpers::ControllerHelpers
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
data/test/helper.rb
CHANGED
@@ -1,18 +1,102 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'bundler'
|
3
|
-
begin
|
4
|
-
Bundler.setup(:default, :development)
|
5
|
-
rescue Bundler::BundlerError => e
|
6
|
-
$stderr.puts e.message
|
7
|
-
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
-
exit e.status_code
|
9
|
-
end
|
10
|
-
require '
|
11
|
-
require '
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'rails/all'
|
11
|
+
require 'rails/test_help'
|
12
|
+
require 'thor'
|
13
|
+
require 'webmock/minitest'
|
14
|
+
|
15
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
16
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
17
|
+
require 'wepay-rails'
|
18
|
+
|
19
|
+
module WepayRails
|
20
|
+
class TestsHelper < Thor
|
21
|
+
include Thor::Actions
|
22
|
+
source_root File.expand_path(File.dirname(__FILE__))
|
23
|
+
|
24
|
+
no_tasks do
|
25
|
+
def create_wepay_config_file(erb=false, defaults=false)
|
26
|
+
copy_file "../lib/generators/wepay_rails/install/templates/wepay.yml", "../config/wepay.yml#{'.erb' if erb}", verbose: false, force: true
|
27
|
+
gsub_file "../config/wepay.yml.erb", "<your access token that you received when you went to http://your.domain.com/wepay/authorize>", "<%= 'abc' * 3 %>", verbose: false if erb
|
28
|
+
add_config_defaults(erb) if defaults
|
29
|
+
end
|
30
|
+
|
31
|
+
def add_config_defaults(erb=false, client_id="168738", client_secret="8d701ad2ac")
|
32
|
+
gsub_file "../config/wepay.yml#{'.erb' if erb}", "<your client id from wepay>", client_id, verbose: false
|
33
|
+
gsub_file "../config/wepay.yml#{'.erb' if erb}", "<your client secret from wepay>", client_secret, verbose: false
|
34
|
+
end
|
35
|
+
|
36
|
+
def delete_wepay_config_file
|
37
|
+
remove_file "../config/wepay.yml", verbose: false
|
38
|
+
remove_file "../config/wepay.yml.erb", verbose: false
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class ActiveSupport::TestCase
|
45
|
+
TEST_ACCESS_TOKEN = "1c69cebd40ababb0447700377dd7751bb645e874edac140f1ba0c35ad6e98c97"
|
46
|
+
|
47
|
+
def wepay_gateway(token=TEST_ACCESS_TOKEN)
|
48
|
+
@wepay_gateway ||= WepayRails::Payments::Gateway.new(token)
|
49
|
+
end
|
50
|
+
|
51
|
+
def helper
|
52
|
+
@helper ||= WepayRails::TestsHelper.new
|
53
|
+
end
|
54
|
+
|
55
|
+
def create_wepay_config_file(erb=false, defaults=false)
|
56
|
+
helper.create_wepay_config_file(erb, defaults)
|
57
|
+
end
|
58
|
+
|
59
|
+
def delete_wepay_config_file
|
60
|
+
helper.delete_wepay_config_file
|
61
|
+
end
|
62
|
+
|
63
|
+
def initialize_wepay_config
|
64
|
+
yml = "../config/wepay.yml"
|
65
|
+
if File.exists?(yml)
|
66
|
+
settings = YAML.load_file(yml)[Rails.env].symbolize_keys
|
67
|
+
elsif File.exists?(yml+".erb")
|
68
|
+
settings = YAML::load(ERB.new(IO.read(yml+".erb")).result)[Rails.env].symbolize_keys
|
69
|
+
end
|
70
|
+
WepayRails::Configuration.init_conf(settings)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Stubs for API calls
|
74
|
+
# Uncomment the next line to allow live API calls
|
75
|
+
# WebMock.allow_net_connect!(:net_http_connect_on_start => true)
|
76
|
+
|
77
|
+
def sample_account_response(options={})
|
78
|
+
{ "account_id" => "12345",
|
79
|
+
"name" => "Example Account",
|
80
|
+
"description" => "This is just an example WePay account.",
|
81
|
+
"account_uri" => "https://stage.wepay.com/account/12345" }.merge(options).to_json
|
82
|
+
end
|
83
|
+
|
84
|
+
def sample_find_response(options={})
|
85
|
+
[{ "account_id" => "12345",
|
86
|
+
"name" => "Custom Reference ID",
|
87
|
+
"description" => "This is just an example WePay account.",
|
88
|
+
"reference_id" => "wepayrailstestaccount123",
|
89
|
+
"account_uri" => "https://stage.wepay.com/account/12345" }.merge(options)].to_json
|
90
|
+
end
|
91
|
+
|
92
|
+
def sample_balance_response(options={})
|
93
|
+
{ "pending_balance" => "500",
|
94
|
+
"available_balance" => "500",
|
95
|
+
"currency" => "USD" }.merge(options).to_json
|
96
|
+
end
|
97
|
+
|
98
|
+
def sample_checkout_response(options={})
|
99
|
+
{ "checkout_id" => "6789",
|
100
|
+
"checkout_uri" => "http://stage.wepay.com/api/checkout/6789" }.merge(options).to_json
|
101
|
+
end
|
102
|
+
end
|