aktivemerchant 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/CHANGELOG +1596 -0
- data/CONTRIBUTORS +511 -0
- data/MIT-LICENSE +20 -0
- data/README.md +18 -0
- data/lib/active_merchant.rb +108 -0
- data/lib/active_merchant/billing.rb +13 -0
- data/lib/active_merchant/billing/apple_pay_payment_token.rb +22 -0
- data/lib/active_merchant/billing/avs_result.rb +98 -0
- data/lib/active_merchant/billing/base.rb +72 -0
- data/lib/active_merchant/billing/check.rb +76 -0
- data/lib/active_merchant/billing/compatibility.rb +120 -0
- data/lib/active_merchant/billing/credit_card.rb +352 -0
- data/lib/active_merchant/billing/credit_card_formatting.rb +24 -0
- data/lib/active_merchant/billing/credit_card_methods.rb +160 -0
- data/lib/active_merchant/billing/cvv_result.rb +38 -0
- data/lib/active_merchant/billing/gateway.rb +268 -0
- data/lib/active_merchant/billing/gateways.rb +17 -0
- data/lib/active_merchant/billing/gateways/adyen.rb +209 -0
- data/lib/active_merchant/billing/gateways/alfabank.rb +117 -0
- data/lib/active_merchant/billing/gateways/app55.rb +176 -0
- data/lib/active_merchant/billing/gateways/authorize_net.rb +419 -0
- data/lib/active_merchant/billing/gateways/authorize_net_arb.rb +417 -0
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +976 -0
- data/lib/active_merchant/billing/gateways/balanced.rb +256 -0
- data/lib/active_merchant/billing/gateways/bank_frick.rb +225 -0
- data/lib/active_merchant/billing/gateways/banwire.rb +105 -0
- data/lib/active_merchant/billing/gateways/barclays_epdq.rb +314 -0
- data/lib/active_merchant/billing/gateways/barclays_epdq_extra_plus.rb +15 -0
- data/lib/active_merchant/billing/gateways/be2bill.rb +131 -0
- data/lib/active_merchant/billing/gateways/beanstream.rb +188 -0
- data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +393 -0
- data/lib/active_merchant/billing/gateways/beanstream_interac.rb +54 -0
- data/lib/active_merchant/billing/gateways/blue_pay.rb +506 -0
- data/lib/active_merchant/billing/gateways/bogus.rb +140 -0
- data/lib/active_merchant/billing/gateways/borgun.rb +210 -0
- data/lib/active_merchant/billing/gateways/braintree.rb +19 -0
- data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +9 -0
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +515 -0
- data/lib/active_merchant/billing/gateways/braintree_orange.rb +20 -0
- data/lib/active_merchant/billing/gateways/bridge_pay.rb +189 -0
- data/lib/active_merchant/billing/gateways/card_save.rb +23 -0
- data/lib/active_merchant/billing/gateways/card_stream.rb +220 -0
- data/lib/active_merchant/billing/gateways/cashnet.rb +191 -0
- data/lib/active_merchant/billing/gateways/cc5.rb +201 -0
- data/lib/active_merchant/billing/gateways/cecabank.rb +229 -0
- data/lib/active_merchant/billing/gateways/certo_direct.rb +278 -0
- data/lib/active_merchant/billing/gateways/checkout.rb +213 -0
- data/lib/active_merchant/billing/gateways/commercegate.rb +143 -0
- data/lib/active_merchant/billing/gateways/conekta.rb +209 -0
- data/lib/active_merchant/billing/gateways/cyber_source.rb +709 -0
- data/lib/active_merchant/billing/gateways/data_cash.rb +600 -0
- data/lib/active_merchant/billing/gateways/efsnet.rb +219 -0
- data/lib/active_merchant/billing/gateways/elavon.rb +348 -0
- data/lib/active_merchant/billing/gateways/epay.rb +275 -0
- data/lib/active_merchant/billing/gateways/evo_ca.rb +308 -0
- data/lib/active_merchant/billing/gateways/eway.rb +214 -0
- data/lib/active_merchant/billing/gateways/eway_managed.rb +291 -0
- data/lib/active_merchant/billing/gateways/eway_rapid.rb +524 -0
- data/lib/active_merchant/billing/gateways/exact.rb +218 -0
- data/lib/active_merchant/billing/gateways/fat_zebra.rb +173 -0
- data/lib/active_merchant/billing/gateways/federated_canada.rb +160 -0
- data/lib/active_merchant/billing/gateways/finansbank.rb +23 -0
- data/lib/active_merchant/billing/gateways/first_giving.rb +143 -0
- data/lib/active_merchant/billing/gateways/first_pay.rb +160 -0
- data/lib/active_merchant/billing/gateways/firstdata_e4.rb +355 -0
- data/lib/active_merchant/billing/gateways/garanti.rb +257 -0
- data/lib/active_merchant/billing/gateways/global_transport.rb +183 -0
- data/lib/active_merchant/billing/gateways/hdfc.rb +207 -0
- data/lib/active_merchant/billing/gateways/hps.rb +288 -0
- data/lib/active_merchant/billing/gateways/iats_payments.rb +251 -0
- data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +246 -0
- data/lib/active_merchant/billing/gateways/ideal/ideal_rabobank.pem +13 -0
- data/lib/active_merchant/billing/gateways/ideal/ideal_response.rb +29 -0
- data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +66 -0
- data/lib/active_merchant/billing/gateways/inspire.rb +213 -0
- data/lib/active_merchant/billing/gateways/instapay.rb +163 -0
- data/lib/active_merchant/billing/gateways/iridium.rb +457 -0
- data/lib/active_merchant/billing/gateways/itransact.rb +448 -0
- data/lib/active_merchant/billing/gateways/jetpay.rb +275 -0
- data/lib/active_merchant/billing/gateways/linkpoint.rb +438 -0
- data/lib/active_merchant/billing/gateways/litle.rb +346 -0
- data/lib/active_merchant/billing/gateways/maxipago.rb +197 -0
- data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +170 -0
- data/lib/active_merchant/billing/gateways/merchant_one.rb +114 -0
- data/lib/active_merchant/billing/gateways/merchant_ware.rb +319 -0
- data/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb +268 -0
- data/lib/active_merchant/billing/gateways/merchant_warrior.rb +195 -0
- data/lib/active_merchant/billing/gateways/mercury.rb +333 -0
- data/lib/active_merchant/billing/gateways/metrics_global.rb +303 -0
- data/lib/active_merchant/billing/gateways/migs.rb +265 -0
- data/lib/active_merchant/billing/gateways/migs/migs_codes.rb +100 -0
- data/lib/active_merchant/billing/gateways/modern_payments.rb +37 -0
- data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +219 -0
- data/lib/active_merchant/billing/gateways/moneris.rb +309 -0
- data/lib/active_merchant/billing/gateways/moneris_us.rb +291 -0
- data/lib/active_merchant/billing/gateways/money_movers.rb +152 -0
- data/lib/active_merchant/billing/gateways/nab_transact.rb +280 -0
- data/lib/active_merchant/billing/gateways/net_registry.rb +198 -0
- data/lib/active_merchant/billing/gateways/netaxept.rb +181 -0
- data/lib/active_merchant/billing/gateways/netbilling.rb +190 -0
- data/lib/active_merchant/billing/gateways/netpay.rb +223 -0
- data/lib/active_merchant/billing/gateways/network_merchants.rb +242 -0
- data/lib/active_merchant/billing/gateways/nmi.rb +256 -0
- data/lib/active_merchant/billing/gateways/ogone.rb +435 -0
- data/lib/active_merchant/billing/gateways/openpay.rb +194 -0
- data/lib/active_merchant/billing/gateways/optimal_payment.rb +313 -0
- data/lib/active_merchant/billing/gateways/orbital.rb +803 -0
- data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +47 -0
- data/lib/active_merchant/billing/gateways/pac_net_raven.rb +207 -0
- data/lib/active_merchant/billing/gateways/pago_facil.rb +122 -0
- data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +261 -0
- data/lib/active_merchant/billing/gateways/pay_junction.rb +390 -0
- data/lib/active_merchant/billing/gateways/pay_secure.rb +112 -0
- data/lib/active_merchant/billing/gateways/pay_u_latam.rb +462 -0
- data/lib/active_merchant/billing/gateways/paybox_direct.rb +188 -0
- data/lib/active_merchant/billing/gateways/payex.rb +412 -0
- data/lib/active_merchant/billing/gateways/payflow.rb +304 -0
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +209 -0
- data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +39 -0
- data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
- data/lib/active_merchant/billing/gateways/payflow_express.rb +224 -0
- data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +15 -0
- data/lib/active_merchant/billing/gateways/payflow_uk.rb +21 -0
- data/lib/active_merchant/billing/gateways/payment_express.rb +353 -0
- data/lib/active_merchant/billing/gateways/paymill.rb +281 -0
- data/lib/active_merchant/billing/gateways/paypal.rb +117 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +670 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +65 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_recurring_api.rb +262 -0
- data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
- data/lib/active_merchant/billing/gateways/paypal_digital_goods.rb +44 -0
- data/lib/active_merchant/billing/gateways/paypal_express.rb +264 -0
- data/lib/active_merchant/billing/gateways/paypal_express_common.rb +30 -0
- data/lib/active_merchant/billing/gateways/payscout.rb +162 -0
- data/lib/active_merchant/billing/gateways/paystation.rb +199 -0
- data/lib/active_merchant/billing/gateways/payway.rb +207 -0
- data/lib/active_merchant/billing/gateways/pin.rb +197 -0
- data/lib/active_merchant/billing/gateways/plugnpay.rb +283 -0
- data/lib/active_merchant/billing/gateways/psigate.rb +216 -0
- data/lib/active_merchant/billing/gateways/psl_card.rb +303 -0
- data/lib/active_merchant/billing/gateways/qbms.rb +292 -0
- data/lib/active_merchant/billing/gateways/quantum.rb +276 -0
- data/lib/active_merchant/billing/gateways/quickpay.rb +367 -0
- data/lib/active_merchant/billing/gateways/realex.rb +298 -0
- data/lib/active_merchant/billing/gateways/redsys.rb +391 -0
- data/lib/active_merchant/billing/gateways/sage.rb +175 -0
- data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +87 -0
- data/lib/active_merchant/billing/gateways/sage/sage_core.rb +114 -0
- data/lib/active_merchant/billing/gateways/sage/sage_vault.rb +149 -0
- data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +102 -0
- data/lib/active_merchant/billing/gateways/sage_pay.rb +398 -0
- data/lib/active_merchant/billing/gateways/sallie_mae.rb +143 -0
- data/lib/active_merchant/billing/gateways/secure_net.rb +252 -0
- data/lib/active_merchant/billing/gateways/secure_pay.rb +201 -0
- data/lib/active_merchant/billing/gateways/secure_pay_au.rb +281 -0
- data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +105 -0
- data/lib/active_merchant/billing/gateways/skip_jack.rb +452 -0
- data/lib/active_merchant/billing/gateways/smart_ps.rb +283 -0
- data/lib/active_merchant/billing/gateways/so_easy_pay.rb +194 -0
- data/lib/active_merchant/billing/gateways/spreedly_core.rb +247 -0
- data/lib/active_merchant/billing/gateways/stripe.rb +411 -0
- data/lib/active_merchant/billing/gateways/swipe_checkout.rb +157 -0
- data/lib/active_merchant/billing/gateways/tns.rb +227 -0
- data/lib/active_merchant/billing/gateways/trans_first.rb +126 -0
- data/lib/active_merchant/billing/gateways/transax.rb +23 -0
- data/lib/active_merchant/billing/gateways/transnational.rb +10 -0
- data/lib/active_merchant/billing/gateways/trust_commerce.rb +416 -0
- data/lib/active_merchant/billing/gateways/usa_epay.rb +25 -0
- data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +1516 -0
- data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +254 -0
- data/lib/active_merchant/billing/gateways/verifi.rb +225 -0
- data/lib/active_merchant/billing/gateways/viaklix.rb +183 -0
- data/lib/active_merchant/billing/gateways/vindicia.rb +385 -0
- data/lib/active_merchant/billing/gateways/webpay.rb +97 -0
- data/lib/active_merchant/billing/gateways/wepay.rb +189 -0
- data/lib/active_merchant/billing/gateways/wirecard.rb +421 -0
- data/lib/active_merchant/billing/gateways/worldpay.rb +331 -0
- data/lib/active_merchant/billing/gateways/worldpay_us.rb +181 -0
- data/lib/active_merchant/billing/model.rb +30 -0
- data/lib/active_merchant/billing/payment_token.rb +21 -0
- data/lib/active_merchant/billing/rails.rb +3 -0
- data/lib/active_merchant/billing/response.rb +91 -0
- data/lib/active_merchant/country.rb +332 -0
- data/lib/active_merchant/empty.rb +20 -0
- data/lib/active_merchant/errors.rb +29 -0
- data/lib/active_merchant/offsite_payments_shim.rb +19 -0
- data/lib/active_merchant/version.rb +3 -0
- data/lib/activemerchant.rb +1 -0
- data/lib/support/gateway_support.rb +71 -0
- data/lib/support/outbound_hosts.rb +25 -0
- data/lib/support/ssl_verify.rb +93 -0
- metadata +400 -0
@@ -0,0 +1,47 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class OrbitalSoftDescriptors < Model
|
4
|
+
PHONE_FORMAT_1 = /\A\d{3}-\d{3}-\d{4}\z/
|
5
|
+
PHONE_FORMAT_2 = /\A\d{3}-\w{7}\z/
|
6
|
+
|
7
|
+
# ==== Tampa PNS Soft Descriptors
|
8
|
+
# The support for Soft Descriptors via the PNS Host is only for customers processing through Chase
|
9
|
+
# Paymentech Canada.
|
10
|
+
|
11
|
+
# Unlike Salem, the only value that gets passed on the cardholder statement is the Merchant Name field.
|
12
|
+
# And for these customers, it is a maximum of 25 bytes of data.
|
13
|
+
#
|
14
|
+
# All other Soft Descriptor fields can optionally be sent, but will not be submitted to the settlement host
|
15
|
+
# and will not display on the cardholder statement.
|
16
|
+
|
17
|
+
attr_accessor :merchant_name, :product_description, :merchant_city, :merchant_phone, :merchant_url, :merchant_email
|
18
|
+
|
19
|
+
def initialize(options = {})
|
20
|
+
self.merchant_name = options[:merchant_name]
|
21
|
+
self.merchant_city = options[:merchant_city]
|
22
|
+
self.merchant_phone = options[:merchant_phone]
|
23
|
+
self.merchant_url = options[:merchant_url]
|
24
|
+
self.merchant_email = options[:merchant_email]
|
25
|
+
end
|
26
|
+
|
27
|
+
def validate
|
28
|
+
errors = []
|
29
|
+
|
30
|
+
errors << [:merchant_name, "is required"] if self.merchant_name.blank?
|
31
|
+
errors << [:merchant_name, "is required to be 25 bytes or less"] if self.merchant_name.bytesize > 25
|
32
|
+
|
33
|
+
if(!empty?(self.merchant_phone) && !self.merchant_phone.match(PHONE_FORMAT_1) && !self.merchant_phone.match(PHONE_FORMAT_2))
|
34
|
+
errors << [:merchant_phone, "is required to follow \"NNN-NNN-NNNN\" or \"NNN-AAAAAAA\" format"]
|
35
|
+
end
|
36
|
+
|
37
|
+
[:merchant_email, :merchant_url].each do |attr|
|
38
|
+
unless self.send(attr).blank?
|
39
|
+
errors << [attr, "is required to be 13 bytes or less"] if(self.send(attr).bytesize > 13)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
errors_hash(errors)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,207 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class PacNetRavenGateway < Gateway
|
4
|
+
|
5
|
+
AVS_ADDRESS_CODES = {
|
6
|
+
'avs_address_unavailable' => 'X',
|
7
|
+
'avs_address_not_checked' => 'X',
|
8
|
+
'avs_address_matched' => 'Y',
|
9
|
+
'avs_address_not_matched' => 'N',
|
10
|
+
'avs_address_partial_match' => 'N'
|
11
|
+
}
|
12
|
+
|
13
|
+
AVS_POSTAL_CODES = {
|
14
|
+
'avs_postal_unavailable' => 'X',
|
15
|
+
'avs_postal_not_checked' => 'X',
|
16
|
+
'avs_postal_matched' => 'Y',
|
17
|
+
'avs_postal_not_matched' => 'N',
|
18
|
+
'avs_postal_partial_match' => 'N'
|
19
|
+
}
|
20
|
+
|
21
|
+
CVV2_CODES = {
|
22
|
+
'cvv2_matched' => 'Y',
|
23
|
+
'cvv2_not_matched' => 'N',
|
24
|
+
'cvv2_unavailable' => 'X',
|
25
|
+
'cvv2_not_checked' => 'X'
|
26
|
+
}
|
27
|
+
|
28
|
+
self.test_url = 'https://demo.deepcovelabs.com/realtime/'
|
29
|
+
self.live_url = 'https://raven.pacnetservices.com/realtime/'
|
30
|
+
|
31
|
+
self.supported_countries = ['US']
|
32
|
+
self.supported_cardtypes = [:visa, :master]
|
33
|
+
self.money_format = :cents
|
34
|
+
self.default_currency = 'USD'
|
35
|
+
self.homepage_url = 'http://www.pacnetservices.com/'
|
36
|
+
self.display_name = 'Raven PacNet'
|
37
|
+
|
38
|
+
def initialize(options = {})
|
39
|
+
requires!(options, :user, :secret, :prn)
|
40
|
+
super
|
41
|
+
end
|
42
|
+
|
43
|
+
def authorize(money, creditcard, options = {})
|
44
|
+
post = {}
|
45
|
+
add_creditcard(post, creditcard)
|
46
|
+
add_currency_code(post, money, options)
|
47
|
+
add_address(post, options)
|
48
|
+
post['PRN'] = @options[:prn]
|
49
|
+
|
50
|
+
commit('cc_preauth', money, post)
|
51
|
+
end
|
52
|
+
|
53
|
+
def purchase(money, creditcard, options = {})
|
54
|
+
post = {}
|
55
|
+
add_currency_code(post, money, options)
|
56
|
+
add_creditcard(post, creditcard)
|
57
|
+
add_address(post, options)
|
58
|
+
post['PRN'] = @options[:prn]
|
59
|
+
|
60
|
+
commit('cc_debit', money, post)
|
61
|
+
end
|
62
|
+
|
63
|
+
def void(authorization, options = {})
|
64
|
+
post = {}
|
65
|
+
post['TrackingNumber'] = authorization
|
66
|
+
post['PymtType'] = options[:pymt_type] || 'cc_debit'
|
67
|
+
|
68
|
+
commit('void', nil, post)
|
69
|
+
end
|
70
|
+
|
71
|
+
def capture(money, authorization, options = {})
|
72
|
+
post = {}
|
73
|
+
post['PreauthNumber'] = authorization
|
74
|
+
post['PRN'] = @options[:prn]
|
75
|
+
add_currency_code(post, money, options)
|
76
|
+
|
77
|
+
commit('cc_settle', money, post)
|
78
|
+
end
|
79
|
+
|
80
|
+
def refund(money, template_number, options = {})
|
81
|
+
post = {}
|
82
|
+
post['PRN'] = @options[:prn]
|
83
|
+
post['TemplateNumber'] = template_number
|
84
|
+
add_currency_code(post, money, options)
|
85
|
+
|
86
|
+
commit('cc_refund', money, post)
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
def add_creditcard(post, creditcard)
|
92
|
+
post['CardNumber'] = creditcard.number
|
93
|
+
post['Expiry'] = expdate(creditcard)
|
94
|
+
post['CVV2'] = creditcard.verification_value if creditcard.verification_value
|
95
|
+
end
|
96
|
+
|
97
|
+
def add_currency_code(post, money, options)
|
98
|
+
post['Currency'] = options[:currency] || currency(money)
|
99
|
+
end
|
100
|
+
|
101
|
+
def add_address(post, options)
|
102
|
+
if address = options[:billing_address] || options[:address]
|
103
|
+
post['BillingStreetAddressLineOne'] = address[:address1].to_s
|
104
|
+
post['BillingStreetAddressLineFour'] = address[:address2].to_s
|
105
|
+
post['BillingPostalCode'] = address[:zip].to_s
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def parse(body)
|
110
|
+
Hash[body.split('&').map{|x| x.split('=').map{|y| CGI.unescape(y)}}]
|
111
|
+
end
|
112
|
+
|
113
|
+
def commit(action, money, parameters)
|
114
|
+
parameters['Amount'] = amount(money) unless action == 'void'
|
115
|
+
|
116
|
+
data = ssl_post url(action), post_data(action, parameters)
|
117
|
+
|
118
|
+
response = parse(data)
|
119
|
+
response[:action] = action
|
120
|
+
|
121
|
+
message = message_from(response)
|
122
|
+
|
123
|
+
test_mode = test? || message =~ /TESTMODE/
|
124
|
+
|
125
|
+
Response.new(success?(response), message, response,
|
126
|
+
:test => test_mode,
|
127
|
+
:authorization => response['TrackingNumber'],
|
128
|
+
:fraud_review => fraud_review?(response),
|
129
|
+
:avs_result => {
|
130
|
+
:postal_match => AVS_POSTAL_CODES[response['AVSPostalResponseCode']],
|
131
|
+
:street_match => AVS_ADDRESS_CODES[response['AVSAddressResponseCode']]
|
132
|
+
},
|
133
|
+
:cvv_result => CVV2_CODES[response['CVV2ResponseCode']]
|
134
|
+
)
|
135
|
+
end
|
136
|
+
|
137
|
+
def url(action)
|
138
|
+
(test? ? self.test_url : self.live_url) + endpoint(action)
|
139
|
+
end
|
140
|
+
|
141
|
+
def endpoint(action)
|
142
|
+
return 'void' if action == 'void'
|
143
|
+
'submit'
|
144
|
+
end
|
145
|
+
|
146
|
+
def fraud_review?(response)
|
147
|
+
false
|
148
|
+
end
|
149
|
+
|
150
|
+
def success?(response)
|
151
|
+
if %w(cc_settle cc_debit cc_preauth cc_refund).include?(response[:action])
|
152
|
+
!response['ApprovalCode'].nil? and response['ErrorCode'].nil? and response['Status'] == 'Approved'
|
153
|
+
elsif response[:action] = 'void'
|
154
|
+
!response['ApprovalCode'].nil? and response['ErrorCode'].nil? and response['Status'] == 'Voided'
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def message_from(response)
|
159
|
+
return response['Message'] if response['Message']
|
160
|
+
|
161
|
+
if response['Status'] == 'Approved'
|
162
|
+
"This transaction has been approved"
|
163
|
+
elsif response['Status'] == 'Declined'
|
164
|
+
"This transaction has been declined"
|
165
|
+
elsif response['Status'] == 'Voided'
|
166
|
+
"This transaction has been voided"
|
167
|
+
else
|
168
|
+
response['Status']
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def post_data(action, parameters = {})
|
173
|
+
post = {}
|
174
|
+
|
175
|
+
post['PymtType'] = action
|
176
|
+
post['RAPIVersion'] = '2'
|
177
|
+
post['UserName'] = @options[:user]
|
178
|
+
post['Timestamp'] = timestamp
|
179
|
+
post['RequestID'] = request_id
|
180
|
+
post['Signature'] = signature(action, post, parameters)
|
181
|
+
|
182
|
+
request = post.merge(parameters).collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&")
|
183
|
+
request
|
184
|
+
end
|
185
|
+
|
186
|
+
def timestamp
|
187
|
+
Time.now.strftime("%Y-%m-%dT%H:%M:%S.Z")
|
188
|
+
end
|
189
|
+
|
190
|
+
def request_id
|
191
|
+
SecureRandom.uuid
|
192
|
+
end
|
193
|
+
|
194
|
+
def signature(action, post, parameters = {})
|
195
|
+
string = if %w(cc_settle cc_debit cc_preauth cc_refund).include?(action)
|
196
|
+
post['UserName'] + post['Timestamp'] + post['RequestID'] + post['PymtType'] + parameters['Amount'].to_s + parameters['Currency']
|
197
|
+
elsif action == 'void'
|
198
|
+
post['UserName'] + post['Timestamp'] + post['RequestID'] + parameters['TrackingNumber']
|
199
|
+
else
|
200
|
+
post['UserName']
|
201
|
+
end
|
202
|
+
OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA1.new(@options[:secret]), @options[:secret], string)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
@@ -0,0 +1,122 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class PagoFacilGateway < Gateway
|
4
|
+
self.test_url = 'https://www.pagofacil.net/st/public/Wsrtransaccion/index/format/json?'
|
5
|
+
self.live_url = 'https://www.pagofacil.net/ws/public/Wsrtransaccion/index/format/json?'
|
6
|
+
|
7
|
+
self.supported_countries = ['MX']
|
8
|
+
self.default_currency = 'MXN'
|
9
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :jcb]
|
10
|
+
|
11
|
+
self.homepage_url = 'http://www.pagofacil.net/'
|
12
|
+
self.display_name = 'PagoFacil'
|
13
|
+
|
14
|
+
def initialize(options={})
|
15
|
+
requires!(options, :branch_id, :merchant_id, :service_id)
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
def purchase(money, credit_card, options={})
|
20
|
+
post = {}
|
21
|
+
add_invoice(post, money, options)
|
22
|
+
add_payment(post, credit_card)
|
23
|
+
add_address(post, options)
|
24
|
+
add_customer_data(post, options)
|
25
|
+
add_merchant_data(post)
|
26
|
+
|
27
|
+
commit(post)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def add_customer_data(post, options)
|
33
|
+
post[:email] = options[:email]
|
34
|
+
post[:celular] = options[:cellphone]
|
35
|
+
end
|
36
|
+
|
37
|
+
def add_address(post, options)
|
38
|
+
address = options.fetch(:billing_address, {})
|
39
|
+
post[:calleyNumero] = address[:address1]
|
40
|
+
post[:colonia] = address[:address2]
|
41
|
+
post[:municipio] = address[:city]
|
42
|
+
post[:estado] = address[:state]
|
43
|
+
post[:pais] = address[:country]
|
44
|
+
post[:telefono] = address[:phone]
|
45
|
+
post[:cp] = address[:zip]
|
46
|
+
end
|
47
|
+
|
48
|
+
def add_invoice(post, money, options)
|
49
|
+
post[:monto] = amount(money)
|
50
|
+
post[:idPedido] = options[:order_id]
|
51
|
+
add_currency(post, money, options)
|
52
|
+
end
|
53
|
+
|
54
|
+
def add_currency(post, money, options)
|
55
|
+
currency = options.fetch(:currency, currency(money))
|
56
|
+
unless currency == self.class.default_currency
|
57
|
+
post[:divisa] = currency
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def add_payment(post, credit_card)
|
62
|
+
post[:nombre] = credit_card.first_name
|
63
|
+
post[:apellidos] = credit_card.last_name
|
64
|
+
post[:numeroTarjeta] = credit_card.number
|
65
|
+
post[:cvt] = credit_card.verification_value
|
66
|
+
post[:mesExpiracion] = sprintf("%02d", credit_card.month)
|
67
|
+
post[:anyoExpiracion] = credit_card.year.to_s.slice(-2, 2)
|
68
|
+
end
|
69
|
+
|
70
|
+
def add_merchant_data(post)
|
71
|
+
post[:idSucursal] = options.fetch(:branch_id)
|
72
|
+
post[:idUsuario] = options.fetch(:merchant_id)
|
73
|
+
post[:idServicio] = options.fetch(:service_id)
|
74
|
+
end
|
75
|
+
|
76
|
+
def parse(body)
|
77
|
+
JSON.parse(body)["WebServices_Transacciones"]["transaccion"]
|
78
|
+
rescue JSON::ParserError
|
79
|
+
json_error(body)
|
80
|
+
end
|
81
|
+
|
82
|
+
def commit(parameters)
|
83
|
+
url = (test? ? test_url : live_url)
|
84
|
+
response = parse(ssl_post(url, post_data(parameters)))
|
85
|
+
Response.new(
|
86
|
+
success_from(response),
|
87
|
+
message_from(response),
|
88
|
+
response,
|
89
|
+
authorization: authorization_from(response),
|
90
|
+
test: test?
|
91
|
+
)
|
92
|
+
end
|
93
|
+
|
94
|
+
def success_from(response)
|
95
|
+
response["autorizado"] == "1" ||
|
96
|
+
response["autorizado"] == true
|
97
|
+
end
|
98
|
+
|
99
|
+
def message_from(response)
|
100
|
+
response["texto"]
|
101
|
+
end
|
102
|
+
|
103
|
+
def authorization_from(response)
|
104
|
+
response["autorizacion"]
|
105
|
+
end
|
106
|
+
|
107
|
+
def post_data(parameters = {})
|
108
|
+
{
|
109
|
+
method: 'transaccion',
|
110
|
+
data: parameters
|
111
|
+
}.to_query
|
112
|
+
end
|
113
|
+
|
114
|
+
def json_error(response)
|
115
|
+
{
|
116
|
+
"texto" => 'Invalid response received from the PagoFacil API.',
|
117
|
+
"raw_response" => response
|
118
|
+
}
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,261 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
|
3
|
+
module ActiveMerchant #:nodoc:
|
4
|
+
module Billing #:nodoc:
|
5
|
+
# This gateway accepts the following arguments:
|
6
|
+
# :login => your PayJunction username
|
7
|
+
# :password => your PayJunction pass
|
8
|
+
# Example use:
|
9
|
+
#
|
10
|
+
# gateway = ActiveMerchant::Billing::Base.gateway(:pay_gate_xml).new(
|
11
|
+
# :login => "my_account",
|
12
|
+
# :password => "my_pass"
|
13
|
+
# )
|
14
|
+
#
|
15
|
+
# # set up credit card obj as in main ActiveMerchant example
|
16
|
+
# creditcard = ActiveMerchant::Billing::CreditCard.new(
|
17
|
+
# :type => 'visa',
|
18
|
+
# :number => '4242424242424242',
|
19
|
+
# :month => 8,
|
20
|
+
# :year => 2009,
|
21
|
+
# :first_name => 'Bob',
|
22
|
+
# :last_name => 'Bobsen'
|
23
|
+
# )
|
24
|
+
#
|
25
|
+
# # run request
|
26
|
+
# response = gateway.purchase(1000, creditcard) # charge 10 dollars
|
27
|
+
#
|
28
|
+
# 1) Check whether the transaction was successful
|
29
|
+
#
|
30
|
+
# response.success?
|
31
|
+
#
|
32
|
+
# 2) Retrieve the message returned by PayJunction
|
33
|
+
#
|
34
|
+
# response.message
|
35
|
+
#
|
36
|
+
# 3) Retrieve the unique transaction ID returned by PayGateXML
|
37
|
+
#
|
38
|
+
# response.authorization
|
39
|
+
#
|
40
|
+
# This gateway has many other features which are not implemented here yet
|
41
|
+
# The basic setup here only supports auth/capture transactions.
|
42
|
+
#
|
43
|
+
# Test Transactions
|
44
|
+
#
|
45
|
+
# PayGateXML has a global test user/pass, but you can also sign up for your own.
|
46
|
+
# The class and the test come equipped with the global test creds
|
47
|
+
#
|
48
|
+
# Usage Details
|
49
|
+
#
|
50
|
+
# Below is a map of only SOME of the values accepted by PayGateXML and how you should submit
|
51
|
+
# each to ActiveMerchant
|
52
|
+
#
|
53
|
+
# PayGateXML Field ActiveMerchant Use
|
54
|
+
#
|
55
|
+
# pgid use :login value to gateway instantation
|
56
|
+
# pwd use :password value to gateway instantiation
|
57
|
+
#
|
58
|
+
# cname credit_card.name
|
59
|
+
# cc credit_card.number
|
60
|
+
# exp credit_card values formatted to YYYYMMDD
|
61
|
+
# budp South Africa only - set to 0 if purchase is not on budget
|
62
|
+
# amt include as argument to method for your transaction type
|
63
|
+
# ver do nothing, always set to current API version
|
64
|
+
#
|
65
|
+
# cref provide as :invoice in options, varchar(80)
|
66
|
+
# cur 3 char field, currently only ZAR
|
67
|
+
# cvv credit_card.verification
|
68
|
+
# bno batch processing number, i.e. you supply this
|
69
|
+
#
|
70
|
+
# others -- not used in this implementation
|
71
|
+
# nurl, rurl - must remain blank or absent or they will use an alternative authentication mechanism
|
72
|
+
# email, ip - must remain blank or absent or they will use a PayGate extra service call PayProtector
|
73
|
+
# threed - must remain blank unless you are using your own 3D Secure server
|
74
|
+
#
|
75
|
+
class PayGateXmlGateway < Gateway
|
76
|
+
self.live_url = 'https://www.paygate.co.za/payxml/process.trans'
|
77
|
+
|
78
|
+
# The countries the gateway supports merchants from as 2 digit ISO country codes
|
79
|
+
self.supported_countries = ['US', 'ZA']
|
80
|
+
|
81
|
+
# The card types supported by the payment gateway
|
82
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club]
|
83
|
+
|
84
|
+
# The homepage URL of the gateway
|
85
|
+
self.homepage_url = 'http://paygate.co.za/'
|
86
|
+
|
87
|
+
# The name of the gateway
|
88
|
+
self.display_name = 'PayGate PayXML'
|
89
|
+
|
90
|
+
# PayGate only supports Rands
|
91
|
+
self.default_currency = 'ZAR'
|
92
|
+
|
93
|
+
# PayGate accepts only lowest denomination
|
94
|
+
self.money_format = :cents
|
95
|
+
|
96
|
+
# PayGateXML public test account - you can get a private one too
|
97
|
+
TEST_ID_3DSECURE = '10011013800'
|
98
|
+
TEST_ID = '10011021600'
|
99
|
+
TEST_PWD = 'test'
|
100
|
+
|
101
|
+
API_VERSION = '4.0'
|
102
|
+
|
103
|
+
DECLINE_CODES = {
|
104
|
+
# Credit Card Errors - These RESULT_CODEs are returned if the transaction cannot be authorized due to a problem with the card. The TRANSACTION_STATUS will be 2
|
105
|
+
900001 => "Call for Approval",
|
106
|
+
900002 => "Card Expired",
|
107
|
+
900003 => "Insufficient Funds",
|
108
|
+
900004 => "Invalid Card Number",
|
109
|
+
900005 => "Bank Interface Timeout", # indicates a communications failure between the banks systems
|
110
|
+
900006 => "Invalid Card",
|
111
|
+
900007 => "Declined",
|
112
|
+
900009 => "Lost Card",
|
113
|
+
900010 => "Invalid Card Length",
|
114
|
+
900011 => "Suspected Fraud",
|
115
|
+
900012 => "Card Reported As Stolen",
|
116
|
+
900013 => "Restricted Card",
|
117
|
+
900014 => "Excessive Card Usage",
|
118
|
+
900015 => "Card Blacklisted",
|
119
|
+
|
120
|
+
900207 => "Declined; authentication failed", # indicates the cardholder did not enter their MasterCard SecureCode / Verified by Visa password correctly
|
121
|
+
|
122
|
+
990020 => "Auth Declined",
|
123
|
+
|
124
|
+
991001 => "Invalid expiry date",
|
125
|
+
991002 => "Invalid amount",
|
126
|
+
|
127
|
+
# Communication Errors - These RESULT_CODEs are returned if the transaction cannot be completed due to an unexpected error. TRANSACTION_STATUS will be 0.
|
128
|
+
900205 => "Unexpected authentication result (phase 1)",
|
129
|
+
900206 => "Unexpected authentication result (phase 1)",
|
130
|
+
|
131
|
+
990001 => "Could not insert into Database",
|
132
|
+
|
133
|
+
990022 => "Bank not available",
|
134
|
+
|
135
|
+
990053 => "Error processing transaction",
|
136
|
+
|
137
|
+
# Miscellaneous - Unless otherwise noted, the TRANSACTION_STATUS will be 0.
|
138
|
+
900209 => "Transaction verification failed (phase 2)", # Indicates the verification data returned from MasterCard SecureCode / Verified by Visa has been altered
|
139
|
+
900210 => "Authentication complete; transaction must be restarted", # Indicates that the MasterCard SecuerCode / Verified by Visa transaction has already been completed. Most likely caused by the customer clicking the refresh button
|
140
|
+
|
141
|
+
990024 => "Duplicate Transaction Detected. Please check before submitting",
|
142
|
+
|
143
|
+
990028 => "Transaction cancelled" # Customer clicks the 'Cancel' button on the payment page
|
144
|
+
}
|
145
|
+
|
146
|
+
SUCCESS_CODES = %w( 990004 990005 990017 990012 990018 990031 )
|
147
|
+
|
148
|
+
TRANSACTION_CODES = {
|
149
|
+
0 => 'Not Done',
|
150
|
+
1 => 'Approved',
|
151
|
+
2 => 'Declined',
|
152
|
+
3 => 'Paid',
|
153
|
+
4 => 'Refunded',
|
154
|
+
5 => 'Received by PayGate',
|
155
|
+
6 => 'Replied to Client'
|
156
|
+
}
|
157
|
+
|
158
|
+
def initialize(options = {})
|
159
|
+
requires!(options, :login, :password)
|
160
|
+
super
|
161
|
+
end
|
162
|
+
|
163
|
+
def purchase(money, creditcard, options = {})
|
164
|
+
MultiResponse.run do |r|
|
165
|
+
r.process{authorize(money, creditcard, options)}
|
166
|
+
r.process{capture(money, r.authorization, options)}
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def authorize(money, creditcard, options = {})
|
171
|
+
action = 'authtx'
|
172
|
+
|
173
|
+
options.merge!(:money => money, :creditcard => creditcard)
|
174
|
+
commit(action, build_request(action, options))
|
175
|
+
end
|
176
|
+
|
177
|
+
def capture(money, authorization, options = {})
|
178
|
+
action = 'settletx'
|
179
|
+
|
180
|
+
options.merge!(:money => money, :authorization => authorization)
|
181
|
+
commit(action, build_request(action, options))
|
182
|
+
end
|
183
|
+
|
184
|
+
private
|
185
|
+
|
186
|
+
def successful?(response)
|
187
|
+
SUCCESS_CODES.include?(response[:res])
|
188
|
+
end
|
189
|
+
|
190
|
+
def build_request(action, options={})
|
191
|
+
xml = Builder::XmlMarkup.new
|
192
|
+
xml.instruct!
|
193
|
+
|
194
|
+
xml.tag! 'protocol', :ver => API_VERSION, :pgid => (test? ? TEST_ID : @options[:login]), :pwd => @options[:password] do |protocol|
|
195
|
+
case action
|
196
|
+
when 'authtx'
|
197
|
+
money = options.delete(:money)
|
198
|
+
creditcard = options.delete(:creditcard)
|
199
|
+
build_authorization(protocol, money, creditcard, options)
|
200
|
+
when 'settletx'
|
201
|
+
money = options.delete(:money)
|
202
|
+
authorization = options.delete(:authorization)
|
203
|
+
build_capture(protocol, money, authorization, options)
|
204
|
+
else
|
205
|
+
raise "no action specified for build_request"
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
xml.target!
|
210
|
+
end
|
211
|
+
|
212
|
+
def build_authorization(xml, money, creditcard, options={})
|
213
|
+
xml.tag! 'authtx', {
|
214
|
+
:cref => options[:order_id],
|
215
|
+
:cname => creditcard.name,
|
216
|
+
:cc => creditcard.number,
|
217
|
+
:exp => "#{format(creditcard.month, :two_digits)}#{format(creditcard.year, :four_digits)}",
|
218
|
+
:budp => 0,
|
219
|
+
:amt => amount(money),
|
220
|
+
:cur => (options[:currency] || currency(money)),
|
221
|
+
:cvv => creditcard.verification_value
|
222
|
+
}
|
223
|
+
end
|
224
|
+
|
225
|
+
def build_capture(xml, money, authorization, options={})
|
226
|
+
xml.tag! 'settletx', {
|
227
|
+
:tid => authorization
|
228
|
+
}
|
229
|
+
end
|
230
|
+
|
231
|
+
def parse(action, body)
|
232
|
+
hash = {}
|
233
|
+
xml = REXML::Document.new(body)
|
234
|
+
|
235
|
+
response_action = action.gsub(/tx/, 'rx')
|
236
|
+
root = REXML::XPath.first(xml.root, response_action)
|
237
|
+
# we might have gotten an error
|
238
|
+
if root.nil?
|
239
|
+
root = REXML::XPath.first(xml.root, 'errorrx')
|
240
|
+
end
|
241
|
+
root.attributes.each do |name, value|
|
242
|
+
hash[name.to_sym] = value
|
243
|
+
end
|
244
|
+
hash
|
245
|
+
end
|
246
|
+
|
247
|
+
def commit(action, request)
|
248
|
+
response = parse(action, ssl_post(self.live_url, request))
|
249
|
+
Response.new(successful?(response), message_from(response), response,
|
250
|
+
:test => test?,
|
251
|
+
:authorization => response[:tid]
|
252
|
+
)
|
253
|
+
end
|
254
|
+
|
255
|
+
def message_from(response)
|
256
|
+
(response[:rdesc] || response[:edesc])
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|