spreedly-core-ruby 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/README.md +18 -18
- data/lib/spreedly-core-ruby.rb +33 -24
- data/lib/spreedly-core-ruby/base.rb +20 -13
- data/lib/spreedly-core-ruby/payment_method.rb +6 -6
- data/lib/spreedly-core-ruby/test_extensions.rb +7 -7
- data/lib/spreedly-core-ruby/transactions.rb +1 -1
- data/lib/spreedly-core-ruby/version.rb +1 -1
- data/test/configuration_test.rb +10 -10
- data/test/spreedly_core_test.rb +31 -13
- data/test/test_common.rb +2 -2
- metadata +40 -59
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NTcwNzJhMjA5NjNlNGJlOTdlNjdiZDQzZWU1ZjJlMWM0MjMyODEzOA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
YjMxYWZhZGU2N2I3ODhmYWM2ZDJiYjI4NTQ1NTMyZTZjNzcxOGU3Nw==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
YTQ3MTFiMzk1NjJkMDY0OTU3MjdkMmVjMGRlYzNiMzQ0OWI2MzYyMGQ0ZDNk
|
10
|
+
NGZiMGRkNDVjNzM0ODY2NmE5ZjdjZWEwN2E0NDBiODdkMTNkYmI4YmVjM2Ni
|
11
|
+
YjgxODliZTlhZmIxYTBmOWY4MTNkNTFjMjVlNGE2ZGIzODhiOWQ=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ZTRiZTgwNzE5OThhOGRmZDhlY2JhOGRlOWE0MGQ5MzNjNGY2ZWE5MmM0M2M5
|
14
|
+
ZDk1ZmQxMmI3ODE1NDc0Y2E0ZjFjOTliZDU5NTk4MTc3YTE3NWM3YjE2ZThl
|
15
|
+
NDZkYmZhNzY3NzYyNzM1MzcxM2E3YzI3ZDgzMDVlMWJlNjVkNzk=
|
data/README.md
CHANGED
@@ -1,20 +1,20 @@
|
|
1
|
-
|
1
|
+
Spreedly
|
2
2
|
======
|
3
|
-
spreedly-core-ruby is a Ruby library for accessing the [Spreedly
|
3
|
+
spreedly-core-ruby is a Ruby library for accessing the [Spreedly API](https://spreedly.com/). Spreedly is a Software-as-a-Service billing solution that serves two major functions for companies and developers.
|
4
4
|
|
5
|
-
* First, it removes your [PCI Compliance](https://www.pcisecuritystandards.org/) requirement by pushing the card data handling and storage outside of your application. This is possible by having your customers POST their credit card info to the Spreedly
|
5
|
+
* First, it removes your [PCI Compliance](https://www.pcisecuritystandards.org/) requirement by pushing the card data handling and storage outside of your application. This is possible by having your customers POST their credit card info to the Spreedly service while embedding a transparent redirect URL back to your application (see "Submit payment form" on [the quick start guide](https://spreedly.com/manual/quickstart)).
|
6
6
|
* Second, it removes any possibility of your gateway locking you in by owning your customer billing data (yes, this happens). By allowing you to charge any card against whatever gateways you as a company have signed up for, you retain all of your customer data and can switch between gateways as you please. Also, expanding internationally won't require an additional technical integration with yet another gateway.
|
7
7
|
|
8
8
|
Credit where credit is due: our friends over at [403 Labs](http://www.403labs.com/) carried most of the weight in cutting the initial version of this gem, and we can't thank them enough for their work.
|
9
9
|
|
10
10
|
Quickstart
|
11
11
|
----------
|
12
|
-
Head over to the [Spreedly
|
12
|
+
Head over to the [Spreedly Website](https://www.spreedly.com) to sign up for an account. It's free to get started and play with test gateways/transactions using our specified test card data.
|
13
13
|
|
14
14
|
RubyGems:
|
15
15
|
|
16
|
-
export
|
17
|
-
export
|
16
|
+
export SPREEDLYCORE_ENVIRONMENT_KEY=your_environment_key_here
|
17
|
+
export SPREEDLYCORE_ACCESS_SECRET=your_secret_here
|
18
18
|
gem install spreedly-core-ruby
|
19
19
|
irb
|
20
20
|
require 'rubygems'
|
@@ -26,12 +26,12 @@ The first thing we'll need to do is set up a test gateway that we can run transa
|
|
26
26
|
tg = SpreedlyCore::TestGateway.get_or_create
|
27
27
|
tg.use!
|
28
28
|
|
29
|
-
Now that you have a test gateway set up, we'll need to set up your payment form to post the credit card data directly to Spreedly
|
29
|
+
Now that you have a test gateway set up, we'll need to set up your payment form to post the credit card data directly to Spreedly. Spreedly will receive your customer's credit card data, and immediately transfer them back to the location you define inside the web payments form. The user won't know that they're being taken off site to record to the card data, and you as the developer will be left with a token identifier. The token identifier is used to make your charges against, and to access the customer's non-sensitive billing information.
|
30
30
|
|
31
|
-
<form action="https://
|
31
|
+
<form action="https://core.spreedly.com/v1/payment_methods" method="POST">
|
32
32
|
<fieldset>
|
33
33
|
<input name="redirect_url" type="hidden" value="http://example.com/transparent_redirect_complete" />
|
34
|
-
<input name="
|
34
|
+
<input name="environment_key" type="hidden" value="Ll6fAtoVSTyVMlJEmtpoJV8Shw5" />
|
35
35
|
<label for="credit_card_first_name">First name</label>
|
36
36
|
<input id="credit_card_first_name" name="credit_card[first_name]" type="text" />
|
37
37
|
|
@@ -52,11 +52,11 @@ Now that you have a test gateway set up, we'll need to set up your payment form
|
|
52
52
|
</fieldset>
|
53
53
|
</form>
|
54
54
|
|
55
|
-
Take special note of the **
|
55
|
+
Take special note of the **environment_key** and **redirect_url** params hidden in the form, as Spreedly will use both of these fields to authenticate the developer's account and to send the customer back to the right location in your app.
|
56
56
|
|
57
57
|
A note about test card data
|
58
58
|
----------------
|
59
|
-
If you've just signed up and have not entered your billing information (or selected a Heroku paid plan), you will only be permitted to deal with [test credit card data](https://
|
59
|
+
If you've just signed up and have not entered your billing information (or selected a Heroku paid plan), you will only be permitted to deal with [test credit card data](https://core.spreedly.com/manual/test-data).
|
60
60
|
|
61
61
|
Once you've created your web form and submitted one of the test cards above, you should be returned to your app with a token identifier by which to identify your newly created payment method. Let's go ahead and look up that payment method by the token returned to your app, and we'll charge $5.50 to it.
|
62
62
|
|
@@ -71,7 +71,7 @@ Once you've created your web form and submitted one of the test cards above, you
|
|
71
71
|
|
72
72
|
Saving Payment Methods
|
73
73
|
----------
|
74
|
-
Spreedly
|
74
|
+
Spreedly allows you to retain payment methods provided by your customer for future use. In general, removing the friction from your checkout process is one of the best things you can do for your application, and using Spreedly will allow you to avoid making your customer input their payment details for every purchase.
|
75
75
|
|
76
76
|
payment_token = 'abc123' # extracted from the URL params
|
77
77
|
payment_method = SpreedlyCore::PaymentMethod.find(payment_token)
|
@@ -81,7 +81,7 @@ Spreedly Core allows you to retain payment methods provided by your customer for
|
|
81
81
|
retain_transaction.succeeded? # true
|
82
82
|
end
|
83
83
|
|
84
|
-
Payment methods that you no longer want to retain can be redacted from Spreedly
|
84
|
+
Payment methods that you no longer want to retain can be redacted from Spreedly. A redacted payment method has its sensitive information removed.
|
85
85
|
|
86
86
|
payment_token = 'abc123' # extracted from the URL params
|
87
87
|
payment_method = SpreedlyCore::PaymentMethod.find(payment_token)
|
@@ -128,7 +128,7 @@ Handling Exceptions
|
|
128
128
|
--------
|
129
129
|
There are 3 types of exceptions which can be raised by the library:
|
130
130
|
|
131
|
-
1. SpreedlyCore::TimeOutError is raised if communication with Spreedly
|
131
|
+
1. SpreedlyCore::TimeOutError is raised if communication with Spreedly takes longer than 10 seconds
|
132
132
|
2. SpreedlyCore::InvalidResponse is raised when the response code is unexpected (I.E. we expect a HTTP response code of 200 bunt instead got a 500) or if the response does not contain an expected attribute. For example, the response from retaining a payment method should contain an XML attribute of "transaction". If this is not found (for example a HTTP response 404 or 500 is returned), then an InvalidResponse is raised.
|
133
133
|
3. SpreedlyCore::UnprocessableRequest is raised when the response code is 422. This denotes a validation error where one or more of the data fields submitted were not valid, or the whole record was unable to be saved/updated. Inspection of the exception message will give an explanation of the issue.
|
134
134
|
|
@@ -144,12 +144,12 @@ For example, let's look up a payment method that does not exist:
|
|
144
144
|
end
|
145
145
|
|
146
146
|
|
147
|
-
Configuring
|
147
|
+
Configuring Spreedly for Use in Production (Rails example)
|
148
148
|
----------
|
149
149
|
When you're ready for primetime, you'll need to complete a couple more steps to start processing real transactions.
|
150
150
|
|
151
|
-
1. First, you'll need to get your business (or personal) payment details on file with Spreedly
|
152
|
-
2. Second, you'll need to acquire a gateway that you can plug into the back of Spreedly
|
151
|
+
1. First, you'll need to get your business (or personal) payment details on file with Spreedly so that we can collect transaction and card retention fees. For those of you using Heroku, simply change your Spreedly addon to the paid tier.
|
152
|
+
2. Second, you'll need to acquire a gateway that you can plug into the back of Spreedly. Any of the major players will work, and you're not at risk of lock-in because Spreedly happily plays middle man. Please consult our [list of supported gateways](https://core.spreedly.com/manual/gateways) to see exactly what information you'll need to pass to Spreedly when creating your gateway profile.
|
153
153
|
|
154
154
|
For this example, I will be using an Authorize.net account that only has a login and password credential.
|
155
155
|
|
@@ -163,7 +163,7 @@ For this example, I will be using an Authorize.net account that only has a login
|
|
163
163
|
For most users, you will start off using only one gateway token, and as such can configure it as an environment variable to hold your gateway token. In addition to the previous environment variables, the `SpreedlyCore.configure` method will also look for a SPREEDLYCORE_GATEWAY_TOKEN environment value.
|
164
164
|
|
165
165
|
# create an initializer at config/initializers/spreedly_core.rb
|
166
|
-
# values already set for ENV['
|
166
|
+
# values already set for ENV['SPREEDLYCORE_ENVIRONMENT_KEY'], ENV['SPREEDLYCORE_ACCESS_SECRET'], and ENV['SPREEDLYCORE_GATEWAY_TOKEN']
|
167
167
|
SpreedlyCore.configure
|
168
168
|
|
169
169
|
If you wish to require additional credit card fields, the initializer is the best place to set this up.
|
data/lib/spreedly-core-ruby.rb
CHANGED
@@ -12,7 +12,7 @@ require 'spreedly-core-ruby/transactions'
|
|
12
12
|
require 'active_support/core_ext/hash/conversions'
|
13
13
|
|
14
14
|
module SpreedlyCore
|
15
|
-
# Hash of user friendly credit card name to
|
15
|
+
# Hash of user friendly credit card name to Spreedly API name
|
16
16
|
CARD_TYPES = {
|
17
17
|
"Visa" => "visa",
|
18
18
|
"MasterCard" => "master",
|
@@ -22,7 +22,7 @@ module SpreedlyCore
|
|
22
22
|
|
23
23
|
class Error < RuntimeError; end
|
24
24
|
|
25
|
-
# Custom exception which occurs when a request to
|
25
|
+
# Custom exception which occurs when a request to Spreedly times out
|
26
26
|
# See SpreedlyCore::Base.default_timeout
|
27
27
|
class TimeOutError < Error; end
|
28
28
|
class InvalidResponse < Error
|
@@ -42,23 +42,23 @@ module SpreedlyCore
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
-
# Configure
|
45
|
+
# Configure Spreedly with a particular account.
|
46
46
|
# Strongly prefers environment variables for credentials
|
47
47
|
# and will issue a stern warning should they not be present.
|
48
|
-
# Reluctantly accepts :
|
48
|
+
# Reluctantly accepts :environment_key and :access_secret as options
|
49
49
|
def self.configure(options = {})
|
50
|
-
|
51
|
-
secret = ENV['SPREEDLYCORE_API_SECRET']
|
50
|
+
environment_key = (ENV["SPREEDLYCORE_ENVIRONMENT_KEY"] || ENV['SPREEDLYCORE_API_LOGIN'])
|
51
|
+
secret = (ENV["SPREEDLYCORE_ACCESS_SECRET"] || ENV['SPREEDLYCORE_API_SECRET'])
|
52
52
|
gateway_token = ENV['SPREEDLYCORE_GATEWAY_TOKEN']
|
53
53
|
|
54
|
-
if options[:api_login]
|
55
|
-
Kernel.warn("ENV and arg both present for
|
56
|
-
|
54
|
+
if(options[:environment_key] || options[:api_login])
|
55
|
+
Kernel.warn("ENV and arg both present for environment_key. Defaulting to arg value") if environment_key
|
56
|
+
environment_key = (options[:environment_key] || options[:api_login])
|
57
57
|
end
|
58
58
|
|
59
|
-
if options[:api_secret]
|
60
|
-
Kernel.warn("ENV and arg both present for
|
61
|
-
secret = options[:api_secret]
|
59
|
+
if(options[:access_secret] || options[:api_secret])
|
60
|
+
Kernel.warn("ENV and arg both present for access_secret. Defaulting to arg value") if secret
|
61
|
+
secret = (options[:access_secret] || options[:api_secret])
|
62
62
|
end
|
63
63
|
|
64
64
|
if options[:gateway_token]
|
@@ -67,18 +67,18 @@ module SpreedlyCore
|
|
67
67
|
end
|
68
68
|
options[:gateway_token] ||= gateway_token
|
69
69
|
|
70
|
-
if
|
71
|
-
Kernel.warn("It is STRONGLY preferred that you house your Spreedly
|
72
|
-
Kernel.warn("This gem prefers only environment variables named
|
70
|
+
if(options[:environment_key] || options[:access_secret])
|
71
|
+
Kernel.warn("It is STRONGLY preferred that you house your Spreedly credentials only in environment variables.")
|
72
|
+
Kernel.warn("This gem prefers only environment variables named SPREEDLYCORE_ENVIRONMENT_KEY, SPREEDLYCORE_ACCESS_SECRET, and optionally SPREEDLYCORE_GATEWAY_TOKEN.")
|
73
73
|
end
|
74
74
|
|
75
|
-
if
|
76
|
-
raise ArgumentError.new("You must provide a
|
75
|
+
if environment_key.nil? || secret.nil?
|
76
|
+
raise ArgumentError.new("You must provide a environment_key and a secret. Gem will look for ENV['SPREEDLYCORE_ENVIRONMENT_KEY'] and ENV['SPREEDLYCORE_ACCESS_SECRET'], but you may also pass in a hash with :environment_key and :access_secret keys.")
|
77
77
|
end
|
78
78
|
|
79
|
-
options[:endpoint] ||= "https://
|
79
|
+
options[:endpoint] ||= "https://core.spreedly.com/#{SpreedlyCore::API_VERSION}"
|
80
80
|
|
81
|
-
Base.configure(
|
81
|
+
Base.configure(environment_key, secret, options)
|
82
82
|
end
|
83
83
|
|
84
84
|
def self.gateway_token=(gateway_token)
|
@@ -89,13 +89,22 @@ module SpreedlyCore
|
|
89
89
|
Base.gateway_token
|
90
90
|
end
|
91
91
|
|
92
|
-
# returns the configured
|
93
|
-
def self.
|
92
|
+
# returns the configured Spreedly environment key
|
93
|
+
def self.environment_key; Base.environment_key; end
|
94
94
|
|
95
95
|
# A container for a response from a payment gateway
|
96
96
|
class Response < Base
|
97
|
-
attr_reader(
|
98
|
-
|
99
|
-
|
97
|
+
attr_reader(
|
98
|
+
:success,
|
99
|
+
:message,
|
100
|
+
:avs_code,
|
101
|
+
:avs_message,
|
102
|
+
:cvv_code,
|
103
|
+
:cvv_message,
|
104
|
+
:error_code,
|
105
|
+
:error_detail,
|
106
|
+
:created_at,
|
107
|
+
:updated_at
|
108
|
+
)
|
100
109
|
end
|
101
110
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spreedly-core-ruby/version'
|
2
2
|
|
3
3
|
module SpreedlyCore
|
4
|
-
# Base class for all
|
4
|
+
# Base class for all Spreedly API requests
|
5
5
|
class Base
|
6
6
|
include HTTParty
|
7
7
|
|
@@ -14,14 +14,14 @@ module SpreedlyCore
|
|
14
14
|
format :xml
|
15
15
|
default_timeout 75
|
16
16
|
|
17
|
-
def self.configure(
|
18
|
-
@@
|
19
|
-
self.basic_auth(@@
|
17
|
+
def self.configure(environment_key, secret, options = {})
|
18
|
+
@@environment_key = environment_key
|
19
|
+
self.basic_auth(@@environment_key, secret)
|
20
20
|
base_uri options[:endpoint]
|
21
21
|
@@gateway_token = options.delete(:gateway_token)
|
22
22
|
end
|
23
23
|
|
24
|
-
def self.
|
24
|
+
def self.environment_key; @@environment_key; end
|
25
25
|
def self.gateway_token; @@gateway_token; end
|
26
26
|
def self.gateway_token=(gateway_token); @@gateway_token = gateway_token; end
|
27
27
|
|
@@ -58,7 +58,7 @@ module SpreedlyCore
|
|
58
58
|
begin
|
59
59
|
response = self.send(request_type, path, options)
|
60
60
|
rescue Timeout::Error, Errno::ETIMEDOUT => e
|
61
|
-
raise TimeOutError.new("Request to #{path} timed out. Is Spreedly
|
61
|
+
raise TimeOutError.new("Request to #{path} timed out. Is Spreedly down?")
|
62
62
|
end
|
63
63
|
|
64
64
|
if allowed_codes.any? && !allowed_codes.include?(response.code)
|
@@ -87,13 +87,20 @@ module SpreedlyCore
|
|
87
87
|
instance_variable_set("@#{k}", v)
|
88
88
|
end
|
89
89
|
# errors may be nil, empty, a string, or an array of strings.
|
90
|
-
@errors = if
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
90
|
+
@errors = if(@errors.nil? || @errors["error"].blank?)
|
91
|
+
[]
|
92
|
+
elsif @errors["error"].is_a?(String)
|
93
|
+
[@errors["error"]]
|
94
|
+
else
|
95
|
+
@errors["error"].collect do |error|
|
96
|
+
case error
|
97
|
+
when Hash
|
98
|
+
error["__content__"]
|
99
|
+
else
|
100
|
+
error
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
97
104
|
end
|
98
105
|
end
|
99
106
|
end
|
@@ -91,12 +91,12 @@ module SpreedlyCore
|
|
91
91
|
@has_been_validated = true
|
92
92
|
self.class.additional_required_cc_fields.each do |field|
|
93
93
|
if instance_variable_get("@#{field}").blank?
|
94
|
-
str_field= field.to_s
|
95
|
-
friendly_name = if
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
94
|
+
str_field = field.to_s
|
95
|
+
friendly_name = if(str_field.respond_to?(:humanize))
|
96
|
+
str_field.humanize
|
97
|
+
else
|
98
|
+
str_field.split("_").join(" ")
|
99
|
+
end
|
100
100
|
|
101
101
|
@errors << "#{friendly_name.capitalize} can't be blank"
|
102
102
|
end
|
@@ -4,18 +4,18 @@ require 'uri'
|
|
4
4
|
module SpreedlyCore
|
5
5
|
module TestHelper
|
6
6
|
extend self
|
7
|
-
|
7
|
+
|
8
8
|
def cc_data(cc_type, options={})
|
9
|
-
|
9
|
+
|
10
10
|
card_numbers = {:master => [5555555555554444, 5105105105105100],
|
11
11
|
:visa => [4111111111111111, 4012888888881881],
|
12
12
|
:american_express => [378282246310005, 371449635398431],
|
13
13
|
:discover => [6011111111111117, 6011000990139424]
|
14
14
|
}
|
15
|
-
|
15
|
+
|
16
16
|
card_number = options[:card_number] == :failed ? :last : :first
|
17
17
|
number = card_numbers[cc_type].send(card_number)
|
18
|
-
|
18
|
+
|
19
19
|
{ :credit_card => {
|
20
20
|
:first_name => "John",
|
21
21
|
:last_name => "Foo",
|
@@ -26,7 +26,7 @@ module SpreedlyCore
|
|
26
26
|
:year => Time.now.year + 1 }.merge(options[:credit_card] || {})
|
27
27
|
}
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
# Return the base uri as a mocking framework would expect
|
31
31
|
def mocked_base_uri_string
|
32
32
|
uri = URI.parse(Base.base_uri)
|
@@ -38,9 +38,9 @@ module SpreedlyCore
|
|
38
38
|
end
|
39
39
|
|
40
40
|
class PaymentMethod
|
41
|
-
# Call spreedly
|
41
|
+
# Call spreedly to create a test token.
|
42
42
|
# pass_through_data will be added as the "data" field.
|
43
|
-
#
|
43
|
+
#
|
44
44
|
def self.create_test_token(cc_overrides = {})
|
45
45
|
card = {
|
46
46
|
:first_name => "John",
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module SpreedlyCore
|
2
|
-
# Abstract class for all the different spreedly
|
2
|
+
# Abstract class for all the different spreedly transactions
|
3
3
|
class Transaction < Base
|
4
4
|
attr_reader(:amount, :on_test_gateway, :created_at, :updated_at, :currency_code,
|
5
5
|
:succeeded, :token, :message, :transaction_type, :gateway_token,
|
data/test/configuration_test.rb
CHANGED
@@ -6,25 +6,25 @@ module SpreedlyCore
|
|
6
6
|
def test_configure
|
7
7
|
old_verbose, $VERBOSE = $VERBOSE, nil
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
old_environment_key = ENV['SPREEDLYCORE_ENVIRONMENT_KEY']
|
10
|
+
old_access_secret = ENV['SPREEDLYCORE_ACCESS_SECRET']
|
11
11
|
old_gateway_token = ENV['SPREEDLYCORE_GATEWAY_TOKEN']
|
12
|
-
ENV['
|
13
|
-
ENV['
|
12
|
+
ENV['SPREEDLYCORE_ENVIRONMENT_KEY'] = nil
|
13
|
+
ENV['SPREEDLYCORE_ACCESS_SECRET'] = nil
|
14
14
|
ENV['SPREEDLYCORE_GATEWAY_TOKEN'] = nil
|
15
15
|
|
16
16
|
assert_nothing_raised ArgumentError do
|
17
|
-
SpreedlyCore.configure :
|
18
|
-
:
|
17
|
+
SpreedlyCore.configure :environment_key => "test",
|
18
|
+
:access_secret => "secret",
|
19
19
|
:gateway_token => "token"
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
assert_raises ArgumentError do
|
23
23
|
SpreedlyCore.configure
|
24
24
|
end
|
25
25
|
|
26
|
-
ENV['
|
27
|
-
ENV['
|
26
|
+
ENV['SPREEDLYCORE_ENVIRONMENT_KEY'] = old_environment_key
|
27
|
+
ENV['SPREEDLYCORE_ACCESS_SECRET'] = old_access_secret
|
28
28
|
ENV['SPREEDLYCORE_GATEWAY_TOKEN'] = 'any_value'
|
29
29
|
|
30
30
|
SpreedlyCore.gateway_token = nil
|
@@ -37,6 +37,6 @@ module SpreedlyCore
|
|
37
37
|
ensure
|
38
38
|
$VERBOSE = old_verbose
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
41
|
end
|
42
42
|
end
|
data/test/spreedly_core_test.rb
CHANGED
@@ -3,7 +3,7 @@ require 'test_common'
|
|
3
3
|
|
4
4
|
# In order to run tests
|
5
5
|
# 1. cp test/config/spreedly_core.yml.example to test/config/spreedly_core.yml
|
6
|
-
# 2. Add your spreedly
|
6
|
+
# 2. Add your spreedly credentials to test/config/spreedly_core.yml
|
7
7
|
module SpreedlyCore
|
8
8
|
class SpreedlyCoreTest < Test::Unit::TestCase
|
9
9
|
include TestCommon
|
@@ -29,6 +29,24 @@ module SpreedlyCore
|
|
29
29
|
assert_equal 2015, payment_method.year
|
30
30
|
end
|
31
31
|
|
32
|
+
def test_payment_token_with_multiple_errors
|
33
|
+
response = HTTParty.post(
|
34
|
+
"https://core.spreedly.com/v1/payment_methods",
|
35
|
+
body: [
|
36
|
+
"environment_key=#{SpreedlyCore.environment_key}",
|
37
|
+
"redirect_url=http://example.com",
|
38
|
+
"credit_card[number]=4111111111111111"
|
39
|
+
].join("&"),
|
40
|
+
format: :plain,
|
41
|
+
follow_redirects: false
|
42
|
+
)
|
43
|
+
token = response.headers["location"].split("token=").last
|
44
|
+
assert payment_method = SpreedlyCore::PaymentMethod.find(token)
|
45
|
+
assert_nil payment_method.first_name
|
46
|
+
assert_nil payment_method.last_name
|
47
|
+
assert !payment_method.errors.empty?, payment_method.errors.inspect
|
48
|
+
end
|
49
|
+
|
32
50
|
def test_can_find_payment_method
|
33
51
|
payment_method = given_a_payment_method
|
34
52
|
assert PaymentMethod.find(payment_method.token)
|
@@ -44,7 +62,7 @@ module SpreedlyCore
|
|
44
62
|
given_a_retained_transaction
|
45
63
|
end
|
46
64
|
|
47
|
-
# Here we change the token to get an invalid response from spreedly
|
65
|
+
# Here we change the token to get an invalid response from spreedly
|
48
66
|
def test_bad_response_on_retain
|
49
67
|
payment_method = given_a_payment_method
|
50
68
|
payment_method.instance_variable_set("@token", "NOT-FOUND")
|
@@ -66,7 +84,7 @@ module SpreedlyCore
|
|
66
84
|
given_a_redacted_transaction
|
67
85
|
end
|
68
86
|
|
69
|
-
# Here we change the token to get an invalid response from spreedly
|
87
|
+
# Here we change the token to get an invalid response from spreedly
|
70
88
|
def test_bad_response_on_redact
|
71
89
|
payment_method = given_a_payment_method
|
72
90
|
payment_method.instance_variable_set("@token", "NOT-FOUND")
|
@@ -79,7 +97,7 @@ module SpreedlyCore
|
|
79
97
|
given_a_purchase
|
80
98
|
end
|
81
99
|
|
82
|
-
# Here we change the token to get an invalid response from spreedly
|
100
|
+
# Here we change the token to get an invalid response from spreedly
|
83
101
|
def test_bad_response_on_purchase
|
84
102
|
payment_method = given_a_payment_method
|
85
103
|
payment_method.instance_variable_set("@token", "NOT-FOUND")
|
@@ -92,7 +110,7 @@ module SpreedlyCore
|
|
92
110
|
given_an_authorized_transaction
|
93
111
|
end
|
94
112
|
|
95
|
-
# Here we change the token to get an invalid response from spreedly
|
113
|
+
# Here we change the token to get an invalid response from spreedly
|
96
114
|
def test_bad_response_on_authorize
|
97
115
|
payment_method = given_a_payment_method
|
98
116
|
payment_method.instance_variable_set("@token", "NOT-FOUND")
|
@@ -106,10 +124,10 @@ module SpreedlyCore
|
|
106
124
|
|
107
125
|
assert transaction = payment_method.purchase(100)
|
108
126
|
assert !transaction.succeeded?
|
109
|
-
assert_equal("Unable to process the transaction.",
|
127
|
+
assert_equal("Unable to process the purchase transaction.",
|
110
128
|
transaction.message)
|
111
129
|
|
112
|
-
assert_equal("Unable to process the transaction.", transaction.response.message)
|
130
|
+
assert_equal("Unable to process the purchase transaction.", transaction.response.message)
|
113
131
|
end
|
114
132
|
|
115
133
|
def test_can_capture_after_authorize
|
@@ -120,7 +138,7 @@ module SpreedlyCore
|
|
120
138
|
given_a_capture 50
|
121
139
|
end
|
122
140
|
|
123
|
-
# Here we change the token to get an invalid response from spreedly
|
141
|
+
# Here we change the token to get an invalid response from spreedly
|
124
142
|
def test_bad_response_on_capture_after_authorize
|
125
143
|
transaction = given_an_authorized_transaction
|
126
144
|
transaction.instance_variable_set("@token", "NOT-FOUND")
|
@@ -133,7 +151,7 @@ module SpreedlyCore
|
|
133
151
|
given_a_purchase_void
|
134
152
|
end
|
135
153
|
|
136
|
-
# Here we change the token to get an invalid response from spreedly
|
154
|
+
# Here we change the token to get an invalid response from spreedly
|
137
155
|
def test_bad_response_on_void
|
138
156
|
purchase = given_a_purchase
|
139
157
|
purchase.instance_variable_set("@token", "NOT-FOUND")
|
@@ -150,7 +168,7 @@ module SpreedlyCore
|
|
150
168
|
given_a_purchase_credit
|
151
169
|
end
|
152
170
|
|
153
|
-
# Here we change the token to get an invalid response from spreedly
|
171
|
+
# Here we change the token to get an invalid response from spreedly
|
154
172
|
def test_bad_response_on_credit
|
155
173
|
purchase = given_a_purchase
|
156
174
|
purchase.instance_variable_set("@token", "NOT-FOUND")
|
@@ -171,7 +189,6 @@ module SpreedlyCore
|
|
171
189
|
given_a_capture_credit(50, 25)
|
172
190
|
end
|
173
191
|
|
174
|
-
|
175
192
|
def test_can_enforce_additional_payment_method_validations
|
176
193
|
PaymentMethod.additional_required_cc_fields :state
|
177
194
|
|
@@ -182,8 +199,9 @@ module SpreedlyCore
|
|
182
199
|
|
183
200
|
assert_equal "State can't be blank", payment_method.errors.first
|
184
201
|
|
185
|
-
token = PaymentMethod.
|
186
|
-
|
202
|
+
token = PaymentMethod.create_test_token(
|
203
|
+
cc_data(:master, :credit_card => {:state => "IL"})
|
204
|
+
)
|
187
205
|
|
188
206
|
assert payment_method = PaymentMethod.find(token)
|
189
207
|
|
data/test/test_common.rb
CHANGED
@@ -6,7 +6,7 @@ module SpreedlyCore
|
|
6
6
|
include TestFactory
|
7
7
|
|
8
8
|
def setup
|
9
|
-
raise "environment variables for
|
9
|
+
raise "environment variables for SPREEDLYCORE_ENVIRONMENT_KEY and SPREEDLYCORE_ACCESS_SECRET must be set" unless ENV['SPREEDLYCORE_ENVIRONMENT_KEY'] && ENV['SPREEDLYCORE_ACCESS_SECRET']
|
10
10
|
|
11
11
|
SpreedlyCore.configure
|
12
12
|
unless SpreedlyCore.gateway_token
|
@@ -17,4 +17,4 @@ module SpreedlyCore
|
|
17
17
|
PaymentMethod.reset_additional_required_cc_fields
|
18
18
|
end
|
19
19
|
end
|
20
|
-
end
|
20
|
+
end
|
metadata
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spreedly-core-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
version: 0.2.2
|
4
|
+
version: 0.3.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Spreedly
|
@@ -10,107 +9,95 @@ authors:
|
|
10
9
|
autorequire:
|
11
10
|
bindir: bin
|
12
11
|
cert_chain: []
|
13
|
-
date: 2013-
|
12
|
+
date: 2013-04-12 00:00:00.000000000 Z
|
14
13
|
dependencies:
|
15
14
|
- !ruby/object:Gem::Dependency
|
16
|
-
type: :runtime
|
17
|
-
version_requirements: !ruby/object:Gem::Requirement
|
18
|
-
none: false
|
19
|
-
requirements:
|
20
|
-
- - ~>
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: '0.0'
|
23
|
-
name: httparty
|
24
15
|
prerelease: false
|
16
|
+
name: httparty
|
25
17
|
requirement: !ruby/object:Gem::Requirement
|
26
|
-
none: false
|
27
18
|
requirements:
|
28
19
|
- - ~>
|
29
20
|
- !ruby/object:Gem::Version
|
30
21
|
version: '0.0'
|
31
|
-
- !ruby/object:Gem::Dependency
|
32
|
-
type: :runtime
|
33
22
|
version_requirements: !ruby/object:Gem::Requirement
|
34
|
-
none: false
|
35
23
|
requirements:
|
36
24
|
- - ~>
|
37
25
|
- !ruby/object:Gem::Version
|
38
|
-
version: '
|
39
|
-
|
26
|
+
version: '0.0'
|
27
|
+
type: :runtime
|
28
|
+
- !ruby/object:Gem::Dependency
|
40
29
|
prerelease: false
|
30
|
+
name: activesupport
|
41
31
|
requirement: !ruby/object:Gem::Requirement
|
42
|
-
none: false
|
43
32
|
requirements:
|
44
33
|
- - ~>
|
45
34
|
- !ruby/object:Gem::Version
|
46
35
|
version: '3.0'
|
47
|
-
- !ruby/object:Gem::Dependency
|
48
|
-
type: :runtime
|
49
36
|
version_requirements: !ruby/object:Gem::Requirement
|
50
|
-
none: false
|
51
37
|
requirements:
|
52
|
-
- -
|
38
|
+
- - ~>
|
53
39
|
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
55
|
-
|
40
|
+
version: '3.0'
|
41
|
+
type: :runtime
|
42
|
+
- !ruby/object:Gem::Dependency
|
56
43
|
prerelease: false
|
44
|
+
name: builder
|
57
45
|
requirement: !ruby/object:Gem::Requirement
|
58
|
-
none: false
|
59
46
|
requirements:
|
60
47
|
- - ! '>='
|
61
48
|
- !ruby/object:Gem::Version
|
62
49
|
version: '0'
|
63
|
-
- !ruby/object:Gem::Dependency
|
64
|
-
type: :development
|
65
50
|
version_requirements: !ruby/object:Gem::Requirement
|
66
|
-
none: false
|
67
51
|
requirements:
|
68
52
|
- - ! '>='
|
69
53
|
- !ruby/object:Gem::Version
|
70
54
|
version: '0'
|
71
|
-
|
55
|
+
type: :runtime
|
56
|
+
- !ruby/object:Gem::Dependency
|
72
57
|
prerelease: false
|
58
|
+
name: ruby-debug19
|
73
59
|
requirement: !ruby/object:Gem::Requirement
|
74
|
-
none: false
|
75
60
|
requirements:
|
76
61
|
- - ! '>='
|
77
62
|
- !ruby/object:Gem::Version
|
78
63
|
version: '0'
|
79
|
-
- !ruby/object:Gem::Dependency
|
80
|
-
type: :development
|
81
64
|
version_requirements: !ruby/object:Gem::Requirement
|
82
|
-
none: false
|
83
65
|
requirements:
|
84
|
-
- - '
|
66
|
+
- - ! '>='
|
85
67
|
- !ruby/object:Gem::Version
|
86
|
-
version: 0
|
87
|
-
|
68
|
+
version: '0'
|
69
|
+
type: :development
|
70
|
+
- !ruby/object:Gem::Dependency
|
88
71
|
prerelease: false
|
72
|
+
name: rake
|
89
73
|
requirement: !ruby/object:Gem::Requirement
|
90
|
-
none: false
|
91
74
|
requirements:
|
92
75
|
- - '='
|
93
76
|
- !ruby/object:Gem::Version
|
94
77
|
version: 0.8.7
|
95
|
-
- !ruby/object:Gem::Dependency
|
96
|
-
type: :development
|
97
78
|
version_requirements: !ruby/object:Gem::Requirement
|
98
|
-
none: false
|
99
79
|
requirements:
|
100
|
-
- -
|
80
|
+
- - '='
|
101
81
|
- !ruby/object:Gem::Version
|
102
|
-
version:
|
103
|
-
|
82
|
+
version: 0.8.7
|
83
|
+
type: :development
|
84
|
+
- !ruby/object:Gem::Dependency
|
104
85
|
prerelease: false
|
86
|
+
name: webmock
|
105
87
|
requirement: !ruby/object:Gem::Requirement
|
106
|
-
none: false
|
107
88
|
requirements:
|
108
89
|
- - ~>
|
109
90
|
- !ruby/object:Gem::Version
|
110
91
|
version: 1.6.2
|
111
|
-
|
112
|
-
|
113
|
-
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ~>
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 1.6.2
|
97
|
+
type: :development
|
98
|
+
description: Spreedly is a cloud service that allows you to store credit cards and
|
99
|
+
run transactions against them, enabling you to accept payments on your website while
|
100
|
+
avoiding all liability and PCI compliance requirements.
|
114
101
|
email: support@spreedly.com
|
115
102
|
executables: []
|
116
103
|
extensions: []
|
@@ -136,33 +123,27 @@ files:
|
|
136
123
|
- test/test_helper.rb
|
137
124
|
- test/transaction_test.rb
|
138
125
|
homepage: http://github.com/spreedly/spreedly-core-ruby
|
139
|
-
licenses:
|
126
|
+
licenses:
|
127
|
+
- LGPL
|
128
|
+
metadata: {}
|
140
129
|
post_install_message:
|
141
130
|
rdoc_options: []
|
142
131
|
require_paths:
|
143
132
|
- lib
|
144
133
|
required_ruby_version: !ruby/object:Gem::Requirement
|
145
|
-
none: false
|
146
134
|
requirements:
|
147
135
|
- - ! '>='
|
148
136
|
- !ruby/object:Gem::Version
|
149
|
-
segments:
|
150
|
-
- 0
|
151
|
-
hash: 46891149260354335
|
152
137
|
version: '0'
|
153
138
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
154
|
-
none: false
|
155
139
|
requirements:
|
156
140
|
- - ! '>='
|
157
141
|
- !ruby/object:Gem::Version
|
158
|
-
segments:
|
159
|
-
- 0
|
160
|
-
hash: 46891149260354335
|
161
142
|
version: '0'
|
162
143
|
requirements: []
|
163
144
|
rubyforge_project:
|
164
|
-
rubygems_version:
|
145
|
+
rubygems_version: 2.0.0
|
165
146
|
signing_key:
|
166
|
-
specification_version:
|
167
|
-
summary: Ruby interface for Spreedly
|
147
|
+
specification_version: 4
|
148
|
+
summary: Ruby interface for Spreedly
|
168
149
|
test_files: []
|