activemerchant 1.42.5 → 1.42.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.
- checksums.yaml +8 -8
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/CHANGELOG +23 -0
- data/CONTRIBUTORS +12 -0
- data/README.md +4 -1
- data/lib/active_merchant.rb +5 -1
- data/lib/active_merchant/billing/gateways/authorize_net.rb +1 -11
- data/lib/active_merchant/billing/gateways/balanced.rb +23 -6
- data/lib/active_merchant/billing/gateways/cecabank.rb +225 -0
- data/lib/active_merchant/billing/gateways/conekta.rb +4 -3
- data/lib/active_merchant/billing/gateways/litle.rb +50 -44
- data/lib/active_merchant/billing/gateways/maxipago.rb +190 -0
- data/lib/active_merchant/billing/gateways/ogone.rb +2 -1
- data/lib/active_merchant/billing/gateways/openpay.rb +200 -0
- data/lib/active_merchant/billing/gateways/orbital.rb +24 -3
- data/lib/active_merchant/billing/gateways/orbital/cvv_result.rb +34 -0
- data/lib/active_merchant/billing/gateways/paymill.rb +2 -2
- data/lib/active_merchant/billing/gateways/sage_pay.rb +6 -1
- data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +2 -1
- data/lib/active_merchant/billing/gateways/wirecard.rb +5 -1
- data/lib/active_merchant/billing/integrations/alipay.rb +18 -0
- data/lib/active_merchant/billing/integrations/alipay/helper.rb +34 -0
- data/lib/active_merchant/billing/integrations/alipay/notification.rb +101 -0
- data/lib/active_merchant/billing/integrations/paydollar.rb +59 -0
- data/lib/active_merchant/billing/integrations/paydollar/helper.rb +41 -0
- data/lib/active_merchant/billing/integrations/paydollar/notification.rb +60 -0
- data/lib/active_merchant/billing/integrations/paydollar/return.rb +15 -0
- data/lib/active_merchant/version.rb +1 -1
- metadata +13 -2
- metadata.gz.sig +0 -0
@@ -1,5 +1,6 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/orbital/orbital_soft_descriptors'
|
2
2
|
require File.dirname(__FILE__) + '/orbital/avs_result'
|
3
|
+
require File.dirname(__FILE__) + '/orbital/cvv_result'
|
3
4
|
require "rexml/document"
|
4
5
|
|
5
6
|
module ActiveMerchant #:nodoc:
|
@@ -40,7 +41,27 @@ module ActiveMerchant #:nodoc:
|
|
40
41
|
"Interface-Version" => "Ruby|ActiveMerchant|Proprietary Gateway"
|
41
42
|
}
|
42
43
|
|
43
|
-
SUCCESS
|
44
|
+
SUCCESS = '0'
|
45
|
+
|
46
|
+
APPROVED = [
|
47
|
+
'00', # Approved
|
48
|
+
'08', # Approved authorization, honor with ID
|
49
|
+
'11', # Approved authorization, VIP approval
|
50
|
+
'24', # Validated
|
51
|
+
'26', # Pre-noted
|
52
|
+
'27', # No reason to decline
|
53
|
+
'28', # Received and stored
|
54
|
+
'29', # Provided authorization
|
55
|
+
'31', # Request received
|
56
|
+
'32', # BIN alert
|
57
|
+
'34', # Approved for partial
|
58
|
+
'91', # Approved low fraud
|
59
|
+
'92', # Approved medium fraud
|
60
|
+
'93', # Approved high fraud
|
61
|
+
'94', # Approved fraud service unavailable
|
62
|
+
'E7', # Stored
|
63
|
+
'PA' # Partial approval
|
64
|
+
]
|
44
65
|
|
45
66
|
class_attribute :secondary_test_url, :secondary_live_url
|
46
67
|
|
@@ -439,7 +460,7 @@ module ActiveMerchant #:nodoc:
|
|
439
460
|
:authorization => authorization_string(response[:tx_ref_num], response[:order_id]),
|
440
461
|
:test => self.test?,
|
441
462
|
:avs_result => OrbitalGateway::AVSResult.new(response[:avs_resp_code]),
|
442
|
-
:cvv_result => response[:cvv2_resp_code]
|
463
|
+
:cvv_result => OrbitalGateway::CVVResult.new(response[:cvv2_resp_code])
|
443
464
|
}
|
444
465
|
)
|
445
466
|
end
|
@@ -459,7 +480,7 @@ module ActiveMerchant #:nodoc:
|
|
459
480
|
response[:profile_proc_status] == SUCCESS
|
460
481
|
else
|
461
482
|
response[:proc_status] == SUCCESS &&
|
462
|
-
response[:resp_code]
|
483
|
+
APPROVED.include?(response[:resp_code])
|
463
484
|
end
|
464
485
|
end
|
465
486
|
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class OrbitalGateway < Gateway
|
4
|
+
# Unfortunately, Orbital uses their own special codes for CVV responses
|
5
|
+
# that are different than the standard codes defined in
|
6
|
+
# <tt>ActiveMerchant::Billing::CVVResult</tt>.
|
7
|
+
#
|
8
|
+
# This class encapsulates the response codes shown on page 255 of their spec:
|
9
|
+
# http://download.chasepaymentech.com/docs/orbital/orbital_gateway_xml_specification.pdf
|
10
|
+
#
|
11
|
+
class CVVResult < ActiveMerchant::Billing::CVVResult
|
12
|
+
MESSAGES = {
|
13
|
+
'M' => 'Match',
|
14
|
+
'N' => 'No match',
|
15
|
+
'P' => 'Not processed',
|
16
|
+
'S' => 'Should have been present',
|
17
|
+
'U' => 'Unsupported by issuer/Issuer unable to process request',
|
18
|
+
'I' => 'Invalid',
|
19
|
+
'Y' => 'Invalid',
|
20
|
+
'' => 'Not applicable'
|
21
|
+
}
|
22
|
+
|
23
|
+
def self.messages
|
24
|
+
MESSAGES
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize(code)
|
28
|
+
@code = code.blank? ? '' : code.upcase
|
29
|
+
@message = MESSAGES[@code]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -2,8 +2,8 @@ module ActiveMerchant #:nodoc:
|
|
2
2
|
module Billing #:nodoc:
|
3
3
|
class PaymillGateway < Gateway
|
4
4
|
self.supported_countries = %w(AD AT BE BG CH CY CZ DE DK EE ES FI FO FR GB
|
5
|
-
GI GR HU IE IL IS IT LI LT LU LV MT
|
6
|
-
PT RO SE SI SK TR VA)
|
5
|
+
GI GR HR HU IE IL IM IS IT LI LT LU LV MC MT
|
6
|
+
NL NO PL PT RO SE SI SK TR VA)
|
7
7
|
|
8
8
|
self.supported_cardtypes = [:visa, :master]
|
9
9
|
self.homepage_url = 'https://paymill.com'
|
@@ -191,7 +191,7 @@ module ActiveMerchant #:nodoc:
|
|
191
191
|
|
192
192
|
def add_invoice(post, options)
|
193
193
|
add_pair(post, :VendorTxCode, sanitize_order_id(options[:order_id]), :required => true)
|
194
|
-
add_pair(post, :Description, options[:description] || options[:order_id])
|
194
|
+
add_pair(post, :Description, truncate_description(options[:description] || options[:order_id]))
|
195
195
|
end
|
196
196
|
|
197
197
|
def add_credit_card(post, credit_card)
|
@@ -213,6 +213,11 @@ module ActiveMerchant #:nodoc:
|
|
213
213
|
order_id.to_s.gsub(/[^-a-zA-Z0-9._]/, '')
|
214
214
|
end
|
215
215
|
|
216
|
+
def truncate_description(description)
|
217
|
+
return nil unless description
|
218
|
+
description[0, 100]
|
219
|
+
end
|
220
|
+
|
216
221
|
def map_card_type(credit_card)
|
217
222
|
raise ArgumentError, "The credit card type must be provided" if card_brand(credit_card).blank?
|
218
223
|
|
@@ -124,7 +124,8 @@ module ActiveMerchant #:nodoc:
|
|
124
124
|
:merchant_receipt => [:boolean, 'MerchReceipt'],
|
125
125
|
:merchant_email => [:boolean, 'MerchReceiptEmail'],
|
126
126
|
:merchant_template => [:boolean, 'MerchReceiptName'],
|
127
|
-
:
|
127
|
+
:recurring => [:boolean, 'isRecurring'],
|
128
|
+
:verification_value => [:string, 'CardCode'],
|
128
129
|
:software => [:string, 'Software']
|
129
130
|
} #:nodoc:
|
130
131
|
|
@@ -71,6 +71,10 @@ module ActiveMerchant #:nodoc:
|
|
71
71
|
|
72
72
|
|
73
73
|
private
|
74
|
+
def clean_description(description)
|
75
|
+
description.to_s.slice(0,32).encode("US-ASCII", invalid: :replace, undef: :replace, replace: '?')
|
76
|
+
end
|
77
|
+
|
74
78
|
def prepare_options_hash(options)
|
75
79
|
result = @options.merge(options)
|
76
80
|
setup_address_hash!(result)
|
@@ -139,7 +143,7 @@ module ActiveMerchant #:nodoc:
|
|
139
143
|
options[:order_id] ||= generate_unique_id
|
140
144
|
|
141
145
|
xml.tag! "FNC_CC_#{options[:action].to_s.upcase}" do
|
142
|
-
xml.tag! 'FunctionID', options[:description]
|
146
|
+
xml.tag! 'FunctionID', clean_description(options[:description])
|
143
147
|
xml.tag! 'CC_TRANSACTION' do
|
144
148
|
xml.tag! 'TransactionID', options[:order_id]
|
145
149
|
case options[:action]
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/alipay/helper.rb'
|
2
|
+
require File.dirname(__FILE__) + '/alipay/notification.rb'
|
3
|
+
|
4
|
+
module ActiveMerchant #:nodoc:
|
5
|
+
module Billing #:nodoc:
|
6
|
+
module Integrations #:nodoc:
|
7
|
+
module Alipay
|
8
|
+
|
9
|
+
mattr_accessor :service_url
|
10
|
+
self.service_url = 'https://www.example.com'
|
11
|
+
|
12
|
+
def self.notification(post)
|
13
|
+
Notification.new(post)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
module Integrations #:nodoc:
|
4
|
+
module Alipay
|
5
|
+
class Helper < ActiveMerchant::Billing::Integrations::Helper
|
6
|
+
# Replace with the real mapping
|
7
|
+
mapping :account, ''
|
8
|
+
mapping :amount, ''
|
9
|
+
|
10
|
+
mapping :order, ''
|
11
|
+
|
12
|
+
mapping :customer, :first_name => '',
|
13
|
+
:last_name => '',
|
14
|
+
:email => '',
|
15
|
+
:phone => ''
|
16
|
+
|
17
|
+
mapping :billing_address, :city => '',
|
18
|
+
:address1 => '',
|
19
|
+
:address2 => '',
|
20
|
+
:state => '',
|
21
|
+
:zip => '',
|
22
|
+
:country => ''
|
23
|
+
|
24
|
+
mapping :notify_url, ''
|
25
|
+
mapping :return_url, ''
|
26
|
+
mapping :cancel_return_url, ''
|
27
|
+
mapping :description, ''
|
28
|
+
mapping :tax, ''
|
29
|
+
mapping :shipping, ''
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
|
3
|
+
module ActiveMerchant #:nodoc:
|
4
|
+
module Billing #:nodoc:
|
5
|
+
module Integrations #:nodoc:
|
6
|
+
module Alipay
|
7
|
+
class Notification < ActiveMerchant::Billing::Integrations::Notification
|
8
|
+
def complete?
|
9
|
+
params['']
|
10
|
+
end
|
11
|
+
|
12
|
+
def item_id
|
13
|
+
params['']
|
14
|
+
end
|
15
|
+
|
16
|
+
def transaction_id
|
17
|
+
params['']
|
18
|
+
end
|
19
|
+
|
20
|
+
# When was this payment received by the client.
|
21
|
+
def received_at
|
22
|
+
params['']
|
23
|
+
end
|
24
|
+
|
25
|
+
def payer_email
|
26
|
+
params['']
|
27
|
+
end
|
28
|
+
|
29
|
+
def receiver_email
|
30
|
+
params['']
|
31
|
+
end
|
32
|
+
|
33
|
+
def security_key
|
34
|
+
params['']
|
35
|
+
end
|
36
|
+
|
37
|
+
# the money amount we received in X.2 decimal.
|
38
|
+
def gross
|
39
|
+
params['']
|
40
|
+
end
|
41
|
+
|
42
|
+
# Was this a test transaction?
|
43
|
+
def test?
|
44
|
+
params[''] == 'test'
|
45
|
+
end
|
46
|
+
|
47
|
+
def status
|
48
|
+
params['']
|
49
|
+
end
|
50
|
+
|
51
|
+
# Acknowledge the transaction to Alipay. This method has to be called after a new
|
52
|
+
# apc arrives. Alipay will verify that all the information we received are correct and will return a
|
53
|
+
# ok or a fail.
|
54
|
+
#
|
55
|
+
# Example:
|
56
|
+
#
|
57
|
+
# def ipn
|
58
|
+
# notify = AlipayNotification.new(request.raw_post)
|
59
|
+
#
|
60
|
+
# if notify.acknowledge
|
61
|
+
# ... process order ... if notify.complete?
|
62
|
+
# else
|
63
|
+
# ... log possible hacking attempt ...
|
64
|
+
# end
|
65
|
+
def acknowledge(authcode = nil)
|
66
|
+
payload = raw
|
67
|
+
|
68
|
+
uri = URI.parse(Alipay.notification_confirmation_url)
|
69
|
+
|
70
|
+
request = Net::HTTP::Post.new(uri.path)
|
71
|
+
|
72
|
+
request['Content-Length'] = "#{payload.size}"
|
73
|
+
request['User-Agent'] = "Active Merchant -- http://home.leetsoft.com/am"
|
74
|
+
request['Content-Type'] = "application/x-www-form-urlencoded"
|
75
|
+
|
76
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
77
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE unless @ssl_strict
|
78
|
+
http.use_ssl = true
|
79
|
+
|
80
|
+
response = http.request(request, payload)
|
81
|
+
|
82
|
+
# Replace with the appropriate codes
|
83
|
+
raise StandardError.new("Faulty Alipay result: #{response.body}") unless ["AUTHORISED", "DECLINED"].include?(response.body)
|
84
|
+
response.body == "AUTHORISED"
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
# Take the posted data and move the relevant data into a hash
|
90
|
+
def parse(post)
|
91
|
+
@raw = post.to_s
|
92
|
+
for line in @raw.split('&')
|
93
|
+
key, value = *line.scan( %r{^([A-Za-z0-9_.-]+)\=(.*)$} ).flatten
|
94
|
+
params[key] = CGI.unescape(value.to_s) if key.present?
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/paydollar/helper.rb'
|
2
|
+
require File.dirname(__FILE__) + '/paydollar/notification.rb'
|
3
|
+
require File.dirname(__FILE__) + '/paydollar/return.rb'
|
4
|
+
|
5
|
+
module ActiveMerchant #:nodoc:
|
6
|
+
module Billing #:nodoc:
|
7
|
+
module Integrations #:nodoc:
|
8
|
+
module Paydollar
|
9
|
+
|
10
|
+
CURRENCY_MAP = {
|
11
|
+
'AED' => '784',
|
12
|
+
'AUD' => '036',
|
13
|
+
'BND' => '096',
|
14
|
+
'CAD' => '124',
|
15
|
+
'CNY' => '156',
|
16
|
+
'EUR' => '978',
|
17
|
+
'GBP' => '826',
|
18
|
+
'HKD' => '344',
|
19
|
+
'IDR' => '360',
|
20
|
+
'JPY' => '392',
|
21
|
+
'KRW' => '410',
|
22
|
+
'MOP' => '446',
|
23
|
+
'MYR' => '458',
|
24
|
+
'NZD' => '554',
|
25
|
+
'PHP' => '608',
|
26
|
+
'SAR' => '682',
|
27
|
+
'SGD' => '702',
|
28
|
+
'THB' => '764',
|
29
|
+
'TWD' => '901',
|
30
|
+
'USD' => '840',
|
31
|
+
}
|
32
|
+
|
33
|
+
def self.service_url
|
34
|
+
case ActiveMerchant::Billing::Base.integration_mode
|
35
|
+
when :production
|
36
|
+
'https://www.paydollar.com/b2c2/eng/payment/payForm.jsp'
|
37
|
+
when :test
|
38
|
+
'https://test.paydollar.com/b2cDemo/eng/payment/payForm.jsp'
|
39
|
+
else
|
40
|
+
raise StandardError, "Integration mode set to an invalid value: #{mode}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.notification(post, options = {})
|
45
|
+
Notification.new(post, options)
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.return(query_string, options = {})
|
49
|
+
Return.new(query_string, options)
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.sign(fields, secret)
|
53
|
+
Digest::SHA1.hexdigest(fields.push(secret).join('|'))
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
module Integrations #:nodoc:
|
4
|
+
module Paydollar
|
5
|
+
class Helper < ActiveMerchant::Billing::Integrations::Helper
|
6
|
+
|
7
|
+
def initialize(order, account, options = {})
|
8
|
+
super
|
9
|
+
add_field('payType', 'N') # normal sale and not just auth
|
10
|
+
@secret = options[:credential2]
|
11
|
+
end
|
12
|
+
|
13
|
+
def form_fields
|
14
|
+
@fields.merge('secureHash' => generate_secure_hash)
|
15
|
+
end
|
16
|
+
|
17
|
+
def generate_secure_hash
|
18
|
+
fields = [@fields[mappings[:account]],
|
19
|
+
@fields[mappings[:order]],
|
20
|
+
@fields[mappings[:currency]],
|
21
|
+
@fields[mappings[:amount]],
|
22
|
+
@fields['payType']]
|
23
|
+
Paydollar.sign(fields, @secret)
|
24
|
+
end
|
25
|
+
|
26
|
+
def currency=(currency_code)
|
27
|
+
add_field(mappings[:currency], CURRENCY_MAP[currency_code])
|
28
|
+
end
|
29
|
+
|
30
|
+
mapping :account, 'merchantId'
|
31
|
+
mapping :amount, 'amount'
|
32
|
+
mapping :order, 'orderRef'
|
33
|
+
mapping :currency, 'currCode'
|
34
|
+
mapping :return_url, 'successUrl'
|
35
|
+
mapping :cancel_return_url, ['cancelUrl','failUrl']
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
|
3
|
+
module ActiveMerchant #:nodoc:
|
4
|
+
module Billing #:nodoc:
|
5
|
+
module Integrations #:nodoc:
|
6
|
+
module Paydollar
|
7
|
+
|
8
|
+
class Notification < ActiveMerchant::Billing::Integrations::Notification
|
9
|
+
|
10
|
+
def complete?
|
11
|
+
status == 'Completed'
|
12
|
+
end
|
13
|
+
|
14
|
+
def item_id
|
15
|
+
@params['Ref']
|
16
|
+
end
|
17
|
+
|
18
|
+
def currency
|
19
|
+
CURRENCY_MAP.key(@params['Cur'])
|
20
|
+
end
|
21
|
+
|
22
|
+
def gross
|
23
|
+
@params['Amt']
|
24
|
+
end
|
25
|
+
|
26
|
+
def transaction_id
|
27
|
+
@params['PayRef']
|
28
|
+
end
|
29
|
+
|
30
|
+
def status
|
31
|
+
case @params['successcode']
|
32
|
+
when '0' then 'Completed'
|
33
|
+
else 'Failed'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def acknowledge(authcode = nil)
|
38
|
+
# paydollar supports multiple signature keys, therefore we need to check if any
|
39
|
+
# of their signatures matches ours
|
40
|
+
@params['secureHash'].split(',').include? generate_secure_hash
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
def generate_secure_hash
|
45
|
+
fields = [@params['src'],
|
46
|
+
@params['prc'],
|
47
|
+
@params['successcode'],
|
48
|
+
@params['Ref'],
|
49
|
+
@params['PayRef'],
|
50
|
+
@params['Cur'],
|
51
|
+
@params['Amt'],
|
52
|
+
@params['payerAuth']]
|
53
|
+
Paydollar.sign(fields, @options[:credential2])
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|