amex 0.3.2 → 0.4.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.
- data/Gemfile +1 -1
- data/Gemfile.lock +2 -2
- data/README.md +22 -8
- data/amex-0.3.2.gem +0 -0
- data/example.rb +25 -1
- data/lib/amex/card_account.rb +43 -4
- data/lib/amex/client.rb +14 -13
- data/lib/amex/data/statement_request.xml +1 -1
- data/lib/amex/version.rb +1 -1
- metadata +2 -1
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
-
amex (0.
|
4
|
+
amex (0.4.0)
|
5
5
|
httparty
|
6
6
|
nokogiri
|
7
7
|
httparty (0.9.0)
|
@@ -15,6 +15,6 @@ PLATFORMS
|
|
15
15
|
ruby
|
16
16
|
|
17
17
|
DEPENDENCIES
|
18
|
-
amex (= 0.
|
18
|
+
amex (= 0.4.0)
|
19
19
|
httparty (= 0.9.0)
|
20
20
|
nokogiri (= 1.5.6)
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
## Amex
|
1
|
+
## Amex *[(view on RubyGems.org)](http://rubygems.org/gems/amex)*
|
2
2
|
|
3
3
|
Welcome to the last continuation of my Ruby-based assault on various online
|
4
4
|
banking systems, much like my
|
@@ -14,15 +14,23 @@ Express login, as well as the most recent statement's transactions.
|
|
14
14
|
### Changelog
|
15
15
|
|
16
16
|
__v0.1.0__ - Original version
|
17
|
+
|
17
18
|
__v0.2.0__ - Support for multiple American Express cards, parsing using
|
18
19
|
Nokogiri
|
20
|
+
|
19
21
|
__v0.3.0__ - Adds support for loading the transactions from the most recent statement
|
20
22
|
(but it's broken because I forgot to change something from testing :( )
|
23
|
+
|
21
24
|
__v0.3.1__ - Working version of v0.3.0 that will successfully load transactions
|
22
25
|
from the most recent statement
|
26
|
+
|
23
27
|
__v0.3.2__ - Generates a fake HardwareId in the first request, since I'm
|
24
28
|
paranoid about American Express blocking 'dummy_device_id'
|
25
29
|
|
30
|
+
__v0.4.0__ - Improves transactions - adds support for lazy-loading and
|
31
|
+
pagination from Amex::CardAccount#transactions
|
32
|
+
|
33
|
+
|
26
34
|
### Usage
|
27
35
|
|
28
36
|
The file `example.rb` provides a very simple example of how the code works, but here's a step by step:
|
@@ -31,7 +39,9 @@ The file `example.rb` provides a very simple example of how the code works, but
|
|
31
39
|
|
32
40
|
```
|
33
41
|
$ gem install amex
|
34
|
-
|
42
|
+
...
|
43
|
+
require 'rubygems'
|
44
|
+
require 'amex'
|
35
45
|
```
|
36
46
|
|
37
47
|
2. You'll just need two variables, @username and @password, each unsurprisingly corresponding to different authentication details used
|
@@ -85,7 +95,16 @@ kind of loyalty scheme active? (e.g. Membership Rewards)
|
|
85
95
|
* __total_balance (float)__ - what American Express refer to as your total balance, whatever that is!
|
86
96
|
* __payment_due (float)__ - the amount of money you need to pay before `payment_due_date`
|
87
97
|
* __payment_due_date (DateTime)__ - when the `payment_due` needs to be paid by
|
88
|
-
|
98
|
+
|
99
|
+
The transactions for a given account can be found by calling the `transaction`
|
100
|
+
method on a CardAccount. This takes a parameter, `billing_period`, which can
|
101
|
+
be an integer referring to a particular statement, or a range of integers.
|
102
|
+
|
103
|
+
To get transactions since the most recent statement, simply call
|
104
|
+
`account.transactions(0)` or `account.transactions`, since this is the default.
|
105
|
+
|
106
|
+
To get the last statement, call `account.transactions(1)`. To get from now up
|
107
|
+
to 5 statements ago, call `account.transactions(0..5)`. You get the idea.
|
89
108
|
|
90
109
|
There are lots of extra useful methods here to make accessing
|
91
110
|
some of the various properties easier. They're very self-explanatory - check `lib/amex/card_account.rb`.
|
@@ -111,11 +130,6 @@ There's one helper method currently available here, `is_foreign_transaction?`,
|
|
111
130
|
which returns a boolean representing whether the transaction was foreign (i.e.
|
112
131
|
in a non-native currency).
|
113
132
|
|
114
|
-
### Limitations
|
115
|
-
|
116
|
-
* You can only view transactions from the most recent statement. I intend
|
117
|
-
to change this in due course to support pagination of some description.
|
118
|
-
|
119
133
|
### License
|
120
134
|
|
121
135
|
Use this for what you will, as long as it isn't evil. If you make any changes or cool improvements, please let me know at <tim+amex@tim-rogers.co.uk>.
|
data/amex-0.3.2.gem
ADDED
Binary file
|
data/example.rb
CHANGED
@@ -5,6 +5,30 @@ require 'amex'
|
|
5
5
|
# but it should just contain two class variables, `username` and `password`
|
6
6
|
require "#{File.dirname(__FILE__)}/settings.rb"
|
7
7
|
|
8
|
+
# Instantiate an Amex::Client object
|
8
9
|
client = Amex::Client.new(@username, @password)
|
10
|
+
|
11
|
+
# Execute the #accounts method on the client, which will return an array
|
12
|
+
# of Amex::CardAccount objects
|
9
13
|
accounts = client.accounts
|
10
|
-
|
14
|
+
|
15
|
+
# Let's take a look at your first account...
|
16
|
+
account = accounts.first
|
17
|
+
puts account.inspect
|
18
|
+
|
19
|
+
# We can find out the transactions since the last statement
|
20
|
+
recent_transactions = account.transactions
|
21
|
+
puts "There have been #{recent_transactions.length} transactions since your " +
|
22
|
+
"last statement."
|
23
|
+
|
24
|
+
# and then look at individual statements to see their transactions...
|
25
|
+
last_statement = account.transactions(1)
|
26
|
+
puts "There were #{last_statement.length} transactions on your last statement."
|
27
|
+
|
28
|
+
# Let's view transactions from now to the end of your last statement, and
|
29
|
+
# then find out how many were made abroad...
|
30
|
+
foreign_transactions = account.transactions(0..1).keep_if do |tx|
|
31
|
+
tx.is_foreign_transaction?
|
32
|
+
end
|
33
|
+
puts "#{foreign_transactions.length} transactions since the start of your " +
|
34
|
+
"last statement period were made abroad."
|
data/lib/amex/card_account.rb
CHANGED
@@ -5,15 +5,54 @@ module Amex
|
|
5
5
|
:is_centurion, :is_platinum, :is_premium, :market, :card_art,
|
6
6
|
:loyalty_indicator, :stmt_balance, :payment_credits, :recent_charges,
|
7
7
|
:total_balance, :payment_due, :payment_due_date, :loyalty_programmes,
|
8
|
-
:
|
8
|
+
:client
|
9
9
|
|
10
10
|
def initialize(options)
|
11
11
|
options.each do |key, value|
|
12
|
-
method = key.underscore + "="
|
13
|
-
send(key.underscore + "=", value) if respond_to? method.to_sym
|
12
|
+
method = key.to_s.underscore + "="
|
13
|
+
send(key.to_s.underscore + "=", value) if respond_to? method.to_sym
|
14
14
|
end
|
15
15
|
@loyalty_programmes = []
|
16
|
-
|
16
|
+
end
|
17
|
+
|
18
|
+
def transactions(billing_period=0)
|
19
|
+
# Fetch the transactions for this account based upon the passed in
|
20
|
+
# options - this can fetch either a single billing period or a range
|
21
|
+
# of billing periods, e.g:
|
22
|
+
#
|
23
|
+
# => account.transaction(0) fetches transactions since the last statement
|
24
|
+
# (default)
|
25
|
+
# => account.transaction(0..5) fetches transactions between now and
|
26
|
+
# five statements ago
|
27
|
+
result = []
|
28
|
+
|
29
|
+
# Build an array of billing periods we need to fetch - this is almost
|
30
|
+
# certainly woefully inefficient code.
|
31
|
+
billing_periods = []
|
32
|
+
if billing_period.class == Fixnum
|
33
|
+
billing_periods << billing_period
|
34
|
+
elsif billing_period.class == Range
|
35
|
+
billing_period.each { |n| billing_periods << n }
|
36
|
+
else
|
37
|
+
raise "The passed in billing period option must be a number or a range"
|
38
|
+
end
|
39
|
+
|
40
|
+
billing_periods.each do |n|
|
41
|
+
options = { :body => {
|
42
|
+
"PayLoadText" => @client.statement_request_xml(@card_index, n)
|
43
|
+
}}
|
44
|
+
response = @client.class.post(
|
45
|
+
'/myca/intl/moblclient/emea/ws.do?Face=en_GB', options
|
46
|
+
)
|
47
|
+
xml = Nokogiri::XML(response.body)
|
48
|
+
xml = xml.css("XMLResponse")
|
49
|
+
|
50
|
+
xml.css('Transaction').each do |transaction|
|
51
|
+
result << Amex::Transaction.new(transaction)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
result
|
17
56
|
end
|
18
57
|
|
19
58
|
def statement_balance
|
data/lib/amex/client.rb
CHANGED
@@ -33,7 +33,7 @@ module Amex
|
|
33
33
|
accounts = [] # We'll store all the accounts in here!
|
34
34
|
|
35
35
|
xml.css('CardAccounts CardAccount').each do |item|
|
36
|
-
account_details = {} # All the attributes from the XML go in here
|
36
|
+
account_details = {client: self} # All the attributes from the XML go in here
|
37
37
|
# For each of the CardAccount objects, let's first go through
|
38
38
|
# the CardData to pull out lots of nice information
|
39
39
|
item.css('CardData param').each do |attribute|
|
@@ -80,6 +80,19 @@ module Amex
|
|
80
80
|
|
81
81
|
end
|
82
82
|
|
83
|
+
def statement_request_xml(card_index, billing_period=0)
|
84
|
+
# Generates XML for grabbing the last statement's transactions for a
|
85
|
+
# card, using the card_index attribute from an account's XML
|
86
|
+
|
87
|
+
xml = File.read(
|
88
|
+
File.expand_path(File.dirname(__FILE__) + '/data/statement_request.xml')
|
89
|
+
)
|
90
|
+
|
91
|
+
security_token = @security_token
|
92
|
+
ERB.new(xml).result(binding)
|
93
|
+
end
|
94
|
+
|
95
|
+
|
83
96
|
private
|
84
97
|
|
85
98
|
def request_xml
|
@@ -97,18 +110,6 @@ module Amex
|
|
97
110
|
ERB.new(xml).result(binding)
|
98
111
|
end
|
99
112
|
|
100
|
-
def statement_request_xml(card_index)
|
101
|
-
# Generates XML for grabbing the last statement's transactions for a
|
102
|
-
# card, using the card_index attribute from an account's XML
|
103
|
-
|
104
|
-
xml = File.read(
|
105
|
-
File.expand_path(File.dirname(__FILE__) + '/data/statement_request.xml')
|
106
|
-
)
|
107
|
-
|
108
|
-
security_token = @security_token
|
109
|
-
ERB.new(xml).result(binding)
|
110
|
-
end
|
111
|
-
|
112
113
|
def hardware_id
|
113
114
|
# Generates a fake HardwareId - a 40 character alphanumeric lower-case
|
114
115
|
# string, which is passed in with the original API request
|
@@ -7,7 +7,7 @@
|
|
7
7
|
<ServiceName>StatementService</ServiceName>
|
8
8
|
<ClientSecurityToken><%= security_token %></ClientSecurityToken>
|
9
9
|
<StatementRequestData>
|
10
|
-
<BillingPeriod
|
10
|
+
<BillingPeriod><%= billing_period %></BillingPeriod>
|
11
11
|
<CardIndex><%= card_index %></CardIndex>
|
12
12
|
</StatementRequestData>
|
13
13
|
</XMLRequest>
|
data/lib/amex/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: amex
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -58,6 +58,7 @@ files:
|
|
58
58
|
- amex-0.2.0.gem
|
59
59
|
- amex-0.3.0.gem
|
60
60
|
- amex-0.3.1.gem
|
61
|
+
- amex-0.3.2.gem
|
61
62
|
- amex.gemspec
|
62
63
|
- example.rb
|
63
64
|
- lib/amex.rb
|