ianlevesque-remit 0.0.6
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/LICENSE +20 -0
- data/README.markdown +91 -0
- data/lib/remit/common.rb +88 -0
- data/lib/remit/data_types.rb +166 -0
- data/lib/remit/error_codes.rb +118 -0
- data/lib/remit/get_pipeline.rb +195 -0
- data/lib/remit/ipn_request.rb +49 -0
- data/lib/remit/operations/cancel_token.rb +18 -0
- data/lib/remit/operations/discard_results.rb +18 -0
- data/lib/remit/operations/fund_prepaid.rb +31 -0
- data/lib/remit/operations/get_account_activity.rb +60 -0
- data/lib/remit/operations/get_account_balance.rb +29 -0
- data/lib/remit/operations/get_all_credit_instruments.rb +18 -0
- data/lib/remit/operations/get_all_prepaid_instruments.rb +18 -0
- data/lib/remit/operations/get_debt_balance.rb +23 -0
- data/lib/remit/operations/get_outstanding_debt_balance.rb +22 -0
- data/lib/remit/operations/get_payment_instruction.rb +21 -0
- data/lib/remit/operations/get_prepaid_balance.rb +23 -0
- data/lib/remit/operations/get_results.rb +27 -0
- data/lib/remit/operations/get_token_by_caller.rb +19 -0
- data/lib/remit/operations/get_token_usage.rb +18 -0
- data/lib/remit/operations/get_tokens.rb +20 -0
- data/lib/remit/operations/get_total_prepaid_liability.rb +22 -0
- data/lib/remit/operations/get_transaction.rb +42 -0
- data/lib/remit/operations/install_payment_instruction.rb +22 -0
- data/lib/remit/operations/pay.rb +35 -0
- data/lib/remit/operations/refund.rb +36 -0
- data/lib/remit/operations/reserve.rb +30 -0
- data/lib/remit/operations/retry_transaction.rb +18 -0
- data/lib/remit/operations/settle.rb +20 -0
- data/lib/remit/operations/settle_debt.rb +30 -0
- data/lib/remit/operations/subscribe_for_caller_notification.rb +18 -0
- data/lib/remit/operations/unsubscribe_for_caller_notification.rb +17 -0
- data/lib/remit/operations/write_off_debt.rb +28 -0
- data/lib/remit/pipeline_response.rb +53 -0
- data/lib/remit.rb +133 -0
- data/spec/integrations/get_account_activity_spec.rb +36 -0
- data/spec/integrations/get_tokens_spec.rb +38 -0
- data/spec/integrations/integrations_helper.rb +8 -0
- data/spec/spec_helper.rb +36 -0
- data/spec/units/get_pipeline_spec.rb +165 -0
- data/spec/units/get_results_spec.rb +49 -0
- data/spec/units/ipn_request_spec.rb +32 -0
- data/spec/units/pay_spec.rb +133 -0
- data/spec/units/units_helper.rb +4 -0
- metadata +106 -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/common.rb
ADDED
@@ -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,166 @@
|
|
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
|
+
EDIT_TOKEN = 'EditToken'
|
125
|
+
end
|
126
|
+
|
127
|
+
class PipelineStatusCode
|
128
|
+
CALLER_EXCEPTION = 'CE' # problem with your code
|
129
|
+
SYSTEM_ERROR = 'SE' # system error, try again
|
130
|
+
SUCCESS_ABT = 'SA' # successful payment with Amazon balance
|
131
|
+
SUCCESS_ACH = 'SB' # successful payment with bank transfer
|
132
|
+
SUCCESS_CC = 'SC' # successful payment with credit card
|
133
|
+
ABORTED = 'A' # user aborted payment
|
134
|
+
PAYMENT_METHOD_MISMATCH = 'PE' # user does not have payment method requested
|
135
|
+
PAYMENT_METHOD_UNSUPPORTED = 'NP' # account doesn't support requested payment method
|
136
|
+
INVALID_CALLER = 'NM' # you are not a valid 3rd party caller to the transaction
|
137
|
+
SUCCESS_RECIPIENT_TOKEN_INSTALLED = 'SR'
|
138
|
+
SUCCESS_NO_CHANGE = 'SU' # the existing token was not changed
|
139
|
+
end
|
140
|
+
|
141
|
+
module RequestTypes
|
142
|
+
class Amount < Remit::Request
|
143
|
+
parameter :amount
|
144
|
+
parameter :currency_code
|
145
|
+
end
|
146
|
+
|
147
|
+
class TemporaryDeclinePolicy < Remit::Request
|
148
|
+
parameter :temporary_decline_policy_type
|
149
|
+
parameter :implicit_retry_timeout_in_mins
|
150
|
+
end
|
151
|
+
|
152
|
+
class DescriptorPolicy < Remit::Request
|
153
|
+
parameter :soft_descriptor_type
|
154
|
+
parameter :CS_number_of
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
class Operation
|
159
|
+
PAY = "Pay"
|
160
|
+
REFUND = "Refund"
|
161
|
+
SETTLE = "Settle"
|
162
|
+
SETTLE_DEBT = "SettleDebt"
|
163
|
+
WRITE_OFF_DEBT = "WriteOffDebt"
|
164
|
+
FUND_PREPAID = "FundPrepaid"
|
165
|
+
end
|
166
|
+
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
|
@@ -0,0 +1,195 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
require 'remit/common'
|
4
|
+
|
5
|
+
module Remit
|
6
|
+
module GetPipeline
|
7
|
+
class Pipeline
|
8
|
+
@parameters = []
|
9
|
+
attr_reader :parameters
|
10
|
+
|
11
|
+
class << self
|
12
|
+
# Create the parameters hash for the subclass.
|
13
|
+
def inherited(subclass) #:nodoc:
|
14
|
+
subclass.instance_variable_set('@parameters', [])
|
15
|
+
end
|
16
|
+
|
17
|
+
def parameter(name)
|
18
|
+
attr_accessor name
|
19
|
+
@parameters << name
|
20
|
+
end
|
21
|
+
|
22
|
+
def convert_key(key)
|
23
|
+
key.to_s.gsub(/_(.)/) { $1.upcase }.to_sym
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns a hash of all of the parameters for this request, including
|
27
|
+
# those that are inherited.
|
28
|
+
def parameters #:nodoc:
|
29
|
+
(superclass.respond_to?(:parameters) ? superclass.parameters : []) + @parameters
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
attr_reader :api
|
34
|
+
|
35
|
+
parameter :pipeline_name
|
36
|
+
parameter :return_url
|
37
|
+
parameter :caller_key
|
38
|
+
parameter :version
|
39
|
+
|
40
|
+
def initialize(api, options)
|
41
|
+
@api = api
|
42
|
+
|
43
|
+
options.each do |k,v|
|
44
|
+
self.send("#{k}=", v)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def url
|
49
|
+
uri = URI.parse(@api.pipeline_url)
|
50
|
+
|
51
|
+
query = {}
|
52
|
+
self.class.parameters.each do |p|
|
53
|
+
val = self.send(p)
|
54
|
+
|
55
|
+
# Convert Time values to seconds from Epoch
|
56
|
+
val = val.to_i if val.class == Time
|
57
|
+
|
58
|
+
query[self.class.convert_key(p.to_s)] = val
|
59
|
+
end
|
60
|
+
|
61
|
+
# Remove any unused optional parameters
|
62
|
+
query.reject! { |key, value| value.nil? }
|
63
|
+
|
64
|
+
uri.query = SignedQuery.new(@api.pipeline_url, @api.secret_key, query).to_s
|
65
|
+
uri.to_s
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
class SingleUsePipeline < Pipeline
|
70
|
+
parameter :caller_reference
|
71
|
+
parameter :payment_reason
|
72
|
+
parameter :payment_method
|
73
|
+
parameter :transaction_amount
|
74
|
+
parameter :recipient_token
|
75
|
+
|
76
|
+
def pipeline_name
|
77
|
+
Remit::PipelineName::SINGLE_USE
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
class MultiUsePipeline < Pipeline
|
82
|
+
parameter :caller_reference
|
83
|
+
parameter :payment_reason
|
84
|
+
parameter :recipient_token_list
|
85
|
+
parameter :amount_type
|
86
|
+
parameter :transaction_amount
|
87
|
+
parameter :validity_start
|
88
|
+
parameter :validity_expiry
|
89
|
+
parameter :payment_method
|
90
|
+
parameter :global_amount_limit
|
91
|
+
parameter :usage_limit_type_1
|
92
|
+
parameter :usage_limit_period_1
|
93
|
+
parameter :usage_limit_value_1
|
94
|
+
parameter :usage_limit_type_2
|
95
|
+
parameter :usage_limit_period_2
|
96
|
+
parameter :usage_limit_value_2
|
97
|
+
parameter :is_recipient_cobranding
|
98
|
+
|
99
|
+
def pipeline_name
|
100
|
+
Remit::PipelineName::MULTI_USE
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
class RecipientPipeline < Pipeline
|
105
|
+
parameter :caller_reference
|
106
|
+
parameter :validity_start # Time or seconds from Epoch
|
107
|
+
parameter :validity_expiry # Time or seconds from Epoch
|
108
|
+
parameter :payment_method
|
109
|
+
parameter :recipient_pays_fee
|
110
|
+
parameter :caller_reference_refund
|
111
|
+
parameter :max_variable_fee
|
112
|
+
parameter :max_fixed_fee
|
113
|
+
|
114
|
+
def pipeline_name
|
115
|
+
Remit::PipelineName::RECIPIENT
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
class RecurringUsePipeline < Pipeline
|
120
|
+
parameter :caller_reference
|
121
|
+
parameter :payment_reason
|
122
|
+
parameter :recipient_token
|
123
|
+
parameter :transaction_amount
|
124
|
+
parameter :validity_start # Time or seconds from Epoch
|
125
|
+
parameter :validity_expiry # Time or seconds from Epoch
|
126
|
+
parameter :payment_method
|
127
|
+
parameter :recurring_period
|
128
|
+
|
129
|
+
def pipeline_name
|
130
|
+
Remit::PipelineName::RECURRING
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
class PostpaidPipeline < Pipeline
|
135
|
+
parameter :caller_reference_sender
|
136
|
+
parameter :caller_reference_settlement
|
137
|
+
parameter :payment_reason
|
138
|
+
parameter :payment_method
|
139
|
+
parameter :validity_start # Time or seconds from Epoch
|
140
|
+
parameter :validity_expiry # Time or seconds from Epoch
|
141
|
+
parameter :credit_limit
|
142
|
+
parameter :global_amount_limit
|
143
|
+
parameter :usage_limit_type1
|
144
|
+
parameter :usage_limit_period1
|
145
|
+
parameter :usage_limit_value1
|
146
|
+
parameter :usage_limit_type2
|
147
|
+
parameter :usage_limit_period2
|
148
|
+
parameter :usage_limit_value2
|
149
|
+
|
150
|
+
def pipeline_name
|
151
|
+
Remit::PipelineName::SETUP_POSTPAID
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
class EditTokenPipeline < Pipeline
|
156
|
+
parameter :caller_reference
|
157
|
+
parameter :payment_method
|
158
|
+
parameter :token_id
|
159
|
+
|
160
|
+
def pipeline_name
|
161
|
+
Remit::PipelineName::EDIT_TOKEN
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def get_single_use_pipeline(options)
|
166
|
+
self.get_pipeline(SingleUsePipeline, options)
|
167
|
+
end
|
168
|
+
|
169
|
+
def get_multi_use_pipeline(options)
|
170
|
+
self.get_pipeline(MultiUsePipeline, options)
|
171
|
+
end
|
172
|
+
|
173
|
+
def get_recipient_pipeline(options)
|
174
|
+
self.get_pipeline(RecipientPipeline, options)
|
175
|
+
end
|
176
|
+
|
177
|
+
def get_recurring_use_pipeline(options)
|
178
|
+
self.get_pipeline(RecurringUsePipeline, options)
|
179
|
+
end
|
180
|
+
|
181
|
+
def get_postpaid_pipeline(options)
|
182
|
+
self.get_pipeline(PostpaidPipeline, options)
|
183
|
+
end
|
184
|
+
|
185
|
+
def get_edit_token_pipeline(options)
|
186
|
+
self.get_pipeline(EditTokenPipeline, options)
|
187
|
+
end
|
188
|
+
|
189
|
+
def get_pipeline(pipeline_subclass, options)
|
190
|
+
pipeline = pipeline_subclass.new(self, {
|
191
|
+
:caller_key => @access_key
|
192
|
+
}.merge(options))
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|