cardconnect 1.0.0
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.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/Gemfile +11 -0
- data/LICENSE.txt +22 -0
- data/README.md +154 -0
- data/Rakefile +178 -0
- data/cardconnect.gemspec +25 -0
- data/lib/cardconnect.rb +49 -0
- data/lib/cardconnect/configuration.rb +13 -0
- data/lib/cardconnect/connection.rb +35 -0
- data/lib/cardconnect/error.rb +3 -0
- data/lib/cardconnect/services/authorization/authorization.rb +17 -0
- data/lib/cardconnect/services/authorization/authorization_request.rb +51 -0
- data/lib/cardconnect/services/authorization/authorization_response.rb +41 -0
- data/lib/cardconnect/services/capture/capture.rb +17 -0
- data/lib/cardconnect/services/capture/capture_request.rb +50 -0
- data/lib/cardconnect/services/capture/capture_response.rb +24 -0
- data/lib/cardconnect/services/deposit/deposit.rb +17 -0
- data/lib/cardconnect/services/deposit/deposit_request.rb +64 -0
- data/lib/cardconnect/services/deposit/deposit_response.rb +40 -0
- data/lib/cardconnect/services/inquire/inquire.rb +17 -0
- data/lib/cardconnect/services/inquire/inquire_request.rb +44 -0
- data/lib/cardconnect/services/inquire/inquire_response.rb +31 -0
- data/lib/cardconnect/services/refund/refund.rb +16 -0
- data/lib/cardconnect/services/refund/refund_request.rb +50 -0
- data/lib/cardconnect/services/refund/refund_response.rb +40 -0
- data/lib/cardconnect/services/service_endpoint.rb +69 -0
- data/lib/cardconnect/services/settlement_status/settlement_status.rb +17 -0
- data/lib/cardconnect/services/settlement_status/settlement_status_request.rb +64 -0
- data/lib/cardconnect/services/settlement_status/settlement_status_response.rb +39 -0
- data/lib/cardconnect/services/void/void.rb +16 -0
- data/lib/cardconnect/services/void/void_request.rb +50 -0
- data/lib/cardconnect/services/void/void_response.rb +40 -0
- data/lib/cardconnect/utils.rb +22 -0
- data/lib/cardconnect/version.rb +3 -0
- data/test/api_request_stubs.rb +83 -0
- data/test/api_response_stubs.rb +120 -0
- data/test/cardconnect/configuration_test.rb +28 -0
- data/test/cardconnect/connection_test.rb +36 -0
- data/test/cardconnect/services/authorization/authorization_request_test.rb +141 -0
- data/test/cardconnect/services/authorization/authorization_response_test.rb +93 -0
- data/test/cardconnect/services/authorization/authorization_test.rb +59 -0
- data/test/cardconnect/services/capture/capture_request_test.rb +65 -0
- data/test/cardconnect/services/capture/capture_response_test.rb +39 -0
- data/test/cardconnect/services/capture/capture_test.rb +58 -0
- data/test/cardconnect/services/deposit/deposit_request_test.rb +65 -0
- data/test/cardconnect/services/deposit/deposit_response_test.rb +75 -0
- data/test/cardconnect/services/deposit/deposit_test.rb +55 -0
- data/test/cardconnect/services/inquire/inquire_request_test.rb +45 -0
- data/test/cardconnect/services/inquire/inquire_response_test.rb +59 -0
- data/test/cardconnect/services/inquire/inquire_test.rb +56 -0
- data/test/cardconnect/services/refund/refund_request_test.rb +49 -0
- data/test/cardconnect/services/refund/refund_response_test.rb +73 -0
- data/test/cardconnect/services/refund/refund_test.rb +57 -0
- data/test/cardconnect/services/settlement_status/settlement_status_request_test.rb +65 -0
- data/test/cardconnect/services/settlement_status/settlement_status_response_test.rb +47 -0
- data/test/cardconnect/services/settlement_status/settlement_status_test.rb +55 -0
- data/test/cardconnect/services/void/void_request_test.rb +49 -0
- data/test/cardconnect/services/void/void_response_test.rb +77 -0
- data/test/cardconnect/services/void/void_test.rb +57 -0
- data/test/cardconnect_test.rb +14 -0
- data/test/test_helper.rb +33 -0
- metadata +179 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a8573cecba2cb8cac90e17b0ce8ca92e73280253
|
4
|
+
data.tar.gz: 5ca366ccec6c686f6e2e19fd159e4761cd93825e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5065e73f0951b0fe238b049dd333f8a1f3fd4c6ca2f328858b0f869a3c9e344bc8a3a42bb7ed916050c3ea1609b56529b9fc60d77086485031872b14cb401d85
|
7
|
+
data.tar.gz: 3561424fc95e5a43e0d2c51db6673c6cedabd8354effa6f9f76abbdd2e7e35c6ff0f4093f9132859ea3cc1e20518fc6b28a5f40ef2db976cad7316abc17f69a9
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 mc-pair2
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
# CardConnect
|
2
|
+
|
3
|
+
CardConnect API Ruby Wrapper
|
4
|
+
|
5
|
+
[](http://badge.fury.io/rb/cardconnect)
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'cardconnect'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install cardconnect
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
For Rails in config/initializers/cardconnect.rb
|
26
|
+
|
27
|
+
NOTE: Merchant ID can also be passed in with params when building a request. If no ID is passed in then the request will use the ID from the configuration.
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
CardConnect.configure do |config|
|
31
|
+
config.merchant_id = '<merchant-id-number>'
|
32
|
+
config.api_username = '<api user id>'
|
33
|
+
config.api_password = '<api user password>'
|
34
|
+
config.endpoint = 'https://url.goeshere.com:6443'
|
35
|
+
end
|
36
|
+
```
|
37
|
+
|
38
|
+
## Services
|
39
|
+
|
40
|
+
### Authorization Service
|
41
|
+
|
42
|
+
CardConnect documentation for this service can be found here: http://developer.cardconnect.com/cardconnect-api/#authorization-service
|
43
|
+
|
44
|
+
Example:
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
service = CardConnect::Service::Authorization.new
|
48
|
+
service.build_request(params)
|
49
|
+
response = service.submit
|
50
|
+
```
|
51
|
+
|
52
|
+
### Capture Service
|
53
|
+
|
54
|
+
CardConnect documentation for this service can be found here: http://developer.cardconnect.com/cardconnect-api/#capture-service
|
55
|
+
|
56
|
+
Example:
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
service = CardConnect::Service::Capture.new
|
60
|
+
service.build_request(params)
|
61
|
+
response = service.submit
|
62
|
+
```
|
63
|
+
|
64
|
+
### Void Service
|
65
|
+
|
66
|
+
CardConnect documentation for this service can be found here: http://developer.cardconnect.com/cardconnect-api/#void-service
|
67
|
+
|
68
|
+
Example:
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
service = CardConnect::Service::Void.new
|
72
|
+
service.build_request(params)
|
73
|
+
response = service.submit
|
74
|
+
```
|
75
|
+
|
76
|
+
### Refund Service
|
77
|
+
|
78
|
+
CardConnect documentation for this service can be found here: http://developer.cardconnect.com/cardconnect-api/#refund-service
|
79
|
+
|
80
|
+
Example:
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
service = CardConnect::Service::Refund.new
|
84
|
+
service.build_request(params)
|
85
|
+
response = service.submit
|
86
|
+
```
|
87
|
+
|
88
|
+
### Inquire Service
|
89
|
+
|
90
|
+
CardConnect documentation for this service can be found here: http://developer.cardconnect.com/cardconnect-api/#inquire-service
|
91
|
+
|
92
|
+
Example:
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
service = CardConnect::Service::Inquire.new
|
96
|
+
service.build_request(params)
|
97
|
+
response = service.submit
|
98
|
+
```
|
99
|
+
|
100
|
+
### Settlement Status Service
|
101
|
+
|
102
|
+
CardConnect documentation for this service can be found here: http://developer.cardconnect.com/cardconnect-api/#settlement-status-service
|
103
|
+
|
104
|
+
Example:
|
105
|
+
|
106
|
+
```ruby
|
107
|
+
service = CardConnect::Service::SettlementStatus.new
|
108
|
+
service.build_request(params)
|
109
|
+
response = service.submit
|
110
|
+
```
|
111
|
+
|
112
|
+
### Deposit Service
|
113
|
+
|
114
|
+
CardConnect documentation for this service can be found here: http://developer.cardconnect.com/cardconnect-api/#deposit-service
|
115
|
+
|
116
|
+
Example:
|
117
|
+
|
118
|
+
```ruby
|
119
|
+
service = CardConnect::Service::Deposit.new
|
120
|
+
service.build_request(params)
|
121
|
+
response = service.submit
|
122
|
+
```
|
123
|
+
|
124
|
+
### Response Codes
|
125
|
+
|
126
|
+
http://developer.cardconnect.com/cardconnect-api/#response-codes
|
127
|
+
|
128
|
+
## To Do:
|
129
|
+
|
130
|
+
#### Authorization Service
|
131
|
+
|
132
|
+
* Support for custom descriptor fields
|
133
|
+
* Support for Card Present authorizations is untested
|
134
|
+
* Support 3D Secure processing
|
135
|
+
|
136
|
+
#### Capture Service
|
137
|
+
|
138
|
+
* Support for Level 3 data including items
|
139
|
+
|
140
|
+
#### Funding Service
|
141
|
+
|
142
|
+
* Funding Service needs to be implemented
|
143
|
+
|
144
|
+
#### Profile Service
|
145
|
+
|
146
|
+
* Profile Service needs to be implemented
|
147
|
+
|
148
|
+
## Contributing
|
149
|
+
|
150
|
+
1. Fork it ( https://github.com/mobilecause/cardconnect/fork )
|
151
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
152
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
153
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
154
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,178 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
|
3
|
+
require 'rake/testtask'
|
4
|
+
|
5
|
+
Rake::TestTask.new do |t|
|
6
|
+
t.libs << 'test'
|
7
|
+
t.pattern = "test/**/*_test.rb"
|
8
|
+
end
|
9
|
+
|
10
|
+
namespace :cardconnect do
|
11
|
+
require 'cardconnect'
|
12
|
+
|
13
|
+
def cardconnect_configure(args)
|
14
|
+
CardConnect.configure do |config|
|
15
|
+
config.merchant_id = args.merchant_id
|
16
|
+
config.api_username = args.api_username
|
17
|
+
config.api_password = args.api_password
|
18
|
+
config.endpoint = args.api_endpoint
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
desc "Ping the API Server"
|
23
|
+
task :ping, [:merchant_id, :api_username, :api_password, :api_endpoint] do |t, args|
|
24
|
+
cardconnect_configure(args)
|
25
|
+
|
26
|
+
response = CardConnect::Connection.new.ping_server
|
27
|
+
puts response.body
|
28
|
+
end
|
29
|
+
|
30
|
+
desc "Simulate an Authorization request"
|
31
|
+
task :authorize, [:capture?, :merchant_id, :api_username, :api_password, :api_endpoint] do |t, args|
|
32
|
+
cardconnect_configure(args)
|
33
|
+
|
34
|
+
auth_params = {
|
35
|
+
'account' => '4111111111111111',
|
36
|
+
"accttype" => "VISA",
|
37
|
+
'expiry' => '1220',
|
38
|
+
'amount' => '1000',
|
39
|
+
'currency' => 'USD',
|
40
|
+
"tokenize" => "Y"
|
41
|
+
}
|
42
|
+
|
43
|
+
auth_params.merge!("capture" => "Y") if args[:capture?]
|
44
|
+
|
45
|
+
auth = CardConnect::Service::Authorization.new
|
46
|
+
auth.build_request(auth_params)
|
47
|
+
|
48
|
+
if auth.request.valid?
|
49
|
+
response = auth.submit
|
50
|
+
puts response.body
|
51
|
+
else
|
52
|
+
puts auth.request.errors
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
desc "Simulate a Capture request"
|
57
|
+
task :capture, [:retref, :merchant_id, :api_username, :api_password, :api_endpoint] do |t, args|
|
58
|
+
cardconnect_configure(args)
|
59
|
+
|
60
|
+
capture_params = {
|
61
|
+
'merchid' => CardConnect.configuration.merchant_id,
|
62
|
+
'retref' => args.retref
|
63
|
+
}
|
64
|
+
|
65
|
+
capture = CardConnect::Service::Capture.new
|
66
|
+
capture.build_request(capture_params)
|
67
|
+
|
68
|
+
if capture.request.valid?
|
69
|
+
response = capture.submit
|
70
|
+
puts response.body
|
71
|
+
else
|
72
|
+
puts capture.request.errors
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
desc "Simulate a Void request"
|
77
|
+
task :void, [:retref, :merchant_id, :api_username, :api_password, :api_endpoint] do |t, args|
|
78
|
+
cardconnect_configure(args)
|
79
|
+
|
80
|
+
void_params = {
|
81
|
+
'merchid' => CardConnect.configuration.merchant_id,
|
82
|
+
'retref' => args[:retref]
|
83
|
+
}
|
84
|
+
|
85
|
+
void = CardConnect::Service::Void.new
|
86
|
+
void.build_request(void_params)
|
87
|
+
|
88
|
+
if void.request.valid?
|
89
|
+
response = void.submit
|
90
|
+
puts response.body
|
91
|
+
else
|
92
|
+
puts void.request.errors
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
desc "Simulate a Refund request"
|
97
|
+
task :refund, [:retref, :merchant_id, :api_username, :api_password, :api_endpoint] do |t, args|
|
98
|
+
cardconnect_configure(args)
|
99
|
+
|
100
|
+
refund_params = {
|
101
|
+
'merchid' => CardConnect.configuration.merchant_id,
|
102
|
+
'retref' => args[:retref]
|
103
|
+
}
|
104
|
+
|
105
|
+
refund = CardConnect::Service::Refund.new
|
106
|
+
refund.build_request(refund_params)
|
107
|
+
|
108
|
+
if refund.request.valid?
|
109
|
+
response = refund.submit
|
110
|
+
puts response.body
|
111
|
+
else
|
112
|
+
puts refund.request.errors
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
desc "Simulate an Inquire request"
|
117
|
+
task :inquire, [:retref, :merchant_id, :api_username, :api_password, :api_endpoint] do |t, args|
|
118
|
+
cardconnect_configure(args)
|
119
|
+
|
120
|
+
inquire_params = {
|
121
|
+
'merchid' => CardConnect.configuration.merchant_id,
|
122
|
+
'retref' => args[:retref]
|
123
|
+
}
|
124
|
+
|
125
|
+
inquire = CardConnect::Service::Inquire.new
|
126
|
+
inquire.build_request(inquire_params)
|
127
|
+
|
128
|
+
if inquire.request.valid?
|
129
|
+
response = inquire.submit
|
130
|
+
puts response.body
|
131
|
+
else
|
132
|
+
puts inquire.request.errors
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
desc "Simulate a Settlement Status request"
|
137
|
+
task :settle_status, [:date, :merchant_id, :api_username, :api_password, :api_endpoint] do |t, args|
|
138
|
+
# Date format is MMDD
|
139
|
+
cardconnect_configure(args)
|
140
|
+
|
141
|
+
settle_params = {
|
142
|
+
'merchid' => CardConnect.configuration.merchant_id,
|
143
|
+
'date' => args[:date]
|
144
|
+
}
|
145
|
+
|
146
|
+
status = CardConnect::Service::SettlementStatus.new
|
147
|
+
status.build_request(settle_params)
|
148
|
+
|
149
|
+
if status.request.valid?
|
150
|
+
response = status.submit
|
151
|
+
puts response.body
|
152
|
+
else
|
153
|
+
puts status.request.errors
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
desc "Simulate a Deposit request"
|
158
|
+
task :deposit, [:date, :merchant_id, :api_username, :api_password, :api_endpoint] do |t, args|
|
159
|
+
# Date format is MMDD
|
160
|
+
cardconnect_configure(args)
|
161
|
+
|
162
|
+
deposit_params = {
|
163
|
+
'merchid' => CardConnect.configuration.merchant_id,
|
164
|
+
'date' => args[:date]
|
165
|
+
}
|
166
|
+
|
167
|
+
deposit = CardConnect::Service::Deposit.new
|
168
|
+
deposit.build_request(deposit_params)
|
169
|
+
|
170
|
+
if deposit.request.valid?
|
171
|
+
response = deposit.submit
|
172
|
+
puts response.body
|
173
|
+
else
|
174
|
+
puts deposit.request.errors
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
data/cardconnect.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'cardconnect/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "cardconnect"
|
8
|
+
spec.version = CardConnect::VERSION
|
9
|
+
spec.authors = ["Tim McKenzie", "Prashant Mokkarala", "Jason Taylor"]
|
10
|
+
spec.email = ["tim@mobilecause.com", "prashant@mobilecause.com", "j.m.taylor1@gmail.com"]
|
11
|
+
spec.summary = %q{CardConnect API Ruby Wrapper}
|
12
|
+
spec.description = %q{CardConnect API Ruby Wrapper}
|
13
|
+
spec.homepage = "http://developer.cardconnect.com/"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency 'bundler', '~> 1.0'
|
22
|
+
|
23
|
+
spec.add_dependency 'faraday', '~> 0.9.0'
|
24
|
+
spec.add_dependency 'faraday_middleware', '~> 0.9.1'
|
25
|
+
end
|
data/lib/cardconnect.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require "cardconnect/version"
|
2
|
+
|
3
|
+
require 'cardconnect/utils'
|
4
|
+
require 'cardconnect/error'
|
5
|
+
require 'cardconnect/configuration'
|
6
|
+
require 'cardconnect/connection'
|
7
|
+
|
8
|
+
require 'cardconnect/services/authorization/authorization_request'
|
9
|
+
require 'cardconnect/services/authorization/authorization_response'
|
10
|
+
require 'cardconnect/services/capture/capture_request'
|
11
|
+
require 'cardconnect/services/capture/capture_response'
|
12
|
+
require 'cardconnect/services/settlement_status/settlement_status_request'
|
13
|
+
require 'cardconnect/services/settlement_status/settlement_status_response'
|
14
|
+
require 'cardconnect/services/inquire/inquire_request'
|
15
|
+
require 'cardconnect/services/inquire/inquire_response'
|
16
|
+
require 'cardconnect/services/refund/refund_request'
|
17
|
+
require 'cardconnect/services/refund/refund_response'
|
18
|
+
require 'cardconnect/services/deposit/deposit_request'
|
19
|
+
require 'cardconnect/services/deposit/deposit_response'
|
20
|
+
require 'cardconnect/services/void/void_request'
|
21
|
+
require 'cardconnect/services/void/void_response'
|
22
|
+
|
23
|
+
require 'cardconnect/services/service_endpoint'
|
24
|
+
require 'cardconnect/services/authorization/authorization'
|
25
|
+
require 'cardconnect/services/capture/capture'
|
26
|
+
require 'cardconnect/services/settlement_status/settlement_status'
|
27
|
+
require 'cardconnect/services/inquire/inquire'
|
28
|
+
require 'cardconnect/services/refund/refund'
|
29
|
+
require 'cardconnect/services/deposit/deposit'
|
30
|
+
require 'cardconnect/services/void/void'
|
31
|
+
|
32
|
+
module CardConnect
|
33
|
+
|
34
|
+
class << self
|
35
|
+
|
36
|
+
def configure
|
37
|
+
yield(configuration)
|
38
|
+
end
|
39
|
+
|
40
|
+
def configuration
|
41
|
+
@configuration ||= Configuration.new
|
42
|
+
end
|
43
|
+
|
44
|
+
def connection
|
45
|
+
@connection ||= Connection.new.connection
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|