vsafe-ruby 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +241 -0
  3. data/Rakefile +6 -0
  4. data/lib/vsafe.rb +14 -0
  5. data/lib/vsafe/auth_result.rb +11 -0
  6. data/lib/vsafe/avs_result.rb +24 -0
  7. data/lib/vsafe/card_type.rb +29 -0
  8. data/lib/vsafe/charge_source.rb +12 -0
  9. data/lib/vsafe/client.rb +101 -0
  10. data/lib/vsafe/client_error.rb +4 -0
  11. data/lib/vsafe/config.rb +22 -0
  12. data/lib/vsafe/cvn_result.rb +17 -0
  13. data/lib/vsafe/payment_status.rb +15 -0
  14. data/lib/vsafe/request_error.rb +11 -0
  15. data/lib/vsafe/response.rb +47 -0
  16. data/lib/vsafe/response_error.rb +36 -0
  17. data/lib/vsafe/responses/charge_account_to_temporary_token.rb +12 -0
  18. data/lib/vsafe/responses/charge_authorize.rb +19 -0
  19. data/lib/vsafe/responses/charge_confirm.rb +10 -0
  20. data/lib/vsafe/responses/charge_sale.rb +20 -0
  21. data/lib/vsafe/responses/get_session_tags.rb +10 -0
  22. data/lib/vsafe/responses/reverse_payment.rb +12 -0
  23. data/lib/vsafe/responses/validate_charge_account.rb +19 -0
  24. data/lib/vsafe/version.rb +3 -0
  25. data/spec/spec_helper.rb +17 -0
  26. data/spec/vsafe/auth_result_spec.rb +12 -0
  27. data/spec/vsafe/avs_result_spec.rb +12 -0
  28. data/spec/vsafe/card_type_spec.rb +44 -0
  29. data/spec/vsafe/charge_source_spec.rb +12 -0
  30. data/spec/vsafe/client_spec.rb +186 -0
  31. data/spec/vsafe/config_spec.rb +14 -0
  32. data/spec/vsafe/cvn_result_spec.rb +12 -0
  33. data/spec/vsafe/payment_status_spec.rb +12 -0
  34. data/spec/vsafe/request_error_spec.rb +12 -0
  35. data/spec/vsafe/response_error_spec.rb +37 -0
  36. data/spec/vsafe/response_spec.rb +161 -0
  37. data/spec/vsafe/responses/charge_account_to_temporary_token_spec.rb +27 -0
  38. data/spec/vsafe/responses/charge_authorize_spec.rb +61 -0
  39. data/spec/vsafe/responses/charge_confirm_spec.rb +18 -0
  40. data/spec/vsafe/responses/charge_sale_spec.rb +68 -0
  41. data/spec/vsafe/responses/get_session_tags_spec.rb +27 -0
  42. data/spec/vsafe/responses/reverse_payment_spec.rb +37 -0
  43. data/spec/vsafe/responses/validate_charge_account.rb +19 -0
  44. data/spec/vsafe/vsafe_spec.rb +12 -0
  45. metadata +174 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9554215e285634ed75d2a15ee084aee48fd4dc21
4
+ data.tar.gz: fc340a8c12c446ec0e6c168b9fcb777e3a7dd819
5
+ SHA512:
6
+ metadata.gz: 15a2f77685b3c972eba40a1c1db35112f0ca56706048c6632889b0be2685bdbf3635307948177c407247b4b95712188cc62b169ae23513d3e78add18c1661c1e
7
+ data.tar.gz: 6668a08b8e4c50006814118e5ce1f8de165f7fc9eec840e84bbe3cb251255a3f6b0d41c29016564a43a67e0fd43c6bd3e5f26bfc9f6bfc3b29ac0f9bc65e9abf
@@ -0,0 +1,241 @@
1
+ # VSafe
2
+
3
+
4
+ ## Installation
5
+
6
+ Add this line to your application's Gemfile:
7
+
8
+ ```ruby
9
+ gem 'vsafe-ruby'
10
+ ```
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install vsafe-ruby
19
+
20
+ ## Configuration
21
+
22
+ ```ruby
23
+ VSafe.configure do |config|
24
+ config.account_name = "YOUR VESTA ACCOUNT"
25
+ config.password = "YOUR VESTA PASSWORD"
26
+ config.sandbox = true # Sandbox mode, Default to true
27
+ config.request_timeout = 20 # Request timeout, default to 20
28
+ end
29
+ ```
30
+
31
+ Config can also be overridden when initializing a request client:
32
+
33
+ ```ruby
34
+ client = VSafe::Client.new do |config|
35
+ config.sandbox = !Rails.env.production?
36
+ config.request_timeout = 3
37
+ end
38
+ ```
39
+
40
+ ## Request & Response
41
+
42
+ First, Setup a client for making request:
43
+
44
+ ```ruby
45
+ client = VSafe::Client.new
46
+ ```
47
+
48
+ ##### Heartbeat request
49
+ ```ruby
50
+ # Check if VSafe API is up or not
51
+ client.heartbeat.success?
52
+
53
+ ```
54
+
55
+ ##### Get vesta session tags
56
+ ```ruby
57
+ response = client.get_session_tags # => #<VSafe::Responses::GetSessionTags ...>
58
+
59
+ # Response attributes
60
+ response.org_id
61
+ response.web_session_id
62
+ ```
63
+
64
+ ##### Authorize charge
65
+ ```ruby
66
+ auth_params = {
67
+ TransactionID: "...",
68
+ ChargeAccountNumberToken: "...",
69
+ ChargeAmount: 10,
70
+ WebSessionID: "100_000000000", # Fingerprint generated by get_session_tags as part of ChargeSource::WEB transaction
71
+ PaymentDescriptor: "...",
72
+ ChargeSource: VSafe::ChargeSource::WEB, # Or VSafe::ChargeSource::PPD/VSafe::ChargeSource::TEL
73
+ RiskInformation: "...", # XML string for the transaction
74
+ IsTempToken: false,
75
+ CardHolderFirstName: "Foo",
76
+ CardHolderLastName: "Bar",
77
+ CardHolderAddressLine1: "...",
78
+ CardHolderAddressLine2: "...",
79
+ CardHolderCity: "...",
80
+ CardHolderRegion: "...",
81
+ CardHolderPostalCode: "...",
82
+ CardHolderCountryCode: "...",
83
+ ChargeCVN: 123, # Card's CVV
84
+ ChargeExpirationMMYY: "1221", # Card's expiration date in MMYY format
85
+ StoreCard: true # Get a permanent token or not
86
+ }
87
+
88
+ client.charge_authorize(params) # => #<VSafe::Responses::ChargeAuthorize ...>
89
+
90
+ # Response attributes
91
+ response.avs_result
92
+ response.auth_result
93
+ response.cvn_result
94
+ response.charge_permanent_token
95
+ response.payment_acquirer_name
96
+ response.payment_id
97
+ response.payment_status
98
+ ```
99
+
100
+ ##### Authorize charge
101
+
102
+ Authorize a credit card charge attempt for later confirm usage.
103
+
104
+ ```ruby
105
+ auth_params = {
106
+ TransactionID: "...",
107
+ ChargeAccountNumberToken: "...",
108
+ ChargeAmount: 10,
109
+ WebSessionID: "100_000000000", # Fingerprint generated by get_session_tags as part of ChargeSource::WEB transaction
110
+ PaymentDescriptor: "...",
111
+ ChargeSource: VSafe::ChargeSource::WEB, # Or VSafe::ChargeSource::PPD/VSafe::ChargeSource::TEL
112
+ RiskInformation: "...", # XML string for the transaction
113
+ IsTempToken: false,
114
+ CardHolderFirstName: "Foo",
115
+ CardHolderLastName: "Bar",
116
+ CardHolderAddressLine1: "...",
117
+ CardHolderAddressLine2: "...",
118
+ CardHolderCity: "...",
119
+ CardHolderRegion: "...",
120
+ CardHolderPostalCode: "...",
121
+ CardHolderCountryCode: "...",
122
+ ChargeCVN: 123, # Card's CVV
123
+ ChargeExpirationMMYY: "1221", # Card's expiration date in MMYY format
124
+ StoreCard: true # Get a permanent token or not
125
+ }
126
+
127
+ response = client.charge_authorize(params) # => #<VSafe::Responses::ChargeAuthorize ...>
128
+
129
+ # Response attributes
130
+ response.avs_result
131
+ response.auth_result
132
+ response.cvn_result
133
+ response.charge_permanent_token
134
+ response.payment_acquirer_name
135
+ response.payment_id
136
+ response.payment_status
137
+ ```
138
+
139
+ ##### Confirm charge
140
+
141
+ This should coupled with `charge_authorize`, confirms the previous authorized charge attempt.
142
+
143
+ ```ruby
144
+ auth_response = client.charge_authorize(auth_params)
145
+
146
+ confirm_params = {
147
+ PaymentID: auth_response.payment_id,
148
+ ChargeAmount: auth_params[:ChargeAmount],
149
+ TransactionID: auth_params[:TransactionID]
150
+ }
151
+
152
+ response = client.charge_confirm(confirm_params) # => #<VSafe::Responses::ChargeConfirm ...>
153
+
154
+ response.payment_status
155
+ ```
156
+
157
+ ##### Charge sale
158
+
159
+ Directly charge credit card.
160
+
161
+ ```ruby
162
+ charge_params = {
163
+ #... Same as authorize charge params
164
+ }
165
+
166
+ response = client.charge_sale(charge_params) # => #<VSafe::Responses::ChargeSale ...>
167
+
168
+ # Response attributes
169
+ response.avs_result
170
+ response.auth_result
171
+ response.cvn_result
172
+ response.charge_permanent_token
173
+ response.payment_acquirer_name
174
+ response.payment_id
175
+ response.payment_id_pk
176
+ response.payment_status
177
+ ```
178
+
179
+ ##### Reverse payment
180
+
181
+ Reverse a previously charged payment.
182
+
183
+ ```ruby
184
+ params = {
185
+ RefundAmount: 10.0,
186
+ PaymentID: "...", # payment id from charge_confirm or charge_sale
187
+ TransactionID: "..." # transaction id passed-in in charge/auth params
188
+ }
189
+
190
+ response = client.reverse_payment(params) # => #<VSafe::Responses::ReversePayment ...>
191
+
192
+ # Response attributes
193
+ response.available_refund_amount
194
+ response.payment_acquirer_name
195
+ response.payment_id
196
+ ```
197
+
198
+ ##### Validate Credit card
199
+
200
+ Check to see if a credit card is valid.
201
+
202
+ ```ruby
203
+ params = {
204
+ TransactionID: "...",
205
+ ChargeAccountNumberToken: "...",
206
+ WebSessionID: "100_000000000", # Fingerprint generated by get_session_tags as part of ChargeSource::WEB transaction
207
+ IsTempToken: true,
208
+ StoreCard: true,
209
+ PaymentDescriptor: "...",
210
+ ChargeSource: VSafe::ChargeSource::WEB,
211
+ CardHolderFirstName: "Foo",
212
+ CardHolderLastName: "Bar",
213
+ CardHolderAddressLine1: "...",
214
+ CardHolderAddressLine2: "...",
215
+ CardHolderCity: "...",
216
+ CardHolderRegion: "...",
217
+ CardHolderPostalCode: "...",
218
+ CardHolderCountryCode: "...",
219
+ ChargeCVN: 123, # Card's CVV
220
+ ChargeExpirationMMYY: "1221", # Card's expiration date in MMYY format
221
+ }
222
+
223
+ response = client.validate_charge_account(params)
224
+
225
+ response.avs_result
226
+ response.auth_result
227
+ response.cvn_result
228
+ response.charge_permanent_token
229
+ response.payment_acquirer_name
230
+ response.payment_id
231
+ response.payment_status
232
+ ```
233
+
234
+
235
+ ## Contributing
236
+
237
+ 1. Fork it ( https://github.com/[my-github-username]/vsafe-ruby/fork )
238
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
239
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
240
+ 4. Push to the branch (`git push origin my-new-feature`)
241
+ 5. Create a new Pull Request
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ task default: :spec
5
+
6
+ RSpec::Core::RakeTask.new
@@ -0,0 +1,14 @@
1
+ require "vsafe/client"
2
+ require "vsafe/config"
3
+
4
+ module VSafe
5
+ def self.configure(&block)
6
+ yield config
7
+
8
+ nil
9
+ end
10
+
11
+ def self.config
12
+ @config ||= Config.new
13
+ end
14
+ end
@@ -0,0 +1,11 @@
1
+ module VSafe
2
+ class AuthResult
3
+ INSUFFICENT_FUNDS = 1
4
+
5
+ attr_reader :code
6
+
7
+ def initialize(code)
8
+ @code = code.to_i
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,24 @@
1
+ module VSafe
2
+ class AvsResult
3
+ AVS_NOT_PERFORMED = 5
4
+ NO_ADDRESS_SUPPLIED = 6
5
+ AVS_DATA_INVALID = 7
6
+ FOREIGN_ADDRESS_MATCH = 8
7
+ FOREIGN_ADDRESS_MISMATCH = 9
8
+ AVS_NOT_AVAILABLE = 10
9
+ AVS_POSTAL_CODE_AND_LOCALE_MATCH = 11
10
+ AVS_LOCALE_MATCH = 12
11
+ AVS_POSTAL_CODE_MATCH = 13
12
+ AVS_NOT_MATCHED = 14
13
+ FORIEGN_ISSUER_AVS_NOT_AVAILABLE = 16
14
+ AVS_SYSTEM_UNAVAILABLE = 24
15
+ AVS_PARTIAL_MATCH = 39
16
+ AMEX_AUTOMATED_ADDRESS_VERIFICATION = 2000
17
+
18
+ attr_reader :code
19
+
20
+ def initialize(code)
21
+ @code = code.to_i
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,29 @@
1
+ module VSafe
2
+ class CardType
3
+ AMERICAN_EXPRESS = 3
4
+ VISA = 4
5
+ MASTERCARD = 5
6
+ DISCOVER = 6
7
+ DINERS_CLUB = 7
8
+ OPTIMA = 10
9
+
10
+ HUMANIZED_NAMES = {
11
+ AMERICAN_EXPRESS => "American Express".freeze,
12
+ VISA => "Visa".freeze,
13
+ MASTERCARD => "MasterCard".freeze,
14
+ DISCOVER => "Discover".freeze,
15
+ DINERS_CLUB => "Diners Club".freeze,
16
+ OPTIMA => "Optima".freeze
17
+ }
18
+
19
+ attr_reader :code
20
+
21
+ def initialize(code)
22
+ @code = code.to_i
23
+ end
24
+
25
+ def description
26
+ HUMANIZED_NAMES[code]
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,12 @@
1
+ module VSafe
2
+ class ChargeSource
3
+ # Use this to specify that the payment has been prearranged. This is used
4
+ # when the payment device has been validated or already had a successful
5
+ # charge against it. When this option is used, the ChargeCVN is not required.
6
+ PPD = "PPD"
7
+ # Use this to specify that the payment has been taken over the telephone.
8
+ TEL = "TEL"
9
+ # Use this to specify that the payment has been taken over the Web.
10
+ WEB = "WEB"
11
+ end
12
+ end
@@ -0,0 +1,101 @@
1
+ require "vsafe/config"
2
+ require "vsafe/charge_source"
3
+ require "vsafe/response"
4
+ require "vsafe/responses/get_session_tags"
5
+ require "vsafe/responses/charge_authorize"
6
+ require "vsafe/responses/charge_confirm"
7
+ require "vsafe/responses/reverse_payment"
8
+ require "vsafe/responses/charge_account_to_temporary_token"
9
+ require "vsafe/responses/charge_sale"
10
+ require "vsafe/responses/validate_charge_account"
11
+ require "securerandom"
12
+ require "uri"
13
+
14
+ module VSafe
15
+ class Client
16
+ SANDBOX_FINGERPRINT_PATH = "ThreatMetrixUIRedirector".freeze
17
+ FINGERPRINT_PATH = "PaySafeUIRedirector".freeze
18
+ # We should only use JSONP_SERVICE_PATH for charge_acct_to_tempory_token call in web js.
19
+ JSONP_SERVICE_PATH = "GatewayProxyJSON/Service".freeze
20
+ SERVICE_PATH = "GatewayProxy/Service".freeze
21
+ REQUEST_CONTENT_TYPE = "application/json; charset=utf-8".freeze
22
+
23
+ attr_reader :config
24
+
25
+ def initialize
26
+ # dup config in case we need to override default settings
27
+ @config = VSafe.config.dup
28
+
29
+ yield config if block_given?
30
+ end
31
+
32
+ def get_session_tags
33
+ params = {
34
+ TransactionID: SecureRandom.uuid
35
+ }
36
+
37
+ VSafe::Responses::GetSessionTags.new(request(service_url("GetSessionTags"), params))
38
+ end
39
+
40
+ def charge_authorize(params)
41
+ VSafe::Responses::ChargeAuthorize.new(request(service_url("ChargeAuthorize"), params))
42
+ end
43
+
44
+ def charge_confirm(params)
45
+ VSafe::Responses::ChargeConfirm.new(request(service_url("ChargeConfirm"), params))
46
+ end
47
+
48
+ def reverse_payment(params)
49
+ VSafe::Responses::ReversePayment.new(request(service_url("ReversePayment"), params))
50
+ end
51
+
52
+ def heartbeat
53
+ VSafe::Response.new(request(service_url("HeartBeat")))
54
+ end
55
+
56
+ def charge_sale(params)
57
+ VSafe::Responses::ChargeSale.new(request(service_url("ChargeSale"), params))
58
+ end
59
+
60
+ def validate_charge_account(params)
61
+ VSafe::Responses::ValidateChargeAccount.new(request(service_url("ValidateChargeAccount"), params))
62
+ end
63
+
64
+ def service_url(endpoint = nil, jsonp = false)
65
+ parts = [
66
+ config.url,
67
+ jsonp ? JSONP_SERVICE_PATH : SERVICE_PATH
68
+ ]
69
+ parts << endpoint if endpoint
70
+
71
+ File.join(parts)
72
+ end
73
+
74
+ def fingerprint_url
75
+ @_fingerprint_url ||= URI.join(config.url, config.sandbox ? SANDBOX_FINGERPRINT_PATH : FINGERPRINT_PATH).to_s
76
+ end
77
+
78
+ private
79
+
80
+ def request(url, params = {})
81
+ options = {
82
+ timeout: config.request_timeout,
83
+ body: params.merge(
84
+ AccountName: config.account_name,
85
+ Password: config.password
86
+ ).to_json,
87
+ headers: {
88
+ "Content-Type" => REQUEST_CONTENT_TYPE
89
+ }
90
+ }
91
+
92
+ # The HTTPS endpoint for VSafe Sandbox has an outdated SSL version.
93
+ # We need to do this so that we can actually connect.
94
+ if config.sandbox
95
+ options[:ssl_version] = :TLSv1
96
+ end
97
+
98
+ response = HTTParty.post(url, options)
99
+ end
100
+ end
101
+ end