beanstream 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: abe714a2b18a419e345b2f43e52ce2aacfadc260
4
+ data.tar.gz: 7a42a8d0ee4870b12d79abbec7ee171441885de7
5
+ SHA512:
6
+ metadata.gz: a3d415ae9448fe7717e59085c686b8b3f1a114c5ffdfc58d8a8fc0b4167c6e9b59abe71aaa02305dceabe8313440f60d3253dcce13fd53d353a1f3a801b40e95
7
+ data.tar.gz: fe7f78d9f92f5d06a198338dcc955007c72cc824e29865fffc84e6970745e4808efa2d088fef55996558693d48a02f537c627fd0d5cc1d47f63d3f6eb4bc2f41
@@ -0,0 +1,35 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /test/tmp/
9
+ /test/version_tmp/
10
+ /tmp/
11
+
12
+ ## Specific to RubyMotion:
13
+ .dat*
14
+ .repl_history
15
+ build/
16
+
17
+ ## Documentation cache and generated files:
18
+ /.yardoc/
19
+ /_yardoc/
20
+ /doc/
21
+ /rdoc/
22
+
23
+ ## Environment normalisation:
24
+ /.bundle/
25
+ /vendor/bundle
26
+ /lib/bundler/man/
27
+
28
+ # for a library or gem, you might want to ignore these files since the code is
29
+ # intended to run in multiple environments; otherwise, check them in:
30
+ # Gemfile.lock
31
+ # .ruby-version
32
+ # .ruby-gemset
33
+
34
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
35
+ .rvmrc
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+ gemspec
3
+
4
+
5
+ gem 'rest-client', '~> 1.8.0'
6
+ gem 'shoulda'
@@ -0,0 +1,66 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ beanstream (1.0.0.rc1)
5
+ json (~> 1.8.1)
6
+ rest-client (~> 1.4)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ activesupport (4.2.3)
12
+ i18n (~> 0.7)
13
+ json (~> 1.7, >= 1.7.7)
14
+ minitest (~> 5.1)
15
+ thread_safe (~> 0.3, >= 0.3.4)
16
+ tzinfo (~> 1.1)
17
+ domain_name (0.5.24)
18
+ unf (>= 0.0.5, < 1.0.0)
19
+ ffi (1.9.10-x64-mingw32)
20
+ http-cookie (1.0.2)
21
+ domain_name (~> 0.5)
22
+ i18n (0.7.0)
23
+ json (1.8.3)
24
+ mime-types (2.6.1)
25
+ minitest (5.8.0)
26
+ netrc (0.10.3)
27
+ power_assert (0.2.4)
28
+ rake (10.4.2)
29
+ rest-client (1.8.0)
30
+ http-cookie (>= 1.0.2, < 2.0)
31
+ mime-types (>= 1.16, < 3.0)
32
+ netrc (~> 0.7)
33
+ rest-client (1.8.0-x64-mingw32)
34
+ ffi (~> 1.9)
35
+ http-cookie (>= 1.0.2, < 2.0)
36
+ mime-types (>= 1.16, < 3.0)
37
+ netrc (~> 0.7)
38
+ shoulda (3.5.0)
39
+ shoulda-context (~> 1.0, >= 1.0.1)
40
+ shoulda-matchers (>= 1.4.1, < 3.0)
41
+ shoulda-context (1.2.1)
42
+ shoulda-matchers (2.8.0)
43
+ activesupport (>= 3.0.0)
44
+ test-unit (3.1.3)
45
+ power_assert
46
+ thread_safe (0.3.5)
47
+ tzinfo (1.2.2)
48
+ thread_safe (~> 0.1)
49
+ unf (0.1.4)
50
+ unf_ext
51
+ unf_ext (0.0.7.1)
52
+ unf_ext (0.0.7.1-x64-mingw32)
53
+
54
+ PLATFORMS
55
+ ruby
56
+ x64-mingw32
57
+
58
+ DEPENDENCIES
59
+ beanstream!
60
+ rake
61
+ rest-client (~> 1.8.0)
62
+ shoulda
63
+ test-unit
64
+
65
+ BUNDLED WITH
66
+ 1.10.6
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Beanstream Digital River World Payments
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
@@ -0,0 +1,4 @@
1
+ # Beanstream's Ruby SDK
2
+ **NOTE! This SDK is currently under development and is not rated for production use.**
3
+
4
+ If you would like to contribute to it and earn some cash from our code bounty program please contact bowens@beanstream.com
@@ -0,0 +1,7 @@
1
+ require 'rake/testtask'
2
+
3
+ task :default => [:test]
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.pattern = './test/**/*_test.rb'
7
+ end
@@ -0,0 +1,26 @@
1
+ #$:.unshift(File.join(File.dirname(__FILE__), 'lib'))
2
+
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'beanstream'
6
+ s.version = '1.0.0.rc1'
7
+ s.date = '2015-08-14'
8
+ s.summary = "Beanstream Ruby SDK"
9
+ s.description = "Accept payments using Beanstream and Ruby"
10
+ s.authors = ["Brent Owens", "Colin Walker", "Tom Mengda"]
11
+ s.email = 'bowens@beanstream.com'
12
+ s.homepage ='http://developer.beanstream.com'
13
+ s.license = 'MIT'
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- test/*`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ s.require_paths = ['lib']
19
+
20
+ s.add_dependency('rest-client', '~> 1.4')
21
+ s.add_dependency('json', '~> 1.8.1')
22
+
23
+ s.add_development_dependency('shoulda', '~> 3.4.0')
24
+ s.add_development_dependency('test-unit')
25
+ s.add_development_dependency('rake')
26
+ end
@@ -0,0 +1,52 @@
1
+ require 'beanstream/transaction'
2
+ require 'beanstream/payments_api'
3
+ require 'beanstream/profiles_api'
4
+ require 'beanstream/reporting_api'
5
+ require 'beanstream/util'
6
+ require 'beanstream/exceptions'
7
+
8
+ module Beanstream
9
+
10
+ @url_prefix = "www"
11
+ @url_suffix = "api"
12
+ @url_base = "beanstream.com"
13
+ @url_version = "v1"
14
+ @ssl_ca_cert = File.dirname(__FILE__) + '/resources/cacert.pem'
15
+ @timeout = 80
16
+ @open_timeout = 40
17
+
18
+ class << self
19
+ attr_accessor :merchant_id, :payments_api_key, :profiles_api_key, :reporting_api_key
20
+ attr_accessor :url_prefix, :url_base, :url_suffix, :url_version
21
+ attr_accessor :url_payments, :url_return, :url_void
22
+ attr_accessor :ssl_ca_cert, :timeout, :open_timeout
23
+ end
24
+
25
+ def self.api_host_url()
26
+ "https://#{@url_prefix}.#{url_base}"
27
+ end
28
+
29
+ def self.api_base_url()
30
+ "/#{url_suffix}/#{url_version}"
31
+ end
32
+
33
+ def self.PaymentsAPI()
34
+ Beanstream::PaymentsAPI.new()
35
+ end
36
+
37
+ def self.ProfilesAPI()
38
+ Beanstream::ProfilesAPI.new()
39
+ end
40
+
41
+ def self.ReportingAPI()
42
+ Beanstream::ReportingAPI.new()
43
+ end
44
+ end
45
+
46
+
47
+ def run()
48
+ Beanstream.merchant_id = "300200578"
49
+ Beanstream.payments_api_key = "4BaD82D9197b4cc4b70a221911eE9f70"
50
+ result = Beanstream.PaymentsAPI().make_creditcard_payment(12.5)
51
+ puts "Payment result: #{result}"
52
+ end
@@ -0,0 +1,71 @@
1
+ module Beanstream
2
+
3
+ class BeanstreamException < StandardError
4
+ attr_reader :code, :category, :message, :http_status_code
5
+ def initialize(code=nil, category=nil, message=nil, http_status_code=nil)
6
+ @code = code
7
+ @category = category
8
+ @message = message
9
+ @http_status_code = http_status_code
10
+ end
11
+
12
+ def is_user_error()
13
+ false
14
+ end
15
+
16
+ def user_facing_message()
17
+ "There was an error processing your request. Please try again or use a different card."
18
+ end
19
+ end
20
+
21
+
22
+ class BusinessRuleException < BeanstreamException
23
+ def initialize(code, category, message, http_status_code)
24
+ super(code, category, message, http_status_code)
25
+ end
26
+ end
27
+
28
+ class UnauthorizedException < BeanstreamException
29
+ def initialize(code, category, message, http_status_code)
30
+ super(code, category, message, http_status_code)
31
+ end
32
+ end
33
+
34
+ class ForbiddenException < BeanstreamException
35
+ def initialize(code, category, message, http_status_code)
36
+ super(code, category, message, http_status_code)
37
+ end
38
+ end
39
+
40
+ class InvalidRequestException < BeanstreamException
41
+ def initialize(code, category, message, http_status_code)
42
+ super(code, category, message, http_status_code)
43
+ end
44
+
45
+ def is_user_error()
46
+ if (@category ==1)
47
+ true
48
+ elsif (@category == 3 && code == 52)
49
+ true
50
+ else
51
+ false
52
+ end
53
+ end
54
+
55
+ def user_facing_message()
56
+ if (is_user_error())
57
+ return @message
58
+ else
59
+ super
60
+ end
61
+ end
62
+
63
+ end
64
+
65
+ class InternalServerException < BeanstreamException
66
+ def initialize(code, category, message, http_status_code)
67
+ super(code, category, message, http_status_code)
68
+ end
69
+ end
70
+
71
+ end
@@ -0,0 +1,161 @@
1
+ require 'securerandom'
2
+
3
+ module Beanstream
4
+
5
+ class PaymentMethods
6
+ CARD = "card"
7
+ CASH = "cash"
8
+ CHEQUE = "cheque"
9
+ TOKEN = "token"
10
+ PROFILE = "payment_profile"
11
+ end
12
+
13
+ class PaymentsAPI < Transaction
14
+
15
+ def self.generateRandomOrderId(prefix)
16
+ "#{prefix}_#{SecureRandom.hex(8)}"
17
+ end
18
+
19
+
20
+ # Urls
21
+
22
+ def make_payment_url
23
+ "#{Beanstream.api_base_url()}/payments/"
24
+ end
25
+
26
+ def payment_returns_url(transaction_id)
27
+ "#{Beanstream.api_base_url}/payments/#{transaction_id}/returns"
28
+ end
29
+
30
+ def payment_void_url(transaction_id)
31
+ "#{Beanstream.api_base_url}/payments/#{transaction_id}/void"
32
+ end
33
+
34
+ def get_transaction_url(transaction_id)
35
+ "#{Beanstream.api_base_url}/payments/#{transaction_id}"
36
+ end
37
+
38
+ #Payment Request Hash for making a payment with a Legato token
39
+ def getTokenPaymentRequestTemplate()
40
+ request = getPaymentRequestTemplate()
41
+ request[:payment_method] = PaymentMethods::TOKEN
42
+ request[:token] = {
43
+ :name => "",
44
+ :code => "",
45
+ :complete => true
46
+ }
47
+ end
48
+
49
+ #Payment Request Hash for making a payment with a credit card number
50
+ def getCardPaymentRequestTemplate()
51
+ request = getPaymentRequestTemplate()
52
+ request[:payment_method] = PaymentMethods::CARD
53
+ request[:card] = {
54
+ :name => "",
55
+ :number => "",
56
+ :expiry_month => "",
57
+ :expiry_year => "",
58
+ :cvd => "",
59
+ :complete => true
60
+ }
61
+ end
62
+
63
+ #Payment Request Hash for making a payment with a Payment Profile
64
+ def getProfilePaymentRequestTemplate()
65
+ request = getPaymentRequestTemplate()
66
+ request[:payment_method] = PaymentMethods::PROFILE
67
+ request[:token] = {
68
+ :customer_code => "",
69
+ :card_id => 1,
70
+ :complete => true
71
+ }
72
+ end
73
+
74
+ # Base Payment Request Hash for making a payments
75
+ # Use one of getTokenPaymentRequestTemplate, getCardPaymentRequestTemplate, or getProfilePaymentRequestTemplate
76
+ # +Required parameters+:: :amount, :order_number, :payment_method, and one of [:card, :token, :payment_profile] if not paying for Cash or Cheque.
77
+ # Use PaymentMethods:: for the available payment_method options
78
+ def getPaymentRequestTemplate()
79
+ request = {
80
+ :order_number => "",
81
+ :amount => 0,
82
+ :language=> "",
83
+ :customer_ip=> "",
84
+ :term_url=> "",
85
+ :comments=> "",
86
+ :billing=> {
87
+ :name=> "",
88
+ :address_line1=> "",
89
+ :address_line2=> "",
90
+ :city=> "",
91
+ :province=> "",
92
+ :country=> "",
93
+ :postal_code=> "",
94
+ :phone_number=> "",
95
+ :email_address=> ""
96
+ },
97
+ :shipping=> {
98
+ :name=> "",
99
+ :address_line1=> "",
100
+ :address_line2=> "",
101
+ :city=> "",
102
+ :province=> "",
103
+ :country=> "",
104
+ :postal_code=> "",
105
+ :phone_number=> "",
106
+ :email_address=> ""
107
+ },
108
+ :custom=> {
109
+ :ref1=> "",
110
+ :ref2=> "",
111
+ :ref3=> "",
112
+ :ref4=> "",
113
+ :ref5=> ""
114
+ }
115
+ }
116
+ end
117
+
118
+ #API operations
119
+
120
+ # Make a payment. If the payment is approved the PaymentResponse will be returned. If for any reason
121
+ # the payment is declined or if there is a connection error an exception will be thrown.
122
+ # This will accept a PaymentRequest Hash as defined by getTokenPaymentRequestTemplate(), getCardPaymentRequestTemplate(),
123
+ # or getProfilePaymentRequestTemplate().
124
+ # +PreAuth+:: For a pre-auth you must set the 'complete' parameter of the Card, Token, or Profile to be 'false'.
125
+ def make_payment(payment)
126
+ val = transaction_post("POST", make_payment_url, Beanstream.merchant_id, Beanstream.payments_api_key, payment)
127
+ end
128
+
129
+ def complete_preauth(transaciton_id, amount)
130
+ complete_url = make_payment_url+transaciton_id+"/completions"
131
+ completion = { :amount => amount }
132
+ val = transaction_post("POST", complete_url, Beanstream.merchant_id, Beanstream.payments_api_key, completion)
133
+ end
134
+
135
+ def self.payment_approved(payment_response)
136
+ success = payment_response['approved'] == "1" && payment_response['message'] == "Approved"
137
+ end
138
+
139
+ def get_legato_token(card_info)
140
+ turl = "/scripts/tokenization/tokens"
141
+ result = Transaction.new().transaction_post("POST", turl, "", "", card_info)
142
+ token = result['token']
143
+ end
144
+
145
+ def get_transaction(transaction_id)
146
+ transaction_post("GET", get_transaction_url(transaction_id), Beanstream.merchant_id, Beanstream.payments_api_key)
147
+ end
148
+
149
+ def return_payment(transaction_id, amount)
150
+ data = { amount: amount }
151
+ transaction_post("POST", payment_returns_url(transaction_id), Beanstream.merchant_id, Beanstream.payments_api_key, data)
152
+ end
153
+
154
+ def void_payment(transaction_id, amount)
155
+ data = { amount: amount }
156
+ transaction_post("POST", payment_void_url(transaction_id), Beanstream.merchant_id, Beanstream.payments_api_key, data)
157
+ end
158
+
159
+ end
160
+
161
+ end