n8_activemerchant 1.9.3
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 +574 -0
- data/CONTRIBUTORS +175 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +151 -0
- data/gem-public_cert.pem +20 -0
- data/lib/active_merchant.rb +49 -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 +161 -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 +169 -0
- data/lib/active_merchant/billing/gateways.rb +18 -0
- data/lib/active_merchant/billing/gateways/authorize_net.rb +654 -0
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +736 -0
- data/lib/active_merchant/billing/gateways/beanstream.rb +102 -0
- data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +244 -0
- data/lib/active_merchant/billing/gateways/beanstream_interac.rb +54 -0
- data/lib/active_merchant/billing/gateways/bogus.rb +102 -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 +210 -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 +406 -0
- data/lib/active_merchant/billing/gateways/data_cash.rb +593 -0
- data/lib/active_merchant/billing/gateways/efsnet.rb +229 -0
- data/lib/active_merchant/billing/gateways/elavon.rb +134 -0
- data/lib/active_merchant/billing/gateways/epay.rb +263 -0
- data/lib/active_merchant/billing/gateways/eway.rb +277 -0
- data/lib/active_merchant/billing/gateways/exact.rb +222 -0
- data/lib/active_merchant/billing/gateways/first_pay.rb +172 -0
- data/lib/active_merchant/billing/gateways/garanti.rb +222 -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 +253 -0
- data/lib/active_merchant/billing/gateways/jetpay.rb +270 -0
- data/lib/active_merchant/billing/gateways/linkpoint.rb +449 -0
- data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +154 -0
- data/lib/active_merchant/billing/gateways/merchant_ware.rb +283 -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 +205 -0
- data/lib/active_merchant/billing/gateways/net_registry.rb +189 -0
- data/lib/active_merchant/billing/gateways/netaxept.rb +234 -0
- data/lib/active_merchant/billing/gateways/netbilling.rb +168 -0
- data/lib/active_merchant/billing/gateways/ogone.rb +279 -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 +203 -0
- data/lib/active_merchant/billing/gateways/payflow.rb +236 -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 +138 -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 +230 -0
- data/lib/active_merchant/billing/gateways/paypal.rb +121 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +326 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +38 -0
- data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
- data/lib/active_merchant/billing/gateways/paypal_express.rb +145 -0
- data/lib/active_merchant/billing/gateways/paypal_express_common.rb +20 -0
- data/lib/active_merchant/billing/gateways/paysimple/paysimple.rb +333 -0
- data/lib/active_merchant/billing/gateways/paysimple/usaepay.wsdl +1596 -0
- data/lib/active_merchant/billing/gateways/plugnpay.rb +292 -0
- data/lib/active_merchant/billing/gateways/psigate.rb +214 -0
- data/lib/active_merchant/billing/gateways/psl_card.rb +304 -0
- data/lib/active_merchant/billing/gateways/quickpay.rb +213 -0
- data/lib/active_merchant/billing/gateways/realex.rb +200 -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 +315 -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 +157 -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 +265 -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 +418 -0
- data/lib/active_merchant/billing/gateways/usa_epay.rb +194 -0
- data/lib/active_merchant/billing/gateways/usa_epay_soap.rb +154 -0
- data/lib/active_merchant/billing/gateways/verifi.rb +228 -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/integrations.rb +17 -0
- data/lib/active_merchant/billing/integrations/action_view_helper.rb +68 -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 +188 -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/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/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 +17 -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 +37 -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 +109 -0
- data/lib/active_merchant/billing/integrations/sage_pay_form/notification.rb +204 -0
- data/lib/active_merchant/billing/integrations/sage_pay_form/return.rb +27 -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/response.rb +32 -0
- data/lib/active_merchant/common.rb +14 -0
- data/lib/active_merchant/common/connection.rb +162 -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 +61 -0
- data/lib/active_merchant/common/requires_parameters.rb +16 -0
- data/lib/active_merchant/common/utils.rb +18 -0
- data/lib/active_merchant/common/validateable.rb +76 -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 +270 -0
|
@@ -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,145 @@
|
|
|
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?cmd=_express-checkout&token='
|
|
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
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
xml.target!
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def build_setup_request(action, money, options)
|
|
90
|
+
currency_code = options[:currency] || currency(money)
|
|
91
|
+
|
|
92
|
+
xml = Builder::XmlMarkup.new :indent => 2
|
|
93
|
+
xml.tag! 'SetExpressCheckoutReq', 'xmlns' => PAYPAL_NAMESPACE do
|
|
94
|
+
xml.tag! 'SetExpressCheckoutRequest', 'xmlns:n2' => EBAY_NAMESPACE do
|
|
95
|
+
xml.tag! 'n2:Version', API_VERSION
|
|
96
|
+
xml.tag! 'n2:SetExpressCheckoutRequestDetails' do
|
|
97
|
+
xml.tag! 'n2:PaymentAction', action
|
|
98
|
+
xml.tag! 'n2:OrderTotal', amount(money).to_f.zero? ? localized_amount(100, currency_code) : localized_amount(money, currency_code), 'currencyID' => currency_code
|
|
99
|
+
if options[:max_amount]
|
|
100
|
+
xml.tag! 'n2:MaxAmount', localized_amount(options[:max_amount], currency_code), 'currencyID' => currency_code
|
|
101
|
+
end
|
|
102
|
+
add_address(xml, 'n2:Address', options[:shipping_address] || options[:address])
|
|
103
|
+
xml.tag! 'n2:AddressOverride', options[:address_override] ? '1' : '0'
|
|
104
|
+
xml.tag! 'n2:NoShipping', options[:no_shipping] ? '1' : '0'
|
|
105
|
+
xml.tag! 'n2:ReturnURL', options[:return_url]
|
|
106
|
+
xml.tag! 'n2:CancelURL', options[:cancel_return_url]
|
|
107
|
+
xml.tag! 'n2:IPAddress', options[:ip] unless options[:ip].blank?
|
|
108
|
+
xml.tag! 'n2:OrderDescription', options[:description]
|
|
109
|
+
xml.tag! 'n2:BuyerEmail', options[:email] unless options[:email].blank?
|
|
110
|
+
xml.tag! 'n2:InvoiceID', options[:order_id]
|
|
111
|
+
|
|
112
|
+
if options[:billing_agreement]
|
|
113
|
+
xml.tag! 'n2:BillingAgreementDetails' do
|
|
114
|
+
xml.tag! 'n2:BillingType', options[:billing_agreement][:type]
|
|
115
|
+
xml.tag! 'n2:BillingAgreementDescription', options[:billing_agreement][:description]
|
|
116
|
+
xml.tag! 'n2:PaymentType', options[:billing_agreement][:payment_type] || 'InstantOnly'
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Customization of the payment page
|
|
121
|
+
xml.tag! 'n2:PageStyle', options[:page_style] unless options[:page_style].blank?
|
|
122
|
+
xml.tag! 'n2:cpp-image-header', options[:header_image] unless options[:header_image].blank?
|
|
123
|
+
xml.tag! 'n2:cpp-header-back-color', options[:header_background_color] unless options[:header_background_color].blank?
|
|
124
|
+
xml.tag! 'n2:cpp-header-border-color', options[:header_border_color] unless options[:header_border_color].blank?
|
|
125
|
+
xml.tag! 'n2:cpp-payflow-color', options[:background_color] unless options[:background_color].blank?
|
|
126
|
+
|
|
127
|
+
if options[:allow_guest_checkout]
|
|
128
|
+
xml.tag! 'n2:SolutionType', 'Sole'
|
|
129
|
+
xml.tag! 'n2:LandingPage', 'Billing'
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
xml.tag! 'n2:LocaleCode', options[:locale] unless options[:locale].blank?
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
xml.target!
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def build_response(success, message, response, options = {})
|
|
141
|
+
PaypalExpressResponse.new(success, message, response, options)
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
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?cmd=_express-checkout&token='
|
|
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}.update(options)
|
|
16
|
+
options[:review] ? "#{redirect_url}#{token}" : "#{redirect_url}#{token}&useraction=commit"
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
gem 'soap4r', '>= 1.5.7' # 1.5.7 or higher
|
|
3
|
+
require 'soap/wsdlDriver'
|
|
4
|
+
require 'digest/sha1'
|
|
5
|
+
|
|
6
|
+
# [PaySimple](http://www.paysimple.com) is a payment gateway providing credit card
|
|
7
|
+
# processing, check processing and recurring / subscription billing services.
|
|
8
|
+
#
|
|
9
|
+
# This library provides a simple interface to find, create, edit, delete, and query subscriptions
|
|
10
|
+
# and single transactions using the PaySimple SOAP API. [PaySimple API](https://www.usaepay.com/developer/docs/beta6)
|
|
11
|
+
#
|
|
12
|
+
# == Installation
|
|
13
|
+
#
|
|
14
|
+
# The simple way:
|
|
15
|
+
# $ sudo gem install paysimple
|
|
16
|
+
#
|
|
17
|
+
# Directly from repository:
|
|
18
|
+
# $ ./script/plugin install svn://svn.roundhaus.com/daikini/plugins/paysimple
|
|
19
|
+
#
|
|
20
|
+
# Directly from repository using piston:
|
|
21
|
+
# $ piston import svn://svn.roundhaus.com/daikini/plugins/paysimple vendor/plugins/paysimple
|
|
22
|
+
#
|
|
23
|
+
# == Configuration
|
|
24
|
+
#
|
|
25
|
+
# When you signup for a PaySimple account you can setup a source key and optionally a pin and client ip address.
|
|
26
|
+
# These are your credentials when using the PaySimple API.
|
|
27
|
+
#
|
|
28
|
+
# PaySimple.source = "My API Source Key Name"
|
|
29
|
+
# PaySimple.key = "123456"
|
|
30
|
+
# PaySimple.pin = "topsecret"
|
|
31
|
+
# PaySimple.client_ip = "192.168.0.1"
|
|
32
|
+
#
|
|
33
|
+
class PaySimple
|
|
34
|
+
VERSION = "1.1.0"
|
|
35
|
+
WSDL_URL = File.dirname(__FILE__) + '/usaepay.wsdl'
|
|
36
|
+
|
|
37
|
+
class << self
|
|
38
|
+
attr_accessor :source, :key, :pin, :client_ip
|
|
39
|
+
end
|
|
40
|
+
self.key = "Spreedly"
|
|
41
|
+
|
|
42
|
+
class Subscription
|
|
43
|
+
class << self
|
|
44
|
+
# # Bill Jennifer $12.00 monthly
|
|
45
|
+
# begin
|
|
46
|
+
# customer_number = PaySimple::Subscription.create(
|
|
47
|
+
# :CustomerID => 12345,
|
|
48
|
+
# :BillingAddress => {
|
|
49
|
+
# :FirstName => "Jennifer",
|
|
50
|
+
# :LastName => "Smith"
|
|
51
|
+
# },
|
|
52
|
+
# :CreditCardData => {
|
|
53
|
+
# :CardNumber => "4444555566667779",
|
|
54
|
+
# :CardExpiration => "0908"
|
|
55
|
+
# },
|
|
56
|
+
# :Schedule => :monthly,
|
|
57
|
+
# :Next => "2008-09-05",
|
|
58
|
+
# :Amount => 12.00
|
|
59
|
+
# )
|
|
60
|
+
#
|
|
61
|
+
# puts "Subscription created with Customer Number: #{customer_number}"
|
|
62
|
+
# rescue Exception => e
|
|
63
|
+
# puts "An error occurred: #{e.message}"
|
|
64
|
+
# end
|
|
65
|
+
def create(options)
|
|
66
|
+
PaySimple.send_request(:addCustomer, { :Source => PaySimple.source, :NumLeft => 0, :Enabled => true }.merge(options))
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# # Update subscription to use new credit card
|
|
70
|
+
# begin
|
|
71
|
+
# customer_number = 12345
|
|
72
|
+
# response = PaySimple::Subscription.update(
|
|
73
|
+
# customer_number,
|
|
74
|
+
# :CreditCardData => {
|
|
75
|
+
# :CardNumber => "4444555566667779",
|
|
76
|
+
# :CardExpiration => "0908"
|
|
77
|
+
# }
|
|
78
|
+
# )
|
|
79
|
+
#
|
|
80
|
+
# puts "Subscription updated"
|
|
81
|
+
# rescue Exception => e
|
|
82
|
+
# puts "An error occurred: #{e.message}"
|
|
83
|
+
# end
|
|
84
|
+
def update(customer_number, options)
|
|
85
|
+
customer = find(customer_number)
|
|
86
|
+
options = PaySimple.symbolize_hash(options)
|
|
87
|
+
|
|
88
|
+
# Add the existing customer properties to the options hash unless they already exist
|
|
89
|
+
[
|
|
90
|
+
:CustomerID,
|
|
91
|
+
:SendReceipt,
|
|
92
|
+
:ReceiptNote,
|
|
93
|
+
:Notes,
|
|
94
|
+
:User,
|
|
95
|
+
:Source,
|
|
96
|
+
:Schedule,
|
|
97
|
+
:Next,
|
|
98
|
+
:NumLeft,
|
|
99
|
+
:Amount,
|
|
100
|
+
:Enabled,
|
|
101
|
+
:CustomData,
|
|
102
|
+
:Description,
|
|
103
|
+
:OrderID
|
|
104
|
+
].each do |property|
|
|
105
|
+
options[property] = customer[property.to_s] unless options.has_key?(property)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Add the existing customer address properties to the options hash unless they already exist
|
|
109
|
+
options[:BillingAddress] ||= {}
|
|
110
|
+
[
|
|
111
|
+
:FirstName,
|
|
112
|
+
:LastName,
|
|
113
|
+
:Company,
|
|
114
|
+
:Street,
|
|
115
|
+
:Street2,
|
|
116
|
+
:City,
|
|
117
|
+
:State,
|
|
118
|
+
:Zip,
|
|
119
|
+
:Country,
|
|
120
|
+
:Phone,
|
|
121
|
+
:Fax,
|
|
122
|
+
:Email
|
|
123
|
+
].each do |property|
|
|
124
|
+
options[:BillingAddress][property] = customer["BillingAddress"][property.to_s] unless options[:BillingAddress].has_key?(property)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Add the existing customer credit card properties to the options hash unless they already exist
|
|
128
|
+
options[:CreditCardData] ||= {}
|
|
129
|
+
[
|
|
130
|
+
:CardNumber,
|
|
131
|
+
:CardExpiration,
|
|
132
|
+
:CardCode,
|
|
133
|
+
:AvsStreet,
|
|
134
|
+
:AvsZip,
|
|
135
|
+
:CardPresent,
|
|
136
|
+
:MagStripe,
|
|
137
|
+
:TermType,
|
|
138
|
+
:MagSupport,
|
|
139
|
+
:XID,
|
|
140
|
+
:CAVV,
|
|
141
|
+
:ECI,
|
|
142
|
+
:InternalCardAuth,
|
|
143
|
+
:Pares
|
|
144
|
+
].each do |property|
|
|
145
|
+
options[:CreditCardData][property] = customer["CreditCardData"][property.to_s] unless options[:CreditCardData].has_key?(property)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
# Add the existing customer check properties to the options hash unless they already exist
|
|
149
|
+
options[:CheckData] ||= {}
|
|
150
|
+
[
|
|
151
|
+
:CheckNumber,
|
|
152
|
+
:Routing,
|
|
153
|
+
:Account,
|
|
154
|
+
:SSN,
|
|
155
|
+
:DriversLicense,
|
|
156
|
+
:DriversLicenseState
|
|
157
|
+
].each do |property|
|
|
158
|
+
options[:CheckData][property] = customer["CheckData"][property.to_s] unless options[:CheckData].has_key?(property)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
PaySimple.send_request(:updateCustomer, customer_number, { :Source => PaySimple.source, :NumLeft => 0 }.merge(options))
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# # Delete subscription
|
|
165
|
+
# begin
|
|
166
|
+
# customer_number = 12345
|
|
167
|
+
# response = PaySimple::Subscription.delete(customer_number)
|
|
168
|
+
#
|
|
169
|
+
# puts "Subscription removed from active use."
|
|
170
|
+
# rescue Exception => e
|
|
171
|
+
# puts "An error occurred: #{e.message}"
|
|
172
|
+
# end
|
|
173
|
+
def delete(customer_number)
|
|
174
|
+
PaySimple.send_request(:deleteCustomer, customer_number)
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# # Find an existing subscription
|
|
178
|
+
# begin
|
|
179
|
+
# customer_number = 12345
|
|
180
|
+
# customer = PaySimple::Subscription.find(customer_number)
|
|
181
|
+
#
|
|
182
|
+
# puts "Found subscription for #{customer["BillingAddress"]["FirstName"], customer["BillingAddress"]["LastName"]].join(" ")}"
|
|
183
|
+
# rescue Exception => e
|
|
184
|
+
# puts "An error occurred: #{e.message}"
|
|
185
|
+
# end
|
|
186
|
+
def find(customer_number)
|
|
187
|
+
PaySimple.send_request(:getCustomer, customer_number)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# # Process one-time sale against existing subscription
|
|
191
|
+
# begin
|
|
192
|
+
# customer_number = 12345
|
|
193
|
+
# response = PaySimple::Subscription.charge(customer_number, :Amount => 34.56)
|
|
194
|
+
#
|
|
195
|
+
# if response["Response"] == "Approved"
|
|
196
|
+
# puts "One-time charge successful."
|
|
197
|
+
# else
|
|
198
|
+
# puts "An error occurred: #{response["Error"]}"
|
|
199
|
+
# end
|
|
200
|
+
# rescue Exception => e
|
|
201
|
+
# puts "An error occurred: #{e.message}"
|
|
202
|
+
# end
|
|
203
|
+
def charge(customer_number, options, command = "", payment_method_id = 0)
|
|
204
|
+
PaySimple.send_request(:runCustomerTransaction, customer_number, options, command, payment_method_id)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# # Search for transactions
|
|
208
|
+
# begin
|
|
209
|
+
# response = PaySimple::Subscription.query(
|
|
210
|
+
# [
|
|
211
|
+
# { :Field => "amount", :Type => "gt", :Value => "5.0" }
|
|
212
|
+
# ]
|
|
213
|
+
# )
|
|
214
|
+
#
|
|
215
|
+
# response.transactions.each do |transaction|
|
|
216
|
+
# puts "CustomerID = #{transaction["CustomerID"]}, Amount = #{transaction["Details"]["Amount"]}"
|
|
217
|
+
# end
|
|
218
|
+
# rescue Exception => e
|
|
219
|
+
# puts "An error occurred: #{e.message}"
|
|
220
|
+
# end
|
|
221
|
+
def query(options)
|
|
222
|
+
match_all = options.delete(:match_all)
|
|
223
|
+
start = options.delete(:start) || 0
|
|
224
|
+
limit = options.delete(:limit) || 100
|
|
225
|
+
PaySimple.send_request(:searchTransactions, options, match_all, start, limit)
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
class Transaction
|
|
231
|
+
class << self
|
|
232
|
+
# # Bill Jennifer $12.00
|
|
233
|
+
# begin
|
|
234
|
+
# transaction = PaySimple::Transaction.create(
|
|
235
|
+
# :CustomerID => 12345,
|
|
236
|
+
# :AccountHolder => "Jennifer Smith",
|
|
237
|
+
# :CreditCardData => {
|
|
238
|
+
# :CardNumber => "4444555566667779",
|
|
239
|
+
# :CardExpiration => "0908"
|
|
240
|
+
# },
|
|
241
|
+
# :Details => {
|
|
242
|
+
# :Amount => 12.00
|
|
243
|
+
# }
|
|
244
|
+
# )
|
|
245
|
+
#
|
|
246
|
+
# puts "Sale transaction created with Reference Number: #{transaction["RefNum"]}"
|
|
247
|
+
# rescue Exception => e
|
|
248
|
+
# puts "An error occurred: #{e.message}"
|
|
249
|
+
# end
|
|
250
|
+
#
|
|
251
|
+
# # Credit Jennifer $12.00
|
|
252
|
+
# begin
|
|
253
|
+
# transaction = PaySimple::Transaction.create(
|
|
254
|
+
# :CustomerID => 12345,
|
|
255
|
+
# :AccountHolder => "Jennifer Smith",
|
|
256
|
+
# :CreditCardData => {
|
|
257
|
+
# :CardNumber => "4444555566667779",
|
|
258
|
+
# :CardExpiration => "0908"
|
|
259
|
+
# },
|
|
260
|
+
# :Details => {
|
|
261
|
+
# :Amount => -12.00
|
|
262
|
+
# }
|
|
263
|
+
# )
|
|
264
|
+
#
|
|
265
|
+
# puts "Credit transaction created with Reference Number: #{transaction["RefNum"]}"
|
|
266
|
+
# rescue Exception => e
|
|
267
|
+
# puts "An error occurred: #{e.message}"
|
|
268
|
+
# end
|
|
269
|
+
def create(options)
|
|
270
|
+
options = PaySimple.symbolize_hash(options)
|
|
271
|
+
options[:Command] ||= (options[:Details][:Amount] > 0.0 ? :sale : :credit)
|
|
272
|
+
options[:Details][:Amount] = options[:Details][:Amount].abs
|
|
273
|
+
PaySimple.send_request(:runTransaction, { :Source => PaySimple.source }.merge(options))
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
# # Void an unsettled transaction
|
|
277
|
+
# begin
|
|
278
|
+
# reference_number = 12345
|
|
279
|
+
# result = PaySimple::Transaction.void(reference_number)
|
|
280
|
+
#
|
|
281
|
+
# if result
|
|
282
|
+
# puts "Transaction was voided"
|
|
283
|
+
# else
|
|
284
|
+
# puts "Unable to void transaction"
|
|
285
|
+
# end
|
|
286
|
+
# rescue Exception => e
|
|
287
|
+
# puts "An error occurred: #{e.message}"
|
|
288
|
+
# end
|
|
289
|
+
def void(reference_number)
|
|
290
|
+
PaySimple.send_request(:voidTransaction, reference_number)
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
# # Find an existing transaction
|
|
294
|
+
# begin
|
|
295
|
+
# reference_number = 12345
|
|
296
|
+
# transaction = PaySimple::Transaction.find(reference_number)
|
|
297
|
+
#
|
|
298
|
+
# puts "Found transaction"
|
|
299
|
+
# rescue Exception => e
|
|
300
|
+
# puts "An error occurred: #{e.message}"
|
|
301
|
+
# end
|
|
302
|
+
def find(reference_number)
|
|
303
|
+
PaySimple.send_request(:getTransaction, reference_number)
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
class << self
|
|
309
|
+
def symbolize_hash(hash)
|
|
310
|
+
hash.inject({}) { |h,(k,v)| h[k.to_sym] = v; h }
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
def token
|
|
314
|
+
seed = "#{Time.now.to_i}#{rand(999999)}"
|
|
315
|
+
hash = Digest::SHA1.hexdigest([key, seed, pin].join)
|
|
316
|
+
{
|
|
317
|
+
'SourceKey' => key,
|
|
318
|
+
'PinHash' => {
|
|
319
|
+
'Type' => "sha1",
|
|
320
|
+
'Seed' => seed,
|
|
321
|
+
'HashValue' => hash
|
|
322
|
+
},
|
|
323
|
+
'ClientIP' => client_ip
|
|
324
|
+
}
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
def send_request(request, *args)
|
|
328
|
+
@driver ||= SOAP::WSDLDriverFactory.new(WSDL_URL).create_rpc_driver
|
|
329
|
+
@driver.send(request, token, *args)
|
|
330
|
+
end
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
end
|