ruby_paypal_nvp 0.1.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 +13 -0
- data/.rspec +3 -0
- data/.rubocop.yml +17 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +84 -0
- data/LICENSE.txt +21 -0
- data/README.md +212 -0
- data/Rakefile +6 -0
- data/bin/console +7 -0
- data/bin/setup +8 -0
- data/lib/ruby_paypal_nvp.rb +32 -0
- data/lib/ruby_paypal_nvp/balance.rb +7 -0
- data/lib/ruby_paypal_nvp/configuration.rb +44 -0
- data/lib/ruby_paypal_nvp/fetcher/balance.rb +41 -0
- data/lib/ruby_paypal_nvp/fetcher/base.rb +114 -0
- data/lib/ruby_paypal_nvp/fetcher/statement.rb +66 -0
- data/lib/ruby_paypal_nvp/model/balance.rb +14 -0
- data/lib/ruby_paypal_nvp/model/item.rb +39 -0
- data/lib/ruby_paypal_nvp/model/statement.rb +81 -0
- data/lib/ruby_paypal_nvp/statement.rb +7 -0
- data/lib/ruby_paypal_nvp/utils/errors.rb +10 -0
- data/lib/ruby_paypal_nvp/version.rb +3 -0
- data/ruby_paypal_nvp.gemspec +39 -0
- metadata +182 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 2fe00c7ddd7983e5511a992b53f1d9c53bed4807
|
|
4
|
+
data.tar.gz: 094c8c4e580882e4a39c0643fbb131e0211aa17e
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 3d307941fa46451f7905d40a64a2d73cc3cad7cea855ada278b07341e973057a3487c9a50474ea2a4f0bcb80f1a29c627b4d19026d6632d2de75c10cbac01555
|
|
7
|
+
data.tar.gz: f89320bd20446303bf864c5b961208b901e29a8f1c5849fc9788f0d09a5dc9f55e02efa5c89d1954a812251d3b80ac74a715cd36d2e711ece6c474b1329a8e2a
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
AllCops:
|
|
2
|
+
Exclude:
|
|
3
|
+
- 'ruby_paypal_nvp.gemspec'
|
|
4
|
+
- 'spec/**/*'
|
|
5
|
+
TargetRubyVersion: 2.3
|
|
6
|
+
|
|
7
|
+
Style/FrozenStringLiteralComment:
|
|
8
|
+
Enabled: false
|
|
9
|
+
|
|
10
|
+
Metrics/LineLength:
|
|
11
|
+
Max: 89
|
|
12
|
+
|
|
13
|
+
Documentation:
|
|
14
|
+
Enabled: false
|
|
15
|
+
|
|
16
|
+
Naming/VariableName:
|
|
17
|
+
Enabled: false
|
data/.travis.yml
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 andrej@antas.cz. 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,84 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
ruby_paypal_nvp (0.1.0)
|
|
5
|
+
activesupport (~> 5.1)
|
|
6
|
+
|
|
7
|
+
GEM
|
|
8
|
+
remote: https://rubygems.org/
|
|
9
|
+
specs:
|
|
10
|
+
activesupport (5.1.4)
|
|
11
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
12
|
+
i18n (~> 0.7)
|
|
13
|
+
minitest (~> 5.1)
|
|
14
|
+
tzinfo (~> 1.1)
|
|
15
|
+
addressable (2.5.2)
|
|
16
|
+
public_suffix (>= 2.0.2, < 4.0)
|
|
17
|
+
ast (2.3.0)
|
|
18
|
+
coderay (1.1.2)
|
|
19
|
+
concurrent-ruby (1.0.5)
|
|
20
|
+
crack (0.4.3)
|
|
21
|
+
safe_yaml (~> 1.0.0)
|
|
22
|
+
diff-lcs (1.3)
|
|
23
|
+
hashdiff (0.3.7)
|
|
24
|
+
i18n (0.9.0)
|
|
25
|
+
concurrent-ruby (~> 1.0)
|
|
26
|
+
method_source (0.9.0)
|
|
27
|
+
minitest (5.10.3)
|
|
28
|
+
parallel (1.12.1)
|
|
29
|
+
parser (2.4.0.2)
|
|
30
|
+
ast (~> 2.3)
|
|
31
|
+
powerpack (0.1.1)
|
|
32
|
+
pry (0.11.2)
|
|
33
|
+
coderay (~> 1.1.0)
|
|
34
|
+
method_source (~> 0.9.0)
|
|
35
|
+
public_suffix (3.0.1)
|
|
36
|
+
rainbow (3.0.0)
|
|
37
|
+
rake (10.5.0)
|
|
38
|
+
rspec (3.5.0)
|
|
39
|
+
rspec-core (~> 3.5.0)
|
|
40
|
+
rspec-expectations (~> 3.5.0)
|
|
41
|
+
rspec-mocks (~> 3.5.0)
|
|
42
|
+
rspec-core (3.5.4)
|
|
43
|
+
rspec-support (~> 3.5.0)
|
|
44
|
+
rspec-expectations (3.5.0)
|
|
45
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
46
|
+
rspec-support (~> 3.5.0)
|
|
47
|
+
rspec-mocks (3.5.0)
|
|
48
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
49
|
+
rspec-support (~> 3.5.0)
|
|
50
|
+
rspec-support (3.5.0)
|
|
51
|
+
rubocop (0.52.0)
|
|
52
|
+
parallel (~> 1.10)
|
|
53
|
+
parser (>= 2.4.0.2, < 3.0)
|
|
54
|
+
powerpack (~> 0.1)
|
|
55
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
56
|
+
ruby-progressbar (~> 1.7)
|
|
57
|
+
unicode-display_width (~> 1.0, >= 1.0.1)
|
|
58
|
+
ruby-progressbar (1.9.0)
|
|
59
|
+
safe_yaml (1.0.4)
|
|
60
|
+
thread_safe (0.3.6)
|
|
61
|
+
tzinfo (1.2.3)
|
|
62
|
+
thread_safe (~> 0.1)
|
|
63
|
+
unicode-display_width (1.3.0)
|
|
64
|
+
vcr (2.9.3)
|
|
65
|
+
webmock (3.1.1)
|
|
66
|
+
addressable (>= 2.3.6)
|
|
67
|
+
crack (>= 0.3.2)
|
|
68
|
+
hashdiff
|
|
69
|
+
|
|
70
|
+
PLATFORMS
|
|
71
|
+
ruby
|
|
72
|
+
|
|
73
|
+
DEPENDENCIES
|
|
74
|
+
bundler (~> 1.16.a)
|
|
75
|
+
pry (~> 0.11)
|
|
76
|
+
rake (~> 10.0)
|
|
77
|
+
rspec (~> 3.0)
|
|
78
|
+
rubocop
|
|
79
|
+
ruby_paypal_nvp!
|
|
80
|
+
vcr (~> 2.2)
|
|
81
|
+
webmock
|
|
82
|
+
|
|
83
|
+
BUNDLED WITH
|
|
84
|
+
1.16.0
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2017 Andrej Antas
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# RubyPaypalNvp
|
|
2
|
+
|
|
3
|
+
Missing paypal account statements.
|
|
4
|
+
|
|
5
|
+
As per communication with PayPal this is apart from PDF and CSV reports
|
|
6
|
+
prefered way of downloading e.x. monthly statements if you have too much and
|
|
7
|
+
need to automate the process...
|
|
8
|
+
|
|
9
|
+
This gem provides you with simple access to specific subject account statement.
|
|
10
|
+
|
|
11
|
+
## Requirements
|
|
12
|
+
|
|
13
|
+
- PayPal account of course
|
|
14
|
+
- Paypal credentials for NVP API can be found under:
|
|
15
|
+
- Login on http://paypal.com/
|
|
16
|
+
- Go to your Profile and settings (upper right corner menu)
|
|
17
|
+
- Click on My selling tools
|
|
18
|
+
- Under first part - Selling online - click on Update API access
|
|
19
|
+
- At the bottom look up NVP/SOAP APIintegration (Classic)
|
|
20
|
+
- Click Manage API credentials there
|
|
21
|
+
- Finally after a while on this page is information needed for you to access
|
|
22
|
+
NVP API data
|
|
23
|
+
- If you take care of multiple account data like we do, They need to give
|
|
24
|
+
you access like this:
|
|
25
|
+
- Login on http://paypal.com/
|
|
26
|
+
- Click Profile“ → „Profile and settings“
|
|
27
|
+
- In the menu choose „My selling tools“ and then „API access“ and click on Update
|
|
28
|
+
- Choose the first option and click on „Grant API permission“
|
|
29
|
+
- On the next page „Add a new third party“
|
|
30
|
+
- In the new window fill in ID given to you (is the one from previous part) and click „Lookup“
|
|
31
|
+
- When the ID was filled in correctly a new menu with permissions will appear („Available Permissions“).
|
|
32
|
+
- Choose the following options:
|
|
33
|
+
- Obtain your PayPal account balance.
|
|
34
|
+
- Obtain information about a single transaction.
|
|
35
|
+
- Search your transactions for items that match specific criteria and display the results.
|
|
36
|
+
- Confirm the selection by clicking „Add“.
|
|
37
|
+
|
|
38
|
+
And after these couple days of setup you are all good to go :)
|
|
39
|
+
|
|
40
|
+
Important to note here is that in first part is your account and setup and
|
|
41
|
+
stuff...
|
|
42
|
+
|
|
43
|
+
Second part is you customer (in our case) who wants you to lookup data for them
|
|
44
|
+
and they use your id that you need to send them (is always in email like form
|
|
45
|
+
without @ in it)
|
|
46
|
+
|
|
47
|
+
Then the `subject` used in search for statements is their email through which
|
|
48
|
+
they granted API access to you...
|
|
49
|
+
|
|
50
|
+
## Installation
|
|
51
|
+
|
|
52
|
+
Add this line to your application's Gemfile:
|
|
53
|
+
|
|
54
|
+
```ruby
|
|
55
|
+
gem 'ruby_paypal_nvp'
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
And then execute:
|
|
59
|
+
|
|
60
|
+
$ bundle
|
|
61
|
+
|
|
62
|
+
Or install it yourself as:
|
|
63
|
+
|
|
64
|
+
$ gem install ruby_paypal_nvp
|
|
65
|
+
|
|
66
|
+
## Usage
|
|
67
|
+
|
|
68
|
+
For the time being this gem provides you with Stamtement download for desired
|
|
69
|
+
period.
|
|
70
|
+
|
|
71
|
+
The weird PayPal pagin and all things considered proven to be correct input for
|
|
72
|
+
accountants to work with.
|
|
73
|
+
|
|
74
|
+
first step is configuration (either as initializer or if you have it in single
|
|
75
|
+
script or so):
|
|
76
|
+
|
|
77
|
+
```ruby
|
|
78
|
+
RubyPaypalNvp.configure do |config|
|
|
79
|
+
config.user = 'YOUR_USER_HERE' # watch out may differ according to setup for sandbox
|
|
80
|
+
config.password = 'YOUR_PWD_HERE'
|
|
81
|
+
config.signature = 'YOUR_SIGNATURE_HERE'
|
|
82
|
+
config.api_url = 'https://api-3t.paypal.com/nvp' # or put 'https://api-3t.andbox.aypal.com/nvp' for sandbox env
|
|
83
|
+
end
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Then you are ready to query PayPal
|
|
87
|
+
|
|
88
|
+
We provide you with Statement class:
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
RubyPaypalNvp::Statement
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Provides search method `where`:
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
RubyPaypalNvp::Statement.where(
|
|
98
|
+
date_from: Time.zone.parse('1.9.2017'),
|
|
99
|
+
date_to: Time.zone.parse('1.9.2017'),
|
|
100
|
+
subject: 'info@uol.cz',
|
|
101
|
+
currency: 'CZK',
|
|
102
|
+
transaction_class: 'BalanceAffecting'
|
|
103
|
+
)
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Where
|
|
107
|
+
- `date_from` beginning of interval to search for (beggining of the day - disregards time)
|
|
108
|
+
- `date_to` end of interval to search for (end of the day - disregards time)
|
|
109
|
+
- Dates and times in particular are converted to utc
|
|
110
|
+
- `subject` is account email you are looking through (as per description in requirements)
|
|
111
|
+
- `currency` is as name says currency of desired account (defaults to `CZK`)
|
|
112
|
+
- `transaction_class` is per description found in docs (here)[https://developer.paypal.com/docs/classic/api/merchant/TransactionSearch_API_Operation_NVP/] defaults to `BalanceAffecting`
|
|
113
|
+
- most problematic since multiple options you should be able to put the as `All` or `Received` result in `500` from PayPal which we are not able to identify (talking here about accounts with 1k+ transactions monthly)
|
|
114
|
+
- default setup is provide to be stable and correct for accounting
|
|
115
|
+
|
|
116
|
+
Response you get from search is in form of Object containing:
|
|
117
|
+
|
|
118
|
+
```ruby
|
|
119
|
+
#<RubyPaypalNvp::Model::Statement:0x007fe4360ac450
|
|
120
|
+
@amount_sum=1000.00,
|
|
121
|
+
@currency_code="CZK",
|
|
122
|
+
@end_date="2017-09-01T21:59:59Z",
|
|
123
|
+
@fee_amount_sum=10.00,
|
|
124
|
+
@items=
|
|
125
|
+
[#<RubyPaypalNvp::Model::Item:0x007fe43679bf90
|
|
126
|
+
@amount=1000.00,
|
|
127
|
+
@currency_code="CZK",
|
|
128
|
+
@email="test@uol.cz",
|
|
129
|
+
@fee_amount=10.00,
|
|
130
|
+
@name="Martin Tester",
|
|
131
|
+
@net_amount=1010.00,
|
|
132
|
+
@status="Completed",
|
|
133
|
+
@timestamp="2017-09-01T12:48:08Z",
|
|
134
|
+
@timezone="GMT",
|
|
135
|
+
@transaction_id="9XXXXXXXXXXXXXXXH",
|
|
136
|
+
@type="Refund">],
|
|
137
|
+
@items_count=4,
|
|
138
|
+
@net_amount_sum=1010.00,
|
|
139
|
+
@start_date="2017-08-31T22:00:00Z",
|
|
140
|
+
@subject="info@uol.cz",
|
|
141
|
+
@timestamp="2017-11-02T10:45:07Z">
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
You can see all the sums and all items which represent all movements on the account in given time period there.
|
|
145
|
+
|
|
146
|
+
Also `RubyPaypalNvp::Model::Statemnt` result class from query provides you method `#generate_csv` which will create CSV from the data for inspection:
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
result = RubyPaypalNvp::Statement.where(
|
|
150
|
+
date_from: Time.zone.parse('1.9.2017'),
|
|
151
|
+
date_to: Time.zone.parse('30.9.2017'),
|
|
152
|
+
subject: 'info@uol.cz',
|
|
153
|
+
currency: 'CZK',
|
|
154
|
+
transaction_class: 'BalanceAffecting'
|
|
155
|
+
)
|
|
156
|
+
result.generate_csv('location_to_save.csv')
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Another thing provided is Balance fetching, where you can ask for balance of
|
|
160
|
+
given account at point in time when asking it... you cannot really ask for
|
|
161
|
+
balance at given point in time, because they simply do not provide it...
|
|
162
|
+
|
|
163
|
+
For this purpose you have:
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
RubyPaypalNvp::Balance
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
it provides you again with simple `.where` method to ask for data:
|
|
170
|
+
|
|
171
|
+
```
|
|
172
|
+
result = RubyPaypalNvp::Balance
|
|
173
|
+
.where(subject: 'info@uol.cz', currency: 'CZK')
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Where
|
|
177
|
+
- `subject` is account email you are looking through (as per description in requirements)
|
|
178
|
+
- `currency` is as name says currency of desired account (defaults to `CZK`)
|
|
179
|
+
|
|
180
|
+
Result provides speak for itself:
|
|
181
|
+
|
|
182
|
+
```
|
|
183
|
+
#<RubyPaypalNvp::Model::Balance:0x007fd8f0a17f90
|
|
184
|
+
@currency_code="CZK",
|
|
185
|
+
@opening_balance=58221.0,
|
|
186
|
+
@subject="info@uol.cz",
|
|
187
|
+
@timestamp="2017-12-06 10:00:14 +0100">
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
## Development
|
|
192
|
+
|
|
193
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
194
|
+
|
|
195
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
196
|
+
|
|
197
|
+
## Contributing
|
|
198
|
+
|
|
199
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/ruby_paypal_nvp. 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.
|
|
200
|
+
|
|
201
|
+
## TODO
|
|
202
|
+
|
|
203
|
+
Pending things that will be done shortly:
|
|
204
|
+
- Rspec
|
|
205
|
+
|
|
206
|
+
## License
|
|
207
|
+
|
|
208
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
209
|
+
|
|
210
|
+
## Code of Conduct
|
|
211
|
+
|
|
212
|
+
Everyone interacting in the RubyPaypalNvp project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/ruby_paypal_nvp/blob/master/CODE_OF_CONDUCT.md).
|
data/Rakefile
ADDED
data/bin/console
ADDED
data/bin/setup
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require 'active_support/all'
|
|
2
|
+
require 'net/http'
|
|
3
|
+
|
|
4
|
+
require 'ruby_paypal_nvp/version'
|
|
5
|
+
require 'ruby_paypal_nvp/configuration'
|
|
6
|
+
|
|
7
|
+
require 'ruby_paypal_nvp/utils/errors'
|
|
8
|
+
|
|
9
|
+
require 'ruby_paypal_nvp/fetcher/base'
|
|
10
|
+
require 'ruby_paypal_nvp/fetcher/balance'
|
|
11
|
+
require 'ruby_paypal_nvp/fetcher/statement'
|
|
12
|
+
|
|
13
|
+
require 'ruby_paypal_nvp/model/statement'
|
|
14
|
+
require 'ruby_paypal_nvp/model/balance'
|
|
15
|
+
require 'ruby_paypal_nvp/model/item'
|
|
16
|
+
|
|
17
|
+
require 'ruby_paypal_nvp/statement'
|
|
18
|
+
require 'ruby_paypal_nvp/balance'
|
|
19
|
+
|
|
20
|
+
module RubyPaypalNvp
|
|
21
|
+
def self.configuration
|
|
22
|
+
@configuration ||= Configuration.new
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.reset
|
|
26
|
+
@configuration = Configuration.new
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.configure
|
|
30
|
+
yield(configuration)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module RubyPaypalNvp
|
|
2
|
+
class Configuration
|
|
3
|
+
attr_writer :version, :user, :password, :signature, :subject, :api_url
|
|
4
|
+
|
|
5
|
+
def initialize
|
|
6
|
+
Time.zone = 'Prague'
|
|
7
|
+
@version = nil
|
|
8
|
+
@user = nil
|
|
9
|
+
@password = nil
|
|
10
|
+
@signature = nil
|
|
11
|
+
@subject = nil
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def version
|
|
15
|
+
return '204.0' unless @version
|
|
16
|
+
@version
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def user
|
|
20
|
+
raise ConfigNotSet, 'user' unless @user
|
|
21
|
+
@user
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def password
|
|
25
|
+
raise ConfigNotSet, 'password' unless @password
|
|
26
|
+
@password
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def signature
|
|
30
|
+
raise ConfigNotSet, 'signature' unless @signature
|
|
31
|
+
@signature
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def subject
|
|
35
|
+
raise ConfigNotSet, 'subject' unless @subject
|
|
36
|
+
@subject
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def api_url
|
|
40
|
+
raise ConfigNotSet, 'api_url' unless @api_url
|
|
41
|
+
@api_url
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module RubyPaypalNvp
|
|
2
|
+
module Fetcher
|
|
3
|
+
class Balance < Base
|
|
4
|
+
RESPONSE_PARAMS = %w[L_AMT L_CURRENCYCODE].freeze
|
|
5
|
+
|
|
6
|
+
private
|
|
7
|
+
|
|
8
|
+
def process_loaded_data(result)
|
|
9
|
+
result = filter_current_currency(result)
|
|
10
|
+
return if result[:values].blank?
|
|
11
|
+
::RubyPaypalNvp::Model::Balance.new(result)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def filter_current_currency(result)
|
|
15
|
+
currency_code = result[:meta]['currency_code']
|
|
16
|
+
balance = result[:values].select do |_key, value|
|
|
17
|
+
{ key: value } if value.values.include?(currency_code)
|
|
18
|
+
end
|
|
19
|
+
result[:values] = balance.values.first
|
|
20
|
+
result
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def load_response
|
|
24
|
+
response = load_api_response(request_options)
|
|
25
|
+
raise response['L_LONGMESSAGE0'] if response['ACK'] == 'Failure'
|
|
26
|
+
parse(response, increment: 0)
|
|
27
|
+
result = result_with_meta(timestamp: Time.zone.parse(response['TIMESTAMP']).to_s)
|
|
28
|
+
@resulting_hash = default_hash
|
|
29
|
+
result
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def request_options
|
|
33
|
+
super.merge! returnallcurrencies: 1
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def api_method
|
|
37
|
+
'GetBalance'
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
##
|
|
2
|
+
# Base for fetching data from Paypal NVP API
|
|
3
|
+
# See docs: https://developer.paypal.com/docs/classic/api/
|
|
4
|
+
##
|
|
5
|
+
module RubyPaypalNvp
|
|
6
|
+
module Fetcher
|
|
7
|
+
class Base
|
|
8
|
+
##
|
|
9
|
+
# Input options:
|
|
10
|
+
# date_from
|
|
11
|
+
# date_to
|
|
12
|
+
# currency
|
|
13
|
+
# subject
|
|
14
|
+
# transaction_class
|
|
15
|
+
#
|
|
16
|
+
# rubocop:disable Metrics/AbcSize
|
|
17
|
+
def initialize(opts)
|
|
18
|
+
@start_date = opts.fetch(:date_from, Time.zone.now).beginning_of_day.utc.iso8601
|
|
19
|
+
@end_date = opts.fetch(:date_to, Time.zone.now).end_of_day.utc.iso8601
|
|
20
|
+
@currency = opts.fetch(:currency, 'CZK')
|
|
21
|
+
@subject = opts[:subject] || RubyPaypalNvp.configuration.subject
|
|
22
|
+
@transaction_class = opts.fetch(:transaction_class, 'BalanceAffecting')
|
|
23
|
+
@resulting_hash = default_hash
|
|
24
|
+
end
|
|
25
|
+
# rubocop:enable Metrics/AbcSize
|
|
26
|
+
|
|
27
|
+
def call
|
|
28
|
+
result = load_response
|
|
29
|
+
process_loaded_data(result)
|
|
30
|
+
rescue NoMethodError
|
|
31
|
+
raise "Error processing #{self.class} for #{@subject}"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.call(options)
|
|
35
|
+
new(options).call
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def load_api_response(options)
|
|
39
|
+
uri = URI(RubyPaypalNvp.configuration.api_url)
|
|
40
|
+
req = Net::HTTP::Post.new(uri)
|
|
41
|
+
req.set_form_data(options)
|
|
42
|
+
res = Net::HTTP.start(uri.hostname, uri.port,
|
|
43
|
+
use_ssl: uri.scheme == 'https') do |http|
|
|
44
|
+
http.open_timeout = 6000
|
|
45
|
+
http.read_timeout = 6000
|
|
46
|
+
http.request(req)
|
|
47
|
+
end
|
|
48
|
+
pretty_json(res.body)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
# rubocop:disable Metrics/AbcSize
|
|
54
|
+
# rubocop:disable Metrics/MethodLength
|
|
55
|
+
def parse(body, options = {})
|
|
56
|
+
@resulting_hash[:values].tap do |parsed_response|
|
|
57
|
+
param_type = self.class::RESPONSE_PARAMS.first
|
|
58
|
+
all_for_params_type = body.select { |k, _v| k.start_with?(param_type) }
|
|
59
|
+
all_for_params_type.each_with_index do |(key, value), index|
|
|
60
|
+
real_index = index + options[:increment]
|
|
61
|
+
parsed_response[real_index] ||= {}
|
|
62
|
+
parsed_response[real_index] = parsed_response[real_index]
|
|
63
|
+
.merge(param_type.to_s => value)
|
|
64
|
+
key = key.gsub(param_type, '')
|
|
65
|
+
self.class::RESPONSE_PARAMS.drop(1).each do |attribute_name|
|
|
66
|
+
pair = { attribute_name => body["#{attribute_name}#{key}"] }
|
|
67
|
+
parsed_response[real_index] = parsed_response[real_index].merge pair
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
# rubocop:enable Metrics/AbcSize
|
|
73
|
+
# rubocop:enable Metrics/MethodLength
|
|
74
|
+
|
|
75
|
+
# Implement in each child to save/send data
|
|
76
|
+
def process_loaded_data(_result)
|
|
77
|
+
true
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def result_with_meta(options = {})
|
|
81
|
+
@resulting_hash[:meta]['timestamp'] = options[:timestamp]
|
|
82
|
+
@resulting_hash[:meta]['start_date'] = @start_date
|
|
83
|
+
@resulting_hash[:meta]['end_date'] = @end_date
|
|
84
|
+
@resulting_hash[:meta]['subject'] = @subject
|
|
85
|
+
@resulting_hash[:meta]['currency_code'] = @currency
|
|
86
|
+
@resulting_hash
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def request_options(_options = {})
|
|
90
|
+
{
|
|
91
|
+
method: api_method,
|
|
92
|
+
version: RubyPaypalNvp.configuration.version,
|
|
93
|
+
user: RubyPaypalNvp.configuration.user,
|
|
94
|
+
pwd: RubyPaypalNvp.configuration.password,
|
|
95
|
+
signature: RubyPaypalNvp.configuration.signature,
|
|
96
|
+
subject: @subject
|
|
97
|
+
}
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Needs to be specific in each child
|
|
101
|
+
def api_method
|
|
102
|
+
''
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def pretty_json(body)
|
|
106
|
+
Hash[URI.decode_www_form(body)]
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def default_hash
|
|
110
|
+
{ meta: {}, values: {} }
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
module RubyPaypalNvp
|
|
2
|
+
module Fetcher
|
|
3
|
+
class Statement < Base
|
|
4
|
+
RESPONSE_PARAMS = %w[L_TIMESTAMP L_TIMEZONE L_TYPE L_EMAIL L_NAME
|
|
5
|
+
L_TRANSACTIONID L_STATUS L_AMT L_CURRENCYCODE
|
|
6
|
+
L_FEEAMT L_NETAMT].freeze
|
|
7
|
+
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
def process_loaded_data(result)
|
|
11
|
+
::RubyPaypalNvp::Model::Statement.new(result)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# rubocop:disable Metrics/AbcSize
|
|
15
|
+
# rubocop:disable Metrics/MethodLength
|
|
16
|
+
def load_response
|
|
17
|
+
@ack = 'Failure'
|
|
18
|
+
while @ack != 'Success'
|
|
19
|
+
enddate = moved_end ? Time.parse(moved_end).utc.iso8601 : nil
|
|
20
|
+
options = request_options(enddate: enddate)
|
|
21
|
+
response = load_api_response(options)
|
|
22
|
+
parse(response, increment: increment)
|
|
23
|
+
|
|
24
|
+
@ack = response['ACK']
|
|
25
|
+
raise response['L_LONGMESSAGE0'] if @ack == 'Failure'
|
|
26
|
+
end
|
|
27
|
+
result = result_with_meta(timestamp: response['TIMESTAMP'])
|
|
28
|
+
@resulting_hash = default_hash
|
|
29
|
+
result[:values] = result[:values].values
|
|
30
|
+
result
|
|
31
|
+
end
|
|
32
|
+
# rubocop:enable Metrics/AbcSize
|
|
33
|
+
# rubocop:enable Metrics/MethodLength
|
|
34
|
+
|
|
35
|
+
# rubocop:disable Style/GuardClause
|
|
36
|
+
def moved_end
|
|
37
|
+
if @resulting_hash[:values].keys.last
|
|
38
|
+
@resulting_hash[:values].values.last['L_TIMESTAMP']
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
# rubocop:enable Style/GuardClause
|
|
42
|
+
|
|
43
|
+
def increment
|
|
44
|
+
if @resulting_hash[:values].keys.last
|
|
45
|
+
(@resulting_hash[:values].keys.last + 1)
|
|
46
|
+
else
|
|
47
|
+
0
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def request_options(options = {})
|
|
52
|
+
additional = {
|
|
53
|
+
startdate: @start_date,
|
|
54
|
+
enddate: options[:enddate] || @end_date,
|
|
55
|
+
transactionclass: @transaction_class,
|
|
56
|
+
currencycode: @currency
|
|
57
|
+
}
|
|
58
|
+
super.merge! additional
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def api_method
|
|
62
|
+
'TransactionSearch'
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module RubyPaypalNvp
|
|
2
|
+
module Model
|
|
3
|
+
class Balance
|
|
4
|
+
attr_accessor :currency_code, :subject, :timestamp, :opening_balance
|
|
5
|
+
|
|
6
|
+
def initialize(result)
|
|
7
|
+
@currency_code = result[:meta]['currency_code']
|
|
8
|
+
@subject = result[:meta]['subject']
|
|
9
|
+
@timestamp = result[:meta]['timestamp']
|
|
10
|
+
@opening_balance = result[:values]['L_AMT'].to_f
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module RubyPaypalNvp
|
|
2
|
+
module Model
|
|
3
|
+
class Item
|
|
4
|
+
attr_accessor :timestamp, :timezone, :type, :email, :name,
|
|
5
|
+
:transaction_id, :status, :amount, :currency_code, :fee_amount,
|
|
6
|
+
:net_amount
|
|
7
|
+
|
|
8
|
+
# rubocop:disable Metrics/AbcSize
|
|
9
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
|
10
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
|
11
|
+
# rubocop:disable Metrics/MethodLength
|
|
12
|
+
def initialize(hash = {})
|
|
13
|
+
@timestamp = hash['L_TIMESTAMP'] || nil
|
|
14
|
+
@timezone = hash['L_TIMEZONE'] || nil
|
|
15
|
+
@type = hash['L_TYPE'] || nil
|
|
16
|
+
@email = hash['L_EMAIL'] || nil
|
|
17
|
+
@name = hash['L_NAME'] || nil
|
|
18
|
+
@transaction_id = hash['L_TRANSACTIONID'] || nil
|
|
19
|
+
@status = hash['L_STATUS'] || nil
|
|
20
|
+
@amount = (hash['L_AMT'] || nil).to_f
|
|
21
|
+
@currency_code = hash['L_CURRENCYCODE'] || nil
|
|
22
|
+
@fee_amount = (hash['L_FEEAMT'] || nil).to_f
|
|
23
|
+
@net_amount = (hash['L_NETAMT'] || nil).to_f
|
|
24
|
+
end
|
|
25
|
+
# rubocop:enable Metrics/AbcSize
|
|
26
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
|
27
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
|
28
|
+
# rubocop:enable Metrics/MethodLength
|
|
29
|
+
|
|
30
|
+
def self.attributes
|
|
31
|
+
new.instance_variable_names.map { |a| a.delete('@') }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def to_csv
|
|
35
|
+
instance_variables.map { |k| instance_variable_get(k) }
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
require 'csv'
|
|
2
|
+
|
|
3
|
+
module RubyPaypalNvp
|
|
4
|
+
module Model
|
|
5
|
+
class Statement
|
|
6
|
+
attr_accessor :timestamp, :start_date, :end_date, :subject,
|
|
7
|
+
:currency_code, :items, :amount_sum, :fee_amount_sum,
|
|
8
|
+
:net_amount_sum, :items_count
|
|
9
|
+
|
|
10
|
+
IGNORED_STATUSES = %w[Cleared Placed Removed].freeze
|
|
11
|
+
|
|
12
|
+
# rubocop:disable Metrics/AbcSize
|
|
13
|
+
# rubocop:disable Metrics/MethodLength
|
|
14
|
+
def initialize(result)
|
|
15
|
+
@timestamp = result[:meta]['timestamp']
|
|
16
|
+
@start_date = result[:meta]['start_date']
|
|
17
|
+
@end_date = result[:meta]['end_date']
|
|
18
|
+
@subject = result[:meta]['subject']
|
|
19
|
+
@currency_code = result[:meta]['currency_code']
|
|
20
|
+
@items = result[:values].map do |value|
|
|
21
|
+
Item.new(value) unless IGNORED_STATUSES.include?(value['L_STATUS'])
|
|
22
|
+
end.compact.uniq(&:transaction_id)
|
|
23
|
+
@items_count = @items.count
|
|
24
|
+
@amount_sum = @items.sum(&:amount)
|
|
25
|
+
@fee_amount_sum = @items.sum(&:fee_amount)
|
|
26
|
+
@net_amount_sum = @items.sum(&:net_amount)
|
|
27
|
+
@raw = result
|
|
28
|
+
end
|
|
29
|
+
# rubocop:enable Metrics/AbcSize
|
|
30
|
+
# rubocop:enable Metrics/MethodLength
|
|
31
|
+
|
|
32
|
+
# rubocop:disable Metrics/AbcSize
|
|
33
|
+
# rubocop:disable Metrics/MethodLength
|
|
34
|
+
def generate_csv(filename = nil)
|
|
35
|
+
raise 'Missing filename/path' unless filename
|
|
36
|
+
::CSV.open(filename, 'w') do |csv|
|
|
37
|
+
csv << ['HEADER']
|
|
38
|
+
csv << ['', 'timestamp', @timestamp]
|
|
39
|
+
csv << ['', 'start_date', @start_date]
|
|
40
|
+
csv << ['', 'end_date', @end_date]
|
|
41
|
+
csv << ['', 'subject', @subject]
|
|
42
|
+
csv << ['', 'currency_code', @currency_code]
|
|
43
|
+
csv << ['', 'items_count', @items_count]
|
|
44
|
+
csv << ['', 'amount_sum', @amount_sum]
|
|
45
|
+
csv << ['', 'fee_amount_sum', @fee_amount_sum]
|
|
46
|
+
csv << ['', 'net_amount_sum', @net_amount_sum]
|
|
47
|
+
csv << ['ITEMS']
|
|
48
|
+
csv << RubyPaypalNvp::Model::Item.attributes
|
|
49
|
+
@items.each do |item|
|
|
50
|
+
csv << item.to_csv
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
# rubocop:enable Metrics/AbcSize
|
|
55
|
+
# rubocop:enable Metrics/MethodLength
|
|
56
|
+
|
|
57
|
+
def to_json
|
|
58
|
+
raw_items.to_json
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def to_iis_json
|
|
62
|
+
{
|
|
63
|
+
'meta': {
|
|
64
|
+
'timestamp': @timestamp,
|
|
65
|
+
'start_date': @start_date,
|
|
66
|
+
'end_date': @end_date,
|
|
67
|
+
'subject': @subject,
|
|
68
|
+
'currency_code': @currency_code
|
|
69
|
+
},
|
|
70
|
+
'values': raw_items
|
|
71
|
+
}.to_json
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
def raw_items
|
|
77
|
+
@raw[:values].compact.uniq { |i| i['L_TRANSACTIONID'] }
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
3
|
+
require 'ruby_paypal_nvp/version'
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = 'ruby_paypal_nvp'
|
|
7
|
+
spec.version = RubyPaypalNvp::VERSION
|
|
8
|
+
spec.authors = ['Andrej Antas']
|
|
9
|
+
spec.email = ['andrej@antas.cz']
|
|
10
|
+
|
|
11
|
+
spec.summary = 'Ruby PayPal NVP wrapper'
|
|
12
|
+
spec.description = 'Ruby wrapper for PayPal NVP API since there was none'
|
|
13
|
+
spec.homepage = 'https://github.com/redrick/ruby_paypal_nvp'
|
|
14
|
+
spec.license = 'MIT'
|
|
15
|
+
|
|
16
|
+
if spec.respond_to?(:metadata)
|
|
17
|
+
spec.metadata['allowed_push_host'] = 'https://rubygems.org/'
|
|
18
|
+
else
|
|
19
|
+
raise 'RubyGems 2.0 or newer is required to protect against ' \
|
|
20
|
+
'public gem pushes.'
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
24
|
+
f.match(%r{^(test|spec|features)/})
|
|
25
|
+
end
|
|
26
|
+
spec.bindir = 'exe'
|
|
27
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
28
|
+
spec.require_paths = ['lib']
|
|
29
|
+
|
|
30
|
+
spec.add_runtime_dependency 'activesupport', '~> 5.1'
|
|
31
|
+
|
|
32
|
+
spec.add_development_dependency 'bundler', '~> 1.16.a'
|
|
33
|
+
spec.add_development_dependency 'pry', '~> 0.11'
|
|
34
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
|
35
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
|
36
|
+
spec.add_development_dependency 'rubocop'
|
|
37
|
+
spec.add_development_dependency 'vcr', '~> 2.2'
|
|
38
|
+
spec.add_development_dependency 'webmock'
|
|
39
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: ruby_paypal_nvp
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Andrej Antas
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: exe
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2017-12-19 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: activesupport
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '5.1'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '5.1'
|
|
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.a
|
|
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.a
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: pry
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0.11'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0.11'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: rake
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '10.0'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '10.0'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: rspec
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "~>"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '3.0'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - "~>"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '3.0'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: rubocop
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - ">="
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ">="
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: vcr
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - "~>"
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '2.2'
|
|
104
|
+
type: :development
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - "~>"
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '2.2'
|
|
111
|
+
- !ruby/object:Gem::Dependency
|
|
112
|
+
name: webmock
|
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
|
114
|
+
requirements:
|
|
115
|
+
- - ">="
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
version: '0'
|
|
118
|
+
type: :development
|
|
119
|
+
prerelease: false
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - ">="
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: '0'
|
|
125
|
+
description: Ruby wrapper for PayPal NVP API since there was none
|
|
126
|
+
email:
|
|
127
|
+
- andrej@antas.cz
|
|
128
|
+
executables: []
|
|
129
|
+
extensions: []
|
|
130
|
+
extra_rdoc_files: []
|
|
131
|
+
files:
|
|
132
|
+
- ".gitignore"
|
|
133
|
+
- ".rspec"
|
|
134
|
+
- ".rubocop.yml"
|
|
135
|
+
- ".travis.yml"
|
|
136
|
+
- CODE_OF_CONDUCT.md
|
|
137
|
+
- Gemfile
|
|
138
|
+
- Gemfile.lock
|
|
139
|
+
- LICENSE.txt
|
|
140
|
+
- README.md
|
|
141
|
+
- Rakefile
|
|
142
|
+
- bin/console
|
|
143
|
+
- bin/setup
|
|
144
|
+
- lib/ruby_paypal_nvp.rb
|
|
145
|
+
- lib/ruby_paypal_nvp/balance.rb
|
|
146
|
+
- lib/ruby_paypal_nvp/configuration.rb
|
|
147
|
+
- lib/ruby_paypal_nvp/fetcher/balance.rb
|
|
148
|
+
- lib/ruby_paypal_nvp/fetcher/base.rb
|
|
149
|
+
- lib/ruby_paypal_nvp/fetcher/statement.rb
|
|
150
|
+
- lib/ruby_paypal_nvp/model/balance.rb
|
|
151
|
+
- lib/ruby_paypal_nvp/model/item.rb
|
|
152
|
+
- lib/ruby_paypal_nvp/model/statement.rb
|
|
153
|
+
- lib/ruby_paypal_nvp/statement.rb
|
|
154
|
+
- lib/ruby_paypal_nvp/utils/errors.rb
|
|
155
|
+
- lib/ruby_paypal_nvp/version.rb
|
|
156
|
+
- ruby_paypal_nvp.gemspec
|
|
157
|
+
homepage: https://github.com/redrick/ruby_paypal_nvp
|
|
158
|
+
licenses:
|
|
159
|
+
- MIT
|
|
160
|
+
metadata:
|
|
161
|
+
allowed_push_host: https://rubygems.org/
|
|
162
|
+
post_install_message:
|
|
163
|
+
rdoc_options: []
|
|
164
|
+
require_paths:
|
|
165
|
+
- lib
|
|
166
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
167
|
+
requirements:
|
|
168
|
+
- - ">="
|
|
169
|
+
- !ruby/object:Gem::Version
|
|
170
|
+
version: '0'
|
|
171
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
172
|
+
requirements:
|
|
173
|
+
- - ">="
|
|
174
|
+
- !ruby/object:Gem::Version
|
|
175
|
+
version: '0'
|
|
176
|
+
requirements: []
|
|
177
|
+
rubyforge_project:
|
|
178
|
+
rubygems_version: 2.6.8
|
|
179
|
+
signing_key:
|
|
180
|
+
specification_version: 4
|
|
181
|
+
summary: Ruby PayPal NVP wrapper
|
|
182
|
+
test_files: []
|