offsite_payments 2.3.0 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/lib/offsite_payments.rb +2 -0
- data/lib/offsite_payments/integrations/checkout_finland.rb +166 -0
- data/lib/offsite_payments/integrations/citrus.rb +3 -3
- data/lib/offsite_payments/integrations/easy_pay.rb +5 -1
- data/lib/offsite_payments/integrations/liqpay.rb +1 -1
- data/lib/offsite_payments/integrations/mollie_ideal.rb +1 -1
- data/lib/offsite_payments/integrations/pay_fast.rb +2 -2
- data/lib/offsite_payments/integrations/paydollar.rb +43 -13
- data/lib/offsite_payments/integrations/paytm.rb +168 -0
- data/lib/offsite_payments/integrations/payu_in.rb +3 -2
- data/lib/offsite_payments/integrations/platron.rb +1 -1
- data/lib/offsite_payments/integrations/realex_offsite.rb +3 -3
- data/lib/offsite_payments/integrations/robokassa.rb +4 -4
- data/lib/offsite_payments/integrations/sage_pay_form.rb +2 -2
- data/lib/offsite_payments/integrations/universal.rb +19 -8
- data/lib/offsite_payments/integrations/web_pay.rb +5 -1
- data/lib/offsite_payments/integrations/webmoney.rb +5 -1
- data/lib/offsite_payments/return.rb +2 -2
- data/lib/offsite_payments/version.rb +1 -1
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9f3751c70ad135fce78fe690b43bd5f14cbabd90
|
4
|
+
data.tar.gz: 6f1a39ec1021b73443533901f56110e91b943ad9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 63a6d6d932073822f7ac36ea377991e0f9af6ffd33cf3a0ae9662ffedd606af5625e5bb11052544d6d50c75e061c5e44243801ceb610e873398de7aee7e5aa69
|
7
|
+
data.tar.gz: 1197aa56f07ce913018dbde66b41186040a8c892657c1739079fe6cc194d990e753d6ef336a65bcb9fdded91367b4368e50fe6e20ce0124cfc2b037f7ee24efb
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Offsite Payments
|
2
|
-
[![Build Status](https://travis-ci.org/activemerchant/offsite_payments.
|
3
|
-
[![Code Climate](https://codeclimate.com/github/activemerchant/offsite_payments.
|
2
|
+
[![Build Status](https://travis-ci.org/activemerchant/offsite_payments.svg?branch=master)](https://travis-ci.org/activemerchant/offsite_payments)
|
3
|
+
[![Code Climate](https://codeclimate.com/github/activemerchant/offsite_payments/badges/gpa.svg)](https://codeclimate.com/github/activemerchant/offsite_payments)
|
4
4
|
|
5
5
|
Offsite Payments is an extraction from the ecommerce system [Shopify](http://www.shopify.com). Shopify's requirements for a simple and unified API to handle dozens of different offsite payment pages (often called hosted payment pages) with very different exposed APIs was the chief principle in designing the library.
|
6
6
|
|
data/lib/offsite_payments.rb
CHANGED
@@ -0,0 +1,166 @@
|
|
1
|
+
module OffsitePayments #:nodoc:
|
2
|
+
module Integrations #:nodoc:
|
3
|
+
module CheckoutFinland
|
4
|
+
|
5
|
+
mattr_accessor :service_url
|
6
|
+
self.service_url = 'https://payment.checkout.fi/'
|
7
|
+
|
8
|
+
def self.notification(post)
|
9
|
+
Notification.new(post)
|
10
|
+
end
|
11
|
+
|
12
|
+
class Helper < OffsitePayments::Helper
|
13
|
+
include ActiveUtils::PostsData
|
14
|
+
self.country_format = :alpha3
|
15
|
+
|
16
|
+
def initialize(order, account, options = {})
|
17
|
+
md5secret options.delete(:credential2)
|
18
|
+
super
|
19
|
+
|
20
|
+
# Add default fields
|
21
|
+
add_field("VERSION", "0001") # API version
|
22
|
+
add_field("ALGORITHM", "3") # Return MAC version (3 is HMAC-SHA256)
|
23
|
+
add_field("TYPE", "0")
|
24
|
+
add_field("DEVICE", "1") # Offsite payment by default
|
25
|
+
end
|
26
|
+
|
27
|
+
def md5secret(value)
|
28
|
+
@md5secret = value
|
29
|
+
end
|
30
|
+
|
31
|
+
# Add MAC to form fields
|
32
|
+
def form_fields
|
33
|
+
@fields.merge("MAC" => generate_md5string)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Apply parameter length limitations recommended by Checkout.fi
|
37
|
+
def add_field(name, value)
|
38
|
+
return if name.blank? || value.blank?
|
39
|
+
@fields[name.to_s] = check_param_length(name_to_s, value.to_s)
|
40
|
+
end
|
41
|
+
|
42
|
+
# API parameter length limitations specified by Checkout.fi
|
43
|
+
# Parameters longer than this cause the HTTP POST to fail
|
44
|
+
def check_param_length(name, value)
|
45
|
+
# Soft limitations, fields that can be clipped
|
46
|
+
max_length_substring = { "FIRSTNAME" => 40, "FAMILYNAME" => 40, "ADDRESS" => 40, "POSTCODE" => 14, "POSTOFFICE" => 18, "MESSAGE" => 1000, "EMAIL" => 200, "PHONE" => 30 }
|
47
|
+
# Hard limitations, fields that cannot be clipped
|
48
|
+
max_length_exception = { "RETURN" => 300, "CANCEL" => 300, "REJECT" => 300, "DELAYED" => 300, "STAMP" => 20, "AMOUNT" => 8, "REFERENCE" => 20, "CONTENT" => 2, "LANGUAGE" => 2, "MERCHANT" => 20, "COUNTRY" => 3, "CURRENCY" => 3, "DELIVERY_DATE" => 8 }
|
49
|
+
if max_length_substring.include? name
|
50
|
+
return value.to_s[0, max_length_substring[name]]
|
51
|
+
end
|
52
|
+
if max_length_exception.include? name
|
53
|
+
if value.to_s.length > max_length_exception[name]
|
54
|
+
raise ArgumentError, "Field #{name} length #{value.length} is longer than permitted by provider API. Maximum length #{max_length_exception[name]}."
|
55
|
+
else
|
56
|
+
return value
|
57
|
+
end
|
58
|
+
end
|
59
|
+
value
|
60
|
+
end
|
61
|
+
|
62
|
+
# Calculate MAC
|
63
|
+
def generate_md5string
|
64
|
+
fields = [@fields["VERSION"], @fields["STAMP"], @fields["AMOUNT"], @fields["REFERENCE"],
|
65
|
+
@fields["MESSAGE"], @fields["LANGUAGE"], @fields["MERCHANT"], @fields["RETURN"],
|
66
|
+
@fields["CANCEL"], @fields["REJECT"], @fields["DELAYED"], @fields["COUNTRY"],
|
67
|
+
@fields["CURRENCY"], @fields["DEVICE"], @fields["CONTENT"], @fields["TYPE"],
|
68
|
+
@fields["ALGORITHM"], @fields["DELIVERY_DATE"], @fields["FIRSTNAME"], @fields["FAMILYNAME"],
|
69
|
+
@fields["ADDRESS"], @fields["POSTCODE"], @fields["POSTOFFICE"], @md5secret]
|
70
|
+
fields = fields.join("+")
|
71
|
+
Digest::MD5.hexdigest(fields).upcase
|
72
|
+
end
|
73
|
+
|
74
|
+
# Mappings
|
75
|
+
mapping :order, 'STAMP' # Unique order number for each payment
|
76
|
+
mapping :account, 'MERCHANT' # Checkout Merchant ID
|
77
|
+
mapping :amount, 'AMOUNT' # Amount in cents
|
78
|
+
mapping :reference, 'REFERENCE' # Reference for bank statement
|
79
|
+
mapping :language, 'LANGUAGE' # "FI" / "SE" / "EN"
|
80
|
+
mapping :currency, 'CURRENCY' # "EUR" currently only
|
81
|
+
mapping :device, 'DEVICE' # "1" = HTML / "10" = XML
|
82
|
+
mapping :content, 'CONTENT' # "1" = NORMAL "2" = ADULT CONTENT
|
83
|
+
mapping :delivery_date, 'DELIVERY_DATE' # "YYYYMMDD"
|
84
|
+
mapping :description, 'MESSAGE' # Description of the order
|
85
|
+
|
86
|
+
# Optional customer data supported by API (not mandatory)
|
87
|
+
mapping :customer, :first_name => 'FIRSTNAME',
|
88
|
+
:last_name => 'FAMILYNAME',
|
89
|
+
:email => 'EMAIL',
|
90
|
+
:phone => 'PHONE'
|
91
|
+
|
92
|
+
# Optional fields supported by API (not mandatory)
|
93
|
+
mapping :billing_address, :city => 'POSTOFFICE',
|
94
|
+
:address1 => 'ADDRESS',
|
95
|
+
:zip => 'POSTCODE',
|
96
|
+
:country => 'COUNTRY'
|
97
|
+
|
98
|
+
mapping :notify_url, 'DELAYED' # Delayed payment URL (mandatory)
|
99
|
+
mapping :reject_url, 'REJECT' # Rejected payment URL (mandatory)
|
100
|
+
mapping :return_url, 'RETURN' # Payment URL (optional)
|
101
|
+
mapping :cancel_return_url, 'CANCEL' # Cancelled payment URL (optional)
|
102
|
+
end
|
103
|
+
|
104
|
+
class Notification < OffsitePayments::Notification
|
105
|
+
# Payment can be market complete with the following status codes
|
106
|
+
def complete?
|
107
|
+
["2", "5", "6", "8", "9", "10"].include? params["STATUS"]
|
108
|
+
end
|
109
|
+
|
110
|
+
# Did the customer choose delayed payment method
|
111
|
+
def delayed?
|
112
|
+
params['STATUS'] == "3"
|
113
|
+
end
|
114
|
+
|
115
|
+
# Did the customer cancel the payment
|
116
|
+
def cancelled?
|
117
|
+
params['STATUS'] == "-1"
|
118
|
+
end
|
119
|
+
|
120
|
+
# Payment requires manual activation (fraud check etc)
|
121
|
+
def activation?
|
122
|
+
params['STATUS'] == "7"
|
123
|
+
end
|
124
|
+
|
125
|
+
# Reference specified by the client when sending payment
|
126
|
+
def reference
|
127
|
+
params['REFERENCE']
|
128
|
+
end
|
129
|
+
|
130
|
+
# Unique ID assigned by Checkout
|
131
|
+
def transaction_id
|
132
|
+
params['PAYMENT']
|
133
|
+
end
|
134
|
+
|
135
|
+
# Unique ID assigned by customer
|
136
|
+
def stamp
|
137
|
+
params['STAMP']
|
138
|
+
end
|
139
|
+
|
140
|
+
# Returned Message Authentication Code
|
141
|
+
def mac
|
142
|
+
params['MAC']
|
143
|
+
end
|
144
|
+
|
145
|
+
def status
|
146
|
+
params['STATUS']
|
147
|
+
end
|
148
|
+
|
149
|
+
# Verify authenticity of returned data
|
150
|
+
def acknowledge(authcode = nil)
|
151
|
+
return_authcode = [params["VERSION"], params["STAMP"], params["REFERENCE"], params["PAYMENT"], params["STATUS"], params["ALGORITHM"]].join("&")
|
152
|
+
OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), authcode, return_authcode).upcase == params["MAC"]
|
153
|
+
end
|
154
|
+
|
155
|
+
private
|
156
|
+
|
157
|
+
# Take the posted data and move the data into params
|
158
|
+
def parse(post)
|
159
|
+
post.each do |key, value|
|
160
|
+
params[key] = value
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
@@ -97,7 +97,7 @@ module OffsitePayments
|
|
97
97
|
end
|
98
98
|
|
99
99
|
def amount_ok?( order_amount )
|
100
|
-
|
100
|
+
amount.to_d == order_amount
|
101
101
|
end
|
102
102
|
|
103
103
|
def item_id
|
@@ -120,7 +120,7 @@ module OffsitePayments
|
|
120
120
|
end
|
121
121
|
|
122
122
|
def amount
|
123
|
-
gross
|
123
|
+
Money.from_amount(BigDecimal.new(gross), currency)
|
124
124
|
end
|
125
125
|
|
126
126
|
def transaction_id
|
@@ -182,7 +182,7 @@ module OffsitePayments
|
|
182
182
|
end
|
183
183
|
|
184
184
|
def checksum_ok?
|
185
|
-
fields = [invoice, transaction_status, amount
|
185
|
+
fields = [invoice, transaction_status, sprintf('%.2f', amount), transaction_id, issuerrefno, authidcode, customer_first_name, customer_last_name, pgrespcode, customer_address[:zip]].join
|
186
186
|
|
187
187
|
unless Citrus.checksum(@secret_key, fields ) == checksum
|
188
188
|
@message = 'checksum mismatch...'
|
@@ -101,7 +101,7 @@ module OffsitePayments #:nodoc:
|
|
101
101
|
end
|
102
102
|
|
103
103
|
def amount
|
104
|
-
BigDecimal.new(gross)
|
104
|
+
Money.from_amount(BigDecimal.new(gross), currency)
|
105
105
|
end
|
106
106
|
|
107
107
|
def item_id
|
@@ -131,6 +131,10 @@ module OffsitePayments #:nodoc:
|
|
131
131
|
def success_response(*args)
|
132
132
|
{ :nothing => true }
|
133
133
|
end
|
134
|
+
|
135
|
+
def currency
|
136
|
+
'BYR'
|
137
|
+
end
|
134
138
|
end
|
135
139
|
end
|
136
140
|
end
|
@@ -7,7 +7,7 @@ module OffsitePayments #:nodoc:
|
|
7
7
|
self.live_issuers = [
|
8
8
|
["ABN AMRO", "ideal_ABNANL2A"],
|
9
9
|
["ASN Bank", "ideal_ASNBNL21"],
|
10
|
-
["
|
10
|
+
["Bunq", "ideal_BUNQNL2A"],
|
11
11
|
["ING", "ideal_INGBNL2A"],
|
12
12
|
["Knab", "ideal_KNABNL2H"],
|
13
13
|
["Rabobank", "ideal_RABONL2U"],
|
@@ -212,7 +212,7 @@ module OffsitePayments #:nodoc:
|
|
212
212
|
|
213
213
|
# The net amount credited to the receiver's account.
|
214
214
|
def amount
|
215
|
-
params['amount_net']
|
215
|
+
Money.from_amount(BigDecimal.new(params['amount_net']), currency)
|
216
216
|
end
|
217
217
|
|
218
218
|
# The name of the item being charged for.
|
@@ -226,7 +226,7 @@ module OffsitePayments #:nodoc:
|
|
226
226
|
end
|
227
227
|
|
228
228
|
def currency
|
229
|
-
|
229
|
+
'ZAR'
|
230
230
|
end
|
231
231
|
|
232
232
|
# Generated hash depends on params order so use OrderedHash instead of Hash
|
@@ -2,26 +2,56 @@ module OffsitePayments #:nodoc:
|
|
2
2
|
module Integrations #:nodoc:
|
3
3
|
module Paydollar
|
4
4
|
CURRENCY_MAP = {
|
5
|
-
'
|
6
|
-
'
|
7
|
-
'
|
8
|
-
'CAD' => '124',
|
5
|
+
'HKD' => '344',
|
6
|
+
'USD' => '840',
|
7
|
+
'SGD' => '702',
|
9
8
|
'CNY' => '156',
|
9
|
+
'JPY' => '392',
|
10
|
+
'TWD' => '901',
|
11
|
+
'AUD' => '036',
|
10
12
|
'EUR' => '978',
|
11
13
|
'GBP' => '826',
|
12
|
-
'
|
13
|
-
'IDR' => '360',
|
14
|
-
'JPY' => '392',
|
15
|
-
'KRW' => '410',
|
14
|
+
'CAD' => '124',
|
16
15
|
'MOP' => '446',
|
16
|
+
'PHP' => '608',
|
17
|
+
'THB' => '764',
|
17
18
|
'MYR' => '458',
|
19
|
+
'IDR' => '360',
|
20
|
+
'KRW' => '410',
|
21
|
+
'BND' => '096',
|
18
22
|
'NZD' => '554',
|
19
|
-
'PHP' => '608',
|
20
23
|
'SAR' => '682',
|
21
|
-
'
|
22
|
-
'
|
23
|
-
'
|
24
|
-
'
|
24
|
+
'AED' => '784',
|
25
|
+
'BRL' => '986',
|
26
|
+
'INR' => '356',
|
27
|
+
'TRY' => '949',
|
28
|
+
'ZAR' => '710',
|
29
|
+
'VND' => '704',
|
30
|
+
'DKK' => '208',
|
31
|
+
'ILS' => '376',
|
32
|
+
'NOK' => '578',
|
33
|
+
'RUB' => '643',
|
34
|
+
'SEK' => '752',
|
35
|
+
'CHF' => '756',
|
36
|
+
'ARS' => '032',
|
37
|
+
'CLP' => '152',
|
38
|
+
'COP' => '170',
|
39
|
+
'CZK' => '203',
|
40
|
+
'EGP' => '818',
|
41
|
+
'HUF' => '348',
|
42
|
+
'KZT' => '398',
|
43
|
+
'LBP' => '422',
|
44
|
+
'MXN' => '484',
|
45
|
+
'NGN' => '566',
|
46
|
+
'PKR' => '586',
|
47
|
+
'PEN' => '604',
|
48
|
+
'PLN' => '985',
|
49
|
+
'QAR' => '634',
|
50
|
+
'RON' => '946',
|
51
|
+
'UAH' => '980',
|
52
|
+
'VEF' => '937',
|
53
|
+
'LKR' => '144',
|
54
|
+
'KWD' => '414',
|
25
55
|
}
|
26
56
|
|
27
57
|
def self.service_url
|
@@ -0,0 +1,168 @@
|
|
1
|
+
module OffsitePayments #:nodoc:
|
2
|
+
module Integrations #:nodoc:
|
3
|
+
module Paytm
|
4
|
+
|
5
|
+
def self.notification(post, options = {})
|
6
|
+
Notification.new(post, options)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.return(query_string, options = {})
|
10
|
+
Return.new(query_string, options)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.sign(fields, key)
|
14
|
+
Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest::SHA256.new, key, fields.sort.join)).delete("\n")
|
15
|
+
end
|
16
|
+
|
17
|
+
class Helper < OffsitePayments::Helper
|
18
|
+
CURRENCY_SPECIAL_MINOR_UNITS = {
|
19
|
+
'BIF' => 0,
|
20
|
+
'BYR' => 0,
|
21
|
+
'CLF' => 0,
|
22
|
+
'CLP' => 0,
|
23
|
+
'CVE' => 0,
|
24
|
+
'DJF' => 0,
|
25
|
+
'GNF' => 0,
|
26
|
+
'HUF' => 0,
|
27
|
+
'ISK' => 0,
|
28
|
+
'JPY' => 0,
|
29
|
+
'KMF' => 0,
|
30
|
+
'KRW' => 0,
|
31
|
+
'PYG' => 0,
|
32
|
+
'RWF' => 0,
|
33
|
+
'UGX' => 0,
|
34
|
+
'UYI' => 0,
|
35
|
+
'VND' => 0,
|
36
|
+
'VUV' => 0,
|
37
|
+
'XAF' => 0,
|
38
|
+
'XOF' => 0,
|
39
|
+
'XPF' => 0,
|
40
|
+
'BHD' => 3,
|
41
|
+
'IQD' => 3,
|
42
|
+
'JOD' => 3,
|
43
|
+
'KWD' => 3,
|
44
|
+
'LYD' => 3,
|
45
|
+
'OMR' => 3,
|
46
|
+
'TND' => 3,
|
47
|
+
'COU' => 4
|
48
|
+
}
|
49
|
+
|
50
|
+
def initialize(order, account, options = {})
|
51
|
+
mid_param = { MID: account }.to_query
|
52
|
+
@forward_url_stag = "https://pguat.paytm.com/oltp-web/genericPT?#{mid_param}"
|
53
|
+
@forward_url_prod = "https://secure.paytm.in/oltp-web/genericPT?#{mid_param}"
|
54
|
+
@key = options[:credential2]
|
55
|
+
@currency = options[:currency]
|
56
|
+
|
57
|
+
super
|
58
|
+
add_field 'x_test', @test.to_s
|
59
|
+
end
|
60
|
+
|
61
|
+
def credential_based_url
|
62
|
+
@test ? @forward_url_stag : @forward_url_prod
|
63
|
+
end
|
64
|
+
|
65
|
+
def form_fields
|
66
|
+
sign_fields
|
67
|
+
end
|
68
|
+
|
69
|
+
def amount=(amount)
|
70
|
+
add_field 'x_amount', format_amount(amount, @currency)
|
71
|
+
end
|
72
|
+
|
73
|
+
def sign_fields
|
74
|
+
@fields.merge!('x_signature' => generate_signature)
|
75
|
+
end
|
76
|
+
|
77
|
+
def generate_signature
|
78
|
+
Paytm.sign(@fields, @key)
|
79
|
+
end
|
80
|
+
|
81
|
+
mapping :account, 'x_account_id'
|
82
|
+
mapping :currency, 'x_currency'
|
83
|
+
mapping :order, 'x_reference'
|
84
|
+
mapping :description, 'x_description'
|
85
|
+
mapping :invoice, 'x_invoice'
|
86
|
+
mapping :credential3, 'x_credential3'
|
87
|
+
mapping :credential4, 'x_credential4'
|
88
|
+
|
89
|
+
mapping :customer, :email => 'x_customer_email',
|
90
|
+
:phone => 'x_customer_phone'
|
91
|
+
|
92
|
+
mapping :notify_url, 'x_url_callback'
|
93
|
+
mapping :return_url, 'x_url_complete'
|
94
|
+
mapping :cancel_return_url, 'x_url_cancel'
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
def format_amount(amount, currency)
|
99
|
+
units = CURRENCY_SPECIAL_MINOR_UNITS[currency] || 2
|
100
|
+
sprintf("%.#{units}f", amount)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
class Notification < OffsitePayments::Notification
|
105
|
+
def initialize(post, options = {})
|
106
|
+
super
|
107
|
+
@key = options[:credential2]
|
108
|
+
end
|
109
|
+
|
110
|
+
def acknowledge(authcode = nil)
|
111
|
+
signature = @params['x_signature']
|
112
|
+
signature == generate_signature ? true : false
|
113
|
+
end
|
114
|
+
|
115
|
+
def item_id
|
116
|
+
@params['x_reference']
|
117
|
+
end
|
118
|
+
|
119
|
+
def currency
|
120
|
+
@params['x_currency']
|
121
|
+
end
|
122
|
+
|
123
|
+
def gross
|
124
|
+
@params['x_amount']
|
125
|
+
end
|
126
|
+
|
127
|
+
def transaction_id
|
128
|
+
@params['x_gateway_reference']
|
129
|
+
end
|
130
|
+
|
131
|
+
def status
|
132
|
+
result = @params['x_result']
|
133
|
+
result && result.capitalize
|
134
|
+
end
|
135
|
+
|
136
|
+
def message
|
137
|
+
@params['x_message']
|
138
|
+
end
|
139
|
+
|
140
|
+
def test?
|
141
|
+
@params['x_test'] == 'true'
|
142
|
+
end
|
143
|
+
|
144
|
+
private
|
145
|
+
|
146
|
+
def generate_signature
|
147
|
+
signature_params = @params.select { |k| k.start_with? 'x_' }.reject { |k| k == 'x_signature' }
|
148
|
+
Paytm.sign(signature_params, @key)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
class Return < OffsitePayments::Return
|
153
|
+
def initialize(query_string, options = {})
|
154
|
+
super
|
155
|
+
@notification = Notification.new(query_string, options)
|
156
|
+
end
|
157
|
+
|
158
|
+
def success?
|
159
|
+
@notification.acknowledge
|
160
|
+
end
|
161
|
+
|
162
|
+
def message
|
163
|
+
@notification.message
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
@@ -84,8 +84,9 @@ module OffsitePayments #:nodoc:
|
|
84
84
|
end
|
85
85
|
|
86
86
|
def sanitize_fields
|
87
|
-
['
|
88
|
-
|
87
|
+
@fields['phone'] = @fields['phone'].gsub(/[^0-9]/, '') if @fields['phone']
|
88
|
+
['address1', 'address2', 'city', 'state', 'country', 'productinfo', 'email'].each do |field|
|
89
|
+
@fields[field] = @fields[field].gsub(/[^a-zA-Z0-9\-_@\/\s.]/, '') if @fields[field]
|
89
90
|
end
|
90
91
|
end
|
91
92
|
|
@@ -71,20 +71,20 @@ module OffsitePayments #:nodoc:
|
|
71
71
|
end
|
72
72
|
|
73
73
|
# Realex accepts currency amounts as an integer in the lowest value
|
74
|
-
# e.g.
|
74
|
+
# e.g.
|
75
75
|
# format_amount(110.56, 'GBP')
|
76
76
|
# => 11056
|
77
77
|
def format_amount(amount, currency)
|
78
78
|
units = CURRENCY_SPECIAL_MINOR_UNITS[currency] || 2
|
79
79
|
multiple = 10**units
|
80
|
-
return (amount.
|
80
|
+
return ((amount || 0).to_d * multiple.to_d).to_i
|
81
81
|
end
|
82
82
|
|
83
83
|
# Realex returns currency amount as an integer
|
84
84
|
def format_amount_as_float(amount, currency)
|
85
85
|
units = CURRENCY_SPECIAL_MINOR_UNITS[currency] || 2
|
86
86
|
divisor = 10**units
|
87
|
-
return (amount.
|
87
|
+
return ((amount || 0).to_d / divisor.to_d)
|
88
88
|
end
|
89
89
|
|
90
90
|
def extract_digits(value)
|
@@ -103,10 +103,6 @@ module OffsitePayments #:nodoc:
|
|
103
103
|
true
|
104
104
|
end
|
105
105
|
|
106
|
-
def amount
|
107
|
-
BigDecimal.new(gross)
|
108
|
-
end
|
109
|
-
|
110
106
|
def item_id
|
111
107
|
params['InvId']
|
112
108
|
end
|
@@ -138,6 +134,10 @@ module OffsitePayments #:nodoc:
|
|
138
134
|
def success_response(*args)
|
139
135
|
"OK#{item_id}"
|
140
136
|
end
|
137
|
+
|
138
|
+
def currency
|
139
|
+
'RUB'
|
140
|
+
end
|
141
141
|
end
|
142
142
|
|
143
143
|
class Return < OffsitePayments::Return
|
@@ -160,8 +160,8 @@ module OffsitePayments #:nodoc:
|
|
160
160
|
parts = fields.map { |k, v| "#{k}=#{sanitize(k, v)}" unless v.nil? }.compact.shuffle
|
161
161
|
parts.unshift(sage_encrypt_salt(key.length, key.length * 2))
|
162
162
|
sage_encrypt(parts.join('&'), key)
|
163
|
-
rescue OpenSSL::Cipher::CipherError => e
|
164
|
-
if e.message == 'key length too short'
|
163
|
+
rescue OpenSSL::Cipher::CipherError, ArgumentError => e
|
164
|
+
if e.message == 'key length too short' || e.message == 'key must be 16 bytes'
|
165
165
|
raise ActionViewHelperError, 'Invalid encryption key.'
|
166
166
|
else
|
167
167
|
raise
|
@@ -73,14 +73,6 @@ module OffsitePayments #:nodoc:
|
|
73
73
|
add_field 'x_amount', format_amount(amount, @currency)
|
74
74
|
end
|
75
75
|
|
76
|
-
def shipping(amount)
|
77
|
-
add_field 'x_amount_shipping', format_amount(amount, @currency)
|
78
|
-
end
|
79
|
-
|
80
|
-
def tax(amount)
|
81
|
-
add_field 'x_amount_tax', format_amount(amount, @currency)
|
82
|
-
end
|
83
|
-
|
84
76
|
def sign_fields
|
85
77
|
@fields.merge!('x_signature' => generate_signature)
|
86
78
|
end
|
@@ -105,6 +97,17 @@ module OffsitePayments #:nodoc:
|
|
105
97
|
:email => 'x_customer_email',
|
106
98
|
:phone => 'x_customer_phone'
|
107
99
|
|
100
|
+
mapping :billing_address, :first_name => 'x_customer_billing_first_name',
|
101
|
+
:last_name => 'x_customer_billing_last_name',
|
102
|
+
:city => 'x_customer_billing_city',
|
103
|
+
:company => 'x_customer_billing_company',
|
104
|
+
:address1 => 'x_customer_billing_address1',
|
105
|
+
:address2 => 'x_customer_billing_address2',
|
106
|
+
:state => 'x_customer_billing_state',
|
107
|
+
:zip => 'x_customer_billing_zip',
|
108
|
+
:country => 'x_customer_billing_country',
|
109
|
+
:phone => 'x_customer_billing_phone'
|
110
|
+
|
108
111
|
mapping :shipping_address, :first_name => 'x_customer_shipping_first_name',
|
109
112
|
:last_name => 'x_customer_shipping_last_name',
|
110
113
|
:city => 'x_customer_shipping_city',
|
@@ -160,6 +163,10 @@ module OffsitePayments #:nodoc:
|
|
160
163
|
result && result.capitalize
|
161
164
|
end
|
162
165
|
|
166
|
+
def message
|
167
|
+
@params['x_message']
|
168
|
+
end
|
169
|
+
|
163
170
|
def test?
|
164
171
|
@params['x_test'] == 'true'
|
165
172
|
end
|
@@ -181,6 +188,10 @@ module OffsitePayments #:nodoc:
|
|
181
188
|
def success?
|
182
189
|
@notification.acknowledge
|
183
190
|
end
|
191
|
+
|
192
|
+
def message
|
193
|
+
@notification.message
|
194
|
+
end
|
184
195
|
end
|
185
196
|
end
|
186
197
|
end
|
@@ -150,7 +150,7 @@ module OffsitePayments #:nodoc:
|
|
150
150
|
end
|
151
151
|
|
152
152
|
def amount
|
153
|
-
BigDecimal.new(gross)
|
153
|
+
Money.from_amount(BigDecimal.new(gross), currency)
|
154
154
|
end
|
155
155
|
|
156
156
|
def item_id
|
@@ -180,6 +180,10 @@ module OffsitePayments #:nodoc:
|
|
180
180
|
def success_response(*args)
|
181
181
|
{:nothing => true}
|
182
182
|
end
|
183
|
+
|
184
|
+
def currency
|
185
|
+
params['currency_id']
|
186
|
+
end
|
183
187
|
end
|
184
188
|
end
|
185
189
|
end
|
@@ -83,7 +83,7 @@ module OffsitePayments #:nodoc:
|
|
83
83
|
end
|
84
84
|
|
85
85
|
def amount
|
86
|
-
BigDecimal.new(gross)
|
86
|
+
Money.from_amount(BigDecimal.new(gross), currency)
|
87
87
|
end
|
88
88
|
|
89
89
|
def key_present?
|
@@ -113,6 +113,10 @@ module OffsitePayments #:nodoc:
|
|
113
113
|
def success_response(*args)
|
114
114
|
{:nothing => true}
|
115
115
|
end
|
116
|
+
|
117
|
+
def currency
|
118
|
+
'RUB'
|
119
|
+
end
|
116
120
|
end
|
117
121
|
end
|
118
122
|
end
|
@@ -25,9 +25,9 @@ module OffsitePayments #:nodoc:
|
|
25
25
|
return {} if query_string.blank?
|
26
26
|
|
27
27
|
query_string.split('&').inject({}) do |memo, chunk|
|
28
|
-
next if chunk.empty?
|
28
|
+
next memo if chunk.empty?
|
29
29
|
key, value = chunk.split('=', 2)
|
30
|
-
next if key.empty?
|
30
|
+
next memo if key.empty?
|
31
31
|
value = value.nil? ? nil : CGI.unescape(value)
|
32
32
|
memo[CGI.unescape(key)] = value
|
33
33
|
memo
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: offsite_payments
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tobias Luetke
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-05-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -98,14 +98,14 @@ dependencies:
|
|
98
98
|
requirements:
|
99
99
|
- - "~>"
|
100
100
|
- !ruby/object:Gem::Version
|
101
|
-
version: '1.
|
101
|
+
version: '1.6'
|
102
102
|
type: :runtime
|
103
103
|
prerelease: false
|
104
104
|
version_requirements: !ruby/object:Gem::Requirement
|
105
105
|
requirements:
|
106
106
|
- - "~>"
|
107
107
|
- !ruby/object:Gem::Version
|
108
|
-
version: '1.
|
108
|
+
version: '1.6'
|
109
109
|
- !ruby/object:Gem::Dependency
|
110
110
|
name: actionpack
|
111
111
|
requirement: !ruby/object:Gem::Requirement
|
@@ -216,6 +216,7 @@ files:
|
|
216
216
|
- lib/offsite_payments/integrations/authorize_net_sim.rb
|
217
217
|
- lib/offsite_payments/integrations/bit_pay.rb
|
218
218
|
- lib/offsite_payments/integrations/bogus.rb
|
219
|
+
- lib/offsite_payments/integrations/checkout_finland.rb
|
219
220
|
- lib/offsite_payments/integrations/chronopay.rb
|
220
221
|
- lib/offsite_payments/integrations/citrus.rb
|
221
222
|
- lib/offsite_payments/integrations/coinbase.rb
|
@@ -248,6 +249,7 @@ files:
|
|
248
249
|
- lib/offsite_payments/integrations/paypal.rb
|
249
250
|
- lib/offsite_payments/integrations/paypal_payments_advanced.rb
|
250
251
|
- lib/offsite_payments/integrations/paysbuy.rb
|
252
|
+
- lib/offsite_payments/integrations/paytm.rb
|
251
253
|
- lib/offsite_payments/integrations/payu_in.rb
|
252
254
|
- lib/offsite_payments/integrations/payu_in_paisa.rb
|
253
255
|
- lib/offsite_payments/integrations/platron.rb
|
@@ -288,7 +290,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
288
290
|
version: '0'
|
289
291
|
requirements: []
|
290
292
|
rubyforge_project:
|
291
|
-
rubygems_version: 2.2
|
293
|
+
rubygems_version: 2.5.2
|
292
294
|
signing_key:
|
293
295
|
specification_version: 4
|
294
296
|
summary: Framework and tools for dealing with offsite (hosted) payment pages.
|