pboling-remit 0.0.2.4 → 0.0.8

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 (46) hide show
  1. data/LICENSE +20 -0
  2. data/README.markdown +91 -0
  3. data/lib/remit/common.rb +110 -0
  4. data/lib/remit/data_types.rb +170 -0
  5. data/lib/remit/error_codes.rb +118 -0
  6. data/lib/remit/get_pipeline.rb +212 -0
  7. data/lib/remit/ipn_request.rb +46 -0
  8. data/lib/remit/operations/cancel_token.rb +18 -0
  9. data/lib/remit/operations/discard_results.rb +18 -0
  10. data/lib/remit/operations/fund_prepaid.rb +31 -0
  11. data/lib/remit/operations/get_account_activity.rb +60 -0
  12. data/lib/remit/operations/get_account_balance.rb +29 -0
  13. data/lib/remit/operations/get_all_credit_instruments.rb +18 -0
  14. data/lib/remit/operations/get_all_prepaid_instruments.rb +18 -0
  15. data/lib/remit/operations/get_debt_balance.rb +23 -0
  16. data/lib/remit/operations/get_outstanding_debt_balance.rb +22 -0
  17. data/lib/remit/operations/get_payment_instruction.rb +21 -0
  18. data/lib/remit/operations/get_prepaid_balance.rb +23 -0
  19. data/lib/remit/operations/get_results.rb +27 -0
  20. data/lib/remit/operations/get_token_by_caller.rb +19 -0
  21. data/lib/remit/operations/get_token_usage.rb +18 -0
  22. data/lib/remit/operations/get_tokens.rb +20 -0
  23. data/lib/remit/operations/get_total_prepaid_liability.rb +22 -0
  24. data/lib/remit/operations/get_transaction.rb +54 -0
  25. data/lib/remit/operations/install_payment_instruction.rb +22 -0
  26. data/lib/remit/operations/pay.rb +30 -0
  27. data/lib/remit/operations/refund.rb +44 -0
  28. data/lib/remit/operations/reserve.rb +30 -0
  29. data/lib/remit/operations/retry_transaction.rb +18 -0
  30. data/lib/remit/operations/settle.rb +20 -0
  31. data/lib/remit/operations/settle_debt.rb +30 -0
  32. data/lib/remit/operations/subscribe_for_caller_notification.rb +18 -0
  33. data/lib/remit/operations/unsubscribe_for_caller_notification.rb +17 -0
  34. data/lib/remit/operations/write_off_debt.rb +28 -0
  35. data/lib/remit/pipeline_response.rb +64 -0
  36. data/lib/remit.rb +127 -0
  37. data/spec/integrations/get_account_activity_spec.rb +36 -0
  38. data/spec/integrations/get_tokens_spec.rb +38 -0
  39. data/spec/integrations/integrations_helper.rb +8 -0
  40. data/spec/spec_helper.rb +36 -0
  41. data/spec/units/get_pipeline_spec.rb +165 -0
  42. data/spec/units/get_results_spec.rb +49 -0
  43. data/spec/units/ipn_request_spec.rb +32 -0
  44. data/spec/units/pay_spec.rb +133 -0
  45. data/spec/units/units_helper.rb +4 -0
  46. metadata +64 -19
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
@@ -0,0 +1,110 @@
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 :errors
30
+ attr_accessor :xml
31
+
32
+ def initialize(xml)
33
+ super
34
+
35
+ @xml = xml
36
+ @errors = []
37
+ if is?(:Response) && has?(:Errors)
38
+ @errors = elements(:Errors).collect do |error|
39
+ Error.new(error)
40
+ end
41
+ else
42
+ @errors = elements('Errors/Errors').collect do |error|
43
+ ServiceError.new(error)
44
+ end unless successful?
45
+ end
46
+ end
47
+
48
+ def successful?
49
+ @errors.empty?
50
+ end
51
+
52
+ def node_name(name, namespace=nil)
53
+ super(name.to_s.split('/').collect{ |tag|
54
+ tag.gsub(/(^|_)(.)/) { $2.upcase }
55
+ }.join('/'), namespace)
56
+ end
57
+ end
58
+
59
+ #do we really need to pass in a uri and query params? Can't we just pass in the uri?
60
+ class SignedQuery < Relax::Query
61
+ def initialize(uri, secret_key, query={})
62
+ super(query)
63
+ @uri = URI.parse(uri.to_s)
64
+ parse_uri #values in the uri take precedence over the ones in the query
65
+ @secret_key = secret_key
66
+ end
67
+
68
+ def sign
69
+ delete(signature_key)
70
+ store(signature_key, signature)
71
+ end
72
+
73
+ def to_s(signed=true)
74
+ sign if signed
75
+ super()
76
+ end
77
+
78
+ def signature
79
+ self.class.signature(@secret_key,self)
80
+ end
81
+
82
+ def signature_key
83
+ :awsSignature
84
+ end
85
+
86
+ def parse_uri
87
+ if @uri.query
88
+ @uri.query.split('&').each do |parameter|
89
+ key, value = parameter.split('=', 2)
90
+ self[key] = self.class.unescape_value(value)
91
+ end
92
+ end
93
+ end
94
+ private :parse_uri
95
+
96
+ class << self
97
+
98
+ def signature(secret_key,hashable = {})
99
+ keys = hashable.keys.sort { |a, b| a.to_s.downcase <=> b.to_s.downcase }
100
+
101
+ signature = keys.inject('') do |signature, key|
102
+ value = hashable[key]
103
+ signature += key.to_s + value.to_s if value
104
+ end
105
+
106
+ Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest::SHA1.new, secret_key, signature)).strip
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,170 @@
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 :value, :type => :float
10
+ end
11
+
12
+ class DescriptorPolicy < BaseResponse
13
+ parameter :soft_descriptor_type
14
+ parameter :CS_number_of
15
+ end
16
+
17
+ class ChargeFeeTo
18
+ CALLER = 'Caller'
19
+ RECIPIENT = 'Recipient'
20
+ end
21
+
22
+ class Error < BaseResponse
23
+ parameter :code
24
+ parameter :message
25
+ end
26
+
27
+ class InstrumentStatus
28
+ ALL = 'ALL'
29
+ ACTIVE = 'Active'
30
+ INACTIVE = 'Inactive'
31
+ end
32
+
33
+ class PaymentMethods
34
+ BALANCE_TRANSFER = 'abt'
35
+ BANK_ACCOUNT = 'ach'
36
+ CREDIT_CARD = 'credit card'
37
+ PREPAID = 'prepaid'
38
+ DEBT = 'Debt'
39
+ end
40
+
41
+ class ServiceError < BaseResponse
42
+ parameter :error_type
43
+ parameter :is_retriable
44
+ parameter :error_code
45
+ parameter :reason_text
46
+
47
+ class ErrorType
48
+ SYSTEM = 'System'
49
+ BUSINESS = 'Business'
50
+ end
51
+ end
52
+
53
+ class ResponseStatus
54
+ SUCCESS = 'Success'
55
+ FAILURE = 'Failure'
56
+ end
57
+
58
+ class Token < BaseResponse
59
+ parameter :token_id
60
+ parameter :friendly_name
61
+ parameter :status
62
+ parameter :date_installed, :type => :time
63
+ parameter :caller_installed
64
+ parameter :caller_reference
65
+ parameter :token_type
66
+ parameter :old_token_id
67
+ parameter :payment_reason
68
+
69
+ class TokenStatus
70
+ ACTIVE = 'Active'
71
+ INACTIVE = 'Inactive'
72
+ end
73
+ end
74
+
75
+ class TokenUsageLimit < BaseResponse
76
+ parameter :count
77
+ parameter :limit
78
+ parameter :last_reset_amount
79
+ parameter :last_reset_count
80
+ parameter :last_reset_time_stamp
81
+ end
82
+
83
+ class TransactionResponse < BaseResponse
84
+ parameter :transaction_id
85
+ parameter :transaction_status
86
+
87
+ %w(reserved success failure pending cancelled).each do |status_name|
88
+ define_method("#{status_name}?") do
89
+ self.transaction_status == Remit::TransactionStatus.const_get(status_name.sub('_', '').upcase)
90
+ end
91
+ end
92
+ end
93
+
94
+ class TransactionStatus
95
+ RESERVED = 'Reserved'
96
+ SUCCESS = 'Success'
97
+ FAILURE = 'Failure'
98
+ PENDING = 'Pending'
99
+ CANCELLED = 'Cancelled'
100
+ end
101
+
102
+ class TokenType
103
+ SINGLE_USE = 'SingleUse'
104
+ MULTI_USE = 'MultiUse'
105
+ RECURRING = 'Recurring'
106
+ UNRESTRICTED = 'Unrestricted'
107
+ end
108
+
109
+ class PipelineName
110
+ SINGLE_USE = 'SingleUse'
111
+ MULTI_USE = 'MultiUse'
112
+ RECURRING = 'Recurring'
113
+ RECIPIENT = 'Recipient'
114
+ SETUP_PREPAID = 'SetupPrepaid'
115
+ SETUP_POSTPAID = 'SetupPostpaid'
116
+ EDIT_TOKEN = 'EditToken'
117
+ end
118
+
119
+ class PipelineStatusCode
120
+ CALLER_EXCEPTION = 'CE' # problem with your code
121
+ SYSTEM_ERROR = 'SE' # system error, try again
122
+ SUCCESS_ABT = 'SA' # successful payment with Amazon balance
123
+ SUCCESS_ACH = 'SB' # successful payment with bank transfer
124
+ SUCCESS_CC = 'SC' # successful payment with credit card
125
+ ABORTED = 'A' # user aborted payment
126
+ PAYMENT_METHOD_MISMATCH = 'PE' # user does not have payment method requested
127
+ PAYMENT_METHOD_UNSUPPORTED = 'NP' # account doesn't support requested payment method
128
+ INVALID_CALLER = 'NM' # you are not a valid 3rd party caller to the transaction
129
+ SUCCESS_RECIPIENT_TOKEN_INSTALLED = 'SR'
130
+ SUCCESS_NO_CHANGE = 'SU' # the existing token was not changed
131
+ end
132
+
133
+ module RequestTypes
134
+ class Amount < Remit::Request
135
+ parameter :value
136
+ parameter :currency_code
137
+ end
138
+
139
+ class DescriptorPolicy < Remit::Request
140
+ parameter :soft_descriptor_type
141
+ parameter :CS_number_of
142
+ end
143
+
144
+ #Amazon Docs list MarketplaceRefundPolicy as a ComplexDataType, but it is not.
145
+ #It really should be listed under Enumerated DataTypes
146
+ #MarketplaceTxnOnly Caller refunds his fee to the recipient. String
147
+ #MasterAndMarketplaceTxn Caller and Amazon FPS refund their fees to the String
148
+ # sender, and the recipient refunds his amount
149
+ #MasterTxnOnly Caller does not refund his fee. Amazon FPS String
150
+ # refunds its fee and the recipient refunds his amount
151
+ # plus the caller's fee to the sender.
152
+ class MarketplaceRefundPolicy < Remit::Request
153
+ POLICY = {
154
+ :marketplace_txn_only => 'MarketplaceTxnOnly',
155
+ :master_and_marketplace_txn => 'MasterAndMarketplaceTxn',
156
+ :master_txn_only => 'MasterTxnOnly'
157
+ }
158
+ end
159
+
160
+ end
161
+
162
+ class Operation
163
+ PAY = "Pay"
164
+ REFUND = "Refund"
165
+ SETTLE = "Settle"
166
+ SETTLE_DEBT = "SettleDebt"
167
+ WRITE_OFF_DEBT = "WriteOffDebt"
168
+ FUND_PREPAID = "FundPrepaid"
169
+ end
170
+ end
@@ -0,0 +1,118 @@
1
+ # Scraped and categorized from http://docs.amazonwebservices.com/AmazonFPS/\
2
+ # 2007-01-08/FPSDeveloperGuide/index.html?ErrorCodesTable.html. You can use
3
+ # these categories to specify default error handling in your application such
4
+ # as asking users to retry or sending an exception email.
5
+ module Remit::ErrorCodes
6
+ class << self
7
+ def sender_error?(code)
8
+ SENDER.include? code.to_sym
9
+ end
10
+
11
+ def recipient_error?(code)
12
+ RECIPIENT.include? code.to_sym
13
+ end
14
+
15
+ def caller_error?(code)
16
+ CALLER.include?(code.to_sym)
17
+ end
18
+
19
+ def amazon_error?(code)
20
+ AMAZON.include? code.to_sym
21
+ end
22
+
23
+ def api_error?(code)
24
+ API.include? code.to_sym
25
+ end
26
+
27
+ def unknown_error?(code)
28
+ UNKNOWN.include? code.to_sym
29
+ end
30
+ end
31
+
32
+ SENDER = [
33
+ :InactiveAccount_Sender, # The sender's account is in suspended or closed state.
34
+ :InactiveInstrument, # The payment instrument used for this transaction is no longer active.
35
+ :InstrumentExpired, # The prepaid or the postpaid instrument has expired.
36
+ :InstrumentNotActive, # The prepaid or postpaid instrument used in the transaction is not active.
37
+ :InvalidAccountState_Sender, # Sender account cannot participate in the transaction.
38
+ :InvalidInstrumentForAccountType, # The sender account can use only credit cards
39
+ :InvalidInstrumentState, # The prepaid or credit instrument should be active
40
+ :InvalidTokenId_Sender, # The send token specified is either invalid or canceled or the token is not active.
41
+ :PaymentInstrumentNotCC, # The payment method specified in the transaction is not a credit card. You can only use a credit card for this transaction.
42
+ :PaymentInstrumentMissing, # There needs to be a payment instrument defined in the token which defines the payment method.
43
+ :TokenNotActive_Sender, # The sender token is canceled.
44
+ :UnverifiedAccount_Sender, # The sender's account must have a verified U.S. credit card or a verified U.S bank account before this transaction can be initiated
45
+ :UnverifiedBankAccount, # A verified bank account should be used for this transaction
46
+ :UnverifiedEmailAddress_Sender, # The sender account must have a verified e-mail address for this payment
47
+ ]
48
+
49
+ RECIPIENT = [
50
+ :InactiveAccount_Recipient, # The recipient's account is in suspended or closed state.
51
+ :InvalidAccountState_Recipient, # Recipient account cannot participate in the transaction
52
+ :InvalidRecipientRoleForAccountType, # The recipient account is not allowed to receive payments
53
+ :InvalidRecipientForCCTransaction, # This account cannot receive credit card payments.
54
+ :InvalidTokenId_Recipient, # The recipient token specified is either invalid or canceled.
55
+ :TokenNotActive_Recipient, # The recipient token is canceled.
56
+ :UnverifiedAccount_Recipient, # The recipient's account must have a verified bank account or a credit card before this transaction can be initiated.
57
+ :UnverifiedEmailAddress_Recipient, # The recipient account must have a verified e-mail address for receiving payments.
58
+ ]
59
+
60
+ CALLER = [
61
+ :InactiveAccount_Caller, # The caller's account is in suspended or closed state.
62
+ :InvalidAccountState_Caller, # The caller account cannot participate in the transaction
63
+ :InvalidTokenId_Caller, # The caller token specified is either invalid or canceled or the specified token is not active.
64
+ :TokenNotActive_Caller, # The caller token is canceled.
65
+ :UnverifiedEmailAddress_Caller, # The caller account must have a verified e-mail address
66
+ ]
67
+
68
+ AMAZON = [
69
+ :InternalError # A retriable error that happens due to some transient problem in the system.
70
+ ]
71
+
72
+ # bad syntax or logic
73
+ API = [
74
+ :AmountOutOfRange, # The transaction amount is more than the allowed range.
75
+ :BadRule, # One of the GK constructs is not well defined
76
+ :CannotSpecifyUsageForSingleUseToken, # Token usages cannot be specified for a single use token.
77
+ :ConcurrentModification, # A retriable error can happen due to concurrent modification of data by two processes.
78
+ :DuplicateRequest, # A different request associated with this caller reference already exists.
79
+ :IncompatibleTokens, # The transaction could not be completed because the tokens have incompatible payment instructions.
80
+ :InstrumentAccessDenied, # The external calling application is not the recipient for this postpaid or prepaid instrument. The caller should be the liability holder
81
+ :InvalidCallerReference, # The CallerReferece does not have a token associated with it.
82
+ :InvalidDateRange, # The end date specified is before the start date or the start date is in the future.
83
+ :InvalidEvent, # The event specified was not subscribed using the SubscribeForCallerNotification operation.
84
+ :InvalidParams, # One or more parameters in the request is invalid.
85
+ :InvalidPaymentInstrument, # The payment method used in the transaction is invalid.
86
+ :InvalidPaymentMethod, # Payment method specified in the GK construct is invalid.
87
+ :InvalidSenderRoleForAccountType, # This token cannot be used for this operation.
88
+ :InvalidTokenId, # The token that you are trying to cancel was not installed by you.
89
+ :InvalidTokenType, # Invalid operation performed on the token. Example, getting the token usage information on a single use token.
90
+ :InvalidTransactionId, # The specified transaction could not be found or the caller did not execute the transaction or this is not a Pay or Reserve call.
91
+ :InvalidTransactionState, # The transaction is not completed or it has been temporarily failed.
92
+ :InvalidUsageDuration, # The duration cannot be less than one hour.
93
+ :InvalidUsageLimitCount, # The usage count is null or empty.
94
+ :InvalidUsageStartTime, # The start time specified for the token is not valid.
95
+ :InvalidUsageType, # The usage type specified is invalid.
96
+ :OriginalTransactionIncomplete, # The original transaction is still in progress.
97
+ :OriginalTransactionFailed, # The original transaction has failed
98
+ :PaymentMethodNotDefined, # Payment method is not defined in the transaction.
99
+ :RefundAmountExceeded, # The refund amount is more than the refundable amount.
100
+ :SameTokenIdUsedMultipleTimes, # This token is already used in earlier transactions.
101
+ :SenderNotOriginalRecipient, # The sender in the refund transaction is not the recipient of the original transaction.
102
+ :SettleAmountGreaterThanReserveAmount, # The amount being settled is greater than the reserved amount.
103
+ :TransactionDenied, # This transaction is not allowed.
104
+ :TransactionExpired, # Returned when the Caller attempts to explicitly retry a transaction that is temporarily declined and is in queue for implicit retry.
105
+ :TransactionFullyRefundedAlready, # The complete refund for this transaction is already completed
106
+ :TransactionTypeNotRefundable, # You cannot refund this transaction.
107
+ :TokenAccessDenied, # Permission is denied to cancel the token.
108
+ :TokenUsageError, # The token usage limit is exceeded.
109
+ :UsageNotDefined, # For a multi-use token or a recurring token the usage limits are not specified in the GateKeeper text.
110
+ ]
111
+
112
+ # these errors don't specify who is at fault
113
+ UNKNOWN = [
114
+ :InvalidAccountState, # The account is either suspended or closed. Payment instructions cannot be installed on this account.
115
+ :InsufficientBalance, # The sender, caller, or recipient's account balance has insufficient funds to complete the transaction.
116
+ :AccountLimitsExceeded, # The spending or the receiving limit on the account is exceeded
117
+ ]
118
+ end