cashstar-ruby 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.rspec +2 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +48 -0
- data/README.md +47 -0
- data/Rakefile +2 -0
- data/cashstar.gemspec +31 -0
- data/lib/.DS_Store +0 -0
- data/lib/cashstar.rb +28 -0
- data/lib/cashstar/.DS_Store +0 -0
- data/lib/cashstar/api.rb +24 -0
- data/lib/cashstar/authentication.rb +23 -0
- data/lib/cashstar/client.rb +24 -0
- data/lib/cashstar/client/catalog.rb +12 -0
- data/lib/cashstar/client/faceplates.rb +14 -0
- data/lib/cashstar/client/gift_card.rb +41 -0
- data/lib/cashstar/client/merchants.rb +13 -0
- data/lib/cashstar/client/order.rb +30 -0
- data/lib/cashstar/configuration.rb +83 -0
- data/lib/cashstar/connection.rb +46 -0
- data/lib/cashstar/error.rb +36 -0
- data/lib/cashstar/request.rb +43 -0
- data/lib/cashstar/version.rb +3 -0
- data/lib/faraday/request/basic_auth.rb +17 -0
- data/lib/faraday/request/gateway.rb +18 -0
- data/lib/faraday/response/raise_http_4xx.rb +45 -0
- data/lib/faraday/response/raise_http_5xx.rb +24 -0
- data/lib/faraday/response/strip_card_numbers.rb +20 -0
- data/spec/fixtures/merchants.json +17 -0
- data/spec/integration/client/merchants_spec.rb +5 -0
- data/spec/integration/get_merchants_spec.rb +20 -0
- data/spec/spec_helper.rb +19 -0
- metadata +211 -0
data/.rspec
ADDED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
cashstar-ruby
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.9.3
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
cashstar-ruby (0.1.7)
|
5
|
+
faraday (~> 0.8.0)
|
6
|
+
faraday_middleware (~> 0.8.0)
|
7
|
+
hashie (~> 1.2.0)
|
8
|
+
multi_json (~> 1.8.0)
|
9
|
+
multi_xml (~> 0.5.0)
|
10
|
+
|
11
|
+
GEM
|
12
|
+
remote: http://rubygems.org/
|
13
|
+
specs:
|
14
|
+
addressable (2.3.2)
|
15
|
+
crack (0.3.2)
|
16
|
+
diff-lcs (1.1.3)
|
17
|
+
faraday (0.8.9)
|
18
|
+
multipart-post (~> 1.2.0)
|
19
|
+
faraday_middleware (0.8.8)
|
20
|
+
faraday (>= 0.7.4, < 0.9)
|
21
|
+
hashie (1.2.0)
|
22
|
+
metaclass (0.0.1)
|
23
|
+
mocha (0.13.1)
|
24
|
+
metaclass (~> 0.0.1)
|
25
|
+
multi_json (1.8.4)
|
26
|
+
multi_xml (0.5.5)
|
27
|
+
multipart-post (1.2.0)
|
28
|
+
rspec (2.12.0)
|
29
|
+
rspec-core (~> 2.12.0)
|
30
|
+
rspec-expectations (~> 2.12.0)
|
31
|
+
rspec-mocks (~> 2.12.0)
|
32
|
+
rspec-core (2.12.2)
|
33
|
+
rspec-expectations (2.12.1)
|
34
|
+
diff-lcs (~> 1.1.3)
|
35
|
+
rspec-mocks (2.12.1)
|
36
|
+
webmock (1.9.0)
|
37
|
+
addressable (>= 2.2.7)
|
38
|
+
crack (>= 0.1.7)
|
39
|
+
|
40
|
+
PLATFORMS
|
41
|
+
java
|
42
|
+
ruby
|
43
|
+
|
44
|
+
DEPENDENCIES
|
45
|
+
cashstar-ruby!
|
46
|
+
mocha (~> 0.13)
|
47
|
+
rspec (~> 2.12)
|
48
|
+
webmock (~> 1.9)
|
data/README.md
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# A CashStar Ruby Gem
|
2
|
+
A Ruby wrapper for the CashStar REST API
|
3
|
+
|
4
|
+
## <a name="installation">Installation</a>
|
5
|
+
gem install cashstar
|
6
|
+
|
7
|
+
## <a name="Full API Docs">Full Documentation</a>
|
8
|
+
please consult your CashStar API documentation for full use cases and support
|
9
|
+
|
10
|
+
## <a name="Notes">Current Limitations</a>
|
11
|
+
as of v0.1.2, this gems supports json only and only one gift card is supported per order.
|
12
|
+
|
13
|
+
## <a name="examples">Usage Examples</a>
|
14
|
+
require "cashstar"
|
15
|
+
|
16
|
+
# Configure your CashStar settings - for Rails, typically in /config/initializers/cashstar.rb
|
17
|
+
# Optionally, store your credentials for each environment in a cashstar.yml file and load from there.
|
18
|
+
|
19
|
+
Cashstar.configure do |config|
|
20
|
+
config.username = 'username'
|
21
|
+
config.password = 'password'
|
22
|
+
config.endpoint = 'production or semi-production url'
|
23
|
+
config.format = 'json' #or 'xml'
|
24
|
+
end
|
25
|
+
|
26
|
+
# Gift Card numbers are not returned by default - only urls to the hosted Gift Card and the associated challenge phrase
|
27
|
+
# If you need the gift card number and pin, include the following in your config block:
|
28
|
+
|
29
|
+
config.return_card_numbers = true
|
30
|
+
|
31
|
+
# Get all merchants enabled for this account
|
32
|
+
puts Cashstar.merchants
|
33
|
+
|
34
|
+
# Get all faceplates for a merchant
|
35
|
+
puts Cashstar.faceplates(:merchant_code)
|
36
|
+
|
37
|
+
# Build an Order Entity
|
38
|
+
# An order is composed of one or many gift card entities, which are in turn composed of delivery and message entities
|
39
|
+
delivery = Cashstar::Client::Delivery.new(:delivered_by => :CLIENT)
|
40
|
+
message = Cashstar::Client::Message.new(:body => 'Thanks for all the hard work!', :from => 'Santa Claus', :to => 'Rudolph')
|
41
|
+
gift_card = Cashstar::Client::GiftCard.new(:merchant_code => 'GAP', :initial_balance => '100.00', :delivery => delivery, :message => message)
|
42
|
+
order = Cashstar::Client::Order.new(:audit_number => '123456', :gift_card => gift_card) #Audit Number is required
|
43
|
+
|
44
|
+
|
45
|
+
# Issue the built order
|
46
|
+
puts Cashstar.issue(order)
|
47
|
+
|
data/Rakefile
ADDED
data/cashstar.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "cashstar/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "cashstar-ruby"
|
7
|
+
s.version = Cashstar::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Charlie White"]
|
10
|
+
s.email = ["cwhite@cashstar.com"]
|
11
|
+
s.homepage = "http://www.cashstar.com"
|
12
|
+
s.summary = %q{Ruby Bindings for the CashStar API}
|
13
|
+
s.description = %q{CashStar's API provides a simple interface for purchasing and issuing electronic gift cards from a variety of brands}
|
14
|
+
s.rubyforge_project = "cashstar-ruby"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
#s.files = Dir['lib/**/*.rb']
|
21
|
+
|
22
|
+
s.add_dependency 'hashie', '~> 1.2.0'
|
23
|
+
s.add_dependency 'faraday', '~> 0.8.0'
|
24
|
+
s.add_dependency 'faraday_middleware', '~> 0.8.0'
|
25
|
+
s.add_dependency 'multi_json', '~> 1.8.0'
|
26
|
+
s.add_dependency 'multi_xml', '~> 0.5.0'
|
27
|
+
|
28
|
+
s.add_development_dependency 'rspec', '~> 2.12'
|
29
|
+
s.add_development_dependency 'mocha', '~> 0.13'
|
30
|
+
s.add_development_dependency 'webmock', '~> 1.9'
|
31
|
+
end
|
data/lib/.DS_Store
ADDED
Binary file
|
data/lib/cashstar.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'cashstar/api'
|
2
|
+
require 'cashstar/client'
|
3
|
+
require 'cashstar/configuration'
|
4
|
+
require 'cashstar/error'
|
5
|
+
|
6
|
+
|
7
|
+
module Cashstar
|
8
|
+
extend Configuration
|
9
|
+
class << self
|
10
|
+
# Alias for Cashstar::Client.new
|
11
|
+
#
|
12
|
+
# @return [Cashstar::Client]
|
13
|
+
def new(options={})
|
14
|
+
Cashstar::Client.new(options)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
# Delegate to Cashstar::Client
|
19
|
+
def method_missing(method, *args, &block)
|
20
|
+
return super unless new.respond_to?(method)
|
21
|
+
new.send(method, *args, &block)
|
22
|
+
end
|
23
|
+
|
24
|
+
def respond_to?(method, include_private = false)
|
25
|
+
new.respond_to?(method, include_private) || super(method, include_private)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
Binary file
|
data/lib/cashstar/api.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'cashstar/authentication'
|
2
|
+
require 'cashstar/configuration'
|
3
|
+
require 'cashstar/connection'
|
4
|
+
require 'cashstar/request'
|
5
|
+
|
6
|
+
module Cashstar
|
7
|
+
# @private
|
8
|
+
class API
|
9
|
+
include Connection
|
10
|
+
include Request
|
11
|
+
include Authentication
|
12
|
+
|
13
|
+
# @private
|
14
|
+
attr_accessor *Configuration::VALID_OPTIONS_KEYS
|
15
|
+
|
16
|
+
# Creates a new API
|
17
|
+
def initialize(options={})
|
18
|
+
options = Cashstar.options.merge(options)
|
19
|
+
Configuration::VALID_OPTIONS_KEYS.each do |key|
|
20
|
+
send("#{key}=", options[key])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Cashstar
|
2
|
+
# @private
|
3
|
+
module Authentication
|
4
|
+
private
|
5
|
+
|
6
|
+
# Authentication hash
|
7
|
+
#
|
8
|
+
# @return [Hash]
|
9
|
+
def authentication
|
10
|
+
{
|
11
|
+
:username => username,
|
12
|
+
:password => password,
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
# Check whether user is authenticated
|
17
|
+
#
|
18
|
+
# @return [Boolean]
|
19
|
+
def authenticated?
|
20
|
+
authentication.values.all?
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Cashstar
|
2
|
+
# Wrapper for the CashStar REST API
|
3
|
+
#
|
4
|
+
# @note All methods have been separated into modules
|
5
|
+
class Client < API
|
6
|
+
# Require client method modules after initializing the Client class in
|
7
|
+
# order to avoid a superclass mismatch error, allowing those modules to be
|
8
|
+
# Client-namespaced.
|
9
|
+
require 'cashstar/client/merchants'
|
10
|
+
require 'cashstar/client/catalog'
|
11
|
+
require 'cashstar/client/faceplates'
|
12
|
+
require 'cashstar/client/order'
|
13
|
+
require 'cashstar/client/gift_card'
|
14
|
+
|
15
|
+
|
16
|
+
alias :api_endpoint :endpoint
|
17
|
+
|
18
|
+
include Cashstar::Client::Merchants
|
19
|
+
include Cashstar::Client::Faceplates
|
20
|
+
include Cashstar::Client::Catalog
|
21
|
+
include Cashstar::Client::OrderMethods
|
22
|
+
include Cashstar::Client::GiftCardMethods
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Cashstar
|
2
|
+
class Client
|
3
|
+
# Defines methods related to a Cashstar Order
|
4
|
+
module Catalog
|
5
|
+
|
6
|
+
def catalog(merchant_code)
|
7
|
+
response = get("/v2/merchant/#{merchant_code}/catalog/")
|
8
|
+
format.to_s.downcase == 'xml' ? response['catalog'] : response['catalog']
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Cashstar
|
2
|
+
class Client
|
3
|
+
# Defines methods related to a Cashstar Order
|
4
|
+
module Faceplates
|
5
|
+
|
6
|
+
def faceplates(merchant_code)
|
7
|
+
response = get("/v2/merchant/#{merchant_code}/faceplate/")
|
8
|
+
format.to_s.downcase == 'xml' ? response['merchant'] : response['faceplates']['faceplate']
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'hashie'
|
2
|
+
|
3
|
+
module Cashstar
|
4
|
+
class Client
|
5
|
+
module GiftCardMethods
|
6
|
+
def balance_inquiry(merchant, egc_code)
|
7
|
+
response = get("/v2/merchant/#{merchant}/egc/#{egc_code}/balance/")
|
8
|
+
format.to_s.downcase == 'xml' ? response['egc'] : response['egc']
|
9
|
+
end
|
10
|
+
|
11
|
+
def cancel(merchant, egc_code)
|
12
|
+
response = delete("/v2/merchant/#{merchant}/egc/#{egc_code}/")
|
13
|
+
format.to_s.downcase == 'xml' ? response['egc'] : response['egc']
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Defines methods related to a Cashstar Order
|
18
|
+
class GiftCard < Hashie::Dash
|
19
|
+
property :merchant_code, :required => true
|
20
|
+
property :initial_balance, :required => true
|
21
|
+
property :currency, :default => 'USD'
|
22
|
+
property :challenge
|
23
|
+
property :challenge_description
|
24
|
+
property :delivery
|
25
|
+
property :message
|
26
|
+
end
|
27
|
+
|
28
|
+
class Delivery < Hashie::Dash
|
29
|
+
property :delivered_by, :default => 'CASHSTAR'
|
30
|
+
property :method
|
31
|
+
property :target
|
32
|
+
property :scheduled
|
33
|
+
end
|
34
|
+
|
35
|
+
class Message < Hashie::Dash
|
36
|
+
property :from
|
37
|
+
property :to
|
38
|
+
property :body
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Cashstar
|
2
|
+
class Client
|
3
|
+
# Defines methods related to Cashstar merchants
|
4
|
+
module Merchants
|
5
|
+
|
6
|
+
def merchants
|
7
|
+
response = get("/v2/merchant/")
|
8
|
+
format.to_s.downcase == 'xml' ? response['merchant'] : response['merchants']['merchant']
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'hashie'
|
2
|
+
|
3
|
+
|
4
|
+
module Cashstar
|
5
|
+
class Client
|
6
|
+
module OrderMethods
|
7
|
+
def issue(order)
|
8
|
+
response = post("/v2/order/", order.to_json)
|
9
|
+
format.to_s.downcase == 'xml' ? response['order'] : response['order']
|
10
|
+
end
|
11
|
+
|
12
|
+
def return(order)
|
13
|
+
true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Defines methods related to a Cashstar Order
|
18
|
+
class Order < Hashie::Dash
|
19
|
+
property :audit_number, :required => true
|
20
|
+
property :gift_card, :required => true
|
21
|
+
property :payment, :default => nil
|
22
|
+
|
23
|
+
def to_json()
|
24
|
+
"{ \"order\" : { \"audit_number\" : \"#{self.audit_number}\", \"egc\" : #{self.gift_card.to_json}}}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'cashstar/version'
|
2
|
+
|
3
|
+
module Cashstar
|
4
|
+
# Defines constants and methods related to configuration
|
5
|
+
module Configuration
|
6
|
+
# An array of valid keys in the options hash when configuring a {Cashstar::API}
|
7
|
+
VALID_OPTIONS_KEYS = [
|
8
|
+
:username,
|
9
|
+
:password,
|
10
|
+
:endpoint,
|
11
|
+
:return_card_numbers,
|
12
|
+
:format,
|
13
|
+
:user_agent,
|
14
|
+
:adapter,
|
15
|
+
:faraday_options].freeze
|
16
|
+
|
17
|
+
# The adapter that will be used to connect if none is set
|
18
|
+
DEFAULT_ADAPTER = :net_http
|
19
|
+
|
20
|
+
# By default, don't set a username
|
21
|
+
DEFAULT_USERNAME = nil
|
22
|
+
|
23
|
+
# By default, don't set a password
|
24
|
+
DEFAULT_PASSWORD = nil
|
25
|
+
|
26
|
+
# The endpoint that will be used to connect if none is set
|
27
|
+
#
|
28
|
+
# @note This is configurable in case you want to connect to CashStar's test environment at https://api-semiprod.cashstar.com
|
29
|
+
DEFAULT_ENDPOINT = 'https://api-semiprod.cashstar.com'.freeze
|
30
|
+
|
31
|
+
# By default, we do not pass card numbers and pins back, only url's and challenge codes. This helps default to the most
|
32
|
+
# secure mode of usage.
|
33
|
+
DEFAULT_RETURN_CARD_NUMBERS = false
|
34
|
+
|
35
|
+
# The response format appended to the path and sent in the 'Accept' header if none is set
|
36
|
+
#
|
37
|
+
# @note JSON is preferred over XML because it is more concise and faster to parse.
|
38
|
+
DEFAULT_FORMAT = :json
|
39
|
+
|
40
|
+
# The value sent in the 'User-Agent' header if none is set
|
41
|
+
DEFAULT_USER_AGENT = "CashStar Ruby Gem #{Cashstar::VERSION}".freeze
|
42
|
+
|
43
|
+
DEFAULT_FARADAY_OPTIONS = {}.freeze
|
44
|
+
|
45
|
+
# @private
|
46
|
+
attr_accessor *VALID_OPTIONS_KEYS
|
47
|
+
|
48
|
+
# When this module is extended, set all configuration options to their default values
|
49
|
+
def self.extended(base)
|
50
|
+
base.reset
|
51
|
+
end
|
52
|
+
|
53
|
+
# Convenience method to allow configuration options to be set in a block
|
54
|
+
def configure
|
55
|
+
yield self
|
56
|
+
end
|
57
|
+
|
58
|
+
# Convienince method determining if pointed to the test env.
|
59
|
+
def test?
|
60
|
+
self.endpoint == DEFAULT_ENDPOINT
|
61
|
+
end
|
62
|
+
|
63
|
+
# Create a hash of options and their values
|
64
|
+
def options
|
65
|
+
options = {}
|
66
|
+
VALID_OPTIONS_KEYS.each{|k| options[k] = send(k)}
|
67
|
+
options
|
68
|
+
end
|
69
|
+
|
70
|
+
# Reset all configuration options to defaults
|
71
|
+
def reset
|
72
|
+
self.adapter = DEFAULT_ADAPTER
|
73
|
+
self.username = DEFAULT_USERNAME
|
74
|
+
self.password = DEFAULT_PASSWORD
|
75
|
+
self.endpoint = DEFAULT_ENDPOINT
|
76
|
+
self.format = DEFAULT_FORMAT
|
77
|
+
self.user_agent = DEFAULT_USER_AGENT
|
78
|
+
self.faraday_options = DEFAULT_FARADAY_OPTIONS
|
79
|
+
self.return_card_numbers = DEFAULT_RETURN_CARD_NUMBERS
|
80
|
+
self
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'faraday_middleware'
|
2
|
+
require 'faraday/request/gateway'
|
3
|
+
require 'faraday/request/basic_auth'
|
4
|
+
require 'faraday/response/raise_http_4xx'
|
5
|
+
require 'faraday/response/raise_http_5xx'
|
6
|
+
require 'faraday/response/strip_card_numbers'
|
7
|
+
|
8
|
+
module Cashstar
|
9
|
+
# @private
|
10
|
+
module Connection
|
11
|
+
private
|
12
|
+
|
13
|
+
def connection(options={})
|
14
|
+
merged_options = faraday_options.merge({
|
15
|
+
:headers => {
|
16
|
+
'Accept' => "application/json",
|
17
|
+
'User-Agent' => user_agent,
|
18
|
+
'Content-Type' => "application/json"
|
19
|
+
},
|
20
|
+
:ssl => {:verify => false},
|
21
|
+
:url => options.fetch(:endpoint, api_endpoint)
|
22
|
+
})
|
23
|
+
|
24
|
+
Faraday.new(merged_options) do |builder|
|
25
|
+
builder.use Faraday::Request::BasicAuth, authentication if authenticated?
|
26
|
+
builder.use Faraday::Request::UrlEncoded
|
27
|
+
builder.use Faraday::Response::RaiseHttp4xx
|
28
|
+
unless return_card_numbers
|
29
|
+
builder.use Faraday::Response::StripCardNumbers
|
30
|
+
end
|
31
|
+
unless options[:raw]
|
32
|
+
case options.fetch(:format, format).to_s.downcase
|
33
|
+
when 'json'
|
34
|
+
builder.use Faraday::Response::Mashify
|
35
|
+
builder.use Faraday::Response::ParseJson
|
36
|
+
when 'xml'
|
37
|
+
builder.use Faraday::Response::Mashify
|
38
|
+
builder.use Faraday::Response::ParseXml
|
39
|
+
end
|
40
|
+
end
|
41
|
+
builder.use Faraday::Response::RaiseHttp5xx
|
42
|
+
builder.adapter(adapter)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Cashstar
|
2
|
+
# Custom error class for rescuing from all Cashstar errors
|
3
|
+
class Error < StandardError
|
4
|
+
attr_reader :http_headers
|
5
|
+
|
6
|
+
def initialize(message, http_headers)
|
7
|
+
@http_headers = Hash[http_headers]
|
8
|
+
super message
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
# Raised when Cashstar returns the HTTP status code 400
|
14
|
+
class BadRequest < Error; end
|
15
|
+
|
16
|
+
# Raised when Cashstar returns the HTTP status code 401
|
17
|
+
class Unauthorized < Error; end
|
18
|
+
|
19
|
+
# Raised when Cashstar returns the HTTP status code 403
|
20
|
+
class Forbidden < Error; end
|
21
|
+
|
22
|
+
# Raised when Cashstar returns the HTTP status code 404
|
23
|
+
class NotFound < Error; end
|
24
|
+
|
25
|
+
# Raised when Cashstar returns the HTTP status code 406
|
26
|
+
class NotAcceptable < Error; end
|
27
|
+
|
28
|
+
# Raised when Cashstar returns the HTTP status code 500
|
29
|
+
class InternalServerError < Error; end
|
30
|
+
|
31
|
+
# Raised when Cashstar returns the HTTP status code 502
|
32
|
+
class BadGateway < Error; end
|
33
|
+
|
34
|
+
# Raised when Cashstar returns the HTTP status code 503
|
35
|
+
class ServiceUnavailable < Error; end
|
36
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Cashstar
|
2
|
+
# Defines HTTP request methods
|
3
|
+
module Request
|
4
|
+
# Perform an HTTP GET request
|
5
|
+
def get(path, params={}, options={})
|
6
|
+
request(:get, path, params, options)
|
7
|
+
end
|
8
|
+
|
9
|
+
def post(path, params={}, options={})
|
10
|
+
request(:post, path, params, options)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Perform an HTTP PUT request
|
14
|
+
def put(path, params={}, options={})
|
15
|
+
request(:put, path, params, options)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Perform an HTTP DELETE request
|
19
|
+
def delete(path, params={}, options={})
|
20
|
+
request(:delete, path, params, options)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
# Perform an HTTP request
|
26
|
+
def request(method, path, params, options)
|
27
|
+
response = connection(options).send(method) do |request|
|
28
|
+
case method.to_sym
|
29
|
+
when :get, :delete
|
30
|
+
request.url(path, params)
|
31
|
+
when :post, :put
|
32
|
+
request.path = path
|
33
|
+
request.body = params unless params.empty?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
options[:raw] ? response : response.body
|
37
|
+
end
|
38
|
+
|
39
|
+
def formatted_path(path, options={})
|
40
|
+
#[path, options.fetch(:format, format)].compact.join('.')
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
|
3
|
+
module Faraday
|
4
|
+
class Request::BasicAuth < Faraday::Middleware
|
5
|
+
require 'base64'
|
6
|
+
|
7
|
+
def call(env)
|
8
|
+
header = Base64.encode64("#{@options[:username]}:#{@options[:password]}")
|
9
|
+
env[:request_headers]['Authorization'] = "Basic #{header.to_s}"
|
10
|
+
@app.call(env)
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(app, options)
|
14
|
+
@app, @options = app, options
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
|
3
|
+
# @private
|
4
|
+
module Faraday
|
5
|
+
# @private
|
6
|
+
class Request::Gateway < Faraday::Middleware
|
7
|
+
def call(env)
|
8
|
+
url = env[:url].dup
|
9
|
+
url.host = @gateway
|
10
|
+
env[:url] = url
|
11
|
+
@app.call(env)
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(app, gateway)
|
15
|
+
@app, @gateway = app, gateway
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
|
3
|
+
# @private
|
4
|
+
module Faraday
|
5
|
+
# @private
|
6
|
+
class Response::RaiseHttp4xx < Response::Middleware
|
7
|
+
def on_complete(env)
|
8
|
+
case env[:status].to_i
|
9
|
+
when 400
|
10
|
+
raise Cashstar::BadRequest.new(error_message(env), env[:response_headers])
|
11
|
+
when 401
|
12
|
+
raise Cashstar::Unauthorized.new(error_message(env), env[:response_headers])
|
13
|
+
when 403
|
14
|
+
raise Cashstar::Forbidden.new(error_message(env), env[:response_headers])
|
15
|
+
when 404
|
16
|
+
raise Cashstar::NotFound.new(error_message(env), env[:response_headers])
|
17
|
+
when 406
|
18
|
+
raise Cashstar::NotAcceptable.new(error_message(env), env[:response_headers])
|
19
|
+
when 420
|
20
|
+
raise Cashstar::EnhanceYourCalm.new(error_message(env), env[:response_headers])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def error_message(env)
|
27
|
+
"#{env[:method].to_s.upcase} #{env[:url].to_s}: #{env[:status]}#{error_body(env[:body])}"
|
28
|
+
end
|
29
|
+
|
30
|
+
def error_body(body)
|
31
|
+
if body.nil?
|
32
|
+
nil
|
33
|
+
elsif body['error']
|
34
|
+
": #{body['error']}"
|
35
|
+
elsif body['errors']
|
36
|
+
first = Array(body['errors']).first
|
37
|
+
if first.kind_of? Hash
|
38
|
+
": #{first['message'].chomp}"
|
39
|
+
else
|
40
|
+
": #{first.chomp}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
|
3
|
+
# @private
|
4
|
+
module Faraday
|
5
|
+
# @private
|
6
|
+
class Response::RaiseHttp5xx < Response::Middleware
|
7
|
+
def on_complete(env)
|
8
|
+
case env[:status].to_i
|
9
|
+
when 500
|
10
|
+
raise Cashstar::InternalServerError.new(error_message(env, "Something is technically wrong."), env[:response_headers])
|
11
|
+
when 502
|
12
|
+
raise Cashstar::BadGateway.new(error_message(env, "Cashstar is down or being upgraded."), env[:response_headers])
|
13
|
+
when 503
|
14
|
+
raise Cashstar::ServiceUnavailable.new(error_message(env, "(__-){ Cashstar is over capacity or a service error occured."), env[:response_headers])
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def error_message(env, body=nil)
|
21
|
+
"#{env[:method].to_s.upcase} #{env[:url].to_s}: #{[env[:status].to_s + ':', body].compact.join(' ')}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
|
3
|
+
module Faraday
|
4
|
+
class Response::StripCardNumbers < Response::Middleware
|
5
|
+
|
6
|
+
def parse(body)
|
7
|
+
if body
|
8
|
+
if body["egc"]
|
9
|
+
body["egc"].delete("egc_number")
|
10
|
+
body["egc"].delete("access_code")
|
11
|
+
end
|
12
|
+
if body["order"] and body["order"]["egc"]
|
13
|
+
body["order"]["egc"].delete("egc_number")
|
14
|
+
body["order"]["egc"].delete("access_code")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
body
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
{
|
2
|
+
"merchants": {
|
3
|
+
"transaction_id": "12421413",
|
4
|
+
"merchant": [
|
5
|
+
{
|
6
|
+
"name": "Widget Store",
|
7
|
+
"legal_name": "The Widget Store, Inc.",
|
8
|
+
"merchant_code": "TWS"
|
9
|
+
},
|
10
|
+
{
|
11
|
+
"name": "Yummy Food",
|
12
|
+
"legal_name": "Yummy Food",
|
13
|
+
"merchant_code": "YUM"
|
14
|
+
}
|
15
|
+
]
|
16
|
+
}
|
17
|
+
}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'get merchants' do
|
4
|
+
subject do
|
5
|
+
Cashstar::Client.new(DEFAULT_OPTIONS)
|
6
|
+
end
|
7
|
+
|
8
|
+
before do
|
9
|
+
stub_get('v2/merchant', 'merchants')
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'returns merchants' do
|
13
|
+
subject.merchants.should == [ { 'name' => 'Widget Store',
|
14
|
+
'legal_name' => 'The Widget Store, Inc.',
|
15
|
+
'merchant_code' => 'TWS' },
|
16
|
+
{ 'name' => 'Yummy Food',
|
17
|
+
'legal_name' => 'Yummy Food',
|
18
|
+
'merchant_code' => 'YUM' } ]
|
19
|
+
end
|
20
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
require 'webmock/rspec'
|
4
|
+
require 'cashstar'
|
5
|
+
|
6
|
+
DEFAULT_OPTIONS = { :username => 'cashstars', :password => 'sekret', :endpoint => 'https://cashstar.example.com' }
|
7
|
+
|
8
|
+
def stub_get(endpoint, json_stub)
|
9
|
+
body = load_fixture(json_stub)
|
10
|
+
stub_request(:get, "https://cashstars:sekret@cashstar.example.com/#{endpoint}/").
|
11
|
+
to_return(:status => 200, :body => body, :headers => {})
|
12
|
+
end
|
13
|
+
|
14
|
+
def load_fixture(file_name)
|
15
|
+
file = File.open(File.join(Dir.pwd, 'spec', 'fixtures', "#{file_name}.json"))
|
16
|
+
contents = file.read
|
17
|
+
file.close
|
18
|
+
contents
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,211 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cashstar-ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.7
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Charlie White
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-02-04 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: hashie
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.2.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.2.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: faraday
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 0.8.0
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.8.0
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: faraday_middleware
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 0.8.0
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.8.0
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: multi_json
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 1.8.0
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 1.8.0
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: multi_xml
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 0.5.0
|
86
|
+
type: :runtime
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 0.5.0
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: rspec
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ~>
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '2.12'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '2.12'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: mocha
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ~>
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0.13'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ~>
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0.13'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: webmock
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ~>
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '1.9'
|
134
|
+
type: :development
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ~>
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '1.9'
|
142
|
+
description: CashStar's API provides a simple interface for purchasing and issuing
|
143
|
+
electronic gift cards from a variety of brands
|
144
|
+
email:
|
145
|
+
- cwhite@cashstar.com
|
146
|
+
executables: []
|
147
|
+
extensions: []
|
148
|
+
extra_rdoc_files: []
|
149
|
+
files:
|
150
|
+
- .rspec
|
151
|
+
- .ruby-gemset
|
152
|
+
- .ruby-version
|
153
|
+
- Gemfile
|
154
|
+
- Gemfile.lock
|
155
|
+
- README.md
|
156
|
+
- Rakefile
|
157
|
+
- cashstar.gemspec
|
158
|
+
- lib/.DS_Store
|
159
|
+
- lib/cashstar.rb
|
160
|
+
- lib/cashstar/.DS_Store
|
161
|
+
- lib/cashstar/api.rb
|
162
|
+
- lib/cashstar/authentication.rb
|
163
|
+
- lib/cashstar/client.rb
|
164
|
+
- lib/cashstar/client/catalog.rb
|
165
|
+
- lib/cashstar/client/faceplates.rb
|
166
|
+
- lib/cashstar/client/gift_card.rb
|
167
|
+
- lib/cashstar/client/merchants.rb
|
168
|
+
- lib/cashstar/client/order.rb
|
169
|
+
- lib/cashstar/configuration.rb
|
170
|
+
- lib/cashstar/connection.rb
|
171
|
+
- lib/cashstar/error.rb
|
172
|
+
- lib/cashstar/request.rb
|
173
|
+
- lib/cashstar/version.rb
|
174
|
+
- lib/faraday/request/basic_auth.rb
|
175
|
+
- lib/faraday/request/gateway.rb
|
176
|
+
- lib/faraday/response/raise_http_4xx.rb
|
177
|
+
- lib/faraday/response/raise_http_5xx.rb
|
178
|
+
- lib/faraday/response/strip_card_numbers.rb
|
179
|
+
- spec/fixtures/merchants.json
|
180
|
+
- spec/integration/client/merchants_spec.rb
|
181
|
+
- spec/integration/get_merchants_spec.rb
|
182
|
+
- spec/spec_helper.rb
|
183
|
+
homepage: http://www.cashstar.com
|
184
|
+
licenses: []
|
185
|
+
post_install_message:
|
186
|
+
rdoc_options: []
|
187
|
+
require_paths:
|
188
|
+
- lib
|
189
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
190
|
+
none: false
|
191
|
+
requirements:
|
192
|
+
- - ! '>='
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '0'
|
195
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
196
|
+
none: false
|
197
|
+
requirements:
|
198
|
+
- - ! '>='
|
199
|
+
- !ruby/object:Gem::Version
|
200
|
+
version: '0'
|
201
|
+
requirements: []
|
202
|
+
rubyforge_project: cashstar-ruby
|
203
|
+
rubygems_version: 1.8.25
|
204
|
+
signing_key:
|
205
|
+
specification_version: 3
|
206
|
+
summary: Ruby Bindings for the CashStar API
|
207
|
+
test_files:
|
208
|
+
- spec/fixtures/merchants.json
|
209
|
+
- spec/integration/client/merchants_spec.rb
|
210
|
+
- spec/integration/get_merchants_spec.rb
|
211
|
+
- spec/spec_helper.rb
|