yetanothernguyen-activemerchant 1.16.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.
- data/CHANGELOG +711 -0
- data/CONTRIBUTORS +245 -0
- data/MIT-LICENSE +20 -0
- data/gem-public_cert.pem +20 -0
- data/lib/active_merchant.rb +52 -0
- data/lib/active_merchant/billing.rb +9 -0
- data/lib/active_merchant/billing/avs_result.rb +98 -0
- data/lib/active_merchant/billing/base.rb +57 -0
- data/lib/active_merchant/billing/check.rb +68 -0
- data/lib/active_merchant/billing/credit_card.rb +178 -0
- data/lib/active_merchant/billing/credit_card_formatting.rb +21 -0
- data/lib/active_merchant/billing/credit_card_methods.rb +125 -0
- data/lib/active_merchant/billing/cvv_result.rb +38 -0
- data/lib/active_merchant/billing/expiry_date.rb +34 -0
- data/lib/active_merchant/billing/gateway.rb +170 -0
- data/lib/active_merchant/billing/gateways.rb +18 -0
- data/lib/active_merchant/billing/gateways/authorize_net.rb +672 -0
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +858 -0
- data/lib/active_merchant/billing/gateways/barclays_epdq.rb +308 -0
- data/lib/active_merchant/billing/gateways/beanstream.rb +139 -0
- data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +282 -0
- data/lib/active_merchant/billing/gateways/beanstream_interac.rb +54 -0
- data/lib/active_merchant/billing/gateways/blue_pay.rb +11 -0
- data/lib/active_merchant/billing/gateways/bogus.rb +142 -0
- data/lib/active_merchant/billing/gateways/braintree.rb +17 -0
- data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +9 -0
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +303 -0
- data/lib/active_merchant/billing/gateways/braintree_orange.rb +17 -0
- data/lib/active_merchant/billing/gateways/card_stream.rb +230 -0
- data/lib/active_merchant/billing/gateways/cyber_source.rb +430 -0
- data/lib/active_merchant/billing/gateways/data_cash.rb +597 -0
- data/lib/active_merchant/billing/gateways/efsnet.rb +235 -0
- data/lib/active_merchant/billing/gateways/elavon.rb +134 -0
- data/lib/active_merchant/billing/gateways/epay.rb +268 -0
- data/lib/active_merchant/billing/gateways/eway.rb +277 -0
- data/lib/active_merchant/billing/gateways/eway_managed.rb +231 -0
- data/lib/active_merchant/billing/gateways/exact.rb +222 -0
- data/lib/active_merchant/billing/gateways/federated_canada.rb +168 -0
- data/lib/active_merchant/billing/gateways/first_pay.rb +177 -0
- data/lib/active_merchant/billing/gateways/garanti.rb +262 -0
- data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +250 -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 +55 -0
- data/lib/active_merchant/billing/gateways/inspire.rb +221 -0
- data/lib/active_merchant/billing/gateways/instapay.rb +164 -0
- data/lib/active_merchant/billing/gateways/iridium.rb +258 -0
- data/lib/active_merchant/billing/gateways/jetpay.rb +276 -0
- data/lib/active_merchant/billing/gateways/linkpoint.rb +454 -0
- data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +156 -0
- data/lib/active_merchant/billing/gateways/merchant_ware.rb +289 -0
- data/lib/active_merchant/billing/gateways/modern_payments.rb +36 -0
- data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +220 -0
- data/lib/active_merchant/billing/gateways/moneris.rb +209 -0
- data/lib/active_merchant/billing/gateways/net_registry.rb +189 -0
- data/lib/active_merchant/billing/gateways/netaxept.rb +239 -0
- data/lib/active_merchant/billing/gateways/netbilling.rb +168 -0
- data/lib/active_merchant/billing/gateways/nmi.rb +13 -0
- data/lib/active_merchant/billing/gateways/ogone.rb +292 -0
- data/lib/active_merchant/billing/gateways/orbital.rb +321 -0
- data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +46 -0
- data/lib/active_merchant/billing/gateways/pay_junction.rb +392 -0
- data/lib/active_merchant/billing/gateways/pay_secure.rb +120 -0
- data/lib/active_merchant/billing/gateways/paybox_direct.rb +207 -0
- data/lib/active_merchant/billing/gateways/payflow.rb +253 -0
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +207 -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 +222 -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 +235 -0
- data/lib/active_merchant/billing/gateways/paypal.rb +121 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +351 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +49 -0
- data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
- data/lib/active_merchant/billing/gateways/paypal_express.rb +177 -0
- data/lib/active_merchant/billing/gateways/paypal_express_common.rb +25 -0
- data/lib/active_merchant/billing/gateways/paystation.rb +201 -0
- data/lib/active_merchant/billing/gateways/plugnpay.rb +298 -0
- data/lib/active_merchant/billing/gateways/psigate.rb +219 -0
- data/lib/active_merchant/billing/gateways/psl_card.rb +304 -0
- data/lib/active_merchant/billing/gateways/qbms.rb +293 -0
- data/lib/active_merchant/billing/gateways/quantum.rb +282 -0
- data/lib/active_merchant/billing/gateways/quickpay.rb +223 -0
- data/lib/active_merchant/billing/gateways/realex.rb +311 -0
- data/lib/active_merchant/billing/gateways/sage.rb +146 -0
- data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +88 -0
- data/lib/active_merchant/billing/gateways/sage/sage_core.rb +116 -0
- data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +97 -0
- data/lib/active_merchant/billing/gateways/sage_pay.rb +320 -0
- data/lib/active_merchant/billing/gateways/sallie_mae.rb +144 -0
- data/lib/active_merchant/billing/gateways/secure_net.rb +330 -0
- data/lib/active_merchant/billing/gateways/secure_pay.rb +31 -0
- data/lib/active_merchant/billing/gateways/secure_pay_au.rb +193 -0
- data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +113 -0
- data/lib/active_merchant/billing/gateways/skip_jack.rb +453 -0
- data/lib/active_merchant/billing/gateways/smart_ps.rb +271 -0
- data/lib/active_merchant/billing/gateways/stripe.rb +212 -0
- data/lib/active_merchant/billing/gateways/trans_first.rb +127 -0
- data/lib/active_merchant/billing/gateways/transax.rb +25 -0
- data/lib/active_merchant/billing/gateways/trust_commerce.rb +423 -0
- data/lib/active_merchant/billing/gateways/usa_epay.rb +194 -0
- data/lib/active_merchant/billing/gateways/verifi.rb +233 -0
- data/lib/active_merchant/billing/gateways/viaklix.rb +189 -0
- data/lib/active_merchant/billing/gateways/wirecard.rb +318 -0
- data/lib/active_merchant/billing/gateways/worldpay.rb +280 -0
- data/lib/active_merchant/billing/integrations.rb +17 -0
- data/lib/active_merchant/billing/integrations/action_view_helper.rb +70 -0
- data/lib/active_merchant/billing/integrations/bogus.rb +23 -0
- data/lib/active_merchant/billing/integrations/bogus/helper.rb +17 -0
- data/lib/active_merchant/billing/integrations/bogus/notification.rb +11 -0
- data/lib/active_merchant/billing/integrations/bogus/return.rb +10 -0
- data/lib/active_merchant/billing/integrations/chronopay.rb +23 -0
- data/lib/active_merchant/billing/integrations/chronopay/helper.rb +120 -0
- data/lib/active_merchant/billing/integrations/chronopay/notification.rb +158 -0
- data/lib/active_merchant/billing/integrations/chronopay/return.rb +10 -0
- data/lib/active_merchant/billing/integrations/direc_pay.rb +41 -0
- data/lib/active_merchant/billing/integrations/direc_pay/helper.rb +200 -0
- data/lib/active_merchant/billing/integrations/direc_pay/notification.rb +76 -0
- data/lib/active_merchant/billing/integrations/direc_pay/return.rb +32 -0
- data/lib/active_merchant/billing/integrations/direc_pay/status.rb +37 -0
- data/lib/active_merchant/billing/integrations/directebanking.rb +47 -0
- data/lib/active_merchant/billing/integrations/directebanking/helper.rb +90 -0
- data/lib/active_merchant/billing/integrations/directebanking/notification.rb +120 -0
- data/lib/active_merchant/billing/integrations/directebanking/return.rb +11 -0
- data/lib/active_merchant/billing/integrations/e_payment_plans.rb +48 -0
- data/lib/active_merchant/billing/integrations/e_payment_plans/helper.rb +34 -0
- data/lib/active_merchant/billing/integrations/e_payment_plans/notification.rb +84 -0
- data/lib/active_merchant/billing/integrations/gestpay.rb +25 -0
- data/lib/active_merchant/billing/integrations/gestpay/common.rb +42 -0
- data/lib/active_merchant/billing/integrations/gestpay/helper.rb +70 -0
- data/lib/active_merchant/billing/integrations/gestpay/notification.rb +85 -0
- data/lib/active_merchant/billing/integrations/gestpay/return.rb +10 -0
- data/lib/active_merchant/billing/integrations/helper.rb +96 -0
- data/lib/active_merchant/billing/integrations/hi_trust.rb +27 -0
- data/lib/active_merchant/billing/integrations/hi_trust/helper.rb +58 -0
- data/lib/active_merchant/billing/integrations/hi_trust/notification.rb +59 -0
- data/lib/active_merchant/billing/integrations/hi_trust/return.rb +67 -0
- data/lib/active_merchant/billing/integrations/migs.rb +22 -0
- data/lib/active_merchant/billing/integrations/migs/helper.rb +64 -0
- data/lib/active_merchant/billing/integrations/migs/return.rb +54 -0
- data/lib/active_merchant/billing/integrations/moneybookers.rb +26 -0
- data/lib/active_merchant/billing/integrations/moneybookers/helper.rb +59 -0
- data/lib/active_merchant/billing/integrations/moneybookers/notification.rb +129 -0
- data/lib/active_merchant/billing/integrations/nochex.rb +88 -0
- data/lib/active_merchant/billing/integrations/nochex/helper.rb +68 -0
- data/lib/active_merchant/billing/integrations/nochex/notification.rb +94 -0
- data/lib/active_merchant/billing/integrations/nochex/return.rb +10 -0
- data/lib/active_merchant/billing/integrations/notification.rb +62 -0
- data/lib/active_merchant/billing/integrations/paypal.rb +39 -0
- data/lib/active_merchant/billing/integrations/paypal/helper.rb +119 -0
- data/lib/active_merchant/billing/integrations/paypal/notification.rb +154 -0
- data/lib/active_merchant/billing/integrations/paypal/return.rb +10 -0
- data/lib/active_merchant/billing/integrations/quickpay.rb +21 -0
- data/lib/active_merchant/billing/integrations/quickpay/helper.rb +72 -0
- data/lib/active_merchant/billing/integrations/quickpay/notification.rb +74 -0
- data/lib/active_merchant/billing/integrations/return.rb +42 -0
- data/lib/active_merchant/billing/integrations/sage_pay_form.rb +37 -0
- data/lib/active_merchant/billing/integrations/sage_pay_form/encryption.rb +33 -0
- data/lib/active_merchant/billing/integrations/sage_pay_form/helper.rb +111 -0
- data/lib/active_merchant/billing/integrations/sage_pay_form/notification.rb +210 -0
- data/lib/active_merchant/billing/integrations/sage_pay_form/return.rb +31 -0
- data/lib/active_merchant/billing/integrations/two_checkout.rb +23 -0
- data/lib/active_merchant/billing/integrations/two_checkout/helper.rb +59 -0
- data/lib/active_merchant/billing/integrations/two_checkout/notification.rb +114 -0
- data/lib/active_merchant/billing/integrations/two_checkout/return.rb +17 -0
- data/lib/active_merchant/billing/integrations/valitor.rb +33 -0
- data/lib/active_merchant/billing/integrations/valitor/helper.rb +86 -0
- data/lib/active_merchant/billing/integrations/valitor/notification.rb +13 -0
- data/lib/active_merchant/billing/integrations/valitor/response_fields.rb +97 -0
- data/lib/active_merchant/billing/integrations/valitor/return.rb +13 -0
- data/lib/active_merchant/billing/integrations/world_pay.rb +27 -0
- data/lib/active_merchant/billing/integrations/world_pay/helper.rb +100 -0
- data/lib/active_merchant/billing/integrations/world_pay/notification.rb +160 -0
- data/lib/active_merchant/billing/response.rb +32 -0
- data/lib/active_merchant/common.rb +14 -0
- data/lib/active_merchant/common/connection.rb +177 -0
- data/lib/active_merchant/common/country.rb +328 -0
- data/lib/active_merchant/common/error.rb +26 -0
- data/lib/active_merchant/common/post_data.rb +24 -0
- data/lib/active_merchant/common/posts_data.rb +63 -0
- data/lib/active_merchant/common/requires_parameters.rb +16 -0
- data/lib/active_merchant/common/utils.rb +22 -0
- data/lib/active_merchant/common/validateable.rb +81 -0
- data/lib/active_merchant/railtie.rb +9 -0
- data/lib/active_merchant/version.rb +3 -0
- data/lib/activemerchant.rb +1 -0
- data/lib/certs/cacert.pem +7815 -0
- data/lib/support/gateway_support.rb +58 -0
- data/lib/support/outbound_hosts.rb +25 -0
- metadata +281 -0
@@ -0,0 +1,49 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class PaypalExpressResponse < Response
|
4
|
+
def email
|
5
|
+
info['Payer']
|
6
|
+
end
|
7
|
+
|
8
|
+
def info
|
9
|
+
(@params['PayerInfo']||{})
|
10
|
+
end
|
11
|
+
|
12
|
+
def name
|
13
|
+
payer = (info['PayerName']||{})
|
14
|
+
[payer['FirstName'], payer['MiddleName'], payer['LastName']].compact.join(' ')
|
15
|
+
end
|
16
|
+
|
17
|
+
def token
|
18
|
+
@params['Token']
|
19
|
+
end
|
20
|
+
|
21
|
+
def payer_id
|
22
|
+
info['PayerID']
|
23
|
+
end
|
24
|
+
|
25
|
+
def payer_country
|
26
|
+
info['PayerCountry']
|
27
|
+
end
|
28
|
+
|
29
|
+
# PayPal returns a contact telephone number only if your Merchant account profile settings require that the buyer enter one.
|
30
|
+
def contact_phone
|
31
|
+
@params['ContactPhone']
|
32
|
+
end
|
33
|
+
|
34
|
+
def address
|
35
|
+
address = (@params['PaymentDetails']||{})['ShipToAddress']
|
36
|
+
{ 'name' => address['Name'],
|
37
|
+
'company' => info['PayerBusiness'],
|
38
|
+
'address1' => address['Street1'],
|
39
|
+
'address2' => address['Street2'],
|
40
|
+
'city' => address['CityName'],
|
41
|
+
'state' => address['StateOrProvince'],
|
42
|
+
'country' => address['Country'],
|
43
|
+
'zip' => address['PostalCode'],
|
44
|
+
'phone' => (contact_phone || address['Phone'])
|
45
|
+
}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/paypal'
|
2
|
+
|
3
|
+
module ActiveMerchant #:nodoc:
|
4
|
+
module Billing #:nodoc:
|
5
|
+
# The PayPal gateway for PayPal Website Payments Pro Canada only supports Visa and MasterCard
|
6
|
+
class PaypalCaGateway < PaypalGateway
|
7
|
+
self.supported_cardtypes = [:visa, :master]
|
8
|
+
self.supported_countries = ['CA']
|
9
|
+
self.homepage_url = 'https://www.paypal.com/cgi-bin/webscr?cmd=_wp-pro-overview-outside'
|
10
|
+
self.display_name = 'PayPal Website Payments Pro (CA)'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,177 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/paypal/paypal_common_api'
|
2
|
+
require File.dirname(__FILE__) + '/paypal/paypal_express_response'
|
3
|
+
require File.dirname(__FILE__) + '/paypal_express_common'
|
4
|
+
|
5
|
+
module ActiveMerchant #:nodoc:
|
6
|
+
module Billing #:nodoc:
|
7
|
+
class PaypalExpressGateway < Gateway
|
8
|
+
include PaypalCommonAPI
|
9
|
+
include PaypalExpressCommon
|
10
|
+
|
11
|
+
self.test_redirect_url = 'https://www.sandbox.paypal.com/cgi-bin/webscr'
|
12
|
+
self.supported_countries = ['US']
|
13
|
+
self.homepage_url = 'https://www.paypal.com/cgi-bin/webscr?cmd=xpt/merchant/ExpressCheckoutIntro-outside'
|
14
|
+
self.display_name = 'PayPal Express Checkout'
|
15
|
+
|
16
|
+
def setup_authorization(money, options = {})
|
17
|
+
requires!(options, :return_url, :cancel_return_url)
|
18
|
+
|
19
|
+
commit 'SetExpressCheckout', build_setup_request('Authorization', money, options)
|
20
|
+
end
|
21
|
+
|
22
|
+
def setup_purchase(money, options = {})
|
23
|
+
requires!(options, :return_url, :cancel_return_url)
|
24
|
+
|
25
|
+
commit 'SetExpressCheckout', build_setup_request('Sale', money, options)
|
26
|
+
end
|
27
|
+
|
28
|
+
def details_for(token)
|
29
|
+
commit 'GetExpressCheckoutDetails', build_get_details_request(token)
|
30
|
+
end
|
31
|
+
|
32
|
+
def authorize(money, options = {})
|
33
|
+
requires!(options, :token, :payer_id)
|
34
|
+
|
35
|
+
commit 'DoExpressCheckoutPayment', build_sale_or_authorization_request('Authorization', money, options)
|
36
|
+
end
|
37
|
+
|
38
|
+
def purchase(money, options = {})
|
39
|
+
requires!(options, :token, :payer_id)
|
40
|
+
|
41
|
+
commit 'DoExpressCheckoutPayment', build_sale_or_authorization_request('Sale', money, options)
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
def build_get_details_request(token)
|
46
|
+
xml = Builder::XmlMarkup.new :indent => 2
|
47
|
+
xml.tag! 'GetExpressCheckoutDetailsReq', 'xmlns' => PAYPAL_NAMESPACE do
|
48
|
+
xml.tag! 'GetExpressCheckoutDetailsRequest', 'xmlns:n2' => EBAY_NAMESPACE do
|
49
|
+
xml.tag! 'n2:Version', API_VERSION
|
50
|
+
xml.tag! 'Token', token
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
xml.target!
|
55
|
+
end
|
56
|
+
|
57
|
+
def build_sale_or_authorization_request(action, money, options)
|
58
|
+
currency_code = options[:currency] || currency(money)
|
59
|
+
|
60
|
+
xml = Builder::XmlMarkup.new :indent => 2
|
61
|
+
xml.tag! 'DoExpressCheckoutPaymentReq', 'xmlns' => PAYPAL_NAMESPACE do
|
62
|
+
xml.tag! 'DoExpressCheckoutPaymentRequest', 'xmlns:n2' => EBAY_NAMESPACE do
|
63
|
+
xml.tag! 'n2:Version', API_VERSION
|
64
|
+
xml.tag! 'n2:DoExpressCheckoutPaymentRequestDetails' do
|
65
|
+
xml.tag! 'n2:PaymentAction', action
|
66
|
+
xml.tag! 'n2:Token', options[:token]
|
67
|
+
xml.tag! 'n2:PayerID', options[:payer_id]
|
68
|
+
xml.tag! 'n2:PaymentDetails' do
|
69
|
+
xml.tag! 'n2:OrderTotal', localized_amount(money, currency_code), 'currencyID' => currency_code
|
70
|
+
|
71
|
+
# All of the values must be included together and add up to the order total
|
72
|
+
if [:subtotal, :shipping, :handling, :tax].all?{ |o| options.has_key?(o) }
|
73
|
+
xml.tag! 'n2:ItemTotal', localized_amount(options[:subtotal], currency_code), 'currencyID' => currency_code
|
74
|
+
xml.tag! 'n2:ShippingTotal', localized_amount(options[:shipping], currency_code),'currencyID' => currency_code
|
75
|
+
xml.tag! 'n2:HandlingTotal', localized_amount(options[:handling], currency_code),'currencyID' => currency_code
|
76
|
+
xml.tag! 'n2:TaxTotal', localized_amount(options[:tax], currency_code), 'currencyID' => currency_code
|
77
|
+
end
|
78
|
+
|
79
|
+
xml.tag! 'n2:NotifyURL', options[:notify_url]
|
80
|
+
xml.tag! 'n2:ButtonSource', application_id.to_s.slice(0,32) unless application_id.blank?
|
81
|
+
xml.tag! 'n2:InvoiceID', options[:order_id]
|
82
|
+
xml.tag! 'n2:OrderDescription', options[:description]
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
xml.target!
|
89
|
+
end
|
90
|
+
|
91
|
+
def build_setup_request(action, money, options)
|
92
|
+
currency_code = options[:currency] || currency(money)
|
93
|
+
|
94
|
+
xml = Builder::XmlMarkup.new :indent => 2
|
95
|
+
xml.tag! 'SetExpressCheckoutReq', 'xmlns' => PAYPAL_NAMESPACE do
|
96
|
+
xml.tag! 'SetExpressCheckoutRequest', 'xmlns:n2' => EBAY_NAMESPACE do
|
97
|
+
xml.tag! 'n2:Version', API_VERSION
|
98
|
+
xml.tag! 'n2:SetExpressCheckoutRequestDetails' do
|
99
|
+
if options[:max_amount]
|
100
|
+
xml.tag! 'n2:MaxAmount', localized_amount(options[:max_amount], currency_code), 'currencyID' => currency_code
|
101
|
+
end
|
102
|
+
if !options[:allow_note].nil?
|
103
|
+
xml.tag! 'n2:AllowNote', options[:allow_note] ? '1' : '0'
|
104
|
+
end
|
105
|
+
xml.tag! 'n2:PaymentDetails' do
|
106
|
+
xml.tag! 'n2:OrderTotal', amount(money).to_f.zero? ? localized_amount(100, currency_code) : localized_amount(money, currency_code), 'currencyID' => currency_code
|
107
|
+
# All of the values must be included together and add up to the order total
|
108
|
+
if [:subtotal, :shipping, :handling, :tax].all? { |o| options.has_key?(o) }
|
109
|
+
xml.tag! 'n2:ItemTotal', localized_amount(options[:subtotal], currency_code), 'currencyID' => currency_code
|
110
|
+
xml.tag! 'n2:ShippingTotal', localized_amount(options[:shipping], currency_code), 'currencyID' => currency_code
|
111
|
+
xml.tag! 'n2:HandlingTotal', localized_amount(options[:handling], currency_code), 'currencyID' => currency_code
|
112
|
+
xml.tag! 'n2:TaxTotal', localized_amount(options[:tax], currency_code), 'currencyID' => currency_code
|
113
|
+
end
|
114
|
+
|
115
|
+
xml.tag! 'n2:OrderDescription', options[:description]
|
116
|
+
xml.tag! 'n2:InvoiceID', options[:order_id]
|
117
|
+
|
118
|
+
if options[:items]
|
119
|
+
options[:items].each do |item|
|
120
|
+
xml.tag! 'n2:PaymentDetailsItem' do
|
121
|
+
xml.tag! 'n2:Name', item[:name]
|
122
|
+
xml.tag! 'n2:Number', item[:number]
|
123
|
+
xml.tag! 'n2:Quantity', item[:quantity]
|
124
|
+
if item[:amount]
|
125
|
+
xml.tag! 'n2:Amount', localized_amount(item[:amount], currency_code), 'currencyID' => currency_code
|
126
|
+
end
|
127
|
+
xml.tag! 'n2:Description', item[:description]
|
128
|
+
xml.tag! 'n2:ItemURL', item[:url]
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
add_address(xml, 'n2:ShipToAddress', options[:shipping_address] || options[:address])
|
133
|
+
|
134
|
+
xml.tag! 'n2:PaymentAction', action
|
135
|
+
end
|
136
|
+
|
137
|
+
xml.tag! 'n2:AddressOverride', options[:address_override] ? '1' : '0'
|
138
|
+
xml.tag! 'n2:NoShipping', options[:no_shipping] ? '1' : '0'
|
139
|
+
xml.tag! 'n2:ReturnURL', options[:return_url]
|
140
|
+
xml.tag! 'n2:CancelURL', options[:cancel_return_url]
|
141
|
+
xml.tag! 'n2:IPAddress', options[:ip] unless options[:ip].blank?
|
142
|
+
xml.tag! 'n2:BuyerEmail', options[:email] unless options[:email].blank?
|
143
|
+
|
144
|
+
if options[:billing_agreement]
|
145
|
+
xml.tag! 'n2:BillingAgreementDetails' do
|
146
|
+
xml.tag! 'n2:BillingType', options[:billing_agreement][:type]
|
147
|
+
xml.tag! 'n2:BillingAgreementDescription', options[:billing_agreement][:description]
|
148
|
+
xml.tag! 'n2:PaymentType', options[:billing_agreement][:payment_type] || 'InstantOnly'
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
# Customization of the payment page
|
153
|
+
xml.tag! 'n2:PageStyle', options[:page_style] unless options[:page_style].blank?
|
154
|
+
xml.tag! 'n2:cpp-header-image', options[:header_image] unless options[:header_image].blank?
|
155
|
+
xml.tag! 'n2:cpp-header-back-color', options[:header_background_color] unless options[:header_background_color].blank?
|
156
|
+
xml.tag! 'n2:cpp-header-border-color', options[:header_border_color] unless options[:header_border_color].blank?
|
157
|
+
xml.tag! 'n2:cpp-payflow-color', options[:background_color] unless options[:background_color].blank?
|
158
|
+
|
159
|
+
if options[:allow_guest_checkout]
|
160
|
+
xml.tag! 'n2:SolutionType', 'Sole'
|
161
|
+
xml.tag! 'n2:LandingPage', 'Billing'
|
162
|
+
end
|
163
|
+
|
164
|
+
xml.tag! 'n2:LocaleCode', options[:locale] unless options[:locale].blank?
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
xml.target!
|
170
|
+
end
|
171
|
+
|
172
|
+
def build_response(success, message, response, options = {})
|
173
|
+
PaypalExpressResponse.new(success, message, response, options)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module ActiveMerchant
|
2
|
+
module Billing
|
3
|
+
module PaypalExpressCommon
|
4
|
+
def self.included(base)
|
5
|
+
base.cattr_accessor :test_redirect_url
|
6
|
+
base.cattr_accessor :live_redirect_url
|
7
|
+
base.live_redirect_url = 'https://www.paypal.com/cgibin/webscr'
|
8
|
+
end
|
9
|
+
|
10
|
+
def redirect_url
|
11
|
+
test? ? test_redirect_url : live_redirect_url
|
12
|
+
end
|
13
|
+
|
14
|
+
def redirect_url_for(token, options = {})
|
15
|
+
options = {:review => true, :mobile => false}.update(options)
|
16
|
+
|
17
|
+
cmd = options[:mobile] ? '_express-checkout-mobile' : '_express-checkout'
|
18
|
+
url = "#{redirect_url}?cmd=#{cmd}&token=#{token}"
|
19
|
+
url += '&useraction=commit' unless options[:review]
|
20
|
+
|
21
|
+
url
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,201 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class PaystationGateway < Gateway
|
4
|
+
|
5
|
+
URL = "https://www.paystation.co.nz/direct/paystation.dll"
|
6
|
+
|
7
|
+
# an "error code" of "0" means "No error - transaction successful"
|
8
|
+
SUCCESSFUL_RESPONSE_CODE = '0'
|
9
|
+
|
10
|
+
# an "error code" of "34" means "Future Payment Stored OK"
|
11
|
+
SUCCESSFUL_FUTURE_PAYMENT = '34'
|
12
|
+
|
13
|
+
# TODO: check this with paystation
|
14
|
+
self.supported_countries = ['NZ']
|
15
|
+
|
16
|
+
# TODO: check this with paystation (amex and diners need to be enabled)
|
17
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club ]
|
18
|
+
|
19
|
+
self.homepage_url = 'http://paystation.co.nz'
|
20
|
+
self.display_name = 'Paystation'
|
21
|
+
|
22
|
+
self.default_currency = 'NZD'
|
23
|
+
self.money_format = :cents
|
24
|
+
|
25
|
+
def initialize(options = {})
|
26
|
+
# You need to pass your Paystation ID and Gateway ID
|
27
|
+
requires!(options, :paystation_id, :gateway_id)
|
28
|
+
@options = options
|
29
|
+
super
|
30
|
+
end
|
31
|
+
|
32
|
+
def authorize(money, credit_card, options = {})
|
33
|
+
post = new_request
|
34
|
+
|
35
|
+
add_invoice(post, options)
|
36
|
+
add_amount(post, money, options)
|
37
|
+
|
38
|
+
add_credit_card(post, credit_card)
|
39
|
+
|
40
|
+
add_authorize_flag(post, options)
|
41
|
+
|
42
|
+
commit(post)
|
43
|
+
end
|
44
|
+
|
45
|
+
def capture(money, authorization_token, options = {})
|
46
|
+
post = new_request
|
47
|
+
|
48
|
+
add_invoice(post, options)
|
49
|
+
add_amount(post, money, options)
|
50
|
+
|
51
|
+
add_authorization_token(post, authorization_token, options[:credit_card_verification])
|
52
|
+
|
53
|
+
commit(post)
|
54
|
+
end
|
55
|
+
|
56
|
+
def purchase(money, payment_source, options = {})
|
57
|
+
post = new_request
|
58
|
+
|
59
|
+
add_invoice(post, options)
|
60
|
+
add_amount(post, money, options)
|
61
|
+
|
62
|
+
if payment_source.is_a?(String)
|
63
|
+
add_token(post, payment_source)
|
64
|
+
else
|
65
|
+
add_credit_card(post, payment_source)
|
66
|
+
end
|
67
|
+
|
68
|
+
add_customer_data(post, options) if options.has_key?(:customer)
|
69
|
+
|
70
|
+
commit(post)
|
71
|
+
end
|
72
|
+
|
73
|
+
def store(credit_card, options = {})
|
74
|
+
post = new_request
|
75
|
+
|
76
|
+
add_invoice(post, options)
|
77
|
+
add_credit_card(post, credit_card)
|
78
|
+
store_credit_card(post, options)
|
79
|
+
|
80
|
+
commit(post)
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def new_request
|
86
|
+
{
|
87
|
+
:pi => @options[:paystation_id], # paystation account id
|
88
|
+
:gi => @options[:gateway_id], # paystation gateway id
|
89
|
+
"2p" => "t", # two-party transaction type
|
90
|
+
:nr => "t", # -- redirect??
|
91
|
+
:df => "yymm" # date format: optional sometimes, required others
|
92
|
+
}
|
93
|
+
end
|
94
|
+
|
95
|
+
def add_customer_data(post, options)
|
96
|
+
post[:mc] = options[:customer]
|
97
|
+
end
|
98
|
+
|
99
|
+
def add_invoice(post, options)
|
100
|
+
requires!(options, :order_id)
|
101
|
+
|
102
|
+
post[:ms] = options[:order_id] # "Merchant Session", must be unique per request
|
103
|
+
post[:mo] = options[:invoice] # "Order Details", displayed in Paystation Admin
|
104
|
+
post[:mr] = options[:description] # "Merchant Reference Code", seen from Paystation Admin
|
105
|
+
end
|
106
|
+
|
107
|
+
def add_credit_card(post, credit_card)
|
108
|
+
|
109
|
+
post[:cn] = credit_card.number
|
110
|
+
post[:ct] = credit_card.type
|
111
|
+
post[:ex] = format_date(credit_card.month, credit_card.year)
|
112
|
+
post[:cc] = credit_card.verification_value if credit_card.verification_value?
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
# bill a token (stored via "store") rather than a Credit Card
|
117
|
+
def add_token(post, token)
|
118
|
+
post[:fp] = "t" # turn on "future payments" - what paystation calls Token Billing
|
119
|
+
post[:ft] = token
|
120
|
+
end
|
121
|
+
|
122
|
+
def store_credit_card(post, options)
|
123
|
+
|
124
|
+
post[:fp] = "t" # turn on "future payments" - what paystation calls Token Billing
|
125
|
+
post[:fs] = "t" # tells paystation to store right now, not bill
|
126
|
+
post[:ft] = options[:token] if options[:token] # specify a token to use that, or let Paystation generate one
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
def add_authorize_flag(post, options)
|
131
|
+
post[:pa] = "t" # tells Paystation that this is a pre-auth authorisation payment (account must be in pre-auth mode)
|
132
|
+
end
|
133
|
+
|
134
|
+
def add_authorization_token(post, auth_token, verification_value = nil)
|
135
|
+
post[:cp] = "t" # Capture Payment flag – tells Paystation this transaction should be treated as a capture payment
|
136
|
+
post[:cx] = auth_token
|
137
|
+
post[:cc] = verification_value
|
138
|
+
end
|
139
|
+
|
140
|
+
def add_amount(post, money, options)
|
141
|
+
|
142
|
+
post[:am] = amount(money)
|
143
|
+
post[:cu] = options[:currency] || currency(money)
|
144
|
+
|
145
|
+
end
|
146
|
+
|
147
|
+
def parse(xml_response)
|
148
|
+
response = {}
|
149
|
+
|
150
|
+
xml = REXML::Document.new(xml_response)
|
151
|
+
|
152
|
+
# for normal payments, the root node is <Response>
|
153
|
+
# for "future payments", it's <PaystationFuturePaymentResponse>
|
154
|
+
xml.elements.each("#{xml.root.name}/*") do |element|
|
155
|
+
response[element.name.underscore.to_sym] = element.text
|
156
|
+
end
|
157
|
+
|
158
|
+
response
|
159
|
+
end
|
160
|
+
|
161
|
+
def commit(post)
|
162
|
+
|
163
|
+
post[:tm] = "T" if test? # test mode
|
164
|
+
|
165
|
+
pstn_prefix_params = post.collect { |key, value| "pstn_#{key}=#{CGI.escape(value.to_s)}" }.join("&")
|
166
|
+
|
167
|
+
# need include paystation param as "initiator flag for payment engine"
|
168
|
+
data = ssl_post(URL, "#{pstn_prefix_params}&paystation=_empty")
|
169
|
+
response = parse(data)
|
170
|
+
message = message_from(response)
|
171
|
+
|
172
|
+
PaystationResponse.new(success?(response), message, response,
|
173
|
+
:test => (response[:tm] && response[:tm].downcase == "t"),
|
174
|
+
:authorization => response[:paystation_transaction_id]
|
175
|
+
)
|
176
|
+
end
|
177
|
+
|
178
|
+
def success?(response)
|
179
|
+
(response[:ec] == SUCCESSFUL_RESPONSE_CODE) || (response[:ec] == SUCCESSFUL_FUTURE_PAYMENT)
|
180
|
+
end
|
181
|
+
|
182
|
+
def message_from(response)
|
183
|
+
response[:em]
|
184
|
+
end
|
185
|
+
|
186
|
+
def format_date(month, year)
|
187
|
+
"#{format(year, :two_digits)}#{format(month, :two_digits)}"
|
188
|
+
end
|
189
|
+
|
190
|
+
end
|
191
|
+
|
192
|
+
class PaystationResponse < Response
|
193
|
+
# add a method to response so we can easily get the token
|
194
|
+
# for Validate transactions
|
195
|
+
def token
|
196
|
+
@params["future_payment_token"]
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|