amex 0.2.0 → 0.3.1
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 +2 -1
- data/Gemfile.lock +4 -0
- data/README.md +33 -4
- data/amex-0.2.0.gem +0 -0
- data/amex-0.3.0.gem +0 -0
- data/lib/amex.rb +1 -0
- data/lib/amex/card_account.rb +4 -2
- data/lib/amex/client.rb +28 -0
- data/lib/amex/data/statement_request.xml +13 -0
- data/lib/amex/transaction.rb +25 -0
- data/lib/amex/version.rb +1 -1
- metadata +4 -1
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
+
amex (0.3.0)
|
5
|
+
httparty
|
6
|
+
nokogiri
|
4
7
|
httparty (0.9.0)
|
5
8
|
multi_json (~> 1.0)
|
6
9
|
multi_xml
|
@@ -12,5 +15,6 @@ PLATFORMS
|
|
12
15
|
ruby
|
13
16
|
|
14
17
|
DEPENDENCIES
|
18
|
+
amex (= 0.3.0)
|
15
19
|
httparty (= 0.9.0)
|
16
20
|
nokogiri (= 1.5.6)
|
data/README.md
CHANGED
@@ -8,11 +8,18 @@ However, this one doesn't rely on nasty screen-scraping. Instead, it uses
|
|
8
8
|
the previous unknown internal API used by American Express for their
|
9
9
|
"Amex UK" iPhone app. I suspect it works elsewhere, but I haven't tested.
|
10
10
|
|
11
|
+
This allows you to fetch the details of all the cards on your American
|
12
|
+
Express login, as well as the most recent statement's transactions.
|
13
|
+
|
11
14
|
### Changelog
|
12
15
|
|
13
16
|
__v0.1.0__ - Original version
|
14
17
|
__v0.2.0__ - Support for multiple American Express cards, parsing using
|
15
18
|
Nokogiri
|
19
|
+
__v0.3.0__ - Adds support for loading the transactions from the most recent statement
|
20
|
+
(but it's broken because I forgot to change something from testing :( )
|
21
|
+
__v0.3.1__ - Working version of v0.3.0 that will successfully load transactions
|
22
|
+
from the most recent statement
|
16
23
|
|
17
24
|
### Usage
|
18
25
|
|
@@ -42,8 +49,10 @@ only supports one card at a time right now.
|
|
42
49
|
|
43
50
|
```
|
44
51
|
accounts = client.accounts
|
45
|
-
|
46
|
-
puts
|
52
|
+
my_account = accounts.first
|
53
|
+
puts my_account.product
|
54
|
+
puts my_account.type
|
55
|
+
puts my_account.transactions.inspect
|
47
56
|
```
|
48
57
|
|
49
58
|
### Data models
|
@@ -55,6 +64,8 @@ An __Amex::CardAccount__ instance has the following attributes:
|
|
55
64
|
|
56
65
|
* __product (string)__ - the type of card (e.g. "The Preferred Rewards Gold Card®")
|
57
66
|
* __card_number_suffix (string)__ - the last five digits of your card number
|
67
|
+
* __card_index (integer)__ - the internal number of the card on your account
|
68
|
+
in the Amex system, starting from 0 *(used internally by the gem)*
|
58
69
|
* __lending_type (string)__ - either "Charge" or "Credit", depending on the type of credit arrangement you have
|
59
70
|
* __card_member_name (string)__ - your name, as recorded as the account holder
|
60
71
|
* __past_due (boolean)__ - is the card past its due payment date?
|
@@ -72,18 +83,36 @@ kind of loyalty scheme active? (e.g. Membership Rewards)
|
|
72
83
|
* __total_balance (float)__ - what American Express refer to as your total balance, whatever that is!
|
73
84
|
* __payment_due (float)__ - the amount of money you need to pay before `payment_due_date`
|
74
85
|
* __payment_due_date (DateTime)__ - when the `payment_due` needs to be paid by
|
86
|
+
* __transactions (array)__ - an array of Amex::Transaction objects)
|
75
87
|
|
76
88
|
There are lots of extra useful methods here to make accessing
|
77
89
|
some of the various properties easier. They're very self-explanatory - check `lib/amex/card_account.rb`.
|
78
90
|
|
79
|
-
A
|
91
|
+
A __Amex::LoyaltyProgramme has just two attributes:
|
80
92
|
|
81
93
|
* __name (string)__ - The name of the programme, most often "Membership Rewards"
|
82
94
|
* __balance (integer)__ - The balance of the programme
|
83
95
|
|
96
|
+
An __Amex::Transaction represents a transaction in your most recent American
|
97
|
+
Express statement. It has four attributes:
|
98
|
+
|
99
|
+
* __amount (float)__ - The amount of the transaction
|
100
|
+
* __date (Date)__ - The date that the transaction was recorded
|
101
|
+
* __narrative (string)__ - The description shown on your statement, usually
|
102
|
+
contaning the name of the merchant and their location
|
103
|
+
* __extra_details (hash)__ - This hash contains any extra pieces of information
|
104
|
+
provided by American Express...for instance, foreign transactions have their
|
105
|
+
exchange rate and commission. The name of the attribute will be the key, and
|
106
|
+
its formatted value in the value in the hash.
|
107
|
+
|
108
|
+
There's one helper method currently available here, `is_foreign_transaction?`,
|
109
|
+
which returns a boolean representing whether the transaction was foreign (i.e.
|
110
|
+
in a non-native currency).
|
111
|
+
|
84
112
|
### Limitations
|
85
113
|
|
86
|
-
*
|
114
|
+
* You can only view transactions from the most recent statement. I intend
|
115
|
+
to change this in due course to support pagination of some description.
|
87
116
|
|
88
117
|
### License
|
89
118
|
|
data/amex-0.2.0.gem
ADDED
Binary file
|
data/amex-0.3.0.gem
ADDED
Binary file
|
data/lib/amex.rb
CHANGED
data/lib/amex/card_account.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
module Amex
|
2
2
|
class CardAccount
|
3
|
-
attr_accessor :card_product, :card_number_suffix,
|
3
|
+
attr_accessor :card_product, :card_number_suffix, :card_index,
|
4
4
|
:lending_type, :card_member_name, :past_due, :cancelled, :is_basic,
|
5
5
|
:is_centurion, :is_platinum, :is_premium, :market, :card_art,
|
6
6
|
:loyalty_indicator, :stmt_balance, :payment_credits, :recent_charges,
|
7
|
-
:total_balance, :payment_due, :payment_due_date, :loyalty_programmes
|
7
|
+
:total_balance, :payment_due, :payment_due_date, :loyalty_programmes,
|
8
|
+
:transactions
|
8
9
|
|
9
10
|
def initialize(options)
|
10
11
|
options.each do |key, value|
|
@@ -12,6 +13,7 @@ module Amex
|
|
12
13
|
send(key.underscore + "=", value) if respond_to? method.to_sym
|
13
14
|
end
|
14
15
|
@loyalty_programmes = []
|
16
|
+
@transactions = []
|
15
17
|
end
|
16
18
|
|
17
19
|
def statement_balance
|
data/lib/amex/client.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'erb'
|
2
2
|
require 'httparty'
|
3
3
|
require 'nokogiri'
|
4
|
+
require 'date'
|
4
5
|
|
5
6
|
module Amex
|
6
7
|
class Client
|
@@ -24,6 +25,15 @@ module Amex
|
|
24
25
|
ERB.new(xml).result(binding)
|
25
26
|
end
|
26
27
|
|
28
|
+
def statement_request_xml(card_index)
|
29
|
+
xml = File.read(
|
30
|
+
File.expand_path(File.dirname(__FILE__) + '/data/statement_request.xml')
|
31
|
+
)
|
32
|
+
|
33
|
+
security_token = @security_token
|
34
|
+
ERB.new(xml).result(binding)
|
35
|
+
end
|
36
|
+
|
27
37
|
def accounts
|
28
38
|
# This only supports one account for now, because I'm lazy and I
|
29
39
|
# hate traversing XML...
|
@@ -38,6 +48,9 @@ module Amex
|
|
38
48
|
if xml.css('ServiceResponse Status').text != "success"
|
39
49
|
raise "There was a problem logging in to American Express."
|
40
50
|
else
|
51
|
+
# Store the security token - we need this for further requests
|
52
|
+
@security_token = xml.css('ClientSecurityToken').text
|
53
|
+
|
41
54
|
accounts = [] # We'll store all the accounts in here!
|
42
55
|
|
43
56
|
xml.css('CardAccounts CardAccount').each do |item|
|
@@ -64,6 +77,21 @@ module Amex
|
|
64
77
|
element.attr('label'), element.attr('formattedValue').gsub(",", "").to_i
|
65
78
|
)
|
66
79
|
end
|
80
|
+
|
81
|
+
# Now we can fetch the transactions...
|
82
|
+
options = { :body => {
|
83
|
+
"PayLoadText" => statement_request_xml(account.card_index)
|
84
|
+
}}
|
85
|
+
response = self.class.post(
|
86
|
+
'/myca/intl/moblclient/emea/ws.do?Face=en_GB', options
|
87
|
+
)
|
88
|
+
xml = Nokogiri::XML(response.body)
|
89
|
+
xml = xml.css("XMLResponse")
|
90
|
+
|
91
|
+
xml.css('Transaction').each do |transaction|
|
92
|
+
account.transactions << Amex::Transaction.new(transaction)
|
93
|
+
end
|
94
|
+
|
67
95
|
accounts << account
|
68
96
|
|
69
97
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<XMLRequest>
|
3
|
+
<ClientType>iPhone</ClientType>
|
4
|
+
<ClientVersion>1.8</ClientVersion>
|
5
|
+
<ServiceVersion>1.0</ServiceVersion>
|
6
|
+
<Locale>en_GB</Locale>
|
7
|
+
<ServiceName>StatementService</ServiceName>
|
8
|
+
<ClientSecurityToken><%= security_token %></ClientSecurityToken>
|
9
|
+
<StatementRequestData>
|
10
|
+
<BillingPeriod>0</BillingPeriod>
|
11
|
+
<CardIndex><%= card_index %></CardIndex>
|
12
|
+
</StatementRequestData>
|
13
|
+
</XMLRequest>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
module Amex
|
4
|
+
class Transaction
|
5
|
+
attr_reader :date, :narrative, :amount, :extra_details
|
6
|
+
|
7
|
+
def initialize(transaction)
|
8
|
+
# Pass this a <Transaction> element, and it'll parse it
|
9
|
+
@date = Date.strptime(transaction.css('TransChargeDate').text, '%m/%d/%y')
|
10
|
+
@narrative = transaction.css('TransDesc').text
|
11
|
+
@amount = transaction.css('TransAmount').text.to_f
|
12
|
+
|
13
|
+
@extra_details = {}
|
14
|
+
transaction.css('TransExtDetail ExtDetailElement').each do |element|
|
15
|
+
@extra_details[element.attr('name')] = element.attr('formattedValue')
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def is_foreign_transaction?
|
20
|
+
return true if @extra_details.has_key?('currencyRate')
|
21
|
+
false
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
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.3.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -56,13 +56,16 @@ files:
|
|
56
56
|
- README.md
|
57
57
|
- amex-0.1.0.gem
|
58
58
|
- amex-0.2.0.gem
|
59
|
+
- amex-0.3.0.gem
|
59
60
|
- amex.gemspec
|
60
61
|
- example.rb
|
61
62
|
- lib/amex.rb
|
62
63
|
- lib/amex/card_account.rb
|
63
64
|
- lib/amex/client.rb
|
64
65
|
- lib/amex/data/request.xml
|
66
|
+
- lib/amex/data/statement_request.xml
|
65
67
|
- lib/amex/loyalty_programme.rb
|
68
|
+
- lib/amex/transaction.rb
|
66
69
|
- lib/amex/utils.rb
|
67
70
|
- lib/amex/version.rb
|
68
71
|
homepage: https://github.com/timrogers/amex
|