localocracy-remit 0.0.5

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.
Files changed (48) hide show
  1. data/LICENSE +20 -0
  2. data/README.markdown +91 -0
  3. data/lib/remit.rb +137 -0
  4. data/lib/remit/common.rb +88 -0
  5. data/lib/remit/data_types.rb +164 -0
  6. data/lib/remit/error_codes.rb +118 -0
  7. data/lib/remit/get_pipeline.rb +189 -0
  8. data/lib/remit/ipn_request.rb +49 -0
  9. data/lib/remit/operations/cancel.rb +20 -0
  10. data/lib/remit/operations/cancel_subscription_and_refund.rb +22 -0
  11. data/lib/remit/operations/cancel_token.rb +18 -0
  12. data/lib/remit/operations/discard_results.rb +18 -0
  13. data/lib/remit/operations/fund_prepaid.rb +31 -0
  14. data/lib/remit/operations/get_account_activity.rb +60 -0
  15. data/lib/remit/operations/get_account_balance.rb +29 -0
  16. data/lib/remit/operations/get_all_credit_instruments.rb +18 -0
  17. data/lib/remit/operations/get_all_prepaid_instruments.rb +18 -0
  18. data/lib/remit/operations/get_debt_balance.rb +23 -0
  19. data/lib/remit/operations/get_outstanding_debt_balance.rb +22 -0
  20. data/lib/remit/operations/get_payment_instruction.rb +21 -0
  21. data/lib/remit/operations/get_prepaid_balance.rb +23 -0
  22. data/lib/remit/operations/get_results.rb +27 -0
  23. data/lib/remit/operations/get_token_by_caller.rb +19 -0
  24. data/lib/remit/operations/get_token_usage.rb +18 -0
  25. data/lib/remit/operations/get_tokens.rb +20 -0
  26. data/lib/remit/operations/get_total_prepaid_liability.rb +22 -0
  27. data/lib/remit/operations/get_transaction.rb +42 -0
  28. data/lib/remit/operations/install_payment_instruction.rb +22 -0
  29. data/lib/remit/operations/pay.rb +35 -0
  30. data/lib/remit/operations/refund.rb +37 -0
  31. data/lib/remit/operations/reserve.rb +31 -0
  32. data/lib/remit/operations/retry_transaction.rb +18 -0
  33. data/lib/remit/operations/settle.rb +20 -0
  34. data/lib/remit/operations/settle_debt.rb +30 -0
  35. data/lib/remit/operations/subscribe_for_caller_notification.rb +18 -0
  36. data/lib/remit/operations/unsubscribe_for_caller_notification.rb +17 -0
  37. data/lib/remit/operations/write_off_debt.rb +28 -0
  38. data/lib/remit/pipeline_response.rb +52 -0
  39. data/spec/integrations/get_account_activity_spec.rb +36 -0
  40. data/spec/integrations/get_tokens_spec.rb +38 -0
  41. data/spec/integrations/integrations_helper.rb +8 -0
  42. data/spec/spec_helper.rb +36 -0
  43. data/spec/units/get_pipeline_spec.rb +165 -0
  44. data/spec/units/get_results_spec.rb +49 -0
  45. data/spec/units/ipn_request_spec.rb +32 -0
  46. data/spec/units/pay_spec.rb +133 -0
  47. data/spec/units/units_helper.rb +4 -0
  48. metadata +137 -0
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2007-2009 Tyler Hunt
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,91 @@
1
+ Remit
2
+ =====
3
+
4
+ This API provides access to the Amazon Flexible Payment Service (FPS). After
5
+ trying to get the SOAP version of the API written, I began working on this REST
6
+ version to provide a cohesive means of access to all of the functionality of
7
+ the FPS without having to get dirty dealing with SOAP requests.
8
+
9
+ I hope you enjoy using it as much as I've enjoyed writing it. I'm interested to
10
+ hear what sort of uses you find for it. If you find any bugs, let me know (or
11
+ better yet, submit a patch).
12
+
13
+
14
+ Sandbox
15
+ -------
16
+
17
+ Amazon provides a testing environment for the FPS called a sandbox. You may
18
+ (and should) use the sandbox while testing your application. It can be enabled
19
+ by passing a value of true to the last argument of the API constructor.
20
+
21
+
22
+ Getting Started
23
+ ---------------
24
+
25
+ The following example shows how to load up the API, initialize the service, and
26
+ make a simple call to get the tokens stored on the account:
27
+
28
+ gem 'remit'
29
+ require 'remit'
30
+
31
+ ACCESS_KEY = '<your AWS access key>'
32
+ SECRET_KEY = '<your AWS secret key>'
33
+
34
+ # connect using the API's sandbox mode
35
+ remit = Remit::API.new(ACCESS_KEY, SECRET_KEY, true)
36
+
37
+ response = remit.get_tokens
38
+ puts response.tokens.first.token_id
39
+
40
+
41
+ Using with Rails
42
+ ----------------
43
+
44
+ To use Remit in a Rails application, you must first specify a dependency on the
45
+ Remit gem in your config/environment.rb file:
46
+
47
+ config.gem 'remit', :version => '~> 0.0.1'
48
+
49
+ Then you should create an initializer to configure your Amazon keys. Create the
50
+ file config/initializers/remit.rb with the following contents:
51
+
52
+ config_file = File.join(Rails.root, 'config', 'amazon_fps.yml')
53
+ config = YAML.load_file(config_file)[RAILS_ENV].symbolize_keys
54
+
55
+ FPS_ACCESS_KEY = config[:access_key]
56
+ FPS_SECRET_KEY = config[:secret_key]
57
+
58
+ Then create the YAML file config/amazon_fps.yml:
59
+
60
+ development: &sandbox
61
+ access_key: <your sandbox access key>
62
+ secret_key: <your sandbox secret key>
63
+
64
+ test:
65
+ <<: *sandbox
66
+
67
+ production:
68
+ access_key: <your access key>
69
+ secret_key: <your secret key>
70
+
71
+ To instantiate and use the Remit API in your application, you could define a
72
+ method in your ApplicationController like this:
73
+
74
+ def remit
75
+ @remit ||= begin
76
+ sandbox = !Rails.env.production?
77
+ Remit::API.new(FPS_ACCESS_KEY, FPS_SECRET_KEY, sandbox)
78
+ end
79
+ end
80
+
81
+
82
+ Sites Using Remit
83
+ -----------------
84
+
85
+ The following production sites are currently using Remit:
86
+
87
+ * http://www.storenvy.com/
88
+ * http://www.obsidianportal.com/
89
+
90
+
91
+ Copyright (c) 2007-2009 Tyler Hunt, released under the MIT license
data/lib/remit.rb ADDED
@@ -0,0 +1,137 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
2
+
3
+ require 'openssl'
4
+ require 'net/https'
5
+ require 'uri'
6
+ require 'date'
7
+ require 'base64'
8
+ require 'erb'
9
+
10
+ require 'rubygems'
11
+
12
+ gem 'relax', '0.0.7'
13
+ require 'relax'
14
+
15
+ require 'remit/common'
16
+ require 'remit/data_types'
17
+ require 'remit/error_codes'
18
+ require 'remit/ipn_request'
19
+ require 'remit/get_pipeline'
20
+ require 'remit/pipeline_response'
21
+
22
+ require 'remit/operations/cancel_subscription_and_refund'
23
+ require 'remit/operations/cancel_token'
24
+ require 'remit/operations/cancel'
25
+ require 'remit/operations/discard_results'
26
+ require 'remit/operations/fund_prepaid'
27
+ require 'remit/operations/get_account_activity'
28
+ require 'remit/operations/get_account_balance'
29
+ require 'remit/operations/get_all_credit_instruments'
30
+ require 'remit/operations/get_all_prepaid_instruments'
31
+ require 'remit/operations/get_debt_balance'
32
+ require 'remit/operations/get_outstanding_debt_balance'
33
+ require 'remit/operations/get_payment_instruction'
34
+ require 'remit/operations/get_prepaid_balance'
35
+ require 'remit/operations/get_results'
36
+ require 'remit/operations/get_token_by_caller'
37
+ require 'remit/operations/get_token_usage'
38
+ require 'remit/operations/get_tokens'
39
+ require 'remit/operations/get_total_prepaid_liability'
40
+ require 'remit/operations/get_transaction'
41
+ require 'remit/operations/install_payment_instruction'
42
+ require 'remit/operations/pay'
43
+ require 'remit/operations/refund'
44
+ require 'remit/operations/reserve'
45
+ require 'remit/operations/retry_transaction'
46
+ require 'remit/operations/settle'
47
+ require 'remit/operations/settle_debt'
48
+ require 'remit/operations/subscribe_for_caller_notification'
49
+ require 'remit/operations/unsubscribe_for_caller_notification'
50
+ require 'remit/operations/write_off_debt'
51
+
52
+ module Remit
53
+ class API < Relax::Service
54
+ include CancelSubscriptionAndRefund
55
+ include CancelToken
56
+ include Cancel
57
+ include DiscardResults
58
+ include FundPrepaid
59
+ include GetAccountActivity
60
+ include GetAccountBalance
61
+ include GetAllCreditInstruments
62
+ include GetAllPrepaidInstruments
63
+ include GetDebtBalance
64
+ include GetOutstandingDebtBalance
65
+ include GetPaymentInstruction
66
+ include GetPipeline
67
+ include GetPrepaidBalance
68
+ include GetResults
69
+ include GetTokenUsage
70
+ include GetTokens
71
+ include GetTokenByCaller
72
+ include GetTotalPrepaidLiability
73
+ include GetTransaction
74
+ include InstallPaymentInstruction
75
+ include Pay
76
+ include Refund
77
+ include Reserve
78
+ include RetryTransaction
79
+ include Settle
80
+ include SettleDebt
81
+ include SubscribeForCallerNotification
82
+ include UnsubscribeForCallerNotification
83
+ include WriteOffDebt
84
+
85
+ API_ENDPOINT = 'https://fps.amazonaws.com/'.freeze
86
+ API_SANDBOX_ENDPOINT = 'https://fps.sandbox.amazonaws.com/'.freeze
87
+ PIPELINE_URL = 'https://authorize.payments.amazon.com/cobranded-ui/actions/start'.freeze
88
+ PIPELINE_SANDBOX_URL = 'https://authorize.payments-sandbox.amazon.com/cobranded-ui/actions/start'.freeze
89
+ API_VERSION = Date.new(2007, 1, 8).to_s.freeze
90
+ SIGNATURE_VERSION = 1.freeze
91
+
92
+ attr_reader :access_key
93
+ attr_reader :secret_key
94
+ attr_reader :pipeline_url
95
+
96
+ def initialize(access_key, secret_key, sandbox=false)
97
+ @access_key = access_key
98
+ @secret_key = secret_key
99
+ @pipeline_url = sandbox ? PIPELINE_SANDBOX_URL : PIPELINE_URL
100
+
101
+ super(sandbox ? API_SANDBOX_ENDPOINT : API_ENDPOINT)
102
+ end
103
+
104
+ def new_query(query={})
105
+ SignedQuery.new(@endpoint, @secret_key, query)
106
+ end
107
+ private :new_query
108
+
109
+ def default_query
110
+ new_query({
111
+ :AWSAccessKeyId => @access_key,
112
+ :SignatureVersion => SIGNATURE_VERSION,
113
+ :Version => API_VERSION,
114
+ :Timestamp => Time.now.utc.strftime('%Y-%m-%dT%H:%M:%SZ')
115
+ })
116
+ end
117
+ private :default_query
118
+
119
+ def query(request)
120
+ query = super
121
+ query[:Signature] = sign(query)
122
+ query
123
+ end
124
+ private :query
125
+
126
+ def sign(values)
127
+ keys = values.keys.sort { |a, b| a.to_s.downcase <=> b.to_s.downcase }
128
+
129
+ signature = keys.inject('') do |signature, key|
130
+ signature += key.to_s + values[key].to_s
131
+ end
132
+
133
+ Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest::SHA1.new, @secret_key, signature)).strip
134
+ end
135
+ private :sign
136
+ end
137
+ end
@@ -0,0 +1,88 @@
1
+ require 'base64'
2
+ require 'erb'
3
+ require 'uri'
4
+
5
+ require 'rubygems'
6
+ require 'relax'
7
+
8
+ module Remit
9
+ class Request < Relax::Request
10
+ def self.action(name)
11
+ parameter :action, :value => name
12
+ end
13
+
14
+ def convert_key(key)
15
+ key.to_s.gsub(/(^|_)(.)/) { $2.upcase }.to_sym
16
+ end
17
+ protected :convert_key
18
+ end
19
+
20
+ class BaseResponse < Relax::Response
21
+ def node_name(name, namespace=nil)
22
+ super(name.to_s.gsub(/(^|_)(.)/) { $2.upcase }, namespace)
23
+ end
24
+ end
25
+
26
+ class Response < BaseResponse
27
+ parameter :request_id
28
+
29
+ attr_accessor :status
30
+ attr_accessor :errors
31
+
32
+ def initialize(xml)
33
+ super
34
+
35
+ if is?(:Response) && has?(:Errors)
36
+ @errors = elements(:Errors).collect do |error|
37
+ Error.new(error)
38
+ end
39
+ else
40
+ @status = text_value(element(:Status))
41
+ @errors = elements('Errors/Errors').collect do |error|
42
+ ServiceError.new(error)
43
+ end unless successful?
44
+ end
45
+ end
46
+
47
+ def successful?
48
+ @status == ResponseStatus::SUCCESS
49
+ end
50
+
51
+ def node_name(name, namespace=nil)
52
+ super(name.to_s.split('/').collect{ |tag|
53
+ tag.gsub(/(^|_)(.)/) { $2.upcase }
54
+ }.join('/'), namespace)
55
+ end
56
+ end
57
+
58
+ class SignedQuery < Relax::Query
59
+ def initialize(uri, secret_key, query={})
60
+ super(query)
61
+ @uri = URI.parse(uri.to_s)
62
+ @secret_key = secret_key
63
+ end
64
+
65
+ def sign
66
+ delete(:awsSignature)
67
+ store(:awsSignature, Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest::SHA1.new, @secret_key, "#{@uri.path}?#{to_s(false)}".gsub('%20', '+'))).strip)
68
+ end
69
+
70
+ def to_s(signed=true)
71
+ sign if signed
72
+ super()
73
+ end
74
+
75
+ class << self
76
+ def parse(uri, secret_key, query_string)
77
+ query = self.new(uri, secret_key)
78
+
79
+ query_string.split('&').each do |parameter|
80
+ key, value = parameter.split('=', 2)
81
+ query[key] = unescape_value(value)
82
+ end
83
+
84
+ query
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,164 @@
1
+ require 'rubygems'
2
+ require 'relax'
3
+
4
+ require 'remit/common'
5
+
6
+ module Remit
7
+ class Amount < BaseResponse
8
+ parameter :currency_code
9
+ parameter :amount, :type => :float
10
+ end
11
+
12
+ class TemporaryDeclinePolicy < BaseResponse
13
+ parameter :temporary_decline_policy_type
14
+ parameter :implicit_retry_timeout_in_mins
15
+ end
16
+
17
+ class DescriptorPolicy < BaseResponse
18
+ parameter :soft_descriptor_type
19
+ parameter :CS_number_of
20
+ end
21
+
22
+ class ChargeFeeTo
23
+ CALLER = 'Caller'
24
+ RECIPIENT = 'Recipient'
25
+ end
26
+
27
+ class Error < BaseResponse
28
+ parameter :code
29
+ parameter :message
30
+ end
31
+
32
+ class InstrumentStatus
33
+ ALL = 'ALL'
34
+ ACTIVE = 'Active'
35
+ INACTIVE = 'Inactive'
36
+ end
37
+
38
+ class PaymentMethods
39
+ BALANCE_TRANSFER = 'abt'
40
+ BANK_ACCOUNT = 'ach'
41
+ CREDIT_CARD = 'credit card'
42
+ PREPAID = 'prepaid'
43
+ DEBT = 'Debt'
44
+ end
45
+
46
+ class ServiceError < BaseResponse
47
+ parameter :error_type
48
+ parameter :is_retriable
49
+ parameter :error_code
50
+ parameter :reason_text
51
+
52
+ class ErrorType
53
+ SYSTEM = 'System'
54
+ BUSINESS = 'Business'
55
+ end
56
+ end
57
+
58
+ class ResponseStatus
59
+ SUCCESS = 'Success'
60
+ FAILURE = 'Failure'
61
+ end
62
+
63
+ class Token < BaseResponse
64
+ parameter :token_id
65
+ parameter :friendly_name
66
+ parameter :status
67
+ parameter :date_installed, :type => :time
68
+ parameter :caller_installed
69
+ parameter :caller_reference
70
+ parameter :token_type
71
+ parameter :old_token_id
72
+ parameter :payment_reason
73
+
74
+ class TokenStatus
75
+ ACTIVE = 'Active'
76
+ INACTIVE = 'Inactive'
77
+ end
78
+ end
79
+
80
+ class TokenUsageLimit < BaseResponse
81
+ parameter :count
82
+ parameter :limit
83
+ parameter :last_reset_amount
84
+ parameter :last_reset_count
85
+ parameter :last_reset_time_stamp
86
+ end
87
+
88
+ class TransactionResponse < BaseResponse
89
+ parameter :transaction_id
90
+ parameter :status
91
+ parameter :status_detail
92
+ parameter :new_sender_token_usage, :type => TokenUsageLimit
93
+
94
+ %w(reserved success failure initiated reinitiated temporary_decline).each do |status_name|
95
+ define_method("#{status_name}?") do
96
+ self.status == Remit::TransactionStatus.const_get(status_name.sub('_', '').upcase)
97
+ end
98
+ end
99
+ end
100
+
101
+ class TransactionStatus
102
+ RESERVED = 'Reserved'
103
+ SUCCESS = 'Success'
104
+ FAILURE = 'Failure'
105
+ INITIATED = 'Initiated'
106
+ REINITIATED = 'Reinitiated'
107
+ TEMPORARYDECLINE = 'TemporaryDecline'
108
+ end
109
+
110
+ class TokenType
111
+ SINGLE_USE = 'SingleUse'
112
+ MULTI_USE = 'MultiUse'
113
+ RECURRING = 'Recurring'
114
+ UNRESTRICTED = 'Unrestricted'
115
+ end
116
+
117
+ class PipelineName
118
+ SINGLE_USE = 'SingleUse'
119
+ MULTI_USE = 'MultiUse'
120
+ RECURRING = 'Recurring'
121
+ RECIPIENT = 'Recipient'
122
+ SETUP_PREPAID = 'SetupPrepaid'
123
+ SETUP_POSTPAID = 'SetupPostpaid'
124
+ end
125
+
126
+ class PipelineStatusCode
127
+ CALLER_EXCEPTION = 'CE' # problem with your code
128
+ SYSTEM_ERROR = 'SE' # system error, try again
129
+ SUCCESS_ABT = 'SA' # successful payment with Amazon balance
130
+ SUCCESS_ACH = 'SB' # successful payment with bank transfer
131
+ SUCCESS_CC = 'SC' # successful payment with credit card
132
+ ABORTED = 'A' # user aborted payment
133
+ PAYMENT_METHOD_MISMATCH = 'PE' # user does not have payment method requested
134
+ PAYMENT_METHOD_UNSUPPORTED = 'NP' # account doesn't support requested payment method
135
+ INVALID_CALLER = 'NM' # you are not a valid 3rd party caller to the transaction
136
+ SUCCESS_RECIPIENT_TOKEN_INSTALLED = 'SR'
137
+ end
138
+
139
+ module RequestTypes
140
+ class Amount < Remit::Request
141
+ parameter :amount
142
+ parameter :currency_code
143
+ end
144
+
145
+ class TemporaryDeclinePolicy < Remit::Request
146
+ parameter :temporary_decline_policy_type
147
+ parameter :implicit_retry_timeout_in_mins
148
+ end
149
+
150
+ class DescriptorPolicy < Remit::Request
151
+ parameter :soft_descriptor_type
152
+ parameter :CS_number_of
153
+ end
154
+ end
155
+
156
+ class Operation
157
+ PAY = "Pay"
158
+ REFUND = "Refund"
159
+ SETTLE = "Settle"
160
+ SETTLE_DEBT = "SettleDebt"
161
+ WRITE_OFF_DEBT = "WriteOffDebt"
162
+ FUND_PREPAID = "FundPrepaid"
163
+ end
164
+ end