transact_pro 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.circleci/config.yml +27 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +89 -0
- data/LICENSE.txt +28 -0
- data/README.md +145 -0
- data/Rakefile +6 -0
- data/assets/account_structure.png +0 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/transact_pro.rb +26 -0
- data/lib/transact_pro/gateway.rb +34 -0
- data/lib/transact_pro/request.rb +97 -0
- data/lib/transact_pro/request_specs.rb +169 -0
- data/lib/transact_pro/response.rb +57 -0
- data/lib/transact_pro/version.rb +3 -0
- data/transact_pro.gemspec +35 -0
- metadata +177 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 645ba37a51c3535eeab929d2f895de23781a90fd
|
4
|
+
data.tar.gz: 538bfa9d7043a9c363621cc09e1d0bf229783411
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 942111d185f8a9788f57f5e046561cc09e60930a77d7befd9c71eaa93877632428562197184dd3d5e5817c5ed198727047254a70d3ac2d1e11a465b6e6e2de4d
|
7
|
+
data.tar.gz: b73c4b1102249947015b3f5f10a86a31bc159a49bd1b67f5740997944809913bb3cfb13c2a8013c78712d5c45f0508acf690a24b9041915887f8ed0ed225d567
|
@@ -0,0 +1,27 @@
|
|
1
|
+
version: 2
|
2
|
+
jobs:
|
3
|
+
build:
|
4
|
+
working_directory: ~/transact_pro
|
5
|
+
docker:
|
6
|
+
#- image: circleci/ruby:2.1.10
|
7
|
+
- image: circleci/ruby@sha256:e49f95920f6294593e99cd6401556a36a8b47703b5bdac0b094b66ae1cdd6569
|
8
|
+
timezone: "Europe/Riga"
|
9
|
+
environment:
|
10
|
+
USER_IP: "78.23.51.103"
|
11
|
+
|
12
|
+
steps:
|
13
|
+
- checkout
|
14
|
+
|
15
|
+
- run: gem install bundler -v 1.16.0 --no-doc
|
16
|
+
|
17
|
+
- restore_cache:
|
18
|
+
key: transact_pro-v1-{{ checksum "Gemfile.lock" }}
|
19
|
+
|
20
|
+
- run: bundle install --path vendor/bundle
|
21
|
+
|
22
|
+
- save_cache:
|
23
|
+
key: transact_pro-v1-{{ checksum "Gemfile.lock" }}
|
24
|
+
paths:
|
25
|
+
- vendor/bundle
|
26
|
+
|
27
|
+
- run: bundle exec rspec
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
2
|
+
|
3
|
+
## Our Pledge
|
4
|
+
|
5
|
+
In the interest of fostering an open and welcoming environment, we as
|
6
|
+
contributors and maintainers pledge to making participation in our project and
|
7
|
+
our community a harassment-free experience for everyone, regardless of age, body
|
8
|
+
size, disability, ethnicity, gender identity and expression, level of experience,
|
9
|
+
nationality, personal appearance, race, religion, or sexual identity and
|
10
|
+
orientation.
|
11
|
+
|
12
|
+
## Our Standards
|
13
|
+
|
14
|
+
Examples of behavior that contributes to creating a positive environment
|
15
|
+
include:
|
16
|
+
|
17
|
+
* Using welcoming and inclusive language
|
18
|
+
* Being respectful of differing viewpoints and experiences
|
19
|
+
* Gracefully accepting constructive criticism
|
20
|
+
* Focusing on what is best for the community
|
21
|
+
* Showing empathy towards other community members
|
22
|
+
|
23
|
+
Examples of unacceptable behavior by participants include:
|
24
|
+
|
25
|
+
* The use of sexualized language or imagery and unwelcome sexual attention or
|
26
|
+
advances
|
27
|
+
* Trolling, insulting/derogatory comments, and personal or political attacks
|
28
|
+
* Public or private harassment
|
29
|
+
* Publishing others' private information, such as a physical or electronic
|
30
|
+
address, without explicit permission
|
31
|
+
* Other conduct which could reasonably be considered inappropriate in a
|
32
|
+
professional setting
|
33
|
+
|
34
|
+
## Our Responsibilities
|
35
|
+
|
36
|
+
Project maintainers are responsible for clarifying the standards of acceptable
|
37
|
+
behavior and are expected to take appropriate and fair corrective action in
|
38
|
+
response to any instances of unacceptable behavior.
|
39
|
+
|
40
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
41
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
42
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
43
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
44
|
+
threatening, offensive, or harmful.
|
45
|
+
|
46
|
+
## Scope
|
47
|
+
|
48
|
+
This Code of Conduct applies both within project spaces and in public spaces
|
49
|
+
when an individual is representing the project or its community. Examples of
|
50
|
+
representing a project or community include using an official project e-mail
|
51
|
+
address, posting via an official social media account, or acting as an appointed
|
52
|
+
representative at an online or offline event. Representation of a project may be
|
53
|
+
further defined and clarified by project maintainers.
|
54
|
+
|
55
|
+
## Enforcement
|
56
|
+
|
57
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
58
|
+
reported by contacting the project team at augusts.bautra@gmail.com. All
|
59
|
+
complaints will be reviewed and investigated and will result in a response that
|
60
|
+
is deemed necessary and appropriate to the circumstances. The project team is
|
61
|
+
obligated to maintain confidentiality with regard to the reporter of an incident.
|
62
|
+
Further details of specific enforcement policies may be posted separately.
|
63
|
+
|
64
|
+
Project maintainers who do not follow or enforce the Code of Conduct in good
|
65
|
+
faith may face temporary or permanent repercussions as determined by other
|
66
|
+
members of the project's leadership.
|
67
|
+
|
68
|
+
## Attribution
|
69
|
+
|
70
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
71
|
+
available at [http://contributor-covenant.org/version/1/4][version]
|
72
|
+
|
73
|
+
[homepage]: http://contributor-covenant.org
|
74
|
+
[version]: http://contributor-covenant.org/version/1/4/
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
transact_pro (0.9.0)
|
5
|
+
rest-client (~> 2.0.2)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
addressable (2.5.2)
|
11
|
+
public_suffix (>= 2.0.2, < 4.0)
|
12
|
+
coderay (1.1.2)
|
13
|
+
coveralls (0.7.1)
|
14
|
+
multi_json (~> 1.3)
|
15
|
+
rest-client
|
16
|
+
simplecov (>= 0.7)
|
17
|
+
term-ansicolor
|
18
|
+
thor
|
19
|
+
crack (0.4.3)
|
20
|
+
safe_yaml (~> 1.0.0)
|
21
|
+
diff-lcs (1.3)
|
22
|
+
docile (1.1.5)
|
23
|
+
domain_name (0.5.20170404)
|
24
|
+
unf (>= 0.0.5, < 1.0.0)
|
25
|
+
hashdiff (0.3.7)
|
26
|
+
http-cookie (1.0.3)
|
27
|
+
domain_name (~> 0.5)
|
28
|
+
json (2.1.0)
|
29
|
+
method_source (0.9.0)
|
30
|
+
mime-types (3.1)
|
31
|
+
mime-types-data (~> 3.2015)
|
32
|
+
mime-types-data (3.2016.0521)
|
33
|
+
multi_json (1.12.2)
|
34
|
+
netrc (0.11.0)
|
35
|
+
pry (0.11.3)
|
36
|
+
coderay (~> 1.1.0)
|
37
|
+
method_source (~> 0.9.0)
|
38
|
+
public_suffix (2.0.5)
|
39
|
+
rake (10.5.0)
|
40
|
+
rest-client (2.0.2)
|
41
|
+
http-cookie (>= 1.0.2, < 2.0)
|
42
|
+
mime-types (>= 1.16, < 4.0)
|
43
|
+
netrc (~> 0.8)
|
44
|
+
rspec (3.7.0)
|
45
|
+
rspec-core (~> 3.7.0)
|
46
|
+
rspec-expectations (~> 3.7.0)
|
47
|
+
rspec-mocks (~> 3.7.0)
|
48
|
+
rspec-core (3.7.1)
|
49
|
+
rspec-support (~> 3.7.0)
|
50
|
+
rspec-expectations (3.7.0)
|
51
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
52
|
+
rspec-support (~> 3.7.0)
|
53
|
+
rspec-mocks (3.7.0)
|
54
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
55
|
+
rspec-support (~> 3.7.0)
|
56
|
+
rspec-support (3.7.0)
|
57
|
+
safe_yaml (1.0.4)
|
58
|
+
simplecov (0.15.1)
|
59
|
+
docile (~> 1.1.0)
|
60
|
+
json (>= 1.8, < 3)
|
61
|
+
simplecov-html (~> 0.10.0)
|
62
|
+
simplecov-html (0.10.2)
|
63
|
+
term-ansicolor (1.6.0)
|
64
|
+
tins (~> 1.0)
|
65
|
+
thor (0.20.0)
|
66
|
+
tins (1.16.3)
|
67
|
+
unf (0.1.4)
|
68
|
+
unf_ext
|
69
|
+
unf_ext (0.0.7.4)
|
70
|
+
webmock (3.2.1)
|
71
|
+
addressable (>= 2.3.6)
|
72
|
+
crack (>= 0.3.2)
|
73
|
+
hashdiff
|
74
|
+
|
75
|
+
PLATFORMS
|
76
|
+
ruby
|
77
|
+
|
78
|
+
DEPENDENCIES
|
79
|
+
bundler (~> 1.16)
|
80
|
+
coveralls (~> 0.7.1)
|
81
|
+
pry (~> 0.11.3)
|
82
|
+
rake (~> 10.0)
|
83
|
+
rspec (~> 3.7)
|
84
|
+
simplecov (~> 0.15.1)
|
85
|
+
transact_pro!
|
86
|
+
webmock
|
87
|
+
|
88
|
+
BUNDLED WITH
|
89
|
+
1.16.1
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
BSD 3-clause "New" or "Revised" License
|
2
|
+
|
3
|
+
Copyright (c) 2017 Creative.gs . All rights reserved.
|
4
|
+
|
5
|
+
Redistribution and use in source and binary forms, with or without modification,
|
6
|
+
are permitted provided that the following conditions are met:
|
7
|
+
|
8
|
+
1. Redistributions of source code must retain the above copyright notice,
|
9
|
+
this list of conditions and the following disclaimer.
|
10
|
+
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
12
|
+
this list of conditions and the following disclaimer in the documentation and/or
|
13
|
+
other materials provided with the distribution.
|
14
|
+
|
15
|
+
3. Neither the name of Creative.gs, TransactPro, 1stpayments.new nor the names of its contributors
|
16
|
+
may be used to endorse or promote products derived from this software without
|
17
|
+
specific prior written permission.
|
18
|
+
|
19
|
+
THIS SOFTWARE IS PROVIDED BY Creative.gs AND CONTRIBUTORS "AS IS"
|
20
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
21
|
+
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
22
|
+
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
23
|
+
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
24
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
25
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
26
|
+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
27
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
28
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
[![Version](https://badge.fury.io/rb/transact_pro.svg)](https://badge.fury.io/rb/transact_pro)
|
2
|
+
[![Build](https://circleci.com/gh/CreativeGS/transact_pro/tree/master.svg?style=shield)](https://circleci.com/gh/CreativeGS/transact_pro/tree/master)
|
3
|
+
[![Coverage](https://coveralls.io/repos/github/CreativeGS/transact_pro/badge.svg?branch=master)](https://coveralls.io/github/CreativeGS/transact_pro?branch=master)
|
4
|
+
|
5
|
+
# TransactPro
|
6
|
+
Lightweight Ruby wrapper for communicating with TransactPro 1stpayments.net card payment API.
|
7
|
+
|
8
|
+
### What can this gem do?
|
9
|
+
Currently core functionality is supported - single and recurring SMS payments with card details entered gateway-side (zero hassle with [PCI compliance](https://www.pcisecuritystandards.org)), and payment outcome check request.
|
10
|
+
As of v1.0.0 (2018-01-04) the full functionality status list is:
|
11
|
+
|
12
|
+
| Functionality | method name | Page in doc | Support in gem | response data |
|
13
|
+
|---|---|---|---|---|
|
14
|
+
| SMS transaction init, card details entered merchant-side | *init | 12 | ✗ | - |
|
15
|
+
| SMS transaction init, card details entered gateway-side | *init | 21 | ✓ | `tid` & `redirect link` |
|
16
|
+
| SMS transaction init with card data save flag, card details entered gateway-side | *init_recurring_registration | 42 | ✓ | - |
|
17
|
+
| DMS init, card details entered merchant-side | make_hold | 37 | ✗ | - |
|
18
|
+
| DMS init, card details entered gateway-side | init_dms | 37 | ✗ | - |
|
19
|
+
| DMS execute | charge_hold | 37 | ✗ | - |
|
20
|
+
| Save card details for subsequent recurring payments, details entered gateway-side | init_store_card_sms | 45 | ✗ | - |
|
21
|
+
| Recurrent SMS, init a recurring payment | init_recurrent | 46 | ✓ | `tid` |
|
22
|
+
| Recurrent SMS, execute a recurring payment | charge_recurrent | 48 | ✓ | Status:Success... |
|
23
|
+
| Credit transaction init | init_credit | 17 | ✗ | - |
|
24
|
+
| Credit transaction execute | do_credit | 17 | ✗ | - |
|
25
|
+
| P2P transaction init | init_p2p | 18 | ✗ | - |
|
26
|
+
| P2P transaction execute | do_p2p | 18 | ✗ | - |
|
27
|
+
| MOTO transaction init | **moto_init | 48 | ✗ | - |
|
28
|
+
| MOTO payment execute | **moto_charge | 48 | ✗ | - |
|
29
|
+
| Payment cancellation | cancel_request | 23 | ✗ | - |
|
30
|
+
| DMS cancellation | cancel_dms | 38 | ✗ | - |
|
31
|
+
| Payment execution (charge) | charge | 24 | ✗ | - |
|
32
|
+
| Payment status request | status_request | 31 | ✓ | Status:Success... |
|
33
|
+
| Payment refund | ***refund | 34 | ✗ | "Refund Success" |
|
34
|
+
| Card verification | verify_card | 39 | ✗ | - |
|
35
|
+
| Terminal Limits | get_terminal_limits | 41 | ✗ | - |
|
36
|
+
| Reconciled Transactions | rt_api | 43 | ✗ | - |
|
37
|
+
|
38
|
+
*init request is the same for both card data entry strategies, since the receiving Merchant __Account__ determines what sort of response to give.
|
39
|
+
**moto methods are recurring payments performed on card data saved in a special manner. They use `init` and `charge` endpoints with tweaked parameters.
|
40
|
+
***refunding can be done via the panel in merchantarea.
|
41
|
+
|
42
|
+
## Installation
|
43
|
+
Bundle or manually install the latest version of the gem:
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
gem 'transact_pro'
|
47
|
+
```
|
48
|
+
|
49
|
+
## Usage
|
50
|
+
The gem implements `gateway`, `request` and `response` objects that handle communication with the remote API for you.
|
51
|
+
All communication is done synchroniously and without failsafes, so if something goes wrong during the remote request (HTTP timeout etc.), you get the raw error and get to handle it.
|
52
|
+
|
53
|
+
Please note that in this gem all configuration option hash keys are constant-case symbols like `:GUID` whereas all parameter keys for requests to the API are snake-case symbols like `:merchant_transaction_id`.
|
54
|
+
|
55
|
+
### 1. `TransactPro::Gateway`
|
56
|
+
|
57
|
+
![TransactPro account structure](assets/account_structure.png)
|
58
|
+
|
59
|
+
The gateway object encapsulates a _Merchant_ with GUID and a password, and at least one _Account_ with a routing string.
|
60
|
+
|
61
|
+
To this end, initialize gateway instances like so:
|
62
|
+
|
63
|
+
```rb
|
64
|
+
options = {
|
65
|
+
TEST: false, # defaults to false, pass `true` if you want the gem to make requests to the sandbox endpoints
|
66
|
+
API_URI: "https://something.new" # gem has the endpoint uri in defaults, you may only need this if the domains used suddeny change
|
67
|
+
GUID: "CAZY-7319-WI00-0C40", # mandatory
|
68
|
+
PASSWORD: "g44B/pAENO2E", # mandatory
|
69
|
+
ACCOUNT_3D: "CS01", # default routing string of Account to be used for 3D transactions
|
70
|
+
ACCOUNT_NON3D: "CS02", # default routing string of Account to be used for non-3D transactions
|
71
|
+
ACCOUNT_RECURRING: "CS03", # default routing string of Account to be used for recurring payment execution
|
72
|
+
custom_return_url: "https://www.example.com/pay/transactpro/response?merchant_transaction_id=ZZZZZZZ" # can be overridden in transaction init request
|
73
|
+
custom_callback_url: "https://www.example.com/pay/transactpro/response?merchant_transaction_id=ZZZZZZZ" # can be overridden in transaction init request
|
74
|
+
}
|
75
|
+
|
76
|
+
gateway = TransactPro::Gateway.new(options)
|
77
|
+
```
|
78
|
+
|
79
|
+
### 2. `TransactPro::Request`
|
80
|
+
|
81
|
+
Use the `Gateway` instance's `#request` method to perform requests.
|
82
|
+
|
83
|
+
```rb
|
84
|
+
options = {
|
85
|
+
method: :status_request, # mandatory, exclusively symbol objects for value
|
86
|
+
request_type: 'transaction_status',
|
87
|
+
init_transaction_id: "abc123",
|
88
|
+
# Note that passing :guid and :pwd is possible and `#call` will always override any defaults with the latest passed values, but generally you should rely on these values being set correctly from GUID and PASSWORD in gateway configuration.
|
89
|
+
guid: "..."
|
90
|
+
pwd: "..."
|
91
|
+
# Note that :rs is optional and will be inferred from gateway defaults, preferring 3D accounts to NON3D, where applicable.
|
92
|
+
rs: "..."
|
93
|
+
}
|
94
|
+
|
95
|
+
request_instance = gateway.request(options)
|
96
|
+
request_instance.call #=> response
|
97
|
+
|
98
|
+
# TransactPro::Request instances also have #to_s method to inspect what parameters are used in the request.
|
99
|
+
```
|
100
|
+
|
101
|
+
### 3. `TransactPro::Response`
|
102
|
+
`Response` objects are thin wrappers around the response bodies received from communicating with the TransactPro API.
|
103
|
+
Use `#to_s` on them to get the raw body and do any handling yourslef.
|
104
|
+
The gem provides a couple methods for ease of use:
|
105
|
+
|
106
|
+
```rb
|
107
|
+
response = request_instance.call
|
108
|
+
|
109
|
+
response.redirect_link #=> "https://..." link to redirect users to for checkout, nil if not applicable
|
110
|
+
|
111
|
+
response.status #=> "OK" if all went well, "FAIL" if a payment status response and it did not go through, "ERROR" if API said request was bad
|
112
|
+
|
113
|
+
response.tid #=> the 40-symbol long hexdigit transaction ID, nil if not applicable
|
114
|
+
|
115
|
+
response.to_s #=> raw body
|
116
|
+
|
117
|
+
response.to_h #=> splits the response on "~" and then on first ":" to make key-value pairs, string keys!
|
118
|
+
```
|
119
|
+
|
120
|
+
## Contributing
|
121
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/CreativeGS/transact_pro. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
122
|
+
|
123
|
+
The project uses TDD approach to software development, follow these steps to set up:
|
124
|
+
1. fork and clone the repo on github
|
125
|
+
2. Install appropriate Ruby and Bundler
|
126
|
+
3. `bundle`
|
127
|
+
4. See if all specs are green with `rspec`
|
128
|
+
5. (optional) Run specs with `USE_LIVE_SANDBOX=true rspec` to disable mocking of remote requests and make live requests to sandbox instead.
|
129
|
+
5. TDD new features
|
130
|
+
6. Make a Pull Request in github
|
131
|
+
|
132
|
+
## Releasing a new version
|
133
|
+
|
134
|
+
```
|
135
|
+
gem push # to set credentials
|
136
|
+
rake release
|
137
|
+
```
|
138
|
+
|
139
|
+
## License
|
140
|
+
|
141
|
+
The gem is available as open source under the terms of the [BSD-3-Clause License](https://opensource.org/licenses/BSD-3-Clause).
|
142
|
+
|
143
|
+
## Code of Conduct
|
144
|
+
|
145
|
+
Everyone interacting in the TransactPro project’s codebases and issue trackers is expected to follow the [code of conduct](https://github.com/CreativeGS/transact_pro/blob/master/CODE_OF_CONDUCT.md).
|
data/Rakefile
ADDED
Binary file
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "transact_pro"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/lib/transact_pro.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require "digest"
|
2
|
+
require "rest-client"
|
3
|
+
|
4
|
+
require "transact_pro/request_specs"
|
5
|
+
require "transact_pro/gateway"
|
6
|
+
require "transact_pro/request"
|
7
|
+
require "transact_pro/response"
|
8
|
+
require "transact_pro/version"
|
9
|
+
|
10
|
+
module TransactPro
|
11
|
+
extend self
|
12
|
+
|
13
|
+
DEFAULTS = {
|
14
|
+
TEST: false,
|
15
|
+
PRODUCTION_ENV: {
|
16
|
+
API_URI: "https://www2.1stpayments.net/gwprocessor2.php"
|
17
|
+
},
|
18
|
+
TEST_ENV: {
|
19
|
+
API_URI: "https://gw2sandbox.tpro.lv:8443/gw2test/gwprocessor2.php"
|
20
|
+
}
|
21
|
+
}.freeze
|
22
|
+
|
23
|
+
def root
|
24
|
+
@@root ||= Pathname.new(Gem::Specification.find_by_name("transact_pro").gem_dir)
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class TransactPro::Gateway
|
2
|
+
attr_reader :options
|
3
|
+
|
4
|
+
def initialize(options)
|
5
|
+
test = TransactPro::DEFAULTS[:TEST] || !!options[:TEST]
|
6
|
+
|
7
|
+
env_key = (test ? :TEST_ENV : :PRODUCTION_ENV)
|
8
|
+
|
9
|
+
@options = {
|
10
|
+
TEST: test,
|
11
|
+
API_URI: TransactPro::DEFAULTS[env_key][:API_URI],
|
12
|
+
pwd: Digest::SHA1.hexdigest(options[:PASSWORD].to_s),
|
13
|
+
guid: options[:GUID].to_s
|
14
|
+
}
|
15
|
+
|
16
|
+
@options.merge!(options)
|
17
|
+
|
18
|
+
unless @options[:GUID].to_s[%r'\A(?:\w){4}-(?:\w){4}-(?:\w){4}-(?:\w){4}\z']
|
19
|
+
raise ArgumentError.new("'#{@options[:GUID]}' is not a valid GUID for a gateway")
|
20
|
+
end
|
21
|
+
|
22
|
+
unless @options[:PASSWORD].to_s.size > 0
|
23
|
+
raise ArgumentError.new("'#{@options[:PASSWORD]}' is not a valid PASSWORD for a gateway")
|
24
|
+
end
|
25
|
+
|
26
|
+
if @options[:ACCOUNT_3D].to_s.size < 1 && @options[:ACCOUNT_NON3D].to_s.size < 1
|
27
|
+
raise ArgumentError.new("As a minimum specify a ACCOUNT_3D or a ACCOUNT_NON3D for a gateway")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def request(request_options)
|
32
|
+
TransactPro::Request.new(options.merge(request_options))
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
class TransactPro::Request
|
2
|
+
class ValidationError < RuntimeError
|
3
|
+
end
|
4
|
+
|
5
|
+
SUPPORTED_METHODS = %i|
|
6
|
+
init init_recurring_registration init_recurrent charge_recurrent
|
7
|
+
status_request
|
8
|
+
|.freeze
|
9
|
+
|
10
|
+
RECURRING_METHODS = %i|init_recurrent charge_recurrent|.freeze
|
11
|
+
|
12
|
+
attr_reader :options, :method
|
13
|
+
|
14
|
+
# Do not use this default initializer!
|
15
|
+
# Instead, initialize a Gateway and call #request method on that.
|
16
|
+
def initialize(options)
|
17
|
+
@options = options
|
18
|
+
@method = @options[:method]
|
19
|
+
|
20
|
+
unless SUPPORTED_METHODS.include?(@method)
|
21
|
+
raise ArgumentError.new(
|
22
|
+
"'#{@method}' is not a supported API request method"
|
23
|
+
)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def call
|
28
|
+
@defaults ||= TransactPro::RequestSpecs.const_get(
|
29
|
+
"#{method.to_s.upcase}_DEFAULTS"
|
30
|
+
)
|
31
|
+
|
32
|
+
@request_options ||= @defaults.merge(options)
|
33
|
+
@request_options[:rs] = routing_string
|
34
|
+
|
35
|
+
@spec ||= TransactPro::RequestSpecs.const_get(
|
36
|
+
"#{method.to_s.upcase}_SPEC"
|
37
|
+
)
|
38
|
+
|
39
|
+
@postable_params = {}
|
40
|
+
@spec.each do |k, spec|
|
41
|
+
do_validation =
|
42
|
+
if spec[:mandatory]
|
43
|
+
# mandatory key, always validate
|
44
|
+
@postable_params[k] = @request_options[k]
|
45
|
+
true
|
46
|
+
else
|
47
|
+
# non-mandatory key, include and validate only if it is present
|
48
|
+
if @request_options[k].to_s.size > 0
|
49
|
+
@postable_params[k] = @request_options[k]
|
50
|
+
true
|
51
|
+
else
|
52
|
+
false
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
validate(k, @postable_params[k], spec[:format]) if do_validation
|
57
|
+
end
|
58
|
+
|
59
|
+
@url = "#{@request_options[:API_URI]}?a=#{sendable_method}"
|
60
|
+
|
61
|
+
@raw_response = RestClient.post(@url, @postable_params)
|
62
|
+
@response = TransactPro::Response.new(@raw_response.to_s)
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
def validate(key, string, regex)
|
67
|
+
unless string[regex]
|
68
|
+
raise TransactPro::Request::ValidationError.new(
|
69
|
+
":#{key} with value '#{string}' is invalid for request, "\
|
70
|
+
"expected a match for regex #{regex.inspect}"
|
71
|
+
)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def routing_string
|
76
|
+
@routing_string =
|
77
|
+
if options[:rs].to_s.size > 0
|
78
|
+
options[:rs]
|
79
|
+
elsif recurring_method?
|
80
|
+
options[:ACCOUNT_RECURRING]
|
81
|
+
else
|
82
|
+
# a regular user-facing method, preferring 3D account
|
83
|
+
options[:ACCOUNT_3D].to_s.size > 0 ?
|
84
|
+
options[:ACCOUNT_3D] :
|
85
|
+
options[:ACCOUNT_NON3D]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def recurring_method?
|
90
|
+
RECURRING_METHODS.include?(method)
|
91
|
+
end
|
92
|
+
|
93
|
+
def sendable_method
|
94
|
+
method == :init_recurring_registration ? :init : method
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
module TransactPro
|
2
|
+
module RequestSpecs
|
3
|
+
# Contants ending with _SPEC here describe the request body fields
|
4
|
+
# (whether the field is mandatory and supposed format)
|
5
|
+
|
6
|
+
# set of allowed characters:
|
7
|
+
# a: alphabetic characters are the upper case letters A through Z; the lower case letters a through z, and the blank (space) character.
|
8
|
+
# h: hexadecimal number.
|
9
|
+
# n: numeric characters are the numbers zero (0) through nine (9).
|
10
|
+
# s: special printable characters are any printable characters that are neither alphabetic nor numeric,
|
11
|
+
# have an ASCII hexadecimal value greater than 20, or an EBCDIC hexadecimal value greater than 40.
|
12
|
+
# Occurrences of values ASCII 00 – 1F and EBCDIC 00 – 3F are not valid. Not all special characters are
|
13
|
+
# usually enabled. See fields’ description for details."
|
14
|
+
# u: Unicode alphabetic characters.
|
15
|
+
|
16
|
+
GUID_REGEX = %r'\A[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}\z'
|
17
|
+
PASSWORD_DIGEST_REGEX = %r'\A.{40}\z'
|
18
|
+
ROUTING_REGEX = %r'\A[[:alnum:]]{1,12}\z' # an(1..12)
|
19
|
+
MERCHANT_TRANSACTION_ID = %r'\A.{5,50}\z' # ans(5..50)
|
20
|
+
TID_REGEX = %r'\A[0-9a-f]+\z'i # h(40)
|
21
|
+
USER_IP = %r'\A
|
22
|
+
(
|
23
|
+
([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.
|
24
|
+
){3}
|
25
|
+
([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])
|
26
|
+
\z'x # ns(7..15)
|
27
|
+
DESCRIPTION = %r'\A.{5,255}\z' # uns(5..255)
|
28
|
+
AMOUNT = %r'\A[1-9]\d{2,}\z' # n
|
29
|
+
CURRENCY = %r'\A[[:upper:]]{3}\z' # a(3)
|
30
|
+
NAME_ON_CARD = %r'\A.{2,100}\z' # ans(2..100)
|
31
|
+
STREET = %r'\A.{2,50}\z' # ans(2..50)
|
32
|
+
ZIP = %r'\A.{2,15}\z' # ans(2..15)
|
33
|
+
CITY = %r'\A.{2,25}\z' # ans(2..25)
|
34
|
+
COUNTRY = %r'\A[[:alpha:]]{2}\z' # a(2)
|
35
|
+
STATE = %r'\A.{2,20}\z' # ans(2..20)
|
36
|
+
EMAIL = %r'\A.{1,100}\z' # ans(1..100)
|
37
|
+
PHONE = %r'\A[0-9\-_]{5,25}\z' # ns(5..25)
|
38
|
+
CARD_BIN = %r'\A\d{6}\z' # n(6)
|
39
|
+
BIN_NAME = %r'\A.{3,50}\z' # uns(3..50)
|
40
|
+
BIN_PHONE = %r'\A[0-9\-_]{3,25}\z' # ns(3..25)
|
41
|
+
MERCHANT_SITE_URL = %r'\A.{1,255}\z' # ans(1..255)
|
42
|
+
MERCHANT_REFERRING_NAME = %r'\A.{1,21}\z' # ans(1..21)
|
43
|
+
F_EXTENDED = %r'\A\d+\z' # n
|
44
|
+
|
45
|
+
# 10. Table
|
46
|
+
# Field Format Description
|
47
|
+
# guid ans(19) Your merchant GUID.
|
48
|
+
# pwd h(40) SHA1 hash of your processing password.
|
49
|
+
# rs an(1..12) Your routing string.
|
50
|
+
# merchant_transaction_id ans(5..50) Your transaction ID, must be unique for every transaction you submit to
|
51
|
+
# the gateway. The transaction ID must be from 5 to 50 characters.
|
52
|
+
# user_ip ns(7..15) Cardholder's IP, as string (AA.BB.CC.DD).
|
53
|
+
# description uns(5..255) Order items description, from 5 to 255 characters (Example: SDHC
|
54
|
+
# Memory card x 2, AAA battery pack x 1).
|
55
|
+
# amount n Transaction amount, in MINOR units (i.e. 2150 for $21.50 transaction).
|
56
|
+
# Notice: check JPY exception notice below!
|
57
|
+
# currency a(3) Transaction currency, ISO 4217 3-character code, USD, EUR, CHF etc.
|
58
|
+
# name_on_card ans(2..100) Cardholder name, as printed on a card (pass client name if card data
|
59
|
+
# collected at gateway side)
|
60
|
+
# street ans(2..50) Cardholder address – street. (min 2 symbols)
|
61
|
+
# zip ans(2..15) Cardholder address – ZIP. (min 2 symbols)
|
62
|
+
# city as(2..25) Cardholder address – City. (min 2 symbols)
|
63
|
+
# country a(2) Cardholder address – country, 2-letter ISO 3166-1-Alpha 2 code.
|
64
|
+
# state ans(2..20) Cardholder address – state (send NA if you don't have state information).
|
65
|
+
# email ans(1..100) Cardholder address – email
|
66
|
+
# phone ns(5..25) Cardholder phone number (min. 5 symbols).
|
67
|
+
# card_bin n(6) Cardholder card BIN (first 6 characters of CC number). - not required if
|
68
|
+
# card data collected at gateway side.
|
69
|
+
# bin_name uns(3..50) Cardholder bank name (non-mandatory).
|
70
|
+
# bin_phone ns(3..25) Cardholder bank phone given on a back side of used card
|
71
|
+
# (non-mandatory).
|
72
|
+
# merchant_site_url ans(1..255) Purchase site URL.
|
73
|
+
# merchant_referring_name ans(1..21) Must not be send by default. See chapter 3.5 for description if you need
|
74
|
+
# to use it.
|
75
|
+
INIT_SPEC = {
|
76
|
+
guid: {mandatory: true, format: GUID_REGEX},
|
77
|
+
pwd: {mandatory: true, format: PASSWORD_DIGEST_REGEX},
|
78
|
+
rs: {mandatory: true, format: ROUTING_REGEX},
|
79
|
+
merchant_transaction_id: {mandatory: true, format: MERCHANT_TRANSACTION_ID},
|
80
|
+
user_ip: {mandatory: true, format: USER_IP},
|
81
|
+
description: {mandatory: true, format: DESCRIPTION},
|
82
|
+
amount: {mandatory: true, format: AMOUNT},
|
83
|
+
currency: {mandatory: true, format: CURRENCY},
|
84
|
+
name_on_card: {mandatory: true, format: NAME_ON_CARD},
|
85
|
+
street: {mandatory: true, format: STREET},
|
86
|
+
zip: {mandatory: true, format: ZIP},
|
87
|
+
city: {mandatory: true, format: CITY},
|
88
|
+
country: {mandatory: true, format: COUNTRY},
|
89
|
+
state: {mandatory: true, format: STATE},
|
90
|
+
email: {mandatory: true, format: EMAIL},
|
91
|
+
phone: {mandatory: true, format: PHONE},
|
92
|
+
card_bin: {mandatory: false, format: CARD_BIN},
|
93
|
+
bin_name: {mandatory: false, format: BIN_NAME},
|
94
|
+
bin_phone: {mandatory: false, format: BIN_PHONE},
|
95
|
+
merchant_site_url: {mandatory: true, format: MERCHANT_SITE_URL},
|
96
|
+
merchant_referring_name: {mandatory: false, format: MERCHANT_REFERRING_NAME}
|
97
|
+
}.freeze
|
98
|
+
|
99
|
+
INIT_DEFAULTS = {
|
100
|
+
name_on_card: "John Doe",
|
101
|
+
street: "NA", zip: "NA", city: "NA", country: "NA", state: "NA",
|
102
|
+
email: "john_doe@example.com", phone: "00371000000"
|
103
|
+
}.freeze
|
104
|
+
|
105
|
+
INIT_RECURRING_REGISTRATION_SPEC = INIT_SPEC.
|
106
|
+
dup.merge(save_card: {mandatory: true, format: %r'\d+'}).freeze
|
107
|
+
INIT_RECURRING_REGISTRATION_DEFAULTS = INIT_DEFAULTS.
|
108
|
+
dup.merge(save_card: "1").freeze
|
109
|
+
|
110
|
+
# 32. Table
|
111
|
+
# Field Format Description
|
112
|
+
# guid ans(19) Your merchant GUID
|
113
|
+
# pwd h(40) SHA1 hash of your processing password
|
114
|
+
# rs an(1..12) Routing string
|
115
|
+
# original_init_id h(40) init_transaction_id of your original transaction
|
116
|
+
# merchant_transaction_id ans(5..50) Your transaction ID
|
117
|
+
# amount n Transaction amount, in MINOR units (i.e. 2150 for $21.50 transaction)
|
118
|
+
# description uns(5..255) Order items description
|
119
|
+
INIT_RECURRENT_SPEC = {
|
120
|
+
guid: {mandatory: true, format: GUID_REGEX},
|
121
|
+
pwd: {mandatory: true, format: PASSWORD_DIGEST_REGEX},
|
122
|
+
rs: {mandatory: true, format: ROUTING_REGEX},
|
123
|
+
original_init_id: {mandatory: true, format: TID_REGEX},
|
124
|
+
merchant_transaction_id: {mandatory: true, format: MERCHANT_TRANSACTION_ID},
|
125
|
+
amount: {mandatory: true, format: AMOUNT},
|
126
|
+
description: {mandatory: true, format: DESCRIPTION},
|
127
|
+
}.freeze
|
128
|
+
|
129
|
+
INIT_RECURRENT_DEFAULTS = {
|
130
|
+
# none
|
131
|
+
}.freeze
|
132
|
+
|
133
|
+
# 34. Table
|
134
|
+
# Field Format Description
|
135
|
+
# init_transaction_id h(40) init_transaction_id received for this recurrent transaction
|
136
|
+
# f_extended n Return extended charge details (optional)
|
137
|
+
CHARGE_RECURRENT_SPEC = {
|
138
|
+
guid: {mandatory: true, format: GUID_REGEX},
|
139
|
+
pwd: {mandatory: true, format: PASSWORD_DIGEST_REGEX},
|
140
|
+
init_transaction_id: {mandatory: true, format: TID_REGEX},
|
141
|
+
f_extended: {mandatory: false, format: F_EXTENDED},
|
142
|
+
}.freeze
|
143
|
+
|
144
|
+
CHARGE_RECURRENT_DEFAULTS = {
|
145
|
+
f_extended: "100" # determines the verbosity of responses
|
146
|
+
}.freeze
|
147
|
+
|
148
|
+
# 19. Table
|
149
|
+
# Field Format Value
|
150
|
+
# request_type as 'transaction_status'
|
151
|
+
# init_transaction_id h(40) Gateway Transaction ID
|
152
|
+
# f_extended n Return extended charge details, see section 2.4 of this manual for more details
|
153
|
+
# (optional)
|
154
|
+
# guid ans(19) Your GUID
|
155
|
+
# pwd h(40) SHA1 hash of your processing password
|
156
|
+
STATUS_REQUEST_SPEC = {
|
157
|
+
guid: {mandatory: true, format: GUID_REGEX},
|
158
|
+
pwd: {mandatory: true, format: PASSWORD_DIGEST_REGEX},
|
159
|
+
request_type: {mandatory: true, format: 'transaction_status'},
|
160
|
+
init_transaction_id: {mandatory: true, format: TID_REGEX},
|
161
|
+
f_extended: {mandatory: false, format: F_EXTENDED}
|
162
|
+
}.freeze
|
163
|
+
|
164
|
+
STATUS_REQUEST_DEFAULTS = {
|
165
|
+
request_type: 'transaction_status',
|
166
|
+
f_extended: "100", # determines the verbosity of responses
|
167
|
+
}.freeze
|
168
|
+
end
|
169
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
class TransactPro::Response
|
2
|
+
attr_reader :body
|
3
|
+
|
4
|
+
def initialize(body)
|
5
|
+
@body = body
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_s
|
9
|
+
body
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_h
|
13
|
+
@to_h ||= body.split("~").inject({}) do |mem, portion|
|
14
|
+
match = portion.match(%r'\A([^\:]+?)\:(.*)')
|
15
|
+
mem[match[1]] = match[2]
|
16
|
+
mem
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def redirect_link
|
21
|
+
link_portion = body.split("~").detect do |portion|
|
22
|
+
portion[%r'\ARedirectOnsite:']
|
23
|
+
end
|
24
|
+
|
25
|
+
link_portion.nil? ?
|
26
|
+
nil :
|
27
|
+
link_portion.match(%r'\ARedirectOnsite:(https?://.*?tid=[[:alnum:]]+)'i)[1]
|
28
|
+
end
|
29
|
+
|
30
|
+
def status
|
31
|
+
status_portion = body.split("~").detect do |portion|
|
32
|
+
portion[%r'\A(OK)|(Status)\:']
|
33
|
+
end
|
34
|
+
|
35
|
+
if status_portion.nil?
|
36
|
+
"ERROR"
|
37
|
+
elsif status_portion[%r'\AOK']
|
38
|
+
"OK"
|
39
|
+
elsif status_portion[%r'\AStatus']
|
40
|
+
status = status_portion.match(%r'\AStatus:(.*)')[1]
|
41
|
+
status == "Success" ? "OK" : "FAIL"
|
42
|
+
else
|
43
|
+
"ERROR"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def tid
|
48
|
+
tid_portion = body.split("~").detect do |portion|
|
49
|
+
portion[%r'\AOK\:']
|
50
|
+
end
|
51
|
+
|
52
|
+
tid_portion.nil? ?
|
53
|
+
nil :
|
54
|
+
tid_portion.match(%r'\A(.*?)\:(.*)')[2]
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "transact_pro/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "transact_pro"
|
8
|
+
spec.required_ruby_version = '>= 2'
|
9
|
+
spec.date = "2018-01-04"
|
10
|
+
spec.version = TransactPro::VERSION
|
11
|
+
spec.authors = ["Epigene"]
|
12
|
+
spec.email = ["cto@creative.gs", "augusts.bautra@gmail.com"]
|
13
|
+
|
14
|
+
spec.summary = "Ruby wrapper for communicating with TransactPro 1stpayments.net card payment API."
|
15
|
+
spec.homepage = "https://github.com/CreativeGS/transact_pro"
|
16
|
+
spec.license = "BSD-3-Clause"
|
17
|
+
|
18
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
19
|
+
f.match(%r{^(test|spec|features)/})
|
20
|
+
end
|
21
|
+
spec.bindir = "exe"
|
22
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
23
|
+
spec.require_paths = ["lib"]
|
24
|
+
|
25
|
+
spec.add_dependency "rest-client", "~> 2.0.2"
|
26
|
+
|
27
|
+
spec.add_development_dependency "bundler", "~> 1.16"
|
28
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
29
|
+
spec.add_development_dependency "rspec", "~> 3.7"
|
30
|
+
spec.add_development_dependency "webmock"#, "~> 3.7"
|
31
|
+
spec.add_development_dependency "pry", "~> 0.11.3"
|
32
|
+
spec.add_development_dependency "simplecov", "~> 0.15.1"
|
33
|
+
spec.add_development_dependency "coveralls", "~> 0.7.1"
|
34
|
+
|
35
|
+
end
|
metadata
ADDED
@@ -0,0 +1,177 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: transact_pro
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Epigene
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-01-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rest-client
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.0.2
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.0.2
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.16'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.16'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.7'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.7'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: webmock
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: pry
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.11.3
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ~>
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.11.3
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: simplecov
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ~>
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 0.15.1
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ~>
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.15.1
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: coveralls
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ~>
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.7.1
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ~>
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.7.1
|
125
|
+
description:
|
126
|
+
email:
|
127
|
+
- cto@creative.gs
|
128
|
+
- augusts.bautra@gmail.com
|
129
|
+
executables: []
|
130
|
+
extensions: []
|
131
|
+
extra_rdoc_files: []
|
132
|
+
files:
|
133
|
+
- .circleci/config.yml
|
134
|
+
- .gitignore
|
135
|
+
- .rspec
|
136
|
+
- CODE_OF_CONDUCT.md
|
137
|
+
- Gemfile
|
138
|
+
- Gemfile.lock
|
139
|
+
- LICENSE.txt
|
140
|
+
- README.md
|
141
|
+
- Rakefile
|
142
|
+
- assets/account_structure.png
|
143
|
+
- bin/console
|
144
|
+
- bin/setup
|
145
|
+
- lib/transact_pro.rb
|
146
|
+
- lib/transact_pro/gateway.rb
|
147
|
+
- lib/transact_pro/request.rb
|
148
|
+
- lib/transact_pro/request_specs.rb
|
149
|
+
- lib/transact_pro/response.rb
|
150
|
+
- lib/transact_pro/version.rb
|
151
|
+
- transact_pro.gemspec
|
152
|
+
homepage: https://github.com/CreativeGS/transact_pro
|
153
|
+
licenses:
|
154
|
+
- BSD-3-Clause
|
155
|
+
metadata: {}
|
156
|
+
post_install_message:
|
157
|
+
rdoc_options: []
|
158
|
+
require_paths:
|
159
|
+
- lib
|
160
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
161
|
+
requirements:
|
162
|
+
- - '>='
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: '2'
|
165
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
166
|
+
requirements:
|
167
|
+
- - '>='
|
168
|
+
- !ruby/object:Gem::Version
|
169
|
+
version: '0'
|
170
|
+
requirements: []
|
171
|
+
rubyforge_project:
|
172
|
+
rubygems_version: 2.4.8
|
173
|
+
signing_key:
|
174
|
+
specification_version: 4
|
175
|
+
summary: Ruby wrapper for communicating with TransactPro 1stpayments.net card payment
|
176
|
+
API.
|
177
|
+
test_files: []
|