offsite_payments 2.0.0
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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +70 -0
- data/lib/offsite_payments.rb +46 -0
- data/lib/offsite_payments/action_view_helper.rb +72 -0
- data/lib/offsite_payments/helper.rb +119 -0
- data/lib/offsite_payments/integrations.rb +14 -0
- data/lib/offsite_payments/integrations/a1agregator.rb +245 -0
- data/lib/offsite_payments/integrations/authorize_net_sim.rb +580 -0
- data/lib/offsite_payments/integrations/bit_pay.rb +150 -0
- data/lib/offsite_payments/integrations/bogus.rb +32 -0
- data/lib/offsite_payments/integrations/chronopay.rb +283 -0
- data/lib/offsite_payments/integrations/citrus.rb +227 -0
- data/lib/offsite_payments/integrations/direc_pay.rb +339 -0
- data/lib/offsite_payments/integrations/directebanking.rb +237 -0
- data/lib/offsite_payments/integrations/doku.rb +171 -0
- data/lib/offsite_payments/integrations/dotpay.rb +166 -0
- data/lib/offsite_payments/integrations/dwolla.rb +160 -0
- data/lib/offsite_payments/integrations/e_payment_plans.rb +146 -0
- data/lib/offsite_payments/integrations/easy_pay.rb +137 -0
- data/lib/offsite_payments/integrations/epay.rb +161 -0
- data/lib/offsite_payments/integrations/first_data.rb +133 -0
- data/lib/offsite_payments/integrations/gestpay.rb +201 -0
- data/lib/offsite_payments/integrations/hi_trust.rb +179 -0
- data/lib/offsite_payments/integrations/ipay88.rb +240 -0
- data/lib/offsite_payments/integrations/klarna.rb +291 -0
- data/lib/offsite_payments/integrations/liqpay.rb +216 -0
- data/lib/offsite_payments/integrations/maksuturva.rb +231 -0
- data/lib/offsite_payments/integrations/mollie_ideal.rb +213 -0
- data/lib/offsite_payments/integrations/moneybookers.rb +199 -0
- data/lib/offsite_payments/integrations/nochex.rb +228 -0
- data/lib/offsite_payments/integrations/pag_seguro.rb +255 -0
- data/lib/offsite_payments/integrations/paxum.rb +114 -0
- data/lib/offsite_payments/integrations/pay_fast.rb +269 -0
- data/lib/offsite_payments/integrations/paydollar.rb +142 -0
- data/lib/offsite_payments/integrations/payflow_link.rb +194 -0
- data/lib/offsite_payments/integrations/paypal.rb +362 -0
- data/lib/offsite_payments/integrations/paypal_payments_advanced.rb +23 -0
- data/lib/offsite_payments/integrations/paysbuy.rb +71 -0
- data/lib/offsite_payments/integrations/payu_in.rb +266 -0
- data/lib/offsite_payments/integrations/payu_in_paisa.rb +46 -0
- data/lib/offsite_payments/integrations/platron.rb +153 -0
- data/lib/offsite_payments/integrations/pxpay.rb +271 -0
- data/lib/offsite_payments/integrations/quickpay.rb +232 -0
- data/lib/offsite_payments/integrations/rbkmoney.rb +110 -0
- data/lib/offsite_payments/integrations/robokassa.rb +154 -0
- data/lib/offsite_payments/integrations/sage_pay_form.rb +425 -0
- data/lib/offsite_payments/integrations/two_checkout.rb +332 -0
- data/lib/offsite_payments/integrations/universal.rb +180 -0
- data/lib/offsite_payments/integrations/valitor.rb +200 -0
- data/lib/offsite_payments/integrations/verkkomaksut.rb +143 -0
- data/lib/offsite_payments/integrations/web_pay.rb +186 -0
- data/lib/offsite_payments/integrations/webmoney.rb +119 -0
- data/lib/offsite_payments/integrations/wirecard_checkout_page.rb +359 -0
- data/lib/offsite_payments/integrations/world_pay.rb +273 -0
- data/lib/offsite_payments/notification.rb +71 -0
- data/lib/offsite_payments/return.rb +37 -0
- data/lib/offsite_payments/version.rb +3 -0
- metadata +270 -0
@@ -0,0 +1,227 @@
|
|
1
|
+
module OffsitePayments
|
2
|
+
module Integrations
|
3
|
+
module Citrus
|
4
|
+
def self.helper(order, account, options = {})
|
5
|
+
Helper.new(order, account, options)
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.notification(post, options = {})
|
9
|
+
Notification.new(post, options)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.return(query_string, options = {})
|
13
|
+
Return.new(query_string, options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.checksum(secret_key, payload_items )
|
17
|
+
digest = OpenSSL::Digest.new('sha1')
|
18
|
+
OpenSSL::HMAC.hexdigest(digest, secret_key, payload_items)
|
19
|
+
end
|
20
|
+
|
21
|
+
class Helper < OffsitePayments::Helper
|
22
|
+
mapping :order, 'merchantTxnId'
|
23
|
+
mapping :amount, 'orderAmount'
|
24
|
+
mapping :account, 'merchantAccessKey'
|
25
|
+
mapping :credential2, 'secret_key'
|
26
|
+
mapping :credential3, 'pmt_url'
|
27
|
+
mapping :currency, 'currency'
|
28
|
+
|
29
|
+
mapping :customer, :first_name => 'firstName',:last_name => 'lastName', :email => 'email', :phone => 'mobileNo'
|
30
|
+
|
31
|
+
mapping :billing_address, :city => 'addressCity', :address1 => 'addressStreet1', :address2 => 'addressStreet2',:state => 'addressState',:zip => 'addressZip', :country => 'addressCountry'
|
32
|
+
|
33
|
+
mapping :checksum, 'secSignature'
|
34
|
+
mapping :return_url, 'returnUrl'
|
35
|
+
|
36
|
+
SANDBOX_URL = 'https://sandbox.citruspay.com/'.freeze
|
37
|
+
STAGING_URL = 'https://stg.citruspay.com/'.freeze
|
38
|
+
PRODUCTION_URL = 'https://www.citruspay.com/'.freeze
|
39
|
+
|
40
|
+
def credential_based_url
|
41
|
+
pmt_url = @fields['pmt_url']
|
42
|
+
case OffsitePayments.mode
|
43
|
+
when :production
|
44
|
+
PRODUCTION_URL + pmt_url
|
45
|
+
when :test
|
46
|
+
SANDBOX_URL + pmt_url
|
47
|
+
when :staging
|
48
|
+
STAGING_URL + pmt_url
|
49
|
+
else
|
50
|
+
raise StandardError, "Integration mode set to an invalid value: #{mode}"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def initialize(order, account, options = {})
|
55
|
+
super
|
56
|
+
add_field 'paymentMode', 'NET_BANKING'
|
57
|
+
add_field 'reqtime', (Time.now.to_i * 1000).to_s
|
58
|
+
end
|
59
|
+
|
60
|
+
def form_fields
|
61
|
+
@fields.merge(mappings[:checksum] => generate_checksum)
|
62
|
+
end
|
63
|
+
|
64
|
+
def generate_checksum
|
65
|
+
checksum_fields = @fields["pmt_url"] + @fields["orderAmount"].to_s + @fields["merchantTxnId"] + @fields["currency"]
|
66
|
+
Citrus.checksum(@fields["secret_key"], checksum_fields )
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
class Notification < OffsitePayments::Notification
|
71
|
+
def initialize(post, options = {})
|
72
|
+
super(post, options)
|
73
|
+
@secret_key = options[:credential2]
|
74
|
+
end
|
75
|
+
|
76
|
+
def complete?
|
77
|
+
status == "Completed" || status == 'Canceled'
|
78
|
+
end
|
79
|
+
|
80
|
+
def status
|
81
|
+
@status ||= if checksum_ok?
|
82
|
+
if transaction_id.blank?
|
83
|
+
'Invalid'
|
84
|
+
else
|
85
|
+
case transaction_status.downcase
|
86
|
+
when 'success' then 'Completed'
|
87
|
+
when 'canceled' then 'Cancelled'
|
88
|
+
end
|
89
|
+
end
|
90
|
+
else
|
91
|
+
'Tampered'
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def invoice_ok?( order_id )
|
96
|
+
order_id.to_s == invoice.to_s
|
97
|
+
end
|
98
|
+
|
99
|
+
def amount_ok?( order_amount )
|
100
|
+
BigDecimal.new( amount ) == order_amount
|
101
|
+
end
|
102
|
+
|
103
|
+
def item_id
|
104
|
+
params['TxId']
|
105
|
+
end
|
106
|
+
|
107
|
+
def invoice
|
108
|
+
item_id
|
109
|
+
end
|
110
|
+
|
111
|
+
# Status of transaction return from the Citrus. List of possible values:
|
112
|
+
# <tt>SUCCESS</tt>::
|
113
|
+
# <tt>CANCELED</tt>::
|
114
|
+
def transaction_status
|
115
|
+
params['TxStatus']
|
116
|
+
end
|
117
|
+
|
118
|
+
def gross
|
119
|
+
params['amount']
|
120
|
+
end
|
121
|
+
|
122
|
+
def amount
|
123
|
+
gross
|
124
|
+
end
|
125
|
+
|
126
|
+
def transaction_id
|
127
|
+
params['pgTxnNo']
|
128
|
+
end
|
129
|
+
|
130
|
+
def issuerrefno
|
131
|
+
params['issuerRefNo']
|
132
|
+
end
|
133
|
+
|
134
|
+
def authidcode
|
135
|
+
params['authIdCode']
|
136
|
+
end
|
137
|
+
|
138
|
+
def pgrespcode
|
139
|
+
params['pgRespCode']
|
140
|
+
end
|
141
|
+
|
142
|
+
def checksum
|
143
|
+
params['signature']
|
144
|
+
end
|
145
|
+
|
146
|
+
def paymentmode
|
147
|
+
params['paymentMode']
|
148
|
+
end
|
149
|
+
|
150
|
+
def currency
|
151
|
+
params['currency']
|
152
|
+
end
|
153
|
+
|
154
|
+
def customer_email
|
155
|
+
params['email']
|
156
|
+
end
|
157
|
+
|
158
|
+
def customer_phone
|
159
|
+
params['mobileNo']
|
160
|
+
end
|
161
|
+
|
162
|
+
def customer_first_name
|
163
|
+
params['firstName']
|
164
|
+
end
|
165
|
+
|
166
|
+
def customer_last_name
|
167
|
+
params['lastName']
|
168
|
+
end
|
169
|
+
|
170
|
+
def customer_address
|
171
|
+
{ :address1 => params['addressStreet1'], :address2 => params['addressStreet2'],
|
172
|
+
:city => params['addressCity'], :state => params['addressState'],
|
173
|
+
:country => params['addressCountry'], :zip => params['addressZip'] }
|
174
|
+
end
|
175
|
+
|
176
|
+
def message
|
177
|
+
@message || params['TxMsg']
|
178
|
+
end
|
179
|
+
|
180
|
+
def acknowledge(authcode = nil)
|
181
|
+
checksum_ok?
|
182
|
+
end
|
183
|
+
|
184
|
+
def checksum_ok?
|
185
|
+
fields = [invoice, transaction_status, amount.to_s, transaction_id, issuerrefno, authidcode, customer_first_name, customer_last_name, pgrespcode, customer_address[:zip]].join
|
186
|
+
|
187
|
+
unless Citrus.checksum(@secret_key, fields ) == checksum
|
188
|
+
@message = 'checksum mismatch...'
|
189
|
+
return false
|
190
|
+
end
|
191
|
+
true
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
class Return < OffsitePayments::Return
|
196
|
+
def initialize(query_string, options = {})
|
197
|
+
super
|
198
|
+
@notification = Notification.new(query_string, options)
|
199
|
+
end
|
200
|
+
|
201
|
+
def transaction_id
|
202
|
+
@notification.transaction_id
|
203
|
+
end
|
204
|
+
|
205
|
+
def status( order_id, order_amount )
|
206
|
+
if @notification.invoice_ok?( order_id ) && @notification.amount_ok?( BigDecimal.new(order_amount) )
|
207
|
+
@notification.status
|
208
|
+
else
|
209
|
+
'Mismatch'
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
def success?
|
214
|
+
status( @params['TxId'], @params['amount'] ) == 'Completed'
|
215
|
+
end
|
216
|
+
|
217
|
+
def message
|
218
|
+
@notification.message
|
219
|
+
end
|
220
|
+
|
221
|
+
def cancelled?
|
222
|
+
@notification.status == 'Cancelled'
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
@@ -0,0 +1,339 @@
|
|
1
|
+
module OffsitePayments #:nodoc:
|
2
|
+
module Integrations #:nodoc:
|
3
|
+
module DirecPay
|
4
|
+
mattr_accessor :production_url, :test_url
|
5
|
+
|
6
|
+
self.production_url = "https://www.timesofmoney.com/direcpay/secure/dpMerchantTransaction.jsp"
|
7
|
+
self.test_url = "https://test.direcpay.com/direcpay/secure/dpMerchantTransaction.jsp"
|
8
|
+
|
9
|
+
def self.service_url
|
10
|
+
mode = OffsitePayments.mode
|
11
|
+
case mode
|
12
|
+
when :production
|
13
|
+
self.production_url
|
14
|
+
when :test
|
15
|
+
self.test_url
|
16
|
+
else
|
17
|
+
raise StandardError, "Integration mode set to an invalid value: #{mode}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.notification(post, options = {})
|
22
|
+
Notification.new(post)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.return(query_string, options = {})
|
26
|
+
Return.new(query_string, options)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.request_status_update(mid, transaction_id, notification_url)
|
30
|
+
Status.new(mid).update(transaction_id, notification_url)
|
31
|
+
end
|
32
|
+
|
33
|
+
class Helper < OffsitePayments::Helper
|
34
|
+
mapping :account, 'MID'
|
35
|
+
mapping :order, 'Merchant Order No'
|
36
|
+
mapping :amount, 'Amount'
|
37
|
+
mapping :currency, 'Currency'
|
38
|
+
mapping :country, 'Country'
|
39
|
+
|
40
|
+
mapping :billing_address, :city => 'custCity',
|
41
|
+
:address1 => 'custAddress',
|
42
|
+
:state => 'custState',
|
43
|
+
:zip => 'custPinCode',
|
44
|
+
:country => 'custCountry',
|
45
|
+
:phone => 'custMobileNo'
|
46
|
+
|
47
|
+
mapping :shipping_address, :name => 'deliveryName',
|
48
|
+
:city => 'deliveryCity',
|
49
|
+
:address1 => 'deliveryAddress',
|
50
|
+
:state => 'deliveryState',
|
51
|
+
:zip => 'deliveryPinCode',
|
52
|
+
:country => 'deliveryCountry',
|
53
|
+
:phone => 'deliveryMobileNo'
|
54
|
+
|
55
|
+
mapping :customer, :name => 'custName',
|
56
|
+
:email => 'custEmailId'
|
57
|
+
|
58
|
+
mapping :description, 'otherNotes'
|
59
|
+
mapping :edit_allowed, 'editAllowed'
|
60
|
+
|
61
|
+
mapping :return_url, 'Success URL'
|
62
|
+
mapping :failure_url, 'Failure URL'
|
63
|
+
|
64
|
+
mapping :operating_mode, 'Operating Mode'
|
65
|
+
mapping :other_details, 'Other Details'
|
66
|
+
mapping :collaborator, 'Collaborator'
|
67
|
+
|
68
|
+
OPERATING_MODE = 'DOM'
|
69
|
+
COUNTRY = 'IND'
|
70
|
+
CURRENCY = 'INR'
|
71
|
+
OTHER_DETAILS = 'NULL'
|
72
|
+
EDIT_ALLOWED = 'Y'
|
73
|
+
|
74
|
+
PHONE_CODES = {
|
75
|
+
'IN' => '91',
|
76
|
+
'US' => '01',
|
77
|
+
'CA' => '01'
|
78
|
+
}
|
79
|
+
|
80
|
+
ENCODED_PARAMS = [ :account, :operating_mode, :country, :currency, :amount, :order, :other_details, :return_url, :failure_url, :collaborator ]
|
81
|
+
|
82
|
+
def initialize(order, account, options = {})
|
83
|
+
super
|
84
|
+
collaborator = OffsitePayments.mode == :test || options[:test] ? 'TOML' : 'DirecPay'
|
85
|
+
add_field(mappings[:collaborator], collaborator)
|
86
|
+
add_field(mappings[:country], 'IND')
|
87
|
+
add_field(mappings[:operating_mode], OPERATING_MODE)
|
88
|
+
add_field(mappings[:other_details], OTHER_DETAILS)
|
89
|
+
add_field(mappings[:edit_allowed], EDIT_ALLOWED)
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
def customer(params = {})
|
94
|
+
add_field(mappings[:customer][:name], full_name(params))
|
95
|
+
add_field(mappings[:customer][:email], params[:email])
|
96
|
+
end
|
97
|
+
|
98
|
+
# Need to format the amount to have 2 decimal places
|
99
|
+
def amount=(money)
|
100
|
+
cents = money.respond_to?(:cents) ? money.cents : money
|
101
|
+
raise ArgumentError, "amount must be a Money object or an integer" if money.is_a?(String)
|
102
|
+
raise ActionViewHelperError, "amount must be greater than $0.00" if cents.to_i <= 0
|
103
|
+
|
104
|
+
add_field(mappings[:amount], sprintf("%.2f", cents.to_f/100))
|
105
|
+
end
|
106
|
+
|
107
|
+
def shipping_address(params = {})
|
108
|
+
super(update_address(:shipping_address, params))
|
109
|
+
end
|
110
|
+
|
111
|
+
def billing_address(params = {})
|
112
|
+
super(update_address(:billing_address, params))
|
113
|
+
end
|
114
|
+
|
115
|
+
def form_fields
|
116
|
+
add_failure_url
|
117
|
+
add_request_parameters
|
118
|
+
|
119
|
+
unencoded_parameters
|
120
|
+
end
|
121
|
+
|
122
|
+
private
|
123
|
+
|
124
|
+
def add_request_parameters
|
125
|
+
params = ENCODED_PARAMS.map{ |param| fields[mappings[param]] }
|
126
|
+
encoded = encode_value(params.join('|'))
|
127
|
+
|
128
|
+
add_field('requestparameter', encoded)
|
129
|
+
end
|
130
|
+
|
131
|
+
def unencoded_parameters
|
132
|
+
params = fields.dup
|
133
|
+
# remove all encoded params from exported fields
|
134
|
+
ENCODED_PARAMS.each{ |param| params.delete(mappings[param]) }
|
135
|
+
# remove all special characters from each field value
|
136
|
+
params = params.collect{|name, value| [name, remove_special_characters(value)] }
|
137
|
+
Hash[params]
|
138
|
+
end
|
139
|
+
|
140
|
+
def add_failure_url
|
141
|
+
if fields[mappings[:failure_url]].nil?
|
142
|
+
add_field(mappings[:failure_url], fields[mappings[:return_url]])
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def update_address(address_type, params)
|
147
|
+
params = params.dup
|
148
|
+
address = params[:address1]
|
149
|
+
address = "#{address} #{params[:address2]}" if params[:address2].present?
|
150
|
+
address = "#{params[:company]} #{address}" if params[:company].present?
|
151
|
+
params[:address1] = address
|
152
|
+
|
153
|
+
params[:phone] = normalize_phone_number(params[:phone])
|
154
|
+
add_land_line_phone_for(address_type, params)
|
155
|
+
|
156
|
+
if address_type == :shipping_address
|
157
|
+
shipping_name = full_name(params) || fields[mappings[:customer][:name]]
|
158
|
+
add_field(mappings[:shipping_address][:name], shipping_name)
|
159
|
+
end
|
160
|
+
params
|
161
|
+
end
|
162
|
+
|
163
|
+
# Split a single phone number into the country code, area code and local number as best as possible
|
164
|
+
def add_land_line_phone_for(address_type, params)
|
165
|
+
address_field = address_type == :billing_address ? 'custPhoneNo' : 'deliveryPhNo'
|
166
|
+
|
167
|
+
if params.has_key?(:phone2)
|
168
|
+
phone = normalize_phone_number(params[:phone2])
|
169
|
+
phone_country_code, phone_area_code, phone_number = nil
|
170
|
+
|
171
|
+
if params[:country] == 'IN' && phone =~ /(91)? *(\d{3}) *(\d{4,})$/
|
172
|
+
phone_country_code, phone_area_code, phone_number = $1, $2, $3
|
173
|
+
else
|
174
|
+
numbers = phone.split(' ')
|
175
|
+
case numbers.size
|
176
|
+
when 3
|
177
|
+
phone_country_code, phone_area_code, phone_number = numbers
|
178
|
+
when 2
|
179
|
+
phone_area_code, phone_number = numbers
|
180
|
+
else
|
181
|
+
phone =~ /(\d{3})(\d+)$/
|
182
|
+
phone_area_code, phone_number = $1, $2
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
add_field("#{address_field}1", phone_country_code || phone_code_for_country(params[:country]) || '91')
|
187
|
+
add_field("#{address_field}2", phone_area_code)
|
188
|
+
add_field("#{address_field}3", phone_number)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def normalize_phone_number(phone)
|
193
|
+
phone.gsub(/[^\d ]+/, '') if phone
|
194
|
+
end
|
195
|
+
|
196
|
+
# Special characters are NOT allowed while posting transaction parameters on DirecPay system
|
197
|
+
def remove_special_characters(string)
|
198
|
+
string.gsub(/[~"'&#%]/, '-')
|
199
|
+
end
|
200
|
+
|
201
|
+
def encode_value(value)
|
202
|
+
encoded = Base64.strict_encode64(value)
|
203
|
+
string_to_encode = encoded[0, 1] + "T" + encoded[1, encoded.length]
|
204
|
+
Base64.strict_encode64(string_to_encode)
|
205
|
+
end
|
206
|
+
|
207
|
+
def decode_value(value)
|
208
|
+
decoded = Base64.decode64(value)
|
209
|
+
string_to_decode = decoded[0, 1] + decoded[2, decoded.length]
|
210
|
+
Base64.decode64(string_to_decode)
|
211
|
+
end
|
212
|
+
|
213
|
+
def phone_code_for_country(country)
|
214
|
+
PHONE_CODES[country]
|
215
|
+
end
|
216
|
+
|
217
|
+
def full_name(params)
|
218
|
+
return if params[:name].blank? && params[:first_name].blank? && params[:last_name].blank?
|
219
|
+
|
220
|
+
params[:name] || "#{params[:first_name]} #{params[:last_name]}"
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
class Notification < OffsitePayments::Notification
|
225
|
+
RESPONSE_PARAMS = ['DirecPay Reference ID', 'Flag', 'Country', 'Currency', 'Other Details', 'Merchant Order No', 'Amount']
|
226
|
+
|
227
|
+
def acknowledge(authcode = nil)
|
228
|
+
true
|
229
|
+
end
|
230
|
+
|
231
|
+
def complete?
|
232
|
+
status == 'Completed' || status == 'Pending'
|
233
|
+
end
|
234
|
+
|
235
|
+
def status
|
236
|
+
case params['Flag']
|
237
|
+
when 'SUCCESS'
|
238
|
+
'Completed'
|
239
|
+
when 'PENDING'
|
240
|
+
'Pending'
|
241
|
+
when 'FAIL'
|
242
|
+
'Failed'
|
243
|
+
else
|
244
|
+
'Error'
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
def item_id
|
249
|
+
params['Merchant Order No']
|
250
|
+
end
|
251
|
+
|
252
|
+
def transaction_id
|
253
|
+
params['DirecPay Reference ID']
|
254
|
+
end
|
255
|
+
|
256
|
+
# the money amount we received in X.2 decimal
|
257
|
+
def gross
|
258
|
+
params['Amount']
|
259
|
+
end
|
260
|
+
|
261
|
+
def currency
|
262
|
+
params['Currency']
|
263
|
+
end
|
264
|
+
|
265
|
+
def country
|
266
|
+
params['Country']
|
267
|
+
end
|
268
|
+
|
269
|
+
def other_details
|
270
|
+
params['Other Details']
|
271
|
+
end
|
272
|
+
|
273
|
+
def test?
|
274
|
+
false
|
275
|
+
end
|
276
|
+
|
277
|
+
# Take the posted data and move the relevant data into a hash
|
278
|
+
def parse(post)
|
279
|
+
super
|
280
|
+
|
281
|
+
values = params['responseparams'].to_s.split('|')
|
282
|
+
response_params = values.size == 3 ? ['DirecPay Reference ID', 'Flag', 'Error message'] : RESPONSE_PARAMS
|
283
|
+
response_params.each_with_index do |name, index|
|
284
|
+
params[name] = values[index]
|
285
|
+
end
|
286
|
+
params
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
class Return < OffsitePayments::Return
|
291
|
+
def initialize(post_data, options = {})
|
292
|
+
@notification = Notification.new(treat_failure_as_pending(post_data), options)
|
293
|
+
end
|
294
|
+
|
295
|
+
def success?
|
296
|
+
notification.complete?
|
297
|
+
end
|
298
|
+
|
299
|
+
def message
|
300
|
+
notification.status
|
301
|
+
end
|
302
|
+
|
303
|
+
private
|
304
|
+
|
305
|
+
# Work around the issue that the initial return from DirecPay is always either SUCCESS or FAIL, there is no PENDING
|
306
|
+
def treat_failure_as_pending(post_data)
|
307
|
+
post_data.sub(/FAIL/, 'PENDING')
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
class Status
|
312
|
+
include ActiveMerchant::PostsData
|
313
|
+
|
314
|
+
STATUS_TEST_URL = 'https://test.direcpay.com/direcpay/secure/dpMerchantTransaction.jsp'
|
315
|
+
STATUS_LIVE_URL = 'https://www.timesofmoney.com/direcpay/secure/dpPullMerchAtrnDtls.jsp'
|
316
|
+
|
317
|
+
attr_reader :account, :options
|
318
|
+
|
319
|
+
def initialize(account, options = {})
|
320
|
+
@account, @options = account, options
|
321
|
+
end
|
322
|
+
|
323
|
+
# Use this method to manually request a status update to the provided notification_url
|
324
|
+
def update(authorization, notification_url)
|
325
|
+
url = test? ? STATUS_TEST_URL : STATUS_LIVE_URL
|
326
|
+
parameters = [ authorization, account, notification_url ]
|
327
|
+
data = ActiveMerchant::PostData.new
|
328
|
+
data[:requestparams] = parameters.join('|')
|
329
|
+
|
330
|
+
response = ssl_get("#{url}?#{data.to_post_data}")
|
331
|
+
end
|
332
|
+
|
333
|
+
def test?
|
334
|
+
OffsitePayments.mode == :test || options[:test]
|
335
|
+
end
|
336
|
+
end
|
337
|
+
end
|
338
|
+
end
|
339
|
+
end
|