vsafe-ruby 0.2.2

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.
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