revo-remit 0.2.3

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 (100) hide show
  1. data/LICENSE +20 -0
  2. data/README.markdown +122 -0
  3. data/lib/remit.rb +132 -0
  4. data/lib/remit/common.rb +151 -0
  5. data/lib/remit/data_types.rb +265 -0
  6. data/lib/remit/error_codes.rb +118 -0
  7. data/lib/remit/get_pipeline.rb +286 -0
  8. data/lib/remit/inbound_request.rb +85 -0
  9. data/lib/remit/ipn_request.rb +8 -0
  10. data/lib/remit/operations/cancel.rb +20 -0
  11. data/lib/remit/operations/cancel_subscription_and_refund.rb +26 -0
  12. data/lib/remit/operations/cancel_token.rb +19 -0
  13. data/lib/remit/operations/fund_prepaid.rb +33 -0
  14. data/lib/remit/operations/get_account_activity.rb +31 -0
  15. data/lib/remit/operations/get_account_balance.rb +32 -0
  16. data/lib/remit/operations/get_all_credit_instruments.rb +20 -0
  17. data/lib/remit/operations/get_all_prepaid_instruments.rb +20 -0
  18. data/lib/remit/operations/get_debt_balance.rb +28 -0
  19. data/lib/remit/operations/get_outstanding_debt_balance.rb +25 -0
  20. data/lib/remit/operations/get_payment_instruction.rb +23 -0
  21. data/lib/remit/operations/get_prepaid_balance.rb +27 -0
  22. data/lib/remit/operations/get_recipient_verification_status.rb +25 -0
  23. data/lib/remit/operations/get_token_by_caller.rb +23 -0
  24. data/lib/remit/operations/get_token_usage.rb +22 -0
  25. data/lib/remit/operations/get_tokens.rb +24 -0
  26. data/lib/remit/operations/get_total_prepaid_liability.rb +26 -0
  27. data/lib/remit/operations/get_transaction.rb +18 -0
  28. data/lib/remit/operations/get_transaction_status.rb +28 -0
  29. data/lib/remit/operations/install_payment_instruction.rb +29 -0
  30. data/lib/remit/operations/pay.rb +31 -0
  31. data/lib/remit/operations/refund.rb +46 -0
  32. data/lib/remit/operations/reserve.rb +28 -0
  33. data/lib/remit/operations/settle.rb +21 -0
  34. data/lib/remit/operations/settle_debt.rb +28 -0
  35. data/lib/remit/operations/subscribe_for_caller_notification.rb +20 -0
  36. data/lib/remit/operations/unsubscribe_for_caller_notification.rb +19 -0
  37. data/lib/remit/operations/write_off_debt.rb +26 -0
  38. data/lib/remit/pipeline_response.rb +20 -0
  39. data/lib/remit/signature_utils_for_outbound.rb +74 -0
  40. data/lib/remit/verify_signature.rb +21 -0
  41. data/spec/integrations/get_account_activity_spec.rb +42 -0
  42. data/spec/integrations/get_tokens_spec.rb +39 -0
  43. data/spec/integrations/integrations_helper.rb +15 -0
  44. data/spec/integrations/ipn_request_spec.rb +40 -0
  45. data/spec/integrations/pipeline_response_spec.rb +27 -0
  46. data/spec/integrations/verify_signature_spec.rb +140 -0
  47. data/spec/mocks/CancelResponse.xml +13 -0
  48. data/spec/mocks/CancelSubscriptionAndRefundResponse.xml +10 -0
  49. data/spec/mocks/CancelTokenResponse.xml +6 -0
  50. data/spec/mocks/ErrorResponse.xml +15 -0
  51. data/spec/mocks/FundPrepaidResponse.xml +11 -0
  52. data/spec/mocks/GetAccountActivityResponse.xml +68 -0
  53. data/spec/mocks/GetAccountBalanceResponse.xml +34 -0
  54. data/spec/mocks/GetDebtBalanceResponse.xml +21 -0
  55. data/spec/mocks/GetOutstandingDebtBalanceResponse.xml +21 -0
  56. data/spec/mocks/GetPaymentInstructionResponse.xml +25 -0
  57. data/spec/mocks/GetPrepaidBalanceResponse.xml +21 -0
  58. data/spec/mocks/GetRecipientVerificationStatusResponse.xml +9 -0
  59. data/spec/mocks/GetTokenByCallerResponse.xml +22 -0
  60. data/spec/mocks/GetTokenUsageResponse.xml +28 -0
  61. data/spec/mocks/GetTokensResponse.xml +22 -0
  62. data/spec/mocks/GetTotalPrepaidLiabilityResponse.xml +21 -0
  63. data/spec/mocks/GetTransactionResponse.xml +76 -0
  64. data/spec/mocks/GetTransactionStatusResponse.xml +16 -0
  65. data/spec/mocks/InstallPaymentInstructionResponse.xml +10 -0
  66. data/spec/mocks/PayResponse.xml +11 -0
  67. data/spec/mocks/RefundResponse.xml +11 -0
  68. data/spec/mocks/ReserveResponse.xml +11 -0
  69. data/spec/mocks/SettleDebtResponse.xml +11 -0
  70. data/spec/mocks/SettleResponse.xml +11 -0
  71. data/spec/mocks/VerifySignatureResponse.xml +11 -0
  72. data/spec/mocks/WriteOffDebtResponse.xml +11 -0
  73. data/spec/mocks/errors/InvalidParameterValue.xml +10 -0
  74. data/spec/mocks/errors/InvalidParams_certificateUrl.xml +2 -0
  75. data/spec/mocks/errors/RequestExpired.xml +10 -0
  76. data/spec/spec_helper.rb +85 -0
  77. data/spec/units/cancel_subscription_and_refund_spec.rb +29 -0
  78. data/spec/units/cancel_token_spec.rb +24 -0
  79. data/spec/units/fund_prepaid_spec.rb +28 -0
  80. data/spec/units/get_account_activity_spec.rb +58 -0
  81. data/spec/units/get_account_balance_spec.rb +28 -0
  82. data/spec/units/get_debt_balance_spec.rb +29 -0
  83. data/spec/units/get_outstanding_debt_balance_spec.rb +29 -0
  84. data/spec/units/get_pipeline_spec.rb +181 -0
  85. data/spec/units/get_prepaid_balance_spec.rb +29 -0
  86. data/spec/units/get_recipient_verification_status_spec.rb +26 -0
  87. data/spec/units/get_token_by_caller_spec.rb +56 -0
  88. data/spec/units/get_token_usage_spec.rb +51 -0
  89. data/spec/units/get_tokens_spec.rb +56 -0
  90. data/spec/units/get_total_prepaid_liability_spec.rb +26 -0
  91. data/spec/units/get_transaction_spec.rb +103 -0
  92. data/spec/units/get_transaction_status_spec.rb +44 -0
  93. data/spec/units/pay_spec.rb +112 -0
  94. data/spec/units/refund_spec.rb +41 -0
  95. data/spec/units/reserve_spec.rb +41 -0
  96. data/spec/units/settle_debt_spec.rb +41 -0
  97. data/spec/units/settle_spec.rb +41 -0
  98. data/spec/units/units_helper.rb +25 -0
  99. data/spec/units/write_off_debt_spec.rb +41 -0
  100. metadata +236 -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.
@@ -0,0 +1,122 @@
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
+ VerifySignature API
42
+ -------------------
43
+ See spec/integrations/verify_signature_spec.rb for examples on correct and incorrect usage!
44
+
45
+
46
+ Using with Rails
47
+ ----------------
48
+
49
+ To use Remit in a Rails application, you must first specify a dependency on the
50
+ Remit gem in your Gemfile:
51
+
52
+ gem 'remit', :git => "git://github.com/nyc-ruby-meetup/remit.git"
53
+
54
+ Then you should create an initializer to configure your Amazon keys. Create the
55
+ file config/initializers/remit.rb with the following contents:
56
+
57
+ config_file = File.join(Rails.root, 'config', 'amazon_fps.yml')
58
+ config = YAML.load_file(config_file)[RAILS_ENV].symbolize_keys
59
+
60
+ FPS_ACCESS_KEY = config[:access_key]
61
+ FPS_SECRET_KEY = config[:secret_key]
62
+
63
+ Then create the YAML file config/amazon_fps.yml:
64
+
65
+ development: &sandbox
66
+ access_key: <your sandbox access key>
67
+ secret_key: <your sandbox secret key>
68
+
69
+ test:
70
+ <<: *sandbox
71
+
72
+ production:
73
+ access_key: <your access key>
74
+ secret_key: <your secret key>
75
+
76
+ To instantiate and use the Remit API in your application, you could define a
77
+ method in your ApplicationController like this:
78
+
79
+ def remit
80
+ @remit ||= begin
81
+ sandbox = !Rails.env.production?
82
+ Remit::API.new(FPS_ACCESS_KEY, FPS_SECRET_KEY, sandbox)
83
+ end
84
+ end
85
+
86
+
87
+ Sites Using Remit
88
+ -----------------
89
+
90
+ The following production sites are currently using Remit:
91
+
92
+ * [Storyenvy](http://www.storenvy.com/)
93
+ * [ObsidianPortal](http://www.obsidianportal.com/)
94
+
95
+
96
+ Amazon API Compliance
97
+ ---------------------
98
+ These are the changes summarized by Amazon from the previous API, and the level of compliance in this branch:
99
+
100
+ 1. You don't have to use InstallPaymentInstruction API to create Caller and Recipient tokens for your account. A Recipient token is now required only in Marketplace applications. We have completely removed the Caller token.
101
+ Compliance: Caller token references removed.
102
+ 2. We removed parameters that are not being used by you today. For example, we removed metadata and recipient description, but we retained sender description and caller description.
103
+ Compliance: DONE! recipient_description and metadata have been removed from the code.
104
+ 3. We simplified the transaction response object.
105
+ Compliance: The former Remit::TransactionResponse object has been accordingly simplified.
106
+ 4. We simplified the GetTransaction response by removing unnecessary parameters.
107
+ Compliance: ?
108
+ 5. By default, implicit retry and cancel will be the method used to handle temporary declines rather than the current explicit retry process.
109
+ Compliance: Removed deprecated statuses
110
+ 6. GetResults, DiscardResults are replaced with GetTransactionStatus API.
111
+ Compliance: GetResults and Discard Results are gone. GetTransactionStatus takes their place.
112
+ 7. Temporary decline status is not exposed to customers as we provide a simpler way to handle this status.
113
+ Compliance: Temporary decline status can no longer be tested for, as it will never be a status.
114
+ 8. Web Service notification is removed and replaced with simplified IPN (Instant Payment Notification) mechanism.
115
+
116
+ Running Specification Suite
117
+ ---------------------------
118
+ 1. Copy test.sh.example to test.sh
119
+ 2. Edit test.sh to have valid Amazon developer account access and secret keys
120
+ 3. Run ./test.sh from the command line.
121
+
122
+ Copyright (c) 2007-2009 Tyler Hunt, released under the MIT license
@@ -0,0 +1,132 @@
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
+ require 'cgi'
10
+
11
+ require 'rubygems'
12
+
13
+ gem 'relax', '0.0.7'
14
+ require 'relax'
15
+
16
+
17
+ require 'remit/data_types'
18
+ require 'remit/common'
19
+ require 'remit/error_codes'
20
+ require 'remit/signature_utils_for_outbound'
21
+ require 'remit/verify_signature'
22
+ require 'remit/inbound_request'
23
+ require 'remit/ipn_request'
24
+ require 'remit/get_pipeline'
25
+ require 'remit/pipeline_response'
26
+
27
+ require 'remit/operations/cancel_subscription_and_refund'
28
+ require 'remit/operations/cancel_token'
29
+ require 'remit/operations/cancel'
30
+ require 'remit/operations/fund_prepaid'
31
+ require 'remit/operations/get_account_activity'
32
+ require 'remit/operations/get_account_balance'
33
+ require 'remit/operations/get_all_credit_instruments'
34
+ require 'remit/operations/get_all_prepaid_instruments'
35
+ require 'remit/operations/get_debt_balance'
36
+ require 'remit/operations/get_outstanding_debt_balance'
37
+ require 'remit/operations/get_payment_instruction'
38
+ require 'remit/operations/get_prepaid_balance'
39
+ require 'remit/operations/get_recipient_verification_status'
40
+ require 'remit/operations/get_token_by_caller'
41
+ require 'remit/operations/get_token_usage'
42
+ require 'remit/operations/get_tokens'
43
+ require 'remit/operations/get_total_prepaid_liability'
44
+ require 'remit/operations/get_transaction'
45
+ require 'remit/operations/get_transaction_status'
46
+ require 'remit/operations/install_payment_instruction'
47
+ require 'remit/operations/pay'
48
+ require 'remit/operations/refund'
49
+ require 'remit/operations/reserve'
50
+ require 'remit/operations/settle'
51
+ require 'remit/operations/settle_debt'
52
+ require 'remit/operations/subscribe_for_caller_notification'
53
+ require 'remit/operations/unsubscribe_for_caller_notification'
54
+ require 'remit/operations/write_off_debt'
55
+
56
+ module Remit
57
+ class API < Relax::Service
58
+
59
+ include VerifySignature
60
+ include CancelSubscriptionAndRefund
61
+ include CancelToken
62
+ include Cancel
63
+ include FundPrepaid
64
+ include GetAccountActivity
65
+ include GetAccountBalance
66
+ include GetAllCreditInstruments
67
+ include GetAllPrepaidInstruments
68
+ include GetDebtBalance
69
+ include GetOutstandingDebtBalance
70
+ include GetPaymentInstruction
71
+ include GetPipeline
72
+ include GetPrepaidBalance
73
+ include GetRecipientVerificationStatus
74
+ include GetTokenUsage
75
+ include GetTokens
76
+ include GetTokenByCaller
77
+ include GetTotalPrepaidLiability
78
+ include GetTransaction
79
+ include InstallPaymentInstruction
80
+ include Pay
81
+ include Refund
82
+ include Reserve
83
+ include Settle
84
+ include SettleDebt
85
+ include SubscribeForCallerNotification
86
+ include UnsubscribeForCallerNotification
87
+ include WriteOffDebt
88
+
89
+ API_ENDPOINT = 'https://fps.amazonaws.com/'.freeze
90
+ API_SANDBOX_ENDPOINT = 'https://fps.sandbox.amazonaws.com/'.freeze
91
+ PIPELINE_URL = 'https://authorize.payments.amazon.com/cobranded-ui/actions/start'.freeze
92
+ PIPELINE_SANDBOX_URL = 'https://authorize.payments-sandbox.amazon.com/cobranded-ui/actions/start'.freeze
93
+ API_VERSION = Date.new(2008, 9, 17).to_s.freeze
94
+ PIPELINE_VERSION = Date.new(2009, 1, 9).to_s.freeze
95
+ SIGNATURE_VERSION = 2.freeze
96
+ SIGNATURE_METHOD = "HmacSHA256".freeze
97
+
98
+ #attr_reader :pipeline # kickstarter
99
+ attr_reader :pipeline_url # nyc
100
+ attr_reader :access_key
101
+ attr_reader :secret_key
102
+ attr_reader :api_endpoint
103
+
104
+ def initialize(access_key, secret_key, sandbox=false)
105
+ @access_key = access_key
106
+ @secret_key = secret_key
107
+ @pipeline_url = sandbox ? PIPELINE_SANDBOX_URL : PIPELINE_URL
108
+ @api_endpoint = sandbox ? API_SANDBOX_ENDPOINT : API_ENDPOINT
109
+ super(@api_endpoint)
110
+ end
111
+
112
+ # generates v1 signatures, for historical purposes.
113
+ def self.signature_v1(path, params, secret_key)
114
+ params = params.reject {|key, val| ['awsSignature', 'action', 'controller', 'id'].include?(key) }.sort_by{ |k,v| k.to_s.downcase }.map{|k,v| "#{CGI::escape(k)}=#{Remit::SignedQuery.escape_value(v)}"}.join('&')
115
+ signable = path + '?' + params
116
+ Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest::SHA1.new, secret_key, signable)).strip
117
+ end
118
+
119
+ private
120
+
121
+ # called from Relax::Service#call
122
+ def query(request)
123
+ params = request.to_query.merge(
124
+ :AWSAccessKeyId => @access_key,
125
+ :Version => API_VERSION,
126
+ :Timestamp => Time.now.utc.strftime('%Y-%m-%dT%H:%M:%SZ')
127
+ )
128
+ ApiQuery.new(@endpoint, @secret_key, params)
129
+ end
130
+ end
131
+ end
132
+
@@ -0,0 +1,151 @@
1
+ require 'base64'
2
+ require 'erb'
3
+ require 'uri'
4
+
5
+ require 'rubygems'
6
+ require 'relax'
7
+
8
+ module Remit
9
+
10
+ module ConvertKey
11
+ def convert_key(key)
12
+ key.to_s.gsub(/(^|_)(.)/) { $2.upcase }.to_sym
13
+ end
14
+ end
15
+
16
+ class Request < Relax::Request
17
+ def self.action(name)
18
+ parameter :action, :value => name
19
+ end
20
+
21
+ include ConvertKey
22
+ protected :convert_key
23
+ end
24
+
25
+ class BaseResponse < Relax::Response
26
+ def node_name(name, namespace=nil)
27
+ super(name.to_s.gsub(/(^|_)(.)/) { $2.upcase }, namespace)
28
+ end
29
+ end
30
+
31
+ class ResponseMetadata < BaseResponse
32
+ # Amazon FPS returns a RequestId element for every API call accepted for processing
33
+ # that means not *every* call will have a request ID.
34
+ parameter :request_id#, :required => true
35
+ parameter :signature_version
36
+ parameter :signature_method
37
+ end
38
+
39
+ class Response < BaseResponse
40
+ parameter :response_metadata, :type => Remit::ResponseMetadata, :required => true
41
+
42
+ attr_accessor :status
43
+ attr_accessor :errors
44
+
45
+ def request_id
46
+ self.response_metadata.respond_to?(:request_id) ? self.response_metadata.request_id : nil
47
+ end
48
+
49
+ def initialize(xml)
50
+ super
51
+
52
+ #TODO: How to differentiate between Error and Service Error
53
+ if is?(:Response) and has?(:Errors)
54
+ @errors = elements(:Errors).collect do |error|
55
+ Error.new(error)
56
+ end
57
+ else
58
+ @status = text_value(element(:Status))
59
+ @errors = elements('errors/errors').collect do |error|
60
+ ServiceError.new(error)
61
+ end if not successful?
62
+ end
63
+ end
64
+
65
+ def successful?
66
+ @status == ResponseStatus::SUCCESS
67
+ end
68
+
69
+ def node_name(name, namespace=nil)
70
+ super(name.to_s.split('/').collect{ |tag|
71
+ tag.gsub(/(^|_)(.)/) { $2.upcase }
72
+ }.join('/'), namespace)
73
+ end
74
+ end
75
+
76
+ class SignedQuery < Relax::Query
77
+ def initialize(uri, secret_key, query = {})
78
+ super(query)
79
+ @uri = URI.parse(uri.to_s)
80
+ @secret_key = secret_key
81
+ sign
82
+ end
83
+
84
+ def sign
85
+ store(:signatureVersion, Remit::API::SIGNATURE_VERSION)
86
+ store(:signatureMethod, Remit::API::SIGNATURE_METHOD)
87
+ store(:signature, signature)
88
+ end
89
+
90
+ def signature
91
+ Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest::SHA256.new, @secret_key, signable_string)).strip
92
+ end
93
+
94
+ def signable_string
95
+ [ 'GET',
96
+ @uri.host,
97
+ @uri.path,
98
+ to_s # the query string, sans :signature (but with :signatureVersion and :signatureMethod)
99
+ ].join("\n")
100
+ end
101
+
102
+ class << self
103
+ def parse(uri, secret_key, query_string)
104
+ query = self.new(uri, secret_key)
105
+ query_string.split('&').each do |parameter|
106
+ key, value = parameter.split('=', 2)
107
+ query[key] = unescape_value(value)
108
+ end
109
+ query
110
+ end
111
+
112
+ UNSAFE = /[^A-Za-z0-9_.~-]/
113
+ # Amazon is very specific about what chars should be escaped, and which should not.
114
+ def escape_value(value)
115
+ # note that URI.escape(' ') => '%20', and CGI.escape(' ') => '+'
116
+ URI.escape(value.to_s, UNSAFE)
117
+ end
118
+ end
119
+ end
120
+
121
+ # Frustratingly enough, API requests want the signature params with slightly different casing.
122
+ class ApiQuery < SignedQuery
123
+ def sign
124
+ store(:SignatureVersion, Remit::API::SIGNATURE_VERSION)
125
+ store(:SignatureMethod, 'HmacSHA256')
126
+ store(:Signature, signature)
127
+ end
128
+ end
129
+ end
130
+
131
+ #Hack on Hash to make it s rocket
132
+ class Hash
133
+ def to_url_params
134
+ elements = []
135
+ keys.size.times do |i|
136
+ elements << "#{(keys[i])}=#{Remit::SignedQuery.escape_value(values[i])}"
137
+ end
138
+ elements.join('&')
139
+ end
140
+
141
+ def self.from_url_params(url_params)
142
+ result = {}
143
+ url_params.split('&').each do |element|
144
+ element = element.split('=')
145
+ # BJM - need to unescape the values in the param string
146
+ #result[element[0]] = element[1]
147
+ result[element[0]] = CGI.unescape(element[1])
148
+ end
149
+ result
150
+ end
151
+ end
@@ -0,0 +1,265 @@
1
+ require 'rubygems'
2
+ require 'relax'
3
+
4
+ require 'remit/common'
5
+
6
+ def camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true)
7
+ if first_letter_in_uppercase
8
+ lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
9
+ else
10
+ lower_case_and_underscored_word.first + camelize(lower_case_and_underscored_word)[1..-1]
11
+ end
12
+ end
13
+
14
+ module Relax
15
+ class Response
16
+ class << self
17
+ alias_method :alias_for_parameter, :parameter
18
+ def parameter(name, options = {})
19
+ opts = {
20
+ :element => camelize(name)
21
+ }.merge!(options)
22
+ alias_for_parameter(name, opts)
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ module Remit
29
+ class Amount < BaseResponse
30
+ parameter :currency_code
31
+ parameter :value, :type => :float
32
+ end
33
+
34
+ class TemporaryDeclinePolicy < BaseResponse
35
+ parameter :temporary_decline_policy_type
36
+ parameter :implicit_retry_timeout_in_mins
37
+ end
38
+
39
+ class DescriptorPolicy < BaseResponse
40
+ parameter :soft_descriptor_type
41
+ parameter :CS_owner
42
+ end
43
+
44
+ class ChargeFeeTo
45
+ CALLER = 'Caller'
46
+ RECIPIENT = 'Recipient'
47
+ end
48
+
49
+ class Error < BaseResponse
50
+ parameter :code
51
+ parameter :message
52
+ def error_code
53
+ self.code
54
+ end
55
+ def reason_text
56
+ self.message
57
+ end
58
+ end
59
+
60
+ class InstrumentStatus
61
+ ALL = 'ALL'
62
+ ACTIVE = 'Active'
63
+ INACTIVE = 'Inactive'
64
+ end
65
+
66
+ class PaymentMethods
67
+ BALANCE_aFER = 'abt'
68
+ BANK_ACCOUNT = 'ach'
69
+ CREDIT_CARD = 'credit card'
70
+ PREPAID = 'prepaid'
71
+ DEBT = 'Debt'
72
+ end
73
+
74
+ class ServiceError < BaseResponse
75
+ parameter :error_type
76
+ parameter :is_retriable
77
+ parameter :error_code
78
+ parameter :reason_text
79
+
80
+ class ErrorType
81
+ SYSTEM = 'System'
82
+ BUSINESS = 'Business'
83
+ end
84
+ end
85
+
86
+ class ResponseStatus
87
+ SUCCESS = 'Success'
88
+ FAILURE = 'Failure'
89
+ end
90
+
91
+ class Token < BaseResponse
92
+ parameter :token_id
93
+ parameter :friendly_name
94
+ parameter :token_status
95
+ parameter :date_installed, :type => :time
96
+ #parameter :caller_installed
97
+ parameter :caller_reference
98
+ parameter :token_type
99
+ parameter :old_token_id
100
+ parameter :payment_reason
101
+
102
+ class TokenStatus
103
+ ACTIVE = 'Active'
104
+ INACTIVE = 'Inactive'
105
+ end
106
+ end
107
+
108
+ class TokenUsageLimit < BaseResponse
109
+ parameter :count
110
+ parameter :limit
111
+ parameter :last_reset_amount
112
+ parameter :last_reset_count
113
+ parameter :last_reset_time_stamp
114
+ end
115
+
116
+ class TransactionPart < Remit::BaseResponse
117
+ parameter :account_id
118
+ parameter :role
119
+ parameter :name
120
+ parameter :reference
121
+ parameter :description
122
+ parameter :fee_paid, :type => Amount
123
+ end
124
+
125
+ class Transaction < BaseResponse
126
+
127
+ parameter :caller_name
128
+ parameter :caller_reference
129
+ parameter :caller_description
130
+ parameter :caller_transaction_date, :type => :time
131
+ parameter :date_completed, :type => :time
132
+ parameter :date_received, :type => :time
133
+ parameter :error_code
134
+ parameter :error_message
135
+ parameter :fees, :type => Amount
136
+ parameter :fps_fees_paid_by, :element=>"FPSFeesPaidBy"
137
+ parameter :fps_operation, :element=>"FPSOperation"
138
+ parameter :meta_data
139
+ parameter :payment_method
140
+ parameter :recipient_name
141
+ parameter :recipient_email
142
+ parameter :recipient_token_id
143
+ parameter :related_transactions
144
+ parameter :sender_email
145
+ parameter :sender_name
146
+ parameter :sender_token_id
147
+ parameter :transaction_status
148
+ parameter :status_code
149
+ parameter :status_history
150
+ parameter :status_message
151
+ parameter :transaction_amount, :type => Amount
152
+ parameter :transaction_id
153
+ parameter :transaction_parts, :collection => TransactionPart, :element=>"TransactionPart"
154
+ end
155
+
156
+ class TransactionResponse < BaseResponse
157
+ parameter :transaction_id
158
+ parameter :transaction_status
159
+
160
+ %w(cancelled failure pending reserved success).each do |status_name|
161
+ define_method("#{status_name}?") do
162
+ self.transaction_status == Remit::TransactionStatus.const_get(status_name.sub('_', '').upcase)
163
+ end
164
+ end
165
+ end
166
+
167
+ class TransactionStatus
168
+ #For IPN operations these strings are upcased. For Non-IPN operations they are not upcased
169
+ CANCELLED = 'Cancelled'
170
+ FAILURE = 'Failure'
171
+ PENDING = 'Pending'
172
+ RESERVED = 'Reserved'
173
+ SUCCESS = 'Success'
174
+ end
175
+
176
+ class TokenType
177
+ SINGLE_USE = 'SingleUse'
178
+ MULTI_USE = 'MultiUse'
179
+ RECURRING = 'Recurring'
180
+ UNRESTRICTED = 'Unrestricted'
181
+ end
182
+
183
+ class PipelineName
184
+ SINGLE_USE = 'SingleUse'
185
+ MULTI_USE = 'MultiUse'
186
+ RECURRING = 'Recurring'
187
+ RECIPIENT = 'Recipient'
188
+ SETUP_PREPAID = 'SetupPrepaid'
189
+ SETUP_POSTPAID = 'SetupPostpaid'
190
+ EDIT_TOKEN = 'EditToken'
191
+ end
192
+
193
+ class PipelineStatusCode
194
+ CALLER_EXCEPTION = 'CE' # problem with your code
195
+ SYSTEM_ERROR = 'SE' # system error, try again
196
+ SUCCESS_UNCHANGED = 'SU' # edit token pipeline finished, but token is unchanged
197
+ SUCCESS_ABT = 'SA' # successful payment with Amazon balance
198
+ SUCCESS_ACH = 'SB' # successful payment with bank transfer
199
+ SUCCESS_CC = 'SC' # successful payment with credit card
200
+ ABORTED = 'A' # user aborted payment
201
+ PAYMENT_METHOD_MISMATCH = 'PE' # user does not have payment method requested
202
+ PAYMENT_METHOD_UNSUPPORTED = 'NP' # account doesn't support requested payment method
203
+ INVALID_CALLER = 'NM' # you are not a valid 3rd party caller to the transaction
204
+ SUCCESS_RECIPIENT_TOKEN_INSTALLED = 'SR'
205
+ end
206
+
207
+ module RequestTypes
208
+ class Amount < Remit::Request
209
+ parameter :value
210
+ parameter :currency_code
211
+ end
212
+
213
+ class TemporaryDeclinePolicy < Remit::Request
214
+ parameter :temporary_decline_policy_type
215
+ parameter :implicit_retry_timeout_in_mins
216
+ end
217
+
218
+ class DescriptorPolicy < Remit::Request
219
+ parameter :soft_descriptor_type
220
+ parameter :CS_owner
221
+ end
222
+
223
+ end
224
+
225
+ class SoftDescriptorType
226
+ STATIC = 'Static'
227
+ DYNAMIC = 'Dynamic'
228
+ end
229
+
230
+ #MarketplaceRefundPolicy is available in these APIs:
231
+ # Amazon FPS Advanced Quick Start
232
+ # Amazon FPS Marketplace Quick Start
233
+ # Amazon FPS Aggregated Payments Quick Start
234
+ # i.e. Not Basic Quick Start
235
+ #It really should be listed under Enumerated DataTypes:
236
+ #MarketplaceTxnOnly Caller refunds his fee to the recipient. String
237
+ #MasterAndMarketplaceTxn Caller and Amazon FPS refund their fees to the String
238
+ # sender, and the recipient refunds his amount
239
+ #MasterTxnOnly Caller does not refund his fee. Amazon FPS String
240
+ # refunds its fee and the recipient refunds his amount
241
+ # plus the caller's fee to the sender.
242
+ class MarketplaceRefundPolicy
243
+ POLICY = {
244
+ :marketplace_txn_only => 'MarketplaceTxnOnly',
245
+ :master_and_marketplace_txn => 'MasterAndMarketplaceTxn',
246
+ :master_txn_only => 'MasterTxnOnly' #default if not specified, set by Amazon FPS
247
+ }
248
+ end
249
+
250
+ class TemporaryDeclinePolicyType
251
+ EXPLICIT_RETRY = 'ExplicitRetry'
252
+ IMPLICIT_RETRY = 'ImplicitRetry'
253
+ FAILURE = 'Failure'
254
+ end
255
+
256
+ class Operation
257
+ PAY = "Pay"
258
+ REFUND = "Refund"
259
+ SETTLE = "Settle"
260
+ SETTLE_DEBT = "SettleDebt"
261
+ WRITE_OFF_DEBT = "WriteOffDebt"
262
+ FUND_PREPAID = "FundPrepaid"
263
+ end
264
+
265
+ end