├── .yardopts ├── lib ├── activemerchant.rb ├── active_merchant │ ├── version.rb │ ├── billing │ │ ├── integrations │ │ │ ├── bogus │ │ │ │ ├── return.rb │ │ │ │ ├── notification.rb │ │ │ │ └── helper.rb │ │ │ ├── gestpay │ │ │ │ ├── return.rb │ │ │ │ └── common.rb │ │ │ ├── nochex │ │ │ │ └── return.rb │ │ │ ├── paypal │ │ │ │ └── return.rb │ │ │ ├── chronopay │ │ │ │ └── return.rb │ │ │ ├── dotpay │ │ │ │ └── return.rb │ │ │ ├── directebanking │ │ │ │ └── return.rb │ │ │ ├── paypal_payments_advanced │ │ │ │ └── helper.rb │ │ │ ├── valitor │ │ │ │ ├── return.rb │ │ │ │ └── notification.rb │ │ │ ├── robokassa │ │ │ │ ├── return.rb │ │ │ │ ├── common.rb │ │ │ │ ├── notification.rb │ │ │ │ └── helper.rb │ │ │ ├── two_checkout │ │ │ │ └── return.rb │ │ │ ├── paypal_payments_advanced.rb │ │ │ ├── quickpay.rb │ │ │ ├── epay.rb │ │ │ ├── verkkomaksut.rb │ │ │ ├── dotpay.rb │ │ │ ├── payflow_link.rb │ │ │ ├── bogus.rb │ │ │ ├── moneybookers.rb │ │ │ ├── chronopay.rb │ │ │ ├── world_pay.rb │ │ │ ├── sage_pay_form │ │ │ │ ├── return.rb │ │ │ │ └── encryption.rb │ │ │ ├── dwolla │ │ │ │ ├── return.rb │ │ │ │ ├── helper.rb │ │ │ │ └── notification.rb │ │ │ ├── gestpay.rb │ │ │ ├── hi_trust.rb │ │ │ ├── direc_pay │ │ │ │ ├── return.rb │ │ │ │ └── status.rb │ │ │ ├── valitor.rb │ │ │ ├── return.rb │ │ │ ├── dwolla.rb │ │ │ ├── authorize_net_sim.rb │ │ │ ├── paypal.rb │ │ │ ├── e_payment_plans │ │ │ │ └── helper.rb │ │ │ ├── sage_pay_form.rb │ │ │ ├── hi_trust │ │ │ │ ├── notification.rb │ │ │ │ └── helper.rb │ │ │ ├── direc_pay.rb │ │ │ ├── two_checkout.rb │ │ │ ├── e_payment_plans.rb │ │ │ ├── directebanking.rb │ │ │ ├── robokassa.rb │ │ │ ├── epay │ │ │ │ └── helper.rb │ │ │ ├── verkkomaksut │ │ │ │ └── notification.rb │ │ │ └── moneybookers │ │ │ │ └── helper.rb │ │ ├── gateways │ │ │ ├── braintree │ │ │ │ └── braintree_common.rb │ │ │ ├── payflow │ │ │ │ ├── payflow_response.rb │ │ │ │ └── payflow_express_response.rb │ │ │ ├── braintree.rb │ │ │ ├── nmi.rb │ │ │ ├── payflow_express_uk.rb │ │ │ ├── paypal_ca.rb │ │ │ ├── braintree_orange.rb │ │ │ ├── ideal │ │ │ │ ├── ideal_response.rb │ │ │ │ └── ideal_rabobank.pem │ │ │ ├── payflow_uk.rb │ │ │ ├── usa_epay.rb │ │ │ ├── transax.rb │ │ │ ├── secure_pay.rb │ │ │ ├── card_save.rb │ │ │ ├── paypal_express_common.rb │ │ │ ├── modern_payments.rb │ │ │ ├── paypal │ │ │ │ └── paypal_express_response.rb │ │ │ ├── beanstream_interac.rb │ │ │ └── paypal_digital_goods.rb │ │ ├── integrations.rb │ │ ├── gateways.rb │ │ ├── credit_card_formatting.rb │ │ ├── expiry_date.rb │ │ ├── response.rb │ │ ├── cvv_result.rb │ │ └── base.rb │ └── billing.rb └── support │ ├── outbound_hosts.rb │ └── gateway_support.rb ├── Gemfile_rails31 ├── Gemfile_rails32 ├── generators ├── gateway │ ├── USAGE │ ├── templates │ │ ├── gateway_test.rb │ │ └── remote_gateway_test.rb │ └── gateway_generator.rb └── integration │ ├── USAGE │ └── templates │ ├── module_test.rb │ ├── integration.rb │ ├── notification_test.rb │ ├── helper.rb │ └── helper_test.rb ├── Gemfile_rails30 ├── .gitignore ├── rails └── init.rb ├── init.rb ├── .travis.yml ├── test ├── unit │ ├── integrations │ │ ├── returns │ │ │ ├── return_test.rb │ │ │ ├── nochex_return_test.rb │ │ │ ├── paypal_return_test.rb │ │ │ ├── gestpay_return_test.rb │ │ │ ├── dotpay_return_test.rb │ │ │ ├── chronopay_return_test.rb │ │ │ ├── directebanking_return_test.rb │ │ │ ├── hi_trust_return_test.rb │ │ │ ├── two_checkout_return_test.rb │ │ │ ├── dwolla_return_test.rb │ │ │ └── direc_pay_return_test.rb │ │ ├── epay_module_test.rb │ │ ├── quickpay_module_test.rb │ │ ├── nochex_module_test.rb │ │ ├── dotpay_module_test.rb │ │ ├── hi_trust_module_test.rb │ │ ├── chronopay_module_test.rb │ │ ├── verkkomaksut_module_test.rb │ │ ├── dwolla_module_test.rb │ │ ├── moneybookers_module_test.rb │ │ ├── helpers │ │ │ ├── hi_trust_helper_test.rb │ │ │ ├── bogus_helper_test.rb │ │ │ ├── robokassa_helper_test.rb │ │ │ ├── epay_helper_test.rb │ │ │ ├── dwolla_helper_test.rb │ │ │ ├── quickpay_helper_test.rb │ │ │ ├── nochex_helper_test.rb │ │ │ ├── authorize_net_sim_helper_test.rb │ │ │ └── e_payment_plans_helper_test.rb │ │ ├── direc_pay_module_test.rb │ │ ├── bogus_module_test.rb │ │ ├── world_pay_module_test.rb │ │ ├── gestpay_module_test.rb │ │ ├── e_payment_plans_module_test.rb │ │ ├── paypal_module_test.rb │ │ ├── robokassa_module_test.rb │ │ ├── sage_pay_form_module_test.rb │ │ ├── two_checkout_module_test.rb │ │ ├── notifications │ │ │ ├── robokassa_notification_test.rb │ │ │ ├── verkkomaksut_notification_test.rb │ │ │ ├── e_payment_plans_notification_test.rb │ │ │ ├── epay_notification_test.rb │ │ │ ├── nochex_notification_test.rb │ │ │ ├── dwolla_notification_test.rb │ │ │ └── hi_trust_notification_test.rb │ │ └── valitor_module_test.rb │ ├── gateways │ │ ├── nmi_test.rb │ │ ├── usa_epay_test.rb │ │ ├── payflow_uk_test.rb │ │ ├── braintree_test.rb │ │ ├── secure_pay_tech_test.rb │ │ ├── sallie_mae_test.rb │ │ ├── gateway_test.rb │ │ └── netbilling_test.rb │ ├── generators │ │ ├── test_generator_helper.rb │ │ ├── test_gateway_generator.rb │ │ └── test_integration_generator.rb │ ├── credit_card_formatting_test.rb │ ├── cvv_result_test.rb │ ├── expiry_date_test.rb │ ├── response_test.rb │ ├── avs_result_test.rb │ └── base_test.rb ├── remote │ ├── integrations │ │ ├── remote_direc_pay_integration_test.rb │ │ ├── remote_paypal_integration_test.rb │ │ └── remote_gestpay_integration_test.rb │ └── gateways │ │ ├── remote_secure_pay_test.rb │ │ ├── remote_trans_first_test.rb │ │ ├── remote_pay_secure_test.rb │ │ ├── remote_viaklix_test.rb │ │ ├── remote_beanstream_interac_test.rb │ │ ├── remote_paypal_express_test.rb │ │ ├── remote_psigate_test.rb │ │ ├── remote_sallie_mae_test.rb │ │ ├── remote_modern_payments_test.rb │ │ ├── remote_sage_virtual_check_test.rb │ │ ├── remote_secure_pay_tech_test.rb │ │ ├── remote_modern_payments_cim_test.rb │ │ ├── remote_instapay_test.rb │ │ ├── remote_exact_test.rb │ │ ├── remote_eway_managed_test.rb │ │ ├── remote_garanti_test.rb │ │ └── remote_eway_test.rb ├── comm_stub.rb └── schema │ └── paypal │ └── EnhancedDataTypes.xsd ├── script ├── destroy └── generate ├── RELEASING ├── Gemfile ├── MIT-LICENSE ├── gem-public_cert.pem └── activemerchant.gemspec /.yardopts: -------------------------------------------------------------------------------- 1 | - GettingStarted.md 2 | -------------------------------------------------------------------------------- /lib/activemerchant.rb: -------------------------------------------------------------------------------- 1 | require 'active_merchant' -------------------------------------------------------------------------------- /Gemfile_rails31: -------------------------------------------------------------------------------- 1 | gem 'activesupport', '3.1.0' 2 | gem 'rails', '3.1.0' 3 | -------------------------------------------------------------------------------- /Gemfile_rails32: -------------------------------------------------------------------------------- 1 | gem 'activesupport', '3.2.1' 2 | gem 'rails', '3.2.1' 3 | -------------------------------------------------------------------------------- /generators/gateway/USAGE: -------------------------------------------------------------------------------- 1 | Description: 2 | 3 | 4 | Usage: 5 | 6 | -------------------------------------------------------------------------------- /Gemfile_rails30: -------------------------------------------------------------------------------- 1 | gem 'activesupport', '3.0.11' 2 | gem 'rails', '3.0.11' 3 | -------------------------------------------------------------------------------- /generators/integration/USAGE: -------------------------------------------------------------------------------- 1 | Description: 2 | 3 | 4 | Usage: 5 | 6 | -------------------------------------------------------------------------------- /lib/active_merchant/version.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant 2 | VERSION = "1.24.0" 3 | end 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .yardoc 2 | pkg 3 | *.orig 4 | 5 | # ignore Gemfile.lock because we support multiple versions of Rails and 6 | # don't want to ship locked version requirements 7 | Gemfile.lock 8 | -------------------------------------------------------------------------------- /rails/init.rb: -------------------------------------------------------------------------------- 1 | # If Active Merchant is included into a Rails project as a gem, then 2 | # this file gets loaded instead of the top-level init.rb 3 | require File.dirname(__FILE__) + '/../init' 4 | -------------------------------------------------------------------------------- /init.rb: -------------------------------------------------------------------------------- 1 | require 'active_merchant' 2 | require 'active_merchant/billing/integrations/action_view_helper' 3 | ActionView::Base.send(:include, ActiveMerchant::Billing::Integrations::ActionViewHelper) 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | rvm: 2 | - 1.8.7 3 | - 1.9.2 4 | - 1.9.3 5 | - rbx 6 | - ree 7 | 8 | script: "bundle exec rake test:units" 9 | 10 | notifications: 11 | email: 12 | - integrations-team@shopify.com 13 | - nathaniel@talbott.ws 14 | -------------------------------------------------------------------------------- /test/unit/integrations/returns/return_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ReturnTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | 7 | def test_return 8 | r = Return.new('') 9 | assert r.success? 10 | end 11 | end -------------------------------------------------------------------------------- /test/unit/integrations/returns/nochex_return_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class NochexReturnTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def test_return 7 | r = Nochex::Return.new('') 8 | assert r.success? 9 | end 10 | end -------------------------------------------------------------------------------- /test/unit/integrations/returns/paypal_return_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class PaypalReturnTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def test_return 7 | r = Paypal::Return.new('') 8 | assert r.success? 9 | end 10 | end -------------------------------------------------------------------------------- /test/unit/gateways/nmi_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | require 'unit/gateways/authorize_net_test' 3 | 4 | class NmiTest < AuthorizeNetTest 5 | def setup 6 | super 7 | @gateway = NmiGateway.new( 8 | :login => 'X', 9 | :password => 'Y' 10 | ) 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /test/unit/integrations/returns/gestpay_return_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class GestpayReturnTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def test_return 7 | r = Gestpay::Return.new('') 8 | assert r.success? 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /test/unit/integrations/returns/dotpay_return_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class DotpayReturnTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def test_return_is_always_succesful 7 | r = Dotpay::Return.new("") 8 | assert r.success? 9 | end 10 | end -------------------------------------------------------------------------------- /test/unit/integrations/returns/chronopay_return_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ChronopayReturnTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def test_return 7 | r = Chronopay::Return.new('') 8 | assert r.success? 9 | end 10 | end 11 | 12 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/bogus/return.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module Bogus 5 | class Return < ActiveMerchant::Billing::Integrations::Return 6 | end 7 | end 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/gestpay/return.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module Gestpay 5 | class Return < ActiveMerchant::Billing::Integrations::Return 6 | end 7 | end 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/nochex/return.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module Nochex 5 | class Return < ActiveMerchant::Billing::Integrations::Return 6 | end 7 | end 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/paypal/return.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module Paypal 5 | class Return < ActiveMerchant::Billing::Integrations::Return 6 | end 7 | end 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /test/unit/integrations/epay_module_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class EpayModuleTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def test_notification_method 7 | assert_instance_of Epay::Notification, Epay.notification('name=cody', {}) 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/chronopay/return.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module Chronopay 5 | class Return < ActiveMerchant::Billing::Integrations::Return 6 | end 7 | end 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/dotpay/return.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module Dotpay 5 | class Return < ActiveMerchant::Billing::Integrations::Return 6 | end 7 | end 8 | end 9 | end 10 | end 11 | 12 | -------------------------------------------------------------------------------- /test/unit/integrations/quickpay_module_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class QuickpayModuleTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def test_notification_method 7 | assert_instance_of Quickpay::Notification, Quickpay.notification('name=cody', {}) 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /test/unit/integrations/returns/directebanking_return_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class DirectebankingReturnTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def test_return_is_always_succesful 7 | r = Directebanking::Return.new("") 8 | assert r.success? 9 | end 10 | end -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/bogus/notification.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module Bogus 5 | class Notification < ActiveMerchant::Billing::Integrations::Notification 6 | 7 | end 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/directebanking/return.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module Directebanking 5 | class Return < ActiveMerchant::Billing::Integrations::Return 6 | end 7 | end 8 | end 9 | end 10 | end 11 | 12 | -------------------------------------------------------------------------------- /generators/integration/templates/module_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class <%= class_name %>ModuleTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def test_notification_method 7 | assert_instance_of <%= class_name %>::Notification, <%= class_name %>.notification('name=cody') 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/gateways/braintree/braintree_common.rb: -------------------------------------------------------------------------------- 1 | module BraintreeCommon 2 | def self.included(base) 3 | base.supported_countries = ['US'] 4 | base.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club] 5 | base.homepage_url = 'http://www.braintreepaymentsolutions.com' 6 | base.display_name = 'Braintree' 7 | base.default_currency = 'USD' 8 | end 9 | end -------------------------------------------------------------------------------- /script/destroy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_ROOT = File.join(File.dirname(__FILE__), '..') 3 | 4 | begin 5 | require 'rubigen' 6 | rescue LoadError 7 | require 'rubygems' 8 | require 'rubigen' 9 | end 10 | require 'rubigen/scripts/destroy' 11 | 12 | ARGV.shift if ['--help', '-h'].include?(ARGV[0]) 13 | RubiGen::Base.use_component_sources! [:activemerchant, :rubygems, :test_unit] 14 | RubiGen::Scripts::Destroy.new.run(ARGV) 15 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/gateways/payflow/payflow_response.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | class PayflowResponse < Response 4 | def profile_id 5 | @params['profile_id'] 6 | end 7 | 8 | def payment_history 9 | @payment_history ||= @params['rp_payment_result'].collect{ |result| result.stringify_keys } rescue [] 10 | end 11 | end 12 | end 13 | end -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/paypal_payments_advanced/helper.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant 2 | module Billing 3 | module Integrations 4 | module PaypalPaymentsAdvanced 5 | class Helper < PayflowLink::Helper 6 | 7 | def initialize(order, account, options) 8 | super 9 | add_field('partner', 'PayPal') 10 | end 11 | end 12 | end 13 | end 14 | end 15 | end -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/valitor/return.rb: -------------------------------------------------------------------------------- 1 | require 'active_merchant/billing/integrations/valitor/response_fields' 2 | 3 | module ActiveMerchant #:nodoc: 4 | module Billing #:nodoc: 5 | module Integrations #:nodoc: 6 | module Valitor 7 | class Return < ActiveMerchant::Billing::Integrations::Return 8 | include ResponseFields 9 | end 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /script/generate: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_ROOT = File.join(File.dirname(__FILE__), '..') 3 | 4 | begin 5 | require 'rubigen' 6 | rescue LoadError 7 | require 'rubygems' 8 | require 'rubigen' 9 | end 10 | require 'rubigen/scripts/generate' 11 | 12 | ARGV.shift if ['--help', '-h'].include?(ARGV[0]) 13 | RubiGen::Base.use_component_sources! [:activemerchant, :rubygems, :test_unit] 14 | RubiGen::Scripts::Generate.new.run(ARGV) 15 | -------------------------------------------------------------------------------- /test/unit/integrations/nochex_module_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ChronopayModuleTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def test_notification_method 7 | assert_instance_of Nochex::Notification, Nochex.notification('name=cody', {}) 8 | end 9 | 10 | def test_return_method 11 | assert_instance_of Nochex::Return, Nochex.return('name=cody', {}) 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/valitor/notification.rb: -------------------------------------------------------------------------------- 1 | require 'active_merchant/billing/integrations/valitor/response_fields' 2 | 3 | module ActiveMerchant #:nodoc: 4 | module Billing #:nodoc: 5 | module Integrations #:nodoc: 6 | module Valitor 7 | class Notification < ActiveMerchant::Billing::Integrations::Notification 8 | include ResponseFields 9 | end 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /test/unit/integrations/dotpay_module_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class DotpayModuleTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def test_notification_method 7 | assert_instance_of Dotpay::Notification, Dotpay.notification('name=cody', :pin => '1234567890') 8 | end 9 | 10 | def test_return 11 | assert_instance_of Dotpay::Return, Dotpay.return("name=me", {}) 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /test/unit/integrations/hi_trust_module_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class HiTrustModuleTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def test_notification_method 7 | assert_instance_of HiTrust::Notification, HiTrust.notification('name=cody', {}) 8 | end 9 | 10 | def test_return_method 11 | assert_instance_of HiTrust::Return, HiTrust.return('name=cody', {}) 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/active_merchant/billing.rb: -------------------------------------------------------------------------------- 1 | require 'active_merchant/billing/avs_result' 2 | require 'active_merchant/billing/cvv_result' 3 | require 'active_merchant/billing/credit_card_methods' 4 | require 'active_merchant/billing/credit_card_formatting' 5 | require 'active_merchant/billing/credit_card' 6 | require 'active_merchant/billing/base' 7 | require 'active_merchant/billing/check' 8 | require 'active_merchant/billing/response' 9 | require 'active_merchant/billing/gateways' -------------------------------------------------------------------------------- /test/unit/integrations/chronopay_module_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ChronopayModuleTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def test_notification_method 7 | assert_instance_of Chronopay::Notification, Chronopay.notification('name=cody', {}) 8 | end 9 | 10 | def test_return_method 11 | assert_instance_of Chronopay::Return, Chronopay.return('name=cody', {}) 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /test/unit/integrations/verkkomaksut_module_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class VerkkomaksutModuleTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def test_notification_method 7 | assert_instance_of Verkkomaksut::Notification, Verkkomaksut.notification({"ORDER_NUMBER"=>"2", "TIMESTAMP"=>"1336058061", "PAID"=>"3DF5BB7E26", "METHOD"=>"4", "RETURN_AUTHCODE"=>"6B40F9B939D03EFE7573D61708FA4126"}) 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/robokassa/return.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module Robokassa 5 | class Return < ActiveMerchant::Billing::Integrations::Return 6 | def item_id 7 | @params['InvId'] 8 | end 9 | 10 | def amount 11 | @params['OutSum'] 12 | end 13 | end 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/two_checkout/return.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module TwoCheckout 5 | class Return < ActiveMerchant::Billing::Integrations::Return 6 | def success? 7 | params['credit_card_processed'] == 'Y' 8 | end 9 | 10 | def message 11 | 12 | end 13 | end 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /test/unit/integrations/dwolla_module_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | 4 | class DwollaModuleTest < Test::Unit::TestCase 5 | include ActiveMerchant::Billing::Integrations 6 | 7 | def test_notification_method 8 | assert_instance_of Dwolla::Notification, Dwolla.notification('{"OrderId":"order-1", "Result": "Error", "Message": "Invalid Credentials", "TestMode":true}') 9 | end 10 | 11 | def test_return 12 | assert_instance_of Dwolla::Return, Dwolla.return("dwolla=awesome") 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /test/unit/integrations/moneybookers_module_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class MoneybookersModuleTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def test_notification_method 7 | assert_instance_of Moneybookers::Notification, Moneybookers.notification('name=cody', :credential2 => 'secret') 8 | end 9 | 10 | def test_service_url 11 | url = 'https://www.moneybookers.com/app/payment.pl' 12 | assert_equal url, Moneybookers.service_url 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/gateways/braintree.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/braintree/braintree_common' 2 | 3 | module ActiveMerchant #:nodoc: 4 | module Billing #:nodoc: 5 | class BraintreeGateway < Gateway 6 | include BraintreeCommon 7 | 8 | def self.new(options={}) 9 | if options.has_key?(:login) 10 | BraintreeOrangeGateway.new(options) 11 | else 12 | BraintreeBlueGateway.new(options) 13 | end 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /test/unit/integrations/helpers/hi_trust_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class HiTrustHelperTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def setup 7 | @helper = HiTrust::Helper.new('order-500','cody@example.com', :amount => 500, :currency => 'USD') 8 | end 9 | 10 | def test_basic_helper_fields 11 | assert_field 'storeid', 'cody@example.com' 12 | assert_field 'amount', '500' 13 | assert_field 'ordernumber', 'order-500' 14 | assert_field 'currency', 'USD' 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /generators/integration/templates/integration.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/<%= name %>/helper.rb' 2 | require File.dirname(__FILE__) + '/<%= name %>/notification.rb' 3 | 4 | module ActiveMerchant #:nodoc: 5 | module Billing #:nodoc: 6 | module Integrations #:nodoc: 7 | module <%= class_name %> 8 | 9 | mattr_accessor :service_url 10 | self.service_url = 'https://www.example.com' 11 | 12 | def self.notification(post) 13 | Notification.new(post) 14 | end 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/gateways/nmi.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | class NmiGateway < AuthorizeNetGateway 4 | self.test_url = 'https://secure.networkmerchants.com/gateway/transact.dll' 5 | self.live_url = 'https://secure.networkmerchants.com/gateway/transact.dll' 6 | self.homepage_url = 'http://nmi.com/' 7 | self.display_name = 'NMI' 8 | self.supported_countries = ['US'] 9 | self.supported_cardtypes = [:visa, :master, :american_express, :discover] 10 | end 11 | end 12 | end 13 | 14 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant 2 | module Billing 3 | module Integrations 4 | 5 | Dir[File.dirname(__FILE__) + '/integrations/*.rb'].each do |f| 6 | 7 | # Get camelized class name 8 | filename = File.basename(f, '.rb') 9 | # Camelize the string to get the class name 10 | gateway_class = filename.camelize.to_sym 11 | 12 | # Register for autoloading 13 | autoload gateway_class, f 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/gateways/payflow_express_uk.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/payflow_express' 2 | 3 | module ActiveMerchant #:nodoc: 4 | module Billing #:nodoc: 5 | class PayflowExpressUkGateway < PayflowExpressGateway 6 | self.default_currency = 'GBP' 7 | self.partner = 'PayPalUk' 8 | 9 | self.supported_countries = ['GB'] 10 | self.homepage_url = 'https://www.paypal.com/uk/cgi-bin/webscr?cmd=_additional-payment-overview-outside' 11 | self.display_name = 'PayPal Express Checkout (UK)' 12 | end 13 | end 14 | end 15 | 16 | -------------------------------------------------------------------------------- /lib/support/outbound_hosts.rb: -------------------------------------------------------------------------------- 1 | require 'uri' 2 | require 'set' 3 | 4 | class OutboundHosts 5 | def self.list 6 | uris = Set.new 7 | 8 | Dir['lib/**/*.rb'].each do |file| 9 | content = File.read(file) 10 | 11 | content.each_line do |line| 12 | next if line =~ /homepage_url/ 13 | 14 | if line =~ /("|')(https:\/\/.*)("|')/ 15 | uri = URI.parse($2) 16 | uris << [uri.host, uri.port] 17 | end 18 | end 19 | end 20 | 21 | uris.each do |uri| 22 | puts "#{uri.first} #{uri.last}" 23 | end 24 | end 25 | end -------------------------------------------------------------------------------- /lib/active_merchant/billing/gateways/paypal_ca.rb: -------------------------------------------------------------------------------- 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 14 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/bogus/helper.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module Bogus 5 | class Helper < ActiveMerchant::Billing::Integrations::Helper 6 | mapping :account, 'account' 7 | mapping :order, 'order' 8 | mapping :amount, 'amount' 9 | mapping :currency, 'currency' 10 | mapping :customer, :first_name => 'first_name', 11 | :last_name => 'last_name' 12 | 13 | end 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /test/unit/generators/test_generator_helper.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | require 'fileutils' 3 | 4 | # Must set before requiring generator libs. 5 | TMP_ROOT = File.dirname(__FILE__) + "/tmp" unless defined?(TMP_ROOT) 6 | PROJECT_NAME = "myproject" unless defined?(PROJECT_NAME) 7 | app_root = File.join(TMP_ROOT, PROJECT_NAME) 8 | if defined?(APP_ROOT) 9 | APP_ROOT.replace(app_root) 10 | else 11 | APP_ROOT = app_root 12 | end 13 | 14 | begin 15 | require 'rubigen' 16 | rescue LoadError 17 | require 'rubygems' 18 | require 'rubigen' 19 | end 20 | require 'rubigen/helpers/generator_test_helper' 21 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/gateways.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant 2 | module Billing 3 | autoload :Gateway, 'active_merchant/billing/gateway' 4 | 5 | Dir[File.dirname(__FILE__) + '/gateways/**/*.rb'].each do |f| 6 | 7 | # Get camelized class name 8 | filename = File.basename(f, '.rb') 9 | # Add _gateway suffix 10 | gateway_name = filename + '_gateway' 11 | # Camelize the string to get the class name 12 | gateway_class = gateway_name.camelize 13 | 14 | # Register for autoloading 15 | autoload gateway_class, f 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/paypal_payments_advanced.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant 2 | module Billing 3 | module Integrations 4 | module PaypalPaymentsAdvanced 5 | autoload :Helper, 'active_merchant/billing/integrations/paypal_payments_advanced/helper.rb' 6 | 7 | mattr_accessor :service_url 8 | self.service_url = 'https://payflowlink.paypal.com' 9 | 10 | def self.notification(post, options = {}) 11 | PayflowLink::Notification.new(post) 12 | end 13 | 14 | def self.return(query_string, options = {}) 15 | Return.new(query_string) 16 | end 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/gateways/braintree_orange.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/smart_ps.rb' 2 | require File.dirname(__FILE__) + '/braintree/braintree_common' 3 | 4 | module ActiveMerchant #:nodoc: 5 | module Billing #:nodoc: 6 | class BraintreeOrangeGateway < SmartPs 7 | include BraintreeCommon 8 | 9 | self.display_name = 'Braintree (Orange Platform)' 10 | 11 | def api_url 12 | 'https://secure.braintreepaymentgateway.com/api/transact.php' 13 | end 14 | 15 | def add_processor(post, options) 16 | post[:processor_id] = options[:processor] unless options[:processor].nil? 17 | end 18 | end 19 | end 20 | end 21 | 22 | -------------------------------------------------------------------------------- /test/unit/credit_card_formatting_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class CreditCardFormattingTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::CreditCardFormatting 5 | 6 | def test_should_format_number_by_rule 7 | assert_equal 2005, format(2005, :steven_colbert) 8 | 9 | assert_equal '0005', format(05, :four_digits) 10 | assert_equal '2005', format(2005, :four_digits) 11 | 12 | assert_equal '05', format(2005, :two_digits) 13 | assert_equal '05', format(05, :two_digits) 14 | assert_equal '08', format(8, :two_digits) 15 | 16 | assert format(nil, :two_digits).blank? 17 | assert format('', :two_digits).blank? 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/credit_card_formatting.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module CreditCardFormatting 4 | 5 | # This method is used to format numerical information pertaining to credit cards. 6 | # 7 | # format(2005, :two_digits) # => "05" 8 | # format(05, :four_digits) # => "0005" 9 | def format(number, option) 10 | return '' if number.blank? 11 | 12 | case option 13 | when :two_digits ; sprintf("%.2i", number)[-2..-1] 14 | when :four_digits ; sprintf("%.4i", number)[-4..-1] 15 | else number 16 | end 17 | end 18 | 19 | end 20 | end 21 | end -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/robokassa/common.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module Robokassa 5 | module Common 6 | def generate_signature_string 7 | custom_param_keys = params.keys.select {|key| key =~ /^shp/}.sort 8 | custom_params = custom_param_keys.map {|key| "#{key}=#{params[key]}"} 9 | [main_params, secret, custom_params].flatten.compact.join(':') 10 | end 11 | 12 | def generate_signature 13 | Digest::MD5.hexdigest(generate_signature_string) 14 | end 15 | end 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /test/unit/integrations/direc_pay_module_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class DirecPayModuleTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def test_notification_method 7 | assert_instance_of DirecPay::Notification, DirecPay.notification('name=me', {}) 8 | end 9 | 10 | def test_return 11 | assert_instance_of DirecPay::Return, DirecPay.return("name=me", {}) 12 | end 13 | 14 | def test_status_update_instantiates_status_class 15 | DirecPay::Status.any_instance.expects(:update).with('authorization', 'http://localhost/return') 16 | DirecPay.request_status_update('mid', 'authorization', 'http://localhost/return') 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/quickpay.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module Quickpay 5 | autoload :Helper, File.dirname(__FILE__) + '/quickpay/helper.rb' 6 | autoload :Notification, File.dirname(__FILE__) + '/quickpay/notification.rb' 7 | 8 | mattr_accessor :service_url 9 | self.service_url = 'https://secure.quickpay.dk/form/' 10 | 11 | def self.notification(post, options = {}) 12 | Notification.new(post) 13 | end 14 | 15 | def self.return(post, options = {}) 16 | Return.new(post, options) 17 | end 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /test/unit/integrations/bogus_module_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class BogusModuleTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def test_notification_method 7 | assert_instance_of Bogus::Notification, Bogus.notification('name=cody', {}) 8 | end 9 | 10 | def test_service_url 11 | new = 'http://www.unbogus.com' 12 | assert_equal 'http://www.bogus.com', Bogus.service_url 13 | Bogus.service_url = new 14 | assert_equal new, Bogus.service_url 15 | end 16 | 17 | def test_return_method 18 | assert_instance_of Bogus::Return, Bogus.return('name=cody', {}) 19 | end 20 | 21 | def teardown 22 | Bogus.service_url = 'http://www.bogus.com' 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/epay.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module Epay 5 | autoload :Helper, File.dirname(__FILE__) + '/epay/helper.rb' 6 | autoload :Notification, File.dirname(__FILE__) + '/epay/notification.rb' 7 | 8 | mattr_accessor :service_url 9 | self.service_url = 'https://ssl.ditonlinebetalingssystem.dk/integration/ewindow/Default.aspx' 10 | 11 | def self.notification(post, options = {}) 12 | Notification.new(post) 13 | end 14 | 15 | def self.return(post, options = {}) 16 | Return.new(post, options) 17 | end 18 | end 19 | end 20 | end 21 | end -------------------------------------------------------------------------------- /lib/active_merchant/billing/gateways/ideal/ideal_response.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | class IdealResponse < Response 4 | 5 | def issuer_list 6 | list = @params.values[0]['Directory']['Issuer'] 7 | case list 8 | when Hash 9 | return [list] 10 | when Array 11 | return list 12 | end 13 | end 14 | 15 | def service_url 16 | @params.values[0]['Issuer']['issuerAuthenticationURL'] 17 | end 18 | 19 | def transaction 20 | @params.values[0]['Transaction'] 21 | end 22 | 23 | def error 24 | @params.values[0]['Error'] 25 | end 26 | 27 | end 28 | end 29 | end -------------------------------------------------------------------------------- /RELEASING: -------------------------------------------------------------------------------- 1 | releasing Active Merchant 2 | 3 | 1. Get the gem-private_key.pem from Cody and store it chmod 660 somewhere safe 4 | 2. Check the Semantic Versioning page for info on how to version the new release: http://semver.org 5 | 3. Update the version of Active Merchant in lib/active_merchant/version.rb and in activemerchant.gemspec 6 | 4. Add a CHANGELOG entry for the new release with the date 7 | 5. Commit the changes with a commit message like "Packaging for release X.Y.Z" 8 | 6. Tag the release with the version (Leave REV blank for HEAD or provide a SHA) 9 | $ git tag vX.Y.Z REV 10 | 7. Push out the changes 11 | $ git push 12 | 8. Push out the tags 13 | $ git push --tags 14 | 9. Publish the Gem to gemcutter 15 | $ rake release GEM_PRIVATE_KEY=/path/to/private/key -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/verkkomaksut.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/verkkomaksut/helper.rb' 2 | require File.dirname(__FILE__) + '/verkkomaksut/notification.rb' 3 | 4 | module ActiveMerchant #:nodoc: 5 | module Billing #:nodoc: 6 | module Integrations #:nodoc: 7 | 8 | # Usage, see the blog post here: http://blog.kiskolabs.com/post/22374612968/understanding-active-merchant-integrations and E1 API documentation here: http://docs.verkkomaksut.fi/ 9 | module Verkkomaksut 10 | 11 | mattr_accessor :service_url 12 | self.service_url = 'https://payment.verkkomaksut.fi/' 13 | 14 | def self.notification(post) 15 | Notification.new(post) 16 | end 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/dotpay.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module Dotpay 5 | autoload :Return, File.dirname(__FILE__) + '/dotpay/return.rb' 6 | autoload :Helper, File.dirname(__FILE__) + '/dotpay/helper.rb' 7 | autoload :Notification, File.dirname(__FILE__) + '/dotpay/notification.rb' 8 | 9 | mattr_accessor :service_url 10 | self.service_url = 'https://ssl.dotpay.pl' 11 | 12 | def self.notification(post, options = {}) 13 | Notification.new(post, options) 14 | end 15 | 16 | def self.return(post, options = {}) 17 | Return.new(post, options) 18 | end 19 | end 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/payflow_link.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module PayflowLink 5 | autoload :Helper, 'active_merchant/billing/integrations/payflow_link/helper.rb' 6 | autoload :Notification, 'active_merchant/billing/integrations/payflow_link/notification.rb' 7 | 8 | mattr_accessor :service_url 9 | self.service_url = 'https://payflowlink.paypal.com' 10 | 11 | def self.notification(post, options = {}) 12 | Notification.new(post) 13 | end 14 | 15 | def self.return(query_string, options = {}) 16 | ActiveMerchant::Billing::Integrations::Return.new(query_string) 17 | end 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /test/unit/integrations/world_pay_module_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class WorldPayModuleTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def setup 7 | ActiveMerchant::Billing::Base.integration_mode = :test 8 | end 9 | 10 | def test_service_url_in_test_mode 11 | assert_equal 'https://secure.wp3.rbsworldpay.com/wcc/purchase', WorldPay.service_url 12 | end 13 | 14 | def test_service_url_in_production_mode 15 | ActiveMerchant::Billing::Base.integration_mode = :production 16 | assert_equal 'https://secure.wp3.rbsworldpay.com/wcc/purchase', WorldPay.service_url 17 | end 18 | 19 | def test_notification_method 20 | assert_instance_of WorldPay::Notification, WorldPay.notification('name=Andrew White', {}) 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /test/remote/integrations/remote_direc_pay_integration_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class RemoteDirecPayIntegrationTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def setup 7 | @helper = DirecPay::Helper.new('#1234', fixtures(:direc_pay)[:mid], :amount => 500, :currency => 'INR') 8 | @notification = DirecPay::Notification.new('test=dummy-value') 9 | end 10 | 11 | def tear_down 12 | ActiveMerchant::Billing::Base.integration_mode = :test 13 | end 14 | 15 | def test_return_is_always_acknowledged 16 | assert_equal "https://test.timesofmoney.com/direcpay/secure/dpMerchantTransaction.jsp", DirecPay.service_url 17 | assert_nothing_raised do 18 | assert_equal true, @notification.acknowledge 19 | end 20 | end 21 | 22 | end 23 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/gateways/payflow_uk.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/payflow' 2 | require File.dirname(__FILE__) + '/payflow_express_uk' 3 | 4 | module ActiveMerchant #:nodoc: 5 | module Billing #:nodoc: 6 | class PayflowUkGateway < PayflowGateway 7 | self.default_currency = 'GBP' 8 | self.partner = 'PayPalUk' 9 | 10 | def express 11 | @express ||= PayflowExpressUkGateway.new(@options) 12 | end 13 | 14 | self.supported_cardtypes = [:visa, :master, :american_express, :discover, :solo, :switch] 15 | self.supported_countries = ['GB'] 16 | self.homepage_url = 'https://www.paypal.com/uk/cgi-bin/webscr?cmd=_wp-pro-overview-outside' 17 | self.display_name = 'PayPal Website Payments Pro (UK)' 18 | end 19 | end 20 | end 21 | 22 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/bogus.rb: -------------------------------------------------------------------------------- 1 | 2 | module ActiveMerchant #:nodoc: 3 | module Billing #:nodoc: 4 | module Integrations #:nodoc: 5 | module Bogus 6 | autoload :Return, 'active_merchant/billing/integrations/bogus/return.rb' 7 | autoload :Helper, 'active_merchant/billing/integrations/bogus/helper.rb' 8 | autoload :Notification, 'active_merchant/billing/integrations/bogus/notification.rb' 9 | 10 | mattr_accessor :service_url 11 | self.service_url = 'http://www.bogus.com' 12 | 13 | def self.notification(post, options = {}) 14 | Notification.new(post) 15 | end 16 | 17 | def self.return(query_string, options = {}) 18 | Return.new(query_string) 19 | end 20 | end 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /test/remote/integrations/remote_paypal_integration_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class RemotePaypalIntegrationTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def setup 7 | @paypal = Paypal::Notification.new('') 8 | end 9 | 10 | def tear_down 11 | ActiveMerchant::Billing::Base.integration_mode = :test 12 | end 13 | 14 | def test_raw 15 | assert_equal "https://www.sandbox.paypal.com/cgi-bin/webscr", Paypal.service_url 16 | assert_nothing_raised do 17 | assert_equal false, @paypal.acknowledge 18 | end 19 | end 20 | 21 | def test_valid_sender_always_true 22 | ActiveMerchant::Billing::Base.integration_mode = :production 23 | assert @paypal.valid_sender?(nil) 24 | assert @paypal.valid_sender?('127.0.0.1') 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/gateways/usa_epay.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | ## 4 | # Delegates to the appropriate gateway, either the Transaction or Advanced 5 | # depending on options passed to new. 6 | # 7 | class UsaEpayGateway < Gateway 8 | 9 | ## 10 | # Creates an instance of UsaEpayTransactionGateway by default, but if 11 | # :software id or :live_url are passed in the options hash it will 12 | # create an instance of UsaEpayAdvancedGateway. 13 | # 14 | def self.new(options={}) 15 | unless options.has_key?(:software_id) || options.has_key?(:live_url) 16 | UsaEpayTransactionGateway.new(options) 17 | else 18 | UsaEpayAdvancedGateway.new(options) 19 | end 20 | end 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /test/remote/gateways/remote_secure_pay_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class RemoteSecurePayTest < Test::Unit::TestCase 4 | 5 | def setup 6 | @gateway = SecurePayGateway.new(fixtures(:secure_pay)) 7 | 8 | @credit_card = credit_card('4111111111111111', 9 | :month => '7', 10 | :year => '2014' 11 | ) 12 | 13 | @options = { :order_id => generate_unique_id, 14 | :description => 'Store purchase', 15 | :billing_address => address 16 | } 17 | 18 | @amount = 100 19 | end 20 | 21 | def test_successful_purchase 22 | assert response = @gateway.purchase(@amount, @credit_card, @options) 23 | assert response.success? 24 | assert response.test? 25 | assert_equal 'This transaction has been approved', response.message 26 | assert response.authorization 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/moneybookers.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module Moneybookers 5 | 6 | autoload :Notification, File.dirname(__FILE__) + '/moneybookers/notification.rb' 7 | autoload :Helper, File.dirname(__FILE__) + '/moneybookers/helper.rb' 8 | 9 | mattr_accessor :production_url 10 | self.production_url = 'https://www.moneybookers.com/app/payment.pl' 11 | 12 | def self.service_url 13 | self.production_url 14 | end 15 | 16 | def self.notification(post, options) 17 | Notification.new(post, options) 18 | end 19 | 20 | def self.return(post, options = {}) 21 | Return.new(post, options) 22 | end 23 | end 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /test/unit/integrations/returns/hi_trust_return_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class HiTrustReturnTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def test_successful_return 7 | r = HiTrust::Return.new('order_id=&mscssid=&retcode=00&ordernumber=1138742&type=Auth') 8 | assert r.success? 9 | assert_equal HiTrust::Return::SUCCESS, r.params['retcode'] 10 | assert_equal HiTrust::Return::CODES[HiTrust::Return::SUCCESS], r.message 11 | end 12 | 13 | def test_failed_return 14 | r = HiTrust::Return.new('retcode=-100') 15 | assert_false r.success? 16 | assert_equal HiTrust::Return::CODES['-100'], r.message 17 | end 18 | 19 | def test_unknown_return 20 | r = HiTrust::Return.new('retcode=unknown') 21 | assert_false r.success? 22 | assert_nil r.message 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/gateways/transax.rb: -------------------------------------------------------------------------------- 1 | require File.join(File.dirname(__FILE__),'smart_ps.rb') 2 | 3 | module ActiveMerchant #:nodoc: 4 | module Billing #:nodoc: 5 | class TransaxGateway < SmartPs 6 | def api_url 7 | 'https://secure.nelixtransax.net/api/transact.php' 8 | end 9 | 10 | # The countries the gateway supports merchants from as 2 digit ISO country codes 11 | self.supported_countries = ['US'] 12 | 13 | # The card types supported by the payment gateway 14 | self.supported_cardtypes = [:visa, :master, :american_express, :discover] 15 | 16 | # The homepage URL of the gateway 17 | self.homepage_url = 'https://www.nelixtransax.com/' 18 | 19 | # The name of the gateway 20 | self.display_name = 'NELiX TransaX' 21 | 22 | end 23 | end 24 | end 25 | 26 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/chronopay.rb: -------------------------------------------------------------------------------- 1 | 2 | module ActiveMerchant #:nodoc: 3 | module Billing #:nodoc: 4 | module Integrations #:nodoc: 5 | module Chronopay 6 | autoload :Return, 'active_merchant/billing/integrations/chronopay/return.rb' 7 | autoload :Helper, 'active_merchant/billing/integrations/chronopay/helper.rb' 8 | autoload :Notification, 'active_merchant/billing/integrations/chronopay/notification.rb' 9 | 10 | mattr_accessor :service_url 11 | self.service_url = 'https://secure.chronopay.com/index_shop.cgi' 12 | 13 | def self.notification(post, options = {}) 14 | Notification.new(post) 15 | end 16 | 17 | def self.return(query_string, options = {}) 18 | Return.new(query_string) 19 | end 20 | end 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /test/unit/integrations/gestpay_module_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class GestpayModuleTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def test_notification_method 7 | Gestpay::Notification.any_instance.expects(:ssl_get).returns('#decryptstring#a=9000000&b=PAY1_UICCODE=242*P1*PAY1_AMOUNT=1234.56*P1*PAY1_TRANSACTIONRESULT=OK*P1*PAY1_BANKTRANSACTIONID=ABCD1234*P1*PAY1_SHOPTRANSACTIONID=1000#/decryptstring#') 8 | assert_instance_of Gestpay::Notification, Gestpay.notification('a=900000&b=F7DEB36478FD84760F9134F23C922697272D57DE6D4518EB9B4D468B769D9A3A8071B6EB160B35CB412FC1820C7CC12D17B3141855B1ED55468613702A2E213DDE9DE5B0209E13C416448AE833525959F05693172D7F0656', {}) 9 | end 10 | 11 | def test_return_method 12 | assert_instance_of Gestpay::Return, Gestpay.return('name=cody', {}) 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /test/unit/gateways/usa_epay_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | require 'logger' 3 | 4 | class UsaEpayTest < Test::Unit::TestCase 5 | 6 | def test_transaction_gateway_created 7 | gateway = UsaEpayGateway.new( 8 | :login => 'X' 9 | ) 10 | assert_kind_of UsaEpayTransactionGateway, gateway 11 | end 12 | 13 | def test_advanced_gateway_created_with_software_id 14 | gateway = UsaEpayGateway.new( 15 | :login => 'X', 16 | :password => 'Y', 17 | :software_id => 'Z' 18 | ) 19 | assert_kind_of UsaEpayAdvancedGateway, gateway 20 | end 21 | 22 | def test_advanced_gateway_created_with_urls 23 | gateway = UsaEpayGateway.new( 24 | :login => 'X', 25 | :password => 'Y', 26 | :test_url => 'Z', 27 | :live_url => 'Z' 28 | ) 29 | assert_kind_of UsaEpayAdvancedGateway, gateway 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/world_pay.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/world_pay/helper.rb' 2 | require File.dirname(__FILE__) + '/world_pay/notification.rb' 3 | 4 | module ActiveMerchant #:nodoc: 5 | module Billing #:nodoc: 6 | module Integrations #:nodoc: 7 | module WorldPay 8 | 9 | # production and test have the same endpoint 10 | mattr_accessor :production_url 11 | self.production_url = 'https://secure.wp3.rbsworldpay.com/wcc/purchase' 12 | 13 | def self.service_url 14 | production_url 15 | end 16 | 17 | def self.notification(post, options = {}) 18 | Notification.new(post, options) 19 | end 20 | 21 | def self.return(post, options = {}) 22 | Return.new(post, options) 23 | end 24 | end 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /test/unit/gateways/payflow_uk_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class PayflowUkTest < Test::Unit::TestCase 4 | def setup 5 | @gateway = PayflowUkGateway.new( 6 | :login => 'LOGIN', 7 | :password => 'PASSWORD' 8 | ) 9 | end 10 | 11 | def test_default_currency 12 | assert_equal 'GBP', PayflowUkGateway.default_currency 13 | end 14 | 15 | def test_express_instance 16 | assert_instance_of PayflowExpressUkGateway, @gateway.express 17 | end 18 | 19 | def test_default_partner 20 | assert_equal 'PayPalUk', PayflowUkGateway.partner 21 | end 22 | 23 | def test_supported_countries 24 | assert_equal ['GB'], PayflowUkGateway.supported_countries 25 | end 26 | 27 | def test_supported_card_types 28 | assert_equal [:visa, :master, :american_express, :discover, :solo, :switch], PayflowUkGateway.supported_cardtypes 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /test/unit/integrations/helpers/bogus_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class BogusHelperTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def setup 7 | @helper = Bogus::Helper.new('order-500','cfauser', :amount => 500, :currency => 'CAD') 8 | end 9 | 10 | def test_basic_helper_fields 11 | assert_field 'order', 'order-500' 12 | assert_field 'account', 'cfauser' 13 | assert_field 'amount', '500' 14 | assert_field 'currency', 'CAD' 15 | end 16 | 17 | def test_customer_fields 18 | @helper.customer :first_name => 'Cody', :last_name => 'Fauser' 19 | assert_field 'first_name', 'Cody' 20 | assert_field 'last_name', 'Fauser' 21 | end 22 | 23 | def test_setting_unknown_field 24 | fields = @helper.fields.dup 25 | @helper.space_shuttle :name => 'Rockety' 26 | assert_equal fields, @helper.fields 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/expiry_date.rb: -------------------------------------------------------------------------------- 1 | require 'date' 2 | 3 | module ActiveMerchant 4 | module Billing 5 | class CreditCard 6 | class ExpiryDate #:nodoc: 7 | attr_reader :month, :year 8 | def initialize(month, year) 9 | @month = month.to_i 10 | @year = year.to_i 11 | end 12 | 13 | def expired? #:nodoc: 14 | Time.now.utc > expiration 15 | end 16 | 17 | def expiration #:nodoc: 18 | begin 19 | Time.utc(year, month, month_days, 23, 59, 59) 20 | rescue ArgumentError 21 | Time.at(0).utc 22 | end 23 | end 24 | 25 | private 26 | def month_days 27 | mdays = [nil,31,28,31,30,31,30,31,31,30,31,30,31] 28 | mdays[2] = 29 if Date.leap?(year) 29 | mdays[month] 30 | end 31 | end 32 | end 33 | end 34 | end -------------------------------------------------------------------------------- /test/unit/integrations/e_payment_plans_module_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class EPaymentPlansModuleTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def test_notification_method 7 | assert_instance_of EPaymentPlans::Notification, EPaymentPlans.notification('name=cody') 8 | end 9 | 10 | def test_test_mode 11 | ActiveMerchant::Billing::Base.integration_mode = :test 12 | assert_equal 'https://test.epaymentplans.com/order/purchase', EPaymentPlans.service_url 13 | end 14 | 15 | def test_production_mode 16 | ActiveMerchant::Billing::Base.integration_mode = :production 17 | assert_equal 'https://www.epaymentplans.com/order/purchase', EPaymentPlans.service_url 18 | end 19 | 20 | def test_invalid_mode 21 | ActiveMerchant::Billing::Base.integration_mode = :coolmode 22 | assert_raise(StandardError){ EPaymentPlans.service_url } 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/gateways/ideal/ideal_rabobank.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICQDCCAakCBELvbPYwDQYJKoZIhvcNAQEEBQAwZzELMAkGA1UEBhMCREUxDzANBgNVBAgTBkhl 3 | c3NlbjESMBAGA1UEBxMJRnJhbmtmdXJ0MQ4wDAYDVQQKEwVpREVBTDEOMAwGA1UECxMFaURFQUwx 4 | EzARBgNVBAMTCmlERUFMIFJhYm8wHhcNMDUwODAyMTI1NDE0WhcNMTUwNzMxMTI1NDE0WjBnMQsw 5 | CQYDVQQGEwJERTEPMA0GA1UECBMGSGVzc2VuMRIwEAYDVQQHEwlGcmFua2Z1cnQxDjAMBgNVBAoT 6 | BWlERUFMMQ4wDAYDVQQLEwVpREVBTDETMBEGA1UEAxMKaURFQUwgUmFibzCBnzANBgkqhkiG9w0B 7 | AQEFAAOBjQAwgYkCgYEA486iIKVhr8RNjxH+PZ3yTWx/8k2fqDFm8XU8I1Z5esRmPFnXmlgA8cG7 8 | e9AaBPaLoP7Dc8dRQoUO66KMakzGI/WAVdHIJiiKrz8xOcioIgrzPSqec7aqse3J28UraEHkGESJ 9 | 7dAW7Pw/shrmpmkzKsunLt6AkXss4W3JUndZUN0CAwEAATANBgkqhkiG9w0BAQQFAAOBgQCGy/FK 10 | Lotp2ZOTtuLMgvDy74eicq/Znv4bLfpglzAPHycRHcHsXuer/lNHyvpKf2gdYe+IFalUW3OJZWIM 11 | jpm4UniJ16RPdgwWVRJEdPr/P7JXMIqD2IEOgujuuTQ7x0VgCf9XrsPsP9ZR5DIPcDDhbrpSE0yF 12 | Do77nwG61xMaGA== 13 | -----END CERTIFICATE----- 14 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/sage_pay_form/return.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module SagePayForm 5 | class Return < ActiveMerchant::Billing::Integrations::Return 6 | 7 | def initialize(query_string, options) 8 | begin 9 | @notification = Notification.new(query_string, options) 10 | rescue Notification::CryptError => e 11 | @message = e.message 12 | end 13 | end 14 | 15 | def success? 16 | @notification && @notification.complete? 17 | end 18 | 19 | def cancelled? 20 | @notification && @notification.cancelled? 21 | end 22 | 23 | def message 24 | @message || @notification.message 25 | end 26 | 27 | end 28 | end 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source :rubygems 2 | gemspec 3 | 4 | group :test do 5 | gem 'json-jruby', :platforms => :jruby 6 | gem 'jruby-openssl', :platforms => :jruby 7 | 8 | # gateway-specific dependencies, keeping these gems out of the gemspec 9 | gem 'samurai', '>= 0.2.25' 10 | gem 'braintree', '>= 2.0.0' 11 | gem 'vindicia-api', :git => 'git://github.com/agoragames/vindicia-api.git', :ref => "4e78744c79cb97448ff46c21301f53b346db4c91" 12 | gem 'LitleOnline', '>= 8.12.4' 13 | end 14 | 15 | group :remote_test do 16 | gem 'mechanize' 17 | gem 'launchy' 18 | gem 'mongrel', '1.2.0.pre2', :platforms => :ruby 19 | 20 | # gateway-specific dependencies, keeping these gems out of the gemspec 21 | gem 'samurai', '>= 0.2.25' 22 | gem 'braintree', '>= 2.0.0' 23 | gem 'vindicia-api', :git => 'git://github.com/agoragames/vindicia-api.git', :ref => "4e78744c79cb97448ff46c21301f53b346db4c91" 24 | gem 'LitleOnline', '>= 8.12.4' 25 | end 26 | 27 | -------------------------------------------------------------------------------- /test/unit/cvv_result_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class CVVResultTest < Test::Unit::TestCase 4 | def test_nil_data 5 | result = CVVResult.new(nil) 6 | assert_nil result.code 7 | assert_nil result.message 8 | end 9 | 10 | def test_blank_data 11 | result = CVVResult.new('') 12 | assert_nil result.code 13 | assert_nil result.message 14 | end 15 | 16 | def test_successful_match 17 | result = CVVResult.new('M') 18 | assert_equal 'M', result.code 19 | assert_equal CVVResult.messages['M'], result.message 20 | end 21 | 22 | def test_failed_match 23 | result = CVVResult.new('N') 24 | assert_equal 'N', result.code 25 | assert_equal CVVResult.messages['N'], result.message 26 | end 27 | 28 | def test_to_hash 29 | result = CVVResult.new('M').to_hash 30 | assert_equal 'M', result['code'] 31 | assert_equal CVVResult.messages['M'], result['message'] 32 | end 33 | end -------------------------------------------------------------------------------- /lib/active_merchant/billing/gateways/secure_pay.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/authorize_net' 2 | 3 | module ActiveMerchant #:nodoc: 4 | module Billing #:nodoc: 5 | class SecurePayGateway < AuthorizeNetGateway 6 | self.live_url = self.test_url = 'https://www.securepay.com/AuthSpayAdapter/process.aspx' 7 | 8 | self.homepage_url = 'http://www.securepay.com/' 9 | self.display_name = 'SecurePay' 10 | 11 | # Limit support to purchase() for the time being 12 | # JRuby chokes here 13 | # undef_method :authorize, :capture, :void, :credit 14 | 15 | undef_method :authorize 16 | undef_method :capture 17 | undef_method :void 18 | undef_method :credit 19 | 20 | def test? 21 | Base.gateway_mode == :test 22 | end 23 | 24 | private 25 | def split(response) 26 | response.split(',') 27 | end 28 | end 29 | end 30 | end 31 | 32 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/dwolla/return.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module Dwolla 5 | class Return < ActiveMerchant::Billing::Integrations::Return 6 | 7 | def success? 8 | self.error.nil? && self.callback_success? 9 | end 10 | 11 | def error 12 | params['error'] 13 | end 14 | 15 | def error_description 16 | params['error_description'] 17 | end 18 | 19 | def checkout_id 20 | params['checkoutid'] 21 | end 22 | 23 | def transaction 24 | params['transaction'] 25 | end 26 | 27 | def test? 28 | params['test'] 29 | end 30 | 31 | def callback_success? 32 | params['postback'] != "failure" 33 | end 34 | end 35 | end 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /test/unit/integrations/paypal_module_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class PaypalModuleTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def test_notification_method 7 | assert_instance_of Paypal::Notification, Paypal.notification('name=cody', {}) 8 | end 9 | 10 | def test_test_mode 11 | ActiveMerchant::Billing::Base.integration_mode = :test 12 | assert_equal 'https://www.sandbox.paypal.com/cgi-bin/webscr', Paypal.service_url 13 | end 14 | 15 | def test_production_mode 16 | ActiveMerchant::Billing::Base.integration_mode = :production 17 | assert_equal 'https://www.paypal.com/cgi-bin/webscr', Paypal.service_url 18 | end 19 | 20 | def test_invalid_mode 21 | ActiveMerchant::Billing::Base.integration_mode = :zoomin 22 | assert_raise(StandardError){ Paypal.service_url } 23 | end 24 | 25 | def test_return_method 26 | assert_instance_of Paypal::Return, Paypal.return('name=cody', {}) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/gestpay.rb: -------------------------------------------------------------------------------- 1 | # With help from Giovanni Intini and his code for RGestPay - http://medlar.it/it/progetti/rgestpay 2 | 3 | module ActiveMerchant #:nodoc: 4 | module Billing #:nodoc: 5 | module Integrations #:nodoc: 6 | module Gestpay 7 | autoload :Return, File.dirname(__FILE__) + '/gestpay/return.rb' 8 | autoload :Common, File.dirname(__FILE__) + '/gestpay/common.rb' 9 | autoload :Helper, File.dirname(__FILE__) + '/gestpay/helper.rb' 10 | autoload :Notification, File.dirname(__FILE__) + '/gestpay/notification.rb' 11 | 12 | mattr_accessor :service_url 13 | self.service_url = 'https://ecomm.sella.it/gestpay/pagam.asp' 14 | 15 | def self.notification(post, options = {}) 16 | Notification.new(post) 17 | end 18 | 19 | def self.return(query_string, options = {}) 20 | Return.new(query_string) 21 | end 22 | end 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/response.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | 4 | class Error < ActiveMerchantError #:nodoc: 5 | end 6 | 7 | class Response 8 | attr_reader :params, :message, :test, :authorization, :avs_result, :cvv_result 9 | 10 | def success? 11 | @success 12 | end 13 | 14 | def test? 15 | @test 16 | end 17 | 18 | def fraud_review? 19 | @fraud_review 20 | end 21 | 22 | def initialize(success, message, params = {}, options = {}) 23 | @success, @message, @params = success, message, params.stringify_keys 24 | @test = options[:test] || false 25 | @authorization = options[:authorization] 26 | @fraud_review = options[:fraud_review] 27 | @avs_result = AVSResult.new(options[:avs_result]).to_hash 28 | @cvv_result = CVVResult.new(options[:cvv_result]).to_hash 29 | end 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/hi_trust.rb: -------------------------------------------------------------------------------- 1 | 2 | module ActiveMerchant #:nodoc: 3 | module Billing #:nodoc: 4 | module Integrations #:nodoc: 5 | module HiTrust 6 | autoload :Helper, File.dirname(__FILE__) + '/hi_trust/helper.rb' 7 | autoload :Return, File.dirname(__FILE__) + '/hi_trust/return.rb' 8 | autoload :Notification, File.dirname(__FILE__) + '/hi_trust/notification.rb' 9 | 10 | TEST_URL = 'https://testtrustlink.hitrust.com.tw/TrustLink/TrxReq' 11 | LIVE_URL = 'https://trustlink.hitrust.com.tw/TrustLink/TrxReq' 12 | 13 | def self.service_url 14 | ActiveMerchant::Billing::Base.integration_mode == :test ? TEST_URL : LIVE_URL 15 | end 16 | 17 | def self.notification(post, options = {}) 18 | Notification.new(post) 19 | end 20 | 21 | def self.return(query_string, options = {}) 22 | Return.new(query_string) 23 | end 24 | end 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/direc_pay/return.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | 5 | module DirecPay 6 | class Return < ActiveMerchant::Billing::Integrations::Return 7 | 8 | def initialize(post_data, options = {}) 9 | @notification = Notification.new(treat_failure_as_pending(post_data), options) 10 | end 11 | 12 | def success? 13 | notification.complete? 14 | end 15 | 16 | def message 17 | notification.status 18 | end 19 | 20 | 21 | private 22 | 23 | # Work around the issue that the initial return from DirecPay is always either SUCCESS or FAIL, there is no PENDING 24 | def treat_failure_as_pending(post_data) 25 | post_data.sub(/FAIL/, 'PENDING') 26 | end 27 | end 28 | end 29 | 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/gateways/card_save.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | class CardSaveGateway < IridiumGateway 4 | #CardSave lets you handle failovers on payments by providing 3 gateways in case one happens to be down 5 | #URLS = ['https://gw1.cardsaveonlinepayments.com:4430/','https://gw2.cardsaveonlinepayments.com:4430/','https://gw3.cardsaveonlinepayments.com:4430/'] 6 | 7 | self.money_format = :cents 8 | self.default_currency = 'GBP' 9 | self.supported_cardtypes = [ :visa, :switch, :maestro, :master, :solo, :american_express, :jcb ] 10 | self.supported_countries = [ 'GB' ] 11 | self.homepage_url = 'http://www.cardsave.net/' 12 | self.display_name = 'CardSave' 13 | 14 | def initialize(options={}) 15 | super 16 | @test_url = 'https://gw1.cardsaveonlinepayments.com:4430/' 17 | @live_url = 'https://gw1.cardsaveonlinepayments.com:4430/' 18 | end 19 | 20 | end 21 | end 22 | end 23 | 24 | -------------------------------------------------------------------------------- /test/comm_stub.rb: -------------------------------------------------------------------------------- 1 | module CommStub 2 | class Stub 3 | def initialize(gateway, action) 4 | @gateway = gateway 5 | @action = action 6 | @complete = false 7 | end 8 | 9 | def check_request(&block) 10 | @check = block 11 | self 12 | end 13 | 14 | def respond_with(*responses) 15 | @complete = true 16 | check = @check 17 | (class << @gateway; self; end).send(:define_method, :ssl_post) do |*args| 18 | check.call(*args) if check 19 | (responses.size == 1 ? responses.last : responses.shift) 20 | end 21 | @action.call 22 | end 23 | 24 | def complete? 25 | @complete 26 | end 27 | end 28 | 29 | def stub_comms(gateway=@gateway, &action) 30 | if @last_comm_stub 31 | assert @last_comm_stub.complete?, "Tried to stub communications when there's a stub already in progress." 32 | end 33 | @last_comm_stub = Stub.new(gateway, action) 34 | end 35 | 36 | def teardown 37 | assert(@last_comm_stub.complete?) if @last_comm_stub 38 | end 39 | end -------------------------------------------------------------------------------- /test/unit/expiry_date_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ExpiryDateTest < Test::Unit::TestCase 4 | def test_should_be_expired 5 | last_month = 2.months.ago 6 | date = CreditCard::ExpiryDate.new(last_month.month, last_month.year) 7 | assert date.expired? 8 | end 9 | 10 | def test_today_should_not_be_expired 11 | today = Time.now.utc 12 | date = CreditCard::ExpiryDate.new(today.month, today.year) 13 | assert_false date.expired? 14 | end 15 | 16 | def test_dates_in_the_future_should_not_be_expired 17 | next_month = 1.month.from_now 18 | date = CreditCard::ExpiryDate.new(next_month.month, next_month.year) 19 | assert_false date.expired? 20 | end 21 | 22 | def test_invalid_date 23 | expiry = CreditCard::ExpiryDate.new(13, 2009) 24 | assert_equal Time.at(0).utc, expiry.expiration 25 | end 26 | 27 | def test_month_and_year_coerced_to_integer 28 | expiry = CreditCard::ExpiryDate.new("13", "2009") 29 | assert_equal 13, expiry.month 30 | assert_equal 2009, expiry.year 31 | end 32 | end -------------------------------------------------------------------------------- /test/unit/response_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ResponseTest < Test::Unit::TestCase 4 | def test_response_success 5 | assert Response.new(true, 'message', :param => 'value').success? 6 | assert !Response.new(false, 'message', :param => 'value').success? 7 | end 8 | 9 | def test_get_params 10 | response = Response.new(true, 'message', :param => 'value') 11 | 12 | assert_equal ['param'], response.params.keys 13 | end 14 | 15 | def test_avs_result 16 | response = Response.new(true, 'message', {}, :avs_result => { :code => 'A', :street_match => 'Y', :zip_match => 'N' }) 17 | avs_result = response.avs_result 18 | assert_equal 'A', avs_result['code'] 19 | assert_equal AVSResult.messages['A'], avs_result['message'] 20 | end 21 | 22 | def test_cvv_result 23 | response = Response.new(true, 'message', {}, :cvv_result => 'M') 24 | cvv_result = response.cvv_result 25 | assert_equal 'M', cvv_result['code'] 26 | assert_equal CVVResult.messages['M'], cvv_result['message'] 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /test/remote/gateways/remote_trans_first_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class RemoteTransFirstTest < Test::Unit::TestCase 4 | 5 | def setup 6 | @gateway = TransFirstGateway.new(fixtures(:trans_first)) 7 | 8 | @credit_card = credit_card('4111111111111111') 9 | @amount = 100 10 | @options = { 11 | :order_id => generate_unique_id, 12 | :invoice => 'ActiveMerchant Sale', 13 | :billing_address => address 14 | } 15 | end 16 | 17 | def test_successful_purchase 18 | assert response = @gateway.purchase(@amount, @credit_card, @options) 19 | assert_equal 'test transaction', response.message 20 | assert response.test? 21 | assert_success response 22 | assert !response.authorization.blank? 23 | end 24 | 25 | def test_invalid_login 26 | gateway = TransFirstGateway.new( 27 | :login => '', 28 | :password => '' 29 | ) 30 | assert response = gateway.purchase(@amount, @credit_card, @options) 31 | assert_equal 'invalid account', response.message 32 | assert_failure response 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /test/unit/integrations/helpers/robokassa_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class RobokassaHelperTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def setup 7 | @helper = Robokassa::Helper.new(123,'test_account', :amount => 500, :currency => 'USD', :secret => 'secret') 8 | end 9 | 10 | def test_basic_helper_fields 11 | assert_field 'MrchLogin', 'test_account' 12 | 13 | assert_field 'OutSum', '500' 14 | assert_field 'InvId', '123' 15 | end 16 | 17 | def test_signature_string 18 | assert_equal 'test_account:500:123:secret', @helper.generate_signature_string 19 | end 20 | 21 | def test_custom_fields 22 | @helper.shpa = '123' 23 | @helper.shpMySuperParam = '456' 24 | 25 | assert_field 'shpa', '123' 26 | assert_field 'shpMySuperParam', '456' 27 | end 28 | 29 | def test_signature_string_with_custom_fields 30 | @helper.shpb = '456' 31 | @helper.shpa = '123' 32 | 33 | assert_equal 'test_account:500:123:secret:shpa=123:shpb=456', @helper.generate_signature_string 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/gateways/paypal_express_common.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant 2 | module Billing 3 | module PaypalExpressCommon 4 | def self.included(base) 5 | if base.respond_to?(:class_attribute) 6 | base.class_attribute :test_redirect_url 7 | base.class_attribute :live_redirect_url 8 | else 9 | base.class_inheritable_accessor :test_redirect_url 10 | base.class_inheritable_accessor :live_redirect_url 11 | end 12 | base.live_redirect_url = 'https://www.paypal.com/cgibin/webscr' 13 | end 14 | 15 | def redirect_url 16 | test? ? test_redirect_url : live_redirect_url 17 | end 18 | 19 | def redirect_url_for(token, options = {}) 20 | options = {:review => true, :mobile => false}.update(options) 21 | 22 | cmd = options[:mobile] ? '_express-checkout-mobile' : '_express-checkout' 23 | url = "#{redirect_url}?cmd=#{cmd}&token=#{token}" 24 | url += '&useraction=commit' unless options[:review] 25 | 26 | url 27 | end 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/sage_pay_form/encryption.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module SagePayForm 5 | module Encryption 6 | def sage_encrypt(plaintext, key) 7 | Base64.strict_encode64(sage_encrypt_xor(plaintext, key)) 8 | end 9 | 10 | def sage_decrypt(ciphertext, key) 11 | sage_encrypt_xor(Base64.decode64(ciphertext), key) 12 | end 13 | 14 | def sage_encrypt_salt(min, max) 15 | length = rand(max - min + 1) + min 16 | SecureRandom.base64(length + 4)[0, length] 17 | end 18 | 19 | private 20 | 21 | def sage_encrypt_xor(data, key) 22 | raise 'No key provided' if key.blank? 23 | 24 | key *= (data.bytesize.to_f / key.bytesize.to_f).ceil 25 | key = key[0, data.bytesize] 26 | 27 | data.bytes.zip(key.bytes).map { |b1, b2| (b1 ^ b2).chr }.join 28 | end 29 | end 30 | end 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /test/unit/integrations/robokassa_module_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class RobokassaModuleTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def test_helper_method 7 | assert_instance_of Robokassa::Helper, Robokassa.helper(123, 'test') 8 | end 9 | 10 | def test_notification_method 11 | assert_instance_of Robokassa::Notification, Robokassa.notification('name=cody') 12 | end 13 | 14 | def test_return_method 15 | assert_instance_of Robokassa::Return, Robokassa.return('name=cody') 16 | end 17 | 18 | def test_test_mode 19 | ActiveMerchant::Billing::Base.integration_mode = :test 20 | assert_equal 'http://test.robokassa.ru/Index.aspx', Robokassa.service_url 21 | end 22 | 23 | def test_production_mode 24 | ActiveMerchant::Billing::Base.integration_mode = :production 25 | assert_equal 'https://merchant.roboxchange.com/Index.aspx', Robokassa.service_url 26 | end 27 | 28 | def test_invalid_mode 29 | ActiveMerchant::Billing::Base.integration_mode = :bro 30 | assert_raise(StandardError){ Robokassa.service_url } 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/dwolla/helper.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module Dwolla 5 | class Helper < ActiveMerchant::Billing::Integrations::Helper 6 | 7 | def initialize(order, account, options = {}) 8 | super 9 | add_field('name', 'Store Purchase') 10 | 11 | if ActiveMerchant::Billing::Base.integration_mode == :test || options[:test] 12 | add_field('test', 'true') 13 | end 14 | end 15 | 16 | # Replace with the real mapping 17 | mapping :account, 'destinationid' 18 | mapping :credential2, 'key' 19 | mapping :credential3, 'secret' 20 | mapping :notify_url, 'callback' 21 | mapping :return_url, 'redirect' 22 | mapping :description, 'description' 23 | mapping :amount, 'amount' 24 | mapping :tax, 'tax' 25 | mapping :shipping, 'shipping' 26 | mapping :order, 'orderid' 27 | end 28 | end 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /MIT-LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2005-2010 Tobias Luetke 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/cvv_result.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant 2 | module Billing 3 | # Result of the Card Verification Value check 4 | # http://www.bbbonline.org/eExport/doc/MerchantGuide_cvv2.pdf 5 | # Check additional codes from cybersource website 6 | class CVVResult 7 | 8 | MESSAGES = { 9 | 'D' => 'Suspicious transaction', 10 | 'I' => 'Failed data validation check', 11 | 'M' => 'Match', 12 | 'N' => 'No Match', 13 | 'P' => 'Not Processed', 14 | 'S' => 'Should have been present', 15 | 'U' => 'Issuer unable to process request', 16 | 'X' => 'Card does not support verification' 17 | } 18 | 19 | def self.messages 20 | MESSAGES 21 | end 22 | 23 | attr_reader :code, :message 24 | 25 | def initialize(code) 26 | @code = code.upcase unless code.blank? 27 | @message = MESSAGES[@code] 28 | end 29 | 30 | def to_hash 31 | { 32 | 'code' => code, 33 | 'message' => message 34 | } 35 | end 36 | end 37 | end 38 | end -------------------------------------------------------------------------------- /test/unit/integrations/sage_pay_form_module_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class SagePayFormModuleTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def test_return_method 7 | assert_instance_of SagePayForm::Return, SagePayForm.return('name=cody', {}) 8 | end 9 | 10 | def test_production_mode 11 | ActiveMerchant::Billing::Base.integration_mode = :production 12 | assert_equal 'https://live.sagepay.com/gateway/service/vspform-register.vsp', SagePayForm.service_url 13 | end 14 | 15 | def test_test_mode 16 | ActiveMerchant::Billing::Base.integration_mode = :test 17 | assert_equal 'https://test.sagepay.com/gateway/service/vspform-register.vsp', SagePayForm.service_url 18 | end 19 | 20 | def test_simulate_mode 21 | ActiveMerchant::Billing::Base.integration_mode = :simulate 22 | assert_equal 'https://test.sagepay.com/Simulator/VSPFormGateway.asp', SagePayForm.service_url 23 | end 24 | 25 | def test_invalid_mode 26 | ActiveMerchant::Billing::Base.integration_mode = :zoomin 27 | assert_raise(StandardError){ SagePayForm.service_url } 28 | end 29 | 30 | end 31 | -------------------------------------------------------------------------------- /generators/integration/templates/notification_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class <%= class_name %>NotificationTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def setup 7 | @<%= name %> = <%= class_name %>::Notification.new(http_raw_data) 8 | end 9 | 10 | def test_accessors 11 | assert @<%= name %>.complete? 12 | assert_equal "", @<%= name %>.status 13 | assert_equal "", @<%= name %>.transaction_id 14 | assert_equal "", @<%= name %>.item_id 15 | assert_equal "", @<%= name %>.gross 16 | assert_equal "", @<%= name %>.currency 17 | assert_equal "", @<%= name %>.received_at 18 | assert @<%= name %>.test? 19 | end 20 | 21 | def test_compositions 22 | assert_equal Money.new(3166, 'USD'), @<%= name %>.amount 23 | end 24 | 25 | # Replace with real successful acknowledgement code 26 | def test_acknowledgement 27 | 28 | end 29 | 30 | def test_send_acknowledgement 31 | end 32 | 33 | def test_respond_to_acknowledge 34 | assert @<%= name %>.respond_to?(:acknowledge) 35 | end 36 | 37 | private 38 | def http_raw_data 39 | "" 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | class PayflowExpressResponse < Response 4 | def email 5 | @params['e_mail'] 6 | end 7 | 8 | def full_name 9 | "#{@params['name']} #{@params['lastname']}" 10 | end 11 | 12 | def token 13 | @params['token'] 14 | end 15 | 16 | def payer_id 17 | @params['payer_id'] 18 | end 19 | 20 | # Really the shipping country, but it is all the information provided 21 | def payer_country 22 | address['country'] 23 | end 24 | 25 | def address 26 | { 'name' => full_name, 27 | 'company' => nil, 28 | 'address1' => @params['street'], 29 | 'address2' => @params['shiptostreet2'] || @params['street2'], 30 | 'city' => @params['city'], 31 | 'state' => @params['state'], 32 | 'country' => @params['country'], 33 | 'zip' => @params['zip'], 34 | 'phone' => nil 35 | } 36 | end 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/valitor.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module Valitor 5 | autoload :Return, 'active_merchant/billing/integrations/valitor/return.rb' 6 | autoload :Helper, 'active_merchant/billing/integrations/valitor/helper.rb' 7 | autoload :Notification, 'active_merchant/billing/integrations/valitor/notification.rb' 8 | 9 | mattr_accessor :test_url 10 | self.test_url = 'https://testvefverslun.valitor.is/1_1/' 11 | 12 | mattr_accessor :production_url 13 | self.production_url = 'https://vefverslun.valitor.is/1_1/' 14 | 15 | def self.test? 16 | (ActiveMerchant::Billing::Base.integration_mode == :test) 17 | end 18 | 19 | def self.service_url 20 | (test? ? test_url : production_url) 21 | end 22 | 23 | def self.notification(params, options={}) 24 | Notification.new(params, options.merge(:test => test?)) 25 | end 26 | 27 | def self.return(query_string, options={}) 28 | Return.new(query_string, options.merge(:test => test?)) 29 | end 30 | end 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /test/unit/integrations/two_checkout_module_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class TwoCheckoutModuleTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def test_default_service_url 7 | assert_equal 'https://www.2checkout.com/checkout/spurchase', TwoCheckout.service_url 8 | end 9 | 10 | def test_legacy_service_url_writer 11 | TwoCheckout.service_url = 'https://www.2checkout.com/checkout/purchase' 12 | assert_equal :multi_page, TwoCheckout.payment_routine 13 | end 14 | 15 | def test_single_page_payment_routine_service_url 16 | TwoCheckout.payment_routine = :single_page 17 | assert_equal 'https://www.2checkout.com/checkout/spurchase', TwoCheckout.service_url 18 | end 19 | 20 | def test_multi_page_payment_routine_service_url 21 | TwoCheckout.payment_routine = :multi_page 22 | assert_equal 'https://www.2checkout.com/checkout/purchase', TwoCheckout.service_url 23 | end 24 | 25 | def test_notification_method 26 | assert_instance_of TwoCheckout::Notification, TwoCheckout.notification('name=cody', {}) 27 | end 28 | 29 | def test_return_method 30 | assert_instance_of TwoCheckout::Return, TwoCheckout.return('name=cody', {}) 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /gem-public_cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDNjCCAh6gAwIBAgIBADANBgkqhkiG9w0BAQUFADBBMRMwEQYDVQQDDApjb2R5 3 | ZmF1c2VyMRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZFgNj 4 | b20wHhcNMDcwMjIyMTcyMTI3WhcNMDgwMjIyMTcyMTI3WjBBMRMwEQYDVQQDDApj 5 | b2R5ZmF1c2VyMRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZ 6 | FgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6T4Iqt5iWvAlU 7 | iXI6L8UO0URQhIC65X/gJ9hL/x4lwSl/ckVm/R/bPrJGmifT+YooFv824N3y/TIX 8 | 25o/lZtRj1TUZJK4OCb0aVzosQVxBHSe6rLmxO8cItNTMOM9wn3thaITFrTa1DOQ 9 | O3wqEjvW2L6VMozVfK1MfjL9IGgy0rCnl+2g4Gh4jDDpkLfnMG5CWI6cTCf3C1ye 10 | ytOpWgi0XpOEy8nQWcFmt/KCQ/kFfzBo4QxqJi54b80842EyvzWT9OB7Oew/CXZG 11 | F2yIHtiYxonz6N09vvSzq4CvEuisoUFLKZnktndxMEBKwJU3XeSHAbuS7ix40OKO 12 | WKuI54fHAgMBAAGjOTA3MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQW 13 | BBR9QQpefI3oDCAxiqJW/3Gg6jI6qjANBgkqhkiG9w0BAQUFAAOCAQEAs0lX26O+ 14 | HpyMp7WL+SgZuM8k76AjfOHuKajl2GEn3S8pWYGpsa0xu07HtehJhKLiavrfUYeE 15 | qlFtyYMUyOh6/1S2vfkH6VqjX7mWjoi7XKHW/99fkMS40B5SbN+ypAUst+6c5R84 16 | w390mjtLHpdDE6WQYhS6bFvBN53vK6jG3DLyCJc0K9uMQ7gdHWoxq7RnG92ncQpT 17 | ThpRA+fky5Xt2Q63YJDnJpkYAz79QIama1enSnd4jslKzSl89JS2luq/zioPe/Us 18 | hbyalWR1+HrhgPoSPq7nk+s2FQUBJ9UZFK1lgMzho/4fZgzJwbu+cO8SNuaLS/bj 19 | hPaSTyVU0yCSnw== 20 | -----END CERTIFICATE----- 21 | -------------------------------------------------------------------------------- /generators/integration/templates/helper.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module <%= class_name %> 5 | class Helper < ActiveMerchant::Billing::Integrations::Helper 6 | # Replace with the real mapping 7 | mapping :account, '' 8 | mapping :amount, '' 9 | 10 | mapping :order, '' 11 | 12 | mapping :customer, :first_name => '', 13 | :last_name => '', 14 | :email => '', 15 | :phone => '' 16 | 17 | mapping :billing_address, :city => '', 18 | :address1 => '', 19 | :address2 => '', 20 | :state => '', 21 | :zip => '', 22 | :country => '' 23 | 24 | mapping :notify_url, '' 25 | mapping :return_url, '' 26 | mapping :cancel_return_url, '' 27 | mapping :description, '' 28 | mapping :tax, '' 29 | mapping :shipping, '' 30 | end 31 | end 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/return.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | class Return 5 | attr_accessor :params 6 | attr_reader :notification 7 | 8 | def initialize(query_string, options = {}) 9 | @params = parse(query_string) 10 | @options = options 11 | end 12 | 13 | # Successful by default. Overridden in the child class 14 | def success? 15 | true 16 | end 17 | 18 | # Not cancelled by default. Overridden in the child class. 19 | def cancelled? 20 | false 21 | end 22 | 23 | def message 24 | 25 | end 26 | 27 | def parse(query_string) 28 | return {} if query_string.blank? 29 | 30 | query_string.split('&').inject({}) do |memo, chunk| 31 | next if chunk.empty? 32 | key, value = chunk.split('=', 2) 33 | next if key.empty? 34 | value = value.nil? ? nil : CGI.unescape(value) 35 | memo[CGI.unescape(key)] = value 36 | memo 37 | end 38 | end 39 | end 40 | end 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/dwolla.rb: -------------------------------------------------------------------------------- 1 | # All mappings in helper.rb are required fields to be sent to Dwolla. 2 | # :account = 'Dwolla Id of merchant' 3 | # :credential1 = 'key from Dwolla Application' 4 | # :credential2 = 'secret from Dwolla Application' 5 | # :redirect_url = 'can be different that what is specified on Dwolla Application creation' 6 | # :return_url = 'can be different that what is specified on Dwolla Application creation' 7 | # :order_id = must be unique for each transaction 8 | 9 | module ActiveMerchant #:nodoc: 10 | module Billing #:nodoc: 11 | module Integrations #:nodoc: 12 | module Dwolla 13 | autoload :Return, 'active_merchant/billing/integrations/dwolla/return.rb' 14 | autoload :Helper, 'active_merchant/billing/integrations/dwolla/helper.rb' 15 | autoload :Notification, 'active_merchant/billing/integrations/dwolla/notification.rb' 16 | 17 | mattr_accessor :service_url 18 | self.service_url = 'https://www.dwolla.com/payment/pay' 19 | 20 | def self.notification(post, options={}) 21 | Notification.new(post) 22 | end 23 | 24 | def self.return(query_string, options={}) 25 | Return.new(query_string) 26 | end 27 | end 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /test/remote/gateways/remote_pay_secure_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class RemotePaySecureTest < Test::Unit::TestCase 4 | 5 | def setup 6 | @gateway = PaySecureGateway.new(fixtures(:pay_secure)) 7 | 8 | @credit_card = credit_card('4000100011112224') 9 | @options = { 10 | :billing_address => address, 11 | :order_id => generate_unique_id 12 | } 13 | @amount = 100 14 | end 15 | 16 | def test_successful_purchase 17 | assert response = @gateway.purchase(@amount, @credit_card, @options) 18 | assert_success response 19 | assert_equal PaySecureGateway::SUCCESS_MESSAGE, response.message 20 | assert response.test? 21 | end 22 | 23 | def test_unsuccessful_purchase 24 | @credit_card.year = '2006' 25 | assert response = @gateway.purchase(@amount, @credit_card, @options) 26 | assert_equal 'Declined, card expired', response.message 27 | assert_failure response 28 | end 29 | 30 | def test_invalid_login 31 | gateway = PaySecureGateway.new( 32 | :login => '', 33 | :password => '' 34 | ) 35 | assert response = gateway.purchase(@amount, @credit_card, @options) 36 | assert_equal "MissingField: 'MERCHANT_ID'", response.message 37 | assert_failure response 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /test/unit/integrations/notifications/robokassa_notification_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class RobokassaNotificationTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def setup 7 | @robokassa = Robokassa::Notification.new(http_raw_data, :secret => 'secret') 8 | end 9 | 10 | def test_accessors 11 | assert @robokassa.complete? 12 | assert_equal "500", @robokassa.gross 13 | assert_equal "123", @robokassa.item_id 14 | end 15 | 16 | def test_compositions 17 | assert_equal Money.new(50000, 'USD'), @robokassa.amount 18 | end 19 | 20 | # Replace with real successful acknowledgement code 21 | def test_acknowledgement 22 | assert @robokassa.acknowledge 23 | end 24 | 25 | def test_respond_to_acknowledge 26 | assert @robokassa.respond_to?(:acknowledge) 27 | end 28 | 29 | def test_wrong_signature 30 | @robokassa = Robokassa::Notification.new(http_raw_data_with_wrong_signature, :secret => 'secret') 31 | assert !@robokassa.acknowledge 32 | end 33 | 34 | private 35 | def http_raw_data 36 | "InvId=123&OutSum=500&SignatureValue=4a827a06c6e54595c2bd8f67fb7a0091&shpMySuperParam=456&shpa=123" 37 | end 38 | 39 | def http_raw_data_with_wrong_signature 40 | "InvId=123&OutSum=500&SignatureValue=wrong&shpMySuperParam=456&shpa=123" 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /test/unit/integrations/notifications/verkkomaksut_notification_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class VerkkomaksutNotificationTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def setup 7 | @verkkomaksut = Verkkomaksut::Notification.new(http_params) 8 | end 9 | 10 | def test_accessors 11 | assert @verkkomaksut.complete? 12 | assert_equal "PAID", @verkkomaksut.status 13 | assert_equal "2", @verkkomaksut.order_id 14 | assert_equal "1336058061", @verkkomaksut.received_at 15 | assert_equal "4", @verkkomaksut.method 16 | assert_equal "6B40F9B939D03EFE7573D61708FA4126", @verkkomaksut.security_key 17 | end 18 | 19 | 20 | def test_acknowledgement 21 | assert @verkkomaksut.acknowledge("6pKF4jkv97zmqBJ3ZL8gUw5DfT2NMQ") 22 | end 23 | 24 | def test_faulty_acknowledgement 25 | @verkkomaksut = Verkkomaksut::Notification.new({"ORDER_NUMBER"=>"2", "TIMESTAMP"=>"1336058061", "PAID"=>"3DF5BB7E26", "METHOD"=>"4", "RETURN_AUTHCODE"=>"6asd0F9B939D03EFE7573D61708FA4126"}) 26 | assert_equal false, @verkkomaksut.acknowledge("6pKF4jkv97zmqBJ3ZL8gUw5DfT2NMQ") 27 | end 28 | 29 | private 30 | def http_params 31 | {"ORDER_NUMBER"=>"2", "TIMESTAMP"=>"1336058061", "PAID"=>"3DF5BB7E26", "METHOD"=>"4", "RETURN_AUTHCODE"=>"6B40F9B939D03EFE7573D61708FA4126"} 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /test/unit/integrations/returns/two_checkout_return_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class TwoCheckoutReturnTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def test_successful_purchase 7 | r = TwoCheckout::Return.new(successful_purchase) 8 | assert r.success? 9 | end 10 | 11 | def test_pending_purchase 12 | r = TwoCheckout::Return.new(failed_purchase) 13 | assert !r.success? 14 | end 15 | 16 | private 17 | def successful_purchase 18 | 'sid=1232919&fixed=Y&key=C17C887BDCCD0499264FAE9F578CCA66&state=ON&email=codyfauser%40gmail.com&street_address=138+Clarence+St.&city=Ottawa&cart_order_id=9&order_number=3860340141&merchant_order_id=%231009&country=CAN&ip_country=&cart_id=9&lang=en&demo=Y&pay_method=CC&total=118.30&phone=%28613%29555-5555+&credit_card_processed=Y&zip=K1N5P8&street_address2=Apartment+1&card_holder_name=Cody++Fauser' 19 | end 20 | 21 | def failed_purchase 22 | 'sid=1232919&fixed=Y&key=C17C887BDCCD0499264FAE9F578CCA66&state=ON&email=codyfauser%40gmail.com&street_address=138+Clarence+St.&city=Ottawa&cart_order_id=9&order_number=3860340141&merchant_order_id=%231009&country=CAN&ip_country=&cart_id=9&lang=en&demo=Y&pay_method=CC&total=118.30&phone=%28613%29555-5555+&credit_card_processed=K&zip=K1N5P8&street_address2=Apartment+1&card_holder_name=Cody++Fauser' 23 | end 24 | end -------------------------------------------------------------------------------- /lib/active_merchant/billing/gateways/modern_payments.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/modern_payments_cim' 2 | 3 | module ActiveMerchant #:nodoc: 4 | module Billing #:nodoc: 5 | class ModernPaymentsGateway < Gateway 6 | self.supported_countries = ModernPaymentsCimGateway.supported_countries 7 | self.supported_cardtypes = ModernPaymentsCimGateway.supported_cardtypes 8 | self.homepage_url = ModernPaymentsCimGateway.homepage_url 9 | self.display_name = ModernPaymentsCimGateway.display_name 10 | 11 | def initialize(options = {}) 12 | requires!(options, :login, :password) 13 | @options = options 14 | super 15 | end 16 | 17 | def purchase(money, credit_card, options = {}) 18 | customer_response = cim.create_customer(options) 19 | return customer_response unless customer_response.success? 20 | 21 | customer_id = customer_response.params["create_customer_result"] 22 | 23 | card_response = cim.modify_customer_credit_card(customer_id, credit_card) 24 | return card_response unless card_response.success? 25 | 26 | cim.authorize_credit_card_payment(customer_id, money) 27 | end 28 | 29 | private 30 | def cim 31 | @cim ||= ModernPaymentsCimGateway.new(@options) 32 | end 33 | end 34 | end 35 | end 36 | 37 | -------------------------------------------------------------------------------- /test/remote/gateways/remote_viaklix_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class RemoteViaklixTest < Test::Unit::TestCase 4 | def setup 5 | @gateway = ViaklixGateway.new(fixtures(:viaklix)) 6 | 7 | @credit_card = credit_card 8 | @bad_credit_card = credit_card('invalid') 9 | 10 | @options = { 11 | :order_id => '#1000.1', 12 | :email => "paul@domain.com", 13 | :description => 'Test Transaction', 14 | :billing_address => address 15 | } 16 | @amount = 100 17 | end 18 | 19 | def test_successful_purchase 20 | assert response = @gateway.purchase(@amount, @credit_card, @options) 21 | 22 | assert_success response 23 | assert response.test? 24 | assert_equal 'APPROVED', response.message 25 | assert response.authorization 26 | end 27 | 28 | def test_failed_purchase 29 | assert response = @gateway.purchase(@amount, @bad_credit_card, @options) 30 | 31 | assert_failure response 32 | assert response.test? 33 | assert_equal 'The Credit Card Number supplied in the authorization request appears invalid.', response.message 34 | end 35 | 36 | def test_credit 37 | assert purchase = @gateway.purchase(@amount, @credit_card, @options) 38 | assert_success purchase 39 | 40 | assert credit = @gateway.credit(@amount, @credit_card) 41 | assert_success credit 42 | end 43 | end -------------------------------------------------------------------------------- /test/unit/integrations/notifications/e_payment_plans_notification_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class EPaymentPlansNotificationTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def setup 7 | @e_payment_plan = EPaymentPlans::Notification.new(http_raw_data) 8 | end 9 | 10 | def test_accessors 11 | assert @e_payment_plan.complete? 12 | assert_equal "Completed", @e_payment_plan.status 13 | assert_equal "12345", @e_payment_plan.item_id 14 | assert_equal "35.52", @e_payment_plan.gross 15 | assert_equal "USD", @e_payment_plan.currency 16 | assert_equal Time.utc(2011,05,24,23,55,52), @e_payment_plan.received_at 17 | assert_equal "789123456", @e_payment_plan.transaction_id 18 | assert_equal "xxxxxxxxxx", @e_payment_plan.security_key 19 | assert @e_payment_plan.test? 20 | end 21 | 22 | def test_acknowledgement 23 | EPaymentPlans::Notification.any_instance.stubs(:ssl_post).returns('AUTHORISED') 24 | assert @e_payment_plan.acknowledge 25 | 26 | EPaymentPlans::Notification.any_instance.stubs(:ssl_post).returns('DECLINED') 27 | assert !@e_payment_plan.acknowledge 28 | end 29 | 30 | private 31 | def http_raw_data 32 | "received_at=2011-05-24 23:55:52 UTC&status=completed&item_id=12345&transaction_id=789123456&security_key=xxxxxxxxxx¤cy=USD&gross=35.52&test=test" 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /test/remote/integrations/remote_gestpay_integration_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class RemoteGestpayIntegrationTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def setup 7 | # Your Gestpay ShopLogin 8 | @shop_login = 'SHOPLOGIN' 9 | 10 | @helper = Gestpay::Helper.new('order-500', @shop_login, :amount => '5.00', :currency => 'EUR') 11 | end 12 | 13 | def test_get_encryption_string 14 | # Extra fields don't work yet 15 | # @helper.customer :first_name => 'Cody', :last_name => 'Fauser', :email => 'cody@example.com' 16 | response = @helper.send(:get_encrypted_string) 17 | assert !response.blank? 18 | end 19 | 20 | def test_get_encryption_string_fails 21 | @helper = Gestpay::Helper.new('order-500','99999999', :amount => '5.00', :currency => 'EUR') 22 | assert_raise(StandardError) do 23 | assert @helper.send(:get_encrypted_string).blank? 24 | end 25 | end 26 | 27 | def test_unknown_shop_for_decryption_request 28 | assert_raise(StandardError) do 29 | Gestpay::Notification.new(raw_query_string) 30 | end 31 | end 32 | 33 | private 34 | def raw_query_string 35 | "a=900000&b=F7DEB36478FD84760F9134F23C922697272D57DE6D4518EB9B4D468B769D9A3A8071B6EB160B35CB412FC1820C7CC12D17B3141855B1ED55468613702A2E213DDE9DE5B0209E13C416448AE833525959F05693172D7F0656" 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /test/unit/integrations/helpers/epay_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class EpayHelperTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def setup 7 | @helper = Epay::Helper.new('order-500','99999999', :amount => 500, :currency => 'DKK') 8 | @helper.md5secret "secretmd5" 9 | @helper.return_url 'http://example.com/ok' 10 | @helper.cancel_return_url 'http://example.com/cancel' 11 | @helper.notify_url 'http://example.com/notify' 12 | end 13 | 14 | def test_basic_helper_fields 15 | assert_field 'merchantnumber', '99999999' 16 | assert_field 'amount', '500' 17 | assert_field 'orderid', 'order500' 18 | end 19 | 20 | def test_generate_md5string 21 | assert_equal 'http://example.com/ok500http://example.com/notifyhttp://example.com/cancelDKK099999999order5003secretmd5', @helper.generate_md5string 22 | end 23 | 24 | def test_generate_md5hash 25 | assert_equal '251c2f80d1dcd120a87a2480025714cb', @helper.generate_md5hash 26 | end 27 | 28 | def test_unknown_mapping 29 | assert_nothing_raised do 30 | @helper.company_address :address => '500 Dwemthy Fox Road' 31 | end 32 | end 33 | 34 | def test_setting_invalid_address_field 35 | fields = @helper.fields.dup 36 | @helper.billing_address :street => 'My Street' 37 | assert_equal fields, @helper.fields 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/dwolla/notification.rb: -------------------------------------------------------------------------------- 1 | require 'net/http' 2 | 3 | module ActiveMerchant #:nodoc: 4 | module Billing #:nodoc: 5 | module Integrations #:nodoc: 6 | module Dwolla 7 | class Notification < ActiveMerchant::Billing::Integrations::Notification 8 | def complete? 9 | status == "Completed" 10 | end 11 | 12 | def status 13 | params["Status"] 14 | end 15 | 16 | def transaction_id 17 | params['TransactionId'] 18 | end 19 | 20 | def item_id 21 | params['OrderId'] 22 | end 23 | 24 | def currency 25 | "USD" 26 | end 27 | 28 | def gross 29 | params['Amount'] 30 | end 31 | 32 | def error 33 | params['Message'] 34 | end 35 | 36 | # Was this a test transaction? 37 | def test? 38 | params['TestMode'] 39 | end 40 | 41 | def acknowledge 42 | true 43 | end 44 | private 45 | # Take the posted data and move the relevant data into a hash 46 | def parse(post) 47 | @raw = post.to_s 48 | json_post = JSON.parse(post) 49 | params.merge!(json_post) 50 | end 51 | end 52 | end 53 | end 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /test/unit/gateways/braintree_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class BraintreeTest < Test::Unit::TestCase 4 | 5 | def test_new_with_login_password_creates_braintree_orange 6 | gateway = BraintreeGateway.new( 7 | :login => 'LOGIN', 8 | :password => 'PASSWORD' 9 | ) 10 | assert_instance_of BraintreeOrangeGateway, gateway 11 | end 12 | 13 | def test_new_with_merchant_id_creates_braintree_blue 14 | gateway = BraintreeGateway.new( 15 | :merchant_id => 'MERCHANT_ID', 16 | :public_key => 'PUBLIC_KEY', 17 | :private_key => 'PRIVATE_KEY' 18 | ) 19 | assert_instance_of BraintreeBlueGateway, gateway 20 | end 21 | 22 | def test_should_have_display_name_of_just_braintree 23 | assert_equal "Braintree", BraintreeGateway.display_name 24 | end 25 | 26 | def test_should_have_homepage_url 27 | assert_equal "http://www.braintreepaymentsolutions.com", BraintreeGateway.homepage_url 28 | end 29 | 30 | def test_should_have_supported_credit_card_types 31 | assert_equal [:visa, :master, :american_express, :discover, :jcb, :diners_club], BraintreeGateway.supported_cardtypes 32 | end 33 | 34 | def test_should_have_supported_countries 35 | assert_equal ['US'], BraintreeGateway.supported_countries 36 | end 37 | 38 | def test_should_have_default_currency 39 | assert_equal "USD", BraintreeGateway.default_currency 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/direc_pay/status.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module DirecPay 5 | 6 | class Status 7 | include PostsData 8 | 9 | STATUS_TEST_URL = 'https://test.timesofmoney.com/direcpay/secure/dpPullMerchAtrnDtls.jsp' 10 | STATUS_LIVE_URL = 'https://www.timesofmoney.com/direcpay/secure/dpPullMerchAtrnDtls.jsp' 11 | 12 | attr_reader :account, :options 13 | 14 | def initialize(account, options = {}) 15 | @account, @options = account, options 16 | end 17 | 18 | 19 | # Use this method to manually request a status update to the provided notification_url 20 | def update(authorization, notification_url) 21 | url = test? ? STATUS_TEST_URL : STATUS_LIVE_URL 22 | parameters = [ authorization, account, notification_url ] 23 | data = PostData.new 24 | data[:requestparams] = parameters.join('|') 25 | 26 | response = ssl_get("#{url}?#{data.to_post_data}") 27 | end 28 | 29 | def test? 30 | ActiveMerchant::Billing::Base.integration_mode == :test || options[:test] 31 | end 32 | 33 | end 34 | end 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /test/unit/gateways/secure_pay_tech_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class SecurePayTechTest < Test::Unit::TestCase 4 | def setup 5 | @gateway = SecurePayTechGateway.new( 6 | :login => 'x', 7 | :password => 'y' 8 | ) 9 | 10 | @amount = 100 11 | @credit_card = credit_card('4987654321098769') 12 | @options = { 13 | :billing_address => address 14 | } 15 | end 16 | 17 | def test_successful_purchase 18 | @gateway.expects(:ssl_post).returns(successful_purchase_response) 19 | 20 | assert response = @gateway.purchase(@amount, @credit_card, @options) 21 | assert_instance_of Response, response 22 | assert_success response 23 | assert response.test? 24 | assert_equal '4--120119220646821', response.authorization 25 | end 26 | 27 | def test_unsuccessful_purchase 28 | @gateway.expects(:ssl_post).returns(unsuccessful_purchase_response) 29 | 30 | assert response = @gateway.purchase(@amount, @credit_card, @options) 31 | assert_instance_of Response, response 32 | assert_failure response 33 | assert response.test? 34 | end 35 | 36 | private 37 | def successful_purchase_response 38 | "1,4--120119220646821,000000014511,23284,014511,20080125\r\n" 39 | end 40 | 41 | def unsuccessful_purchase_response 42 | "4,4--120119180936527,000000014510,23283,014510,20080125\r\n" 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/robokassa/notification.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module Robokassa 5 | class Notification < ActiveMerchant::Billing::Integrations::Notification 6 | include Common 7 | 8 | def self.recognizes?(params) 9 | params.has_key?('InvId') && params.has_key?('OutSum') 10 | end 11 | 12 | def complete? 13 | true 14 | end 15 | 16 | def amount 17 | BigDecimal.new(gross) 18 | end 19 | 20 | def item_id 21 | params['InvId'] 22 | end 23 | 24 | def security_key 25 | params[ActiveMerchant::Billing::Integrations::Robokassa.signature_parameter_name].to_s.downcase 26 | end 27 | 28 | def gross 29 | params['OutSum'] 30 | end 31 | 32 | def status 33 | 'success' 34 | end 35 | 36 | def secret 37 | @options[:secret] 38 | end 39 | 40 | def main_params 41 | [gross, item_id] 42 | end 43 | 44 | def acknowledge 45 | security_key == generate_signature 46 | end 47 | 48 | def success_response(*args) 49 | "OK#{item_id}" 50 | end 51 | end 52 | end 53 | end 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /generators/gateway/templates/gateway_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class <%= class_name %>Test < Test::Unit::TestCase 4 | def setup 5 | @gateway = <%= class_name %>Gateway.new( 6 | :login => 'login', 7 | :password => 'password' 8 | ) 9 | 10 | @credit_card = credit_card 11 | @amount = 100 12 | 13 | @options = { 14 | :order_id => '1', 15 | :billing_address => address, 16 | :description => 'Store Purchase' 17 | } 18 | end 19 | 20 | def test_successful_purchase 21 | @gateway.expects(:ssl_post).returns(successful_purchase_response) 22 | 23 | assert response = @gateway.purchase(@amount, @credit_card, @options) 24 | assert_instance_of 25 | assert_success response 26 | 27 | # Replace with authorization number from the successful response 28 | assert_equal '', response.authorization 29 | assert response.test? 30 | end 31 | 32 | def test_unsuccessful_request 33 | @gateway.expects(:ssl_post).returns(failed_purchase_response) 34 | 35 | assert response = @gateway.purchase(@amount, @credit_card, @options) 36 | assert_failure response 37 | assert response.test? 38 | end 39 | 40 | private 41 | 42 | # Place raw successful response from gateway here 43 | def successful_purchase_response 44 | end 45 | 46 | # Place raw failed response from gateway here 47 | def failed_purchase_response 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /test/unit/integrations/helpers/dwolla_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class DwollaHelperTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def setup 7 | @helper = Dwolla::Helper.new('order-500','812-546-3855', :credential2 => 'mykey', :credential3 => 'mysecret', :amount => 500, :currency => 'USD') 8 | end 9 | 10 | def test_basic_helper_fields 11 | assert_field 'amount', '500' 12 | assert_field 'orderid', 'order-500' 13 | assert_field 'destinationid', '812-546-3855' 14 | assert_field 'key', 'mykey' 15 | assert_field 'secret', 'mysecret' 16 | end 17 | 18 | def test_other_fields 19 | @helper.return_url 'http://test.com/ecommerce/redirect.aspx' 20 | @helper.notify_url 'http://test.com/test/callback' 21 | @helper.test_mode true 22 | @helper.description 'Store Purchase Description' 23 | @helper.shipping 0.00 24 | @helper.tax 0.00 25 | 26 | assert_field 'key', 'mykey' 27 | assert_field 'destinationid', '812-546-3855' 28 | assert_field 'secret', 'mysecret' 29 | assert_field 'redirect', 'http://test.com/ecommerce/redirect.aspx' 30 | assert_field 'callback', 'http://test.com/test/callback' 31 | assert_field 'test', 'true' 32 | assert_field 'description', 'Store Purchase Description' 33 | assert_field 'destinationid', '812-546-3855' 34 | assert_field 'shipping', '0.0' 35 | assert_field 'tax', '0.0' 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /test/unit/gateways/sallie_mae_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class SallieMaeTest < Test::Unit::TestCase 4 | def setup 5 | @gateway = SallieMaeGateway.new( 6 | :login => 'FAKEACCOUNT' 7 | ) 8 | 9 | @credit_card = credit_card 10 | @amount = 100 11 | 12 | @options = { 13 | :order_id => '1', 14 | :billing_address => address, 15 | :description => 'Store Purchase' 16 | } 17 | end 18 | 19 | def test_successful_purchase 20 | @gateway.expects(:ssl_post).returns(successful_purchase_response) 21 | 22 | assert response = @gateway.purchase(@amount, @credit_card, @options) 23 | assert_success response 24 | end 25 | 26 | def test_unsuccessful_request 27 | @gateway.expects(:ssl_post).returns(failed_purchase_response) 28 | 29 | assert response = @gateway.purchase(@amount, @credit_card, @options) 30 | assert_failure response 31 | end 32 | 33 | def test_non_test_account 34 | assert !@gateway.test? 35 | end 36 | 37 | def test_test_account 38 | gateway = SallieMaeGateway.new(:login => "TEST0") 39 | assert !@gateway.test? 40 | end 41 | 42 | private 43 | 44 | # Place raw successful response from gateway here 45 | def successful_purchase_response 46 | "Status=Accepted" 47 | end 48 | 49 | # Place raw failed response from gateway here 50 | def failed_purchase_response 51 | "Status=Declined" 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /test/unit/integrations/helpers/quickpay_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class QuickpayHelperTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def setup 7 | @helper = Quickpay::Helper.new('order-500','24352435', :amount => 500, :currency => 'USD') 8 | @helper.md5secret "mysecretmd5string" 9 | @helper.return_url 'http://example.com/ok' 10 | @helper.cancel_return_url 'http://example.com/cancel' 11 | @helper.notify_url 'http://example.com/notify' 12 | end 13 | 14 | def test_basic_helper_fields 15 | assert_field 'merchant', '24352435' 16 | assert_field 'amount', '500' 17 | assert_field 'ordernumber', 'order500' 18 | end 19 | 20 | def test_generate_md5string 21 | assert_equal '3authorize24352435daorder500500USDhttp://example.com/okhttp://example.com/cancelhttp://example.com/notify01mysecretmd5string', 22 | @helper.generate_md5string 23 | end 24 | 25 | def test_generate_md5check 26 | assert_equal '3dc7b51567c4911cc38511f796773366', @helper.generate_md5check 27 | end 28 | 29 | def test_unknown_mapping 30 | assert_nothing_raised do 31 | @helper.company_address :address => '500 Dwemthy Fox Road' 32 | end 33 | end 34 | 35 | def test_setting_invalid_address_field 36 | fields = @helper.fields.dup 37 | @helper.billing_address :street => 'My Street' 38 | assert_equal fields, @helper.fields 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/authorize_net_sim.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module AuthorizeNetSim 5 | autoload :Helper, 'active_merchant/billing/integrations/authorize_net_sim/helper.rb' 6 | autoload :Notification, 'active_merchant/billing/integrations/authorize_net_sim/notification.rb' 7 | 8 | # Overwrite this if you want to change the ANS test url 9 | mattr_accessor :test_url 10 | self.test_url = 'https://test.authorize.net/gateway/transact.dll' 11 | 12 | # Overwrite this if you want to change the ANS production url 13 | mattr_accessor :production_url 14 | self.production_url = 'https://secure.authorize.net/gateway/transact.dll' 15 | 16 | def self.service_url 17 | mode = ActiveMerchant::Billing::Base.integration_mode 18 | case mode 19 | when :production 20 | self.production_url 21 | when :test 22 | self.test_url 23 | else 24 | raise StandardError, "Integration mode set to an invalid value: #{mode}" 25 | end 26 | end 27 | 28 | def self.notification(post) 29 | Notification.new(post) 30 | end 31 | 32 | def self.return(query_string) 33 | Return.new(query_string) 34 | end 35 | end 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/gestpay/common.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module Gestpay 5 | module Common 6 | VERSION = "2.0" 7 | ENCRYPTION_PATH = "/CryptHTTPS/Encrypt.asp" 8 | DECRYPTION_PATH = "/CryptHTTPS/Decrypt.asp" 9 | DELIMITER = '*P1*' 10 | 11 | CURRENCY_MAPPING = { 12 | 'EUR' => '242', 13 | 'ITL' => '18', 14 | 'BRL' => '234', 15 | 'USD' => '1', 16 | 'JPY' => '71', 17 | 'HKD' => '103' 18 | } 19 | 20 | def parse_response(response) 21 | case response 22 | when /#cryptstring#(.*)#\/cryptstring#/, /#decryptstring#(.*)#\/decryptstring#/ 23 | $1 24 | when /#error#(.*)#\/error#/ 25 | raise StandardError, "An error occurred retrieving the encrypted string from GestPay: #{$1}" 26 | else 27 | raise StandardError, "No response was received by GestPay" 28 | end 29 | end 30 | 31 | def ssl_get(url, path) 32 | uri = URI.parse(url) 33 | site = Net::HTTP.new(uri.host, uri.port) 34 | site.use_ssl = true 35 | site.verify_mode = OpenSSL::SSL::VERIFY_NONE 36 | site.get(path).body 37 | end 38 | end 39 | end 40 | end 41 | end 42 | end -------------------------------------------------------------------------------- /test/schema/paypal/EnhancedDataTypes.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /lib/support/gateway_support.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'active_support' 3 | require 'active_merchant' 4 | 5 | 6 | class GatewaySupport #:nodoc: 7 | ACTIONS = [:purchase, :authorize, :capture, :void, :credit, :recurring] 8 | 9 | include ActiveMerchant::Billing 10 | 11 | attr_reader :gateways 12 | 13 | def initialize 14 | @gateways = Gateway.implementations.sort_by(&:name) 15 | @gateways.delete(ActiveMerchant::Billing::BogusGateway) 16 | end 17 | 18 | def each_gateway 19 | @gateways.each{|g| yield g } 20 | end 21 | 22 | def features 23 | width = 15 24 | 25 | print "Name".center(width + 20) 26 | ACTIONS.each{|f| print "#{f.to_s.capitalize.center(width)}" } 27 | puts 28 | 29 | each_gateway do |g| 30 | print "#{g.display_name.ljust(width + 20)}" 31 | ACTIONS.each do |f| 32 | print "#{(g.instance_methods.include?(f.to_s) ? "Y" : "N").center(width)}" 33 | end 34 | puts 35 | end 36 | end 37 | 38 | def to_rdoc 39 | each_gateway do |g| 40 | puts "* {#{g.display_name}}[#{g.homepage_url}] - #{g.supported_countries.join(', ')}" 41 | end 42 | end 43 | 44 | def to_textile 45 | each_gateway do |g| 46 | puts %/ * "#{g.display_name}":#{g.homepage_url} [#{g.supported_countries.join(', ')}]/ 47 | end 48 | end 49 | 50 | def to_s 51 | each_gateway do |g| 52 | puts "#{g.display_name} - #{g.homepage_url} [#{g.supported_countries.join(', ')}]" 53 | end 54 | end 55 | end 56 | 57 | 58 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/paypal.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module Paypal 5 | autoload :Return, 'active_merchant/billing/integrations/paypal/return.rb' 6 | autoload :Helper, 'active_merchant/billing/integrations/paypal/helper.rb' 7 | autoload :Notification, 'active_merchant/billing/integrations/paypal/notification.rb' 8 | 9 | # Overwrite this if you want to change the Paypal test url 10 | mattr_accessor :test_url 11 | self.test_url = 'https://www.sandbox.paypal.com/cgi-bin/webscr' 12 | 13 | # Overwrite this if you want to change the Paypal production url 14 | mattr_accessor :production_url 15 | self.production_url = 'https://www.paypal.com/cgi-bin/webscr' 16 | 17 | def self.service_url 18 | mode = ActiveMerchant::Billing::Base.integration_mode 19 | case mode 20 | when :production 21 | self.production_url 22 | when :test 23 | self.test_url 24 | else 25 | raise StandardError, "Integration mode set to an invalid value: #{mode}" 26 | end 27 | end 28 | 29 | def self.notification(post, options = {}) 30 | Notification.new(post) 31 | end 32 | 33 | def self.return(query_string, options = {}) 34 | Return.new(query_string) 35 | end 36 | end 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/e_payment_plans/helper.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module EPaymentPlans 5 | class Helper < ActiveMerchant::Billing::Integrations::Helper 6 | mapping :account, 'order[account]' 7 | mapping :amount, 'order[amount]' 8 | 9 | mapping :order, 'order[num]' 10 | 11 | mapping :customer, :first_name => 'order[first_name]', 12 | :last_name => 'order[last_name]', 13 | :email => 'order[email]', 14 | :phone => 'order[phone]' 15 | 16 | mapping :billing_address, :city => 'order[city]', 17 | :address1 => 'order[address1]', 18 | :address2 => 'order[address2]', 19 | :company => 'order[company]', 20 | :state => 'order[state]', 21 | :zip => 'order[zip]', 22 | :country => 'order[country]' 23 | 24 | mapping :notify_url, 'order[notify_url]' 25 | mapping :return_url, 'order[return_url]' 26 | mapping :cancel_return_url, 'order[cancel_return_url]' 27 | mapping :description, 'order[description]' 28 | mapping :tax, 'order[tax]' 29 | mapping :shipping, 'order[shipping]' 30 | end 31 | end 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/robokassa/helper.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module Robokassa 5 | class Helper < ActiveMerchant::Billing::Integrations::Helper 6 | include Common 7 | 8 | def initialize(order, account, options = {}) 9 | @md5secret = options.delete(:secret) 10 | super 11 | end 12 | 13 | def form_fields 14 | @fields.merge(ActiveMerchant::Billing::Integrations::Robokassa.signature_parameter_name => generate_signature) 15 | end 16 | 17 | def main_params 18 | [:account, :amount, :order].map {|key| @fields[mappings[key]]} 19 | end 20 | 21 | def params 22 | @fields 23 | end 24 | 25 | def secret 26 | @md5secret 27 | end 28 | 29 | def method_missing(method_id, *args) 30 | method_id = method_id.to_s.gsub(/=$/, '') 31 | 32 | # support for robokassa custom parameters 33 | if method_id =~ /^shp/ 34 | add_field method_id, args.last 35 | end 36 | 37 | super 38 | end 39 | 40 | mapping :account, 'MrchLogin' 41 | mapping :amount, 'OutSum' 42 | mapping :currency, 'IncCurrLabel' 43 | mapping :order, 'InvId' 44 | mapping :description, 'Desc' 45 | mapping :email, 'Email' 46 | end 47 | end 48 | end 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/sage_pay_form.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module SagePayForm 5 | autoload :Helper, File.dirname(__FILE__) + '/sage_pay_form/helper.rb' 6 | autoload :Return, File.dirname(__FILE__) + '/sage_pay_form/return.rb' 7 | autoload :Notification, File.dirname(__FILE__) + '/sage_pay_form/notification.rb' 8 | autoload :Encryption, File.dirname(__FILE__) + '/sage_pay_form/encryption.rb' 9 | 10 | mattr_accessor :production_url 11 | mattr_accessor :test_url 12 | mattr_accessor :simulate_url 13 | self.production_url = 'https://live.sagepay.com/gateway/service/vspform-register.vsp' 14 | self.test_url = 'https://test.sagepay.com/gateway/service/vspform-register.vsp' 15 | self.simulate_url = 'https://test.sagepay.com/Simulator/VSPFormGateway.asp' 16 | 17 | def self.return(query_string, options = {}) 18 | Return.new(query_string, options) 19 | end 20 | 21 | def self.service_url 22 | mode = ActiveMerchant::Billing::Base.integration_mode 23 | case mode 24 | when :production 25 | self.production_url 26 | when :test 27 | self.test_url 28 | when :simulate 29 | self.simulate_url 30 | else 31 | raise StandardError, "Integration mode set to an invalid value: #{mode}" 32 | end 33 | end 34 | end 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb: -------------------------------------------------------------------------------- 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 50 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/hi_trust/notification.rb: -------------------------------------------------------------------------------- 1 | require 'net/http' 2 | 3 | module ActiveMerchant #:nodoc: 4 | module Billing #:nodoc: 5 | module Integrations #:nodoc: 6 | module HiTrust 7 | class Notification < ActiveMerchant::Billing::Integrations::Notification 8 | SUCCESS = '00' 9 | 10 | self.production_ips = [ '203.75.242.8' ] 11 | 12 | def complete? 13 | status == 'Completed' 14 | end 15 | 16 | def transaction_id 17 | params['authRRN'] 18 | end 19 | 20 | def item_id 21 | params['ordernumber'] 22 | end 23 | 24 | def received_at 25 | Time.parse(params['orderdate']) rescue nil 26 | end 27 | 28 | def currency 29 | params['currency'] 30 | end 31 | 32 | def gross 33 | sprintf("%.2f", gross_cents.to_f / 100) 34 | end 35 | 36 | def gross_cents 37 | params['approveamount'].to_i 38 | end 39 | 40 | def account 41 | params['storeid'] 42 | end 43 | 44 | def status 45 | params['retcode'] == SUCCESS ? 'Completed' : 'Failed' 46 | end 47 | 48 | def test? 49 | ActiveMerchant::Billing::Base.integration_mode == :test 50 | end 51 | 52 | def acknowledge 53 | true 54 | end 55 | end 56 | end 57 | end 58 | end 59 | end 60 | -------------------------------------------------------------------------------- /test/remote/gateways/remote_beanstream_interac_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class RemoteBeanstreamInteracTest < Test::Unit::TestCase 4 | 5 | def setup 6 | @gateway = BeanstreamInteracGateway.new(fixtures(:beanstream_interac)) 7 | 8 | @amount = 100 9 | 10 | @options = { 11 | :order_id => generate_unique_id, 12 | :billing_address => { 13 | :name => 'xiaobo zzz', 14 | :phone => '555-555-5555', 15 | :address1 => '1234 Levesque St.', 16 | :address2 => 'Apt B', 17 | :city => 'Montreal', 18 | :state => 'QC', 19 | :country => 'CA', 20 | :zip => 'H2C1X8' 21 | }, 22 | :email => 'xiaobozzz@example.com', 23 | :subtotal => 800, 24 | :shipping => 100, 25 | :tax1 => 100, 26 | :tax2 => 100, 27 | :custom => 'reference one' 28 | } 29 | end 30 | 31 | def test_successful_purchase 32 | assert response = @gateway.purchase(@amount, @options) 33 | assert_success response 34 | assert_equal "R", response.params["responseType"] 35 | assert_false response.redirect.blank? 36 | end 37 | 38 | def test_failed_confirmation 39 | assert response = @gateway.confirm("") 40 | assert_failure response 41 | end 42 | 43 | def test_invalid_login 44 | gateway = BeanstreamInteracGateway.new( 45 | :merchant_id => '', 46 | :login => '', 47 | :password => '' 48 | ) 49 | assert response = gateway.purchase(@amount, @options) 50 | assert_failure response 51 | assert_equal 'Invalid merchant id (merchant_id = 0)', response.message 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/direc_pay.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module DirecPay 5 | autoload :Helper, File.dirname(__FILE__) + '/direc_pay/helper.rb' 6 | autoload :Return, File.dirname(__FILE__) + '/direc_pay/return.rb' 7 | autoload :Notification, File.dirname(__FILE__) + '/direc_pay/notification.rb' 8 | autoload :Status, File.dirname(__FILE__) + '/direc_pay/status.rb' 9 | 10 | mattr_accessor :production_url, :test_url 11 | 12 | self.production_url = "https://www.timesofmoney.com/direcpay/secure/dpMerchantTransaction.jsp" 13 | self.test_url = "https://test.timesofmoney.com/direcpay/secure/dpMerchantTransaction.jsp" 14 | 15 | def self.service_url 16 | mode = ActiveMerchant::Billing::Base.integration_mode 17 | case mode 18 | when :production 19 | self.production_url 20 | when :test 21 | self.test_url 22 | else 23 | raise StandardError, "Integration mode set to an invalid value: #{mode}" 24 | end 25 | end 26 | 27 | def self.notification(post, options = {}) 28 | Notification.new(post) 29 | end 30 | 31 | def self.return(query_string, options = {}) 32 | Return.new(query_string, options) 33 | end 34 | 35 | def self.request_status_update(mid, transaction_id, notification_url) 36 | Status.new(mid).update(transaction_id, notification_url) 37 | end 38 | end 39 | end 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /test/unit/integrations/valitor_module_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ValitorModuleTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def test_notification_method 7 | notification = Valitor.notification('Land=USA', :credential2 => 'password') 8 | assert_instance_of Valitor::Notification, notification 9 | assert_equal 'password', notification.instance_eval{@options}[:credential2] 10 | assert_equal 'USA', notification.customer_country 11 | assert notification.test? 12 | 13 | ActiveMerchant::Billing::Base.integration_mode = :production 14 | assert !Valitor.notification('Land=USA', :credential2 => 'password').test? 15 | ensure 16 | ActiveMerchant::Billing::Base.integration_mode = :test 17 | end 18 | 19 | def test_return_method 20 | ret = Valitor.return('Land=USA', :credential2 => 'password') 21 | assert_instance_of Valitor::Return, ret 22 | assert_equal 'password', ret.instance_eval{@options}[:credential2] 23 | assert_equal 'USA', ret.customer_country 24 | assert ret.test? 25 | 26 | ActiveMerchant::Billing::Base.integration_mode = :production 27 | assert !Valitor.return('Land=USA', :credential2 => 'password').test? 28 | ensure 29 | ActiveMerchant::Billing::Base.integration_mode = :test 30 | end 31 | 32 | def test_service_url 33 | assert_equal "https://testvefverslun.valitor.is/1_1/", Valitor.service_url 34 | ActiveMerchant::Billing::Base.integration_mode = :production 35 | assert_equal "https://vefverslun.valitor.is/1_1/", Valitor.service_url 36 | ensure 37 | ActiveMerchant::Billing::Base.integration_mode = :test 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /test/unit/gateways/gateway_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class GatewayTest < Test::Unit::TestCase 4 | def test_should_detect_if_a_card_is_supported 5 | Gateway.supported_cardtypes = [:visa, :bogus] 6 | assert [:visa, :bogus].all? { |supported_cardtype| Gateway.supports?(supported_cardtype) } 7 | 8 | Gateway.supported_cardtypes = [] 9 | assert_false [:visa, :bogus].all? { |invalid_cardtype| Gateway.supports?(invalid_cardtype) } 10 | end 11 | 12 | def test_should_gateway_uses_ssl_strict_checking_by_default 13 | assert Gateway.ssl_strict 14 | end 15 | 16 | def test_should_be_able_to_look_for_test_mode 17 | Base.gateway_mode = :test 18 | assert Gateway.new.test? 19 | 20 | Base.gateway_mode = :production 21 | assert_false Gateway.new.test? 22 | end 23 | 24 | def test_amount_style 25 | assert_equal '10.34', Gateway.new.send(:amount, 1034) 26 | 27 | assert_raise(ArgumentError) do 28 | Gateway.new.send(:amount, '10.34') 29 | end 30 | end 31 | 32 | def test_invalid_type 33 | credit_card = stub(:brand => "visa") 34 | assert_equal "visa", Gateway.card_brand(credit_card) 35 | end 36 | 37 | def test_invalid_type 38 | credit_card = stub(:type => "String", :brand => "visa") 39 | assert_equal "visa", Gateway.card_brand(credit_card) 40 | end 41 | 42 | def test_setting_application_id_outside_the_class_definition 43 | assert_equal SimpleTestGateway.application_id, SubclassGateway.application_id 44 | SimpleTestGateway.application_id = "New Application ID" 45 | 46 | assert_equal SimpleTestGateway.application_id, SubclassGateway.application_id 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/two_checkout.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module TwoCheckout 5 | autoload 'Helper', File.dirname(__FILE__) + '/two_checkout/helper' 6 | autoload 'Return', File.dirname(__FILE__) + '/two_checkout/return' 7 | autoload 'Notification', File.dirname(__FILE__) + '/two_checkout/notification' 8 | 9 | mattr_accessor :payment_routine 10 | self.payment_routine = :single_page 11 | 12 | def self.service_url 13 | case self.payment_routine 14 | when :multi_page 15 | 'https://www.2checkout.com/checkout/purchase' 16 | when :single_page 17 | 'https://www.2checkout.com/checkout/spurchase' 18 | else 19 | raise StandardError, "Integration payment routine set to an invalid value: #{self.payment_routine}" 20 | end 21 | end 22 | 23 | def self.service_url=(service_url) 24 | # Note: do not use this method, it is here for backward compatibility 25 | # Use the payment_routine method to change service_url 26 | if service_url =~ /spurchase/ 27 | self.payment_routine = :single_page 28 | else 29 | self.payment_routine = :multi_page 30 | end 31 | end 32 | 33 | 34 | def self.notification(post, options = {}) 35 | Notification.new(post) 36 | end 37 | 38 | def self.return(query_string, options = {}) 39 | Return.new(query_string) 40 | end 41 | end 42 | end 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /activemerchant.gemspec: -------------------------------------------------------------------------------- 1 | $:.push File.expand_path("../lib", __FILE__) 2 | require 'active_merchant/version' 3 | 4 | Gem::Specification.new do |s| 5 | s.platform = Gem::Platform::RUBY 6 | s.name = 'activemerchant' 7 | s.version = ActiveMerchant::VERSION 8 | s.summary = 'Framework and tools for dealing with credit card transactions.' 9 | s.description = 'Active Merchant is a simple payment abstraction library used in and sponsored by Shopify. It is written by Tobias Luetke, Cody Fauser, and contributors. The aim of the project is to feel natural to Ruby users and to abstract as many parts as possible away from the user to offer a consistent interface across all supported gateways.' 10 | 11 | s.author = 'Tobias Luetke' 12 | s.email = 'tobi@leetsoft.com' 13 | s.homepage = 'http://activemerchant.org/' 14 | s.rubyforge_project = 'activemerchant' 15 | 16 | s.files = Dir['CHANGELOG', 'README.md', 'MIT-LICENSE', 'CONTRIBUTORS', 'gem-public_cert.pem', 'lib/**/*', 'vendor/**/*'] 17 | s.require_path = 'lib' 18 | 19 | s.has_rdoc = true if Gem::VERSION < '1.7.0' 20 | 21 | s.add_dependency('activesupport', '>= 2.3.11') 22 | s.add_dependency('i18n') 23 | s.add_dependency('money') 24 | s.add_dependency('builder', '>= 2.0.0') 25 | s.add_dependency('json', '>= 1.5.1') 26 | s.add_dependency('active_utils', '>= 1.0.2') 27 | s.add_dependency('nokogiri') 28 | 29 | s.add_development_dependency('rake') 30 | s.add_development_dependency('mocha', '~> 0.11.3') 31 | s.add_development_dependency('rails', '>= 2.3.11') 32 | s.add_development_dependency('rubigen') 33 | s.signing_key = ENV['GEM_PRIVATE_KEY'] 34 | s.cert_chain = ['gem-public_cert.pem'] 35 | end 36 | -------------------------------------------------------------------------------- /test/unit/integrations/notifications/epay_notification_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class EpayNotificationTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def setup 7 | @epay = Epay::Notification.new(http_raw_data, :credential3 => "secretmd5") 8 | end 9 | 10 | def test_accessors 11 | assert @epay.complete? 12 | assert_equal "9572252", @epay.transaction_id 13 | assert_equal "189139", @epay.item_id 14 | assert_equal "3987.50", @epay.gross 15 | assert_equal "DKK", @epay.currency 16 | assert_equal Time.parse("2012-04-03 14:42:00"), @epay.received_at 17 | assert !@epay.test? 18 | end 19 | 20 | def test_compositions 21 | assert_equal Money.new(398750, 'DKK'), @epay.amount 22 | end 23 | 24 | def test_acknowledgement 25 | assert @epay.acknowledge 26 | end 27 | 28 | def test_failed_acknnowledgement 29 | @epay = Epay::Notification.new(http_raw_data, :credential3 => "badmd5string") 30 | assert !@epay.acknowledge 31 | end 32 | 33 | def test_generate_md5string 34 | assert_equal "1957225218913939875020820120403144203453903XXXXXX9862secretmd5", 35 | @epay.generate_md5string 36 | end 37 | 38 | def test_generate_md5hash 39 | assert_equal "6f81086c474f03af80ef894e48f81f99", @epay.generate_md5hash 40 | end 41 | 42 | def test_respond_to_acknowledge 43 | assert @epay.respond_to?(:acknowledge) 44 | end 45 | 46 | private 47 | def http_raw_data 48 | "language=1&txnid=9572252&orderid=189139&amount=398750¤cy=208&date=20120403&time=1442&txnfee=0&paymenttype=3&cardno=453903XXXXXX9862&hash=6f81086c474f03af80ef894e48f81f99" 49 | end 50 | 51 | end 52 | -------------------------------------------------------------------------------- /test/remote/gateways/remote_paypal_express_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class PaypalExpressTest < Test::Unit::TestCase 4 | def setup 5 | Base.gateway_mode = :test 6 | 7 | @gateway = PaypalExpressGateway.new(fixtures(:paypal_certificate)) 8 | 9 | @options = { 10 | :order_id => '230000', 11 | :email => 'buyer@jadedpallet.com', 12 | :billing_address => { :name => 'Fred Brooks', 13 | :address1 => '1234 Penny Lane', 14 | :city => 'Jonsetown', 15 | :state => 'NC', 16 | :country => 'US', 17 | :zip => '23456' 18 | } , 19 | :description => 'Stuff that you purchased, yo!', 20 | :ip => '10.0.0.1', 21 | :return_url => 'http://example.com/return', 22 | :cancel_return_url => 'http://example.com/cancel' 23 | } 24 | end 25 | 26 | def test_set_express_authorization 27 | @options.update( 28 | :return_url => 'http://example.com', 29 | :cancel_return_url => 'http://example.com', 30 | :email => 'Buyer1@paypal.com' 31 | ) 32 | response = @gateway.setup_authorization(500, @options) 33 | assert response.success? 34 | assert response.test? 35 | assert !response.params['token'].blank? 36 | end 37 | 38 | def test_set_express_purchase 39 | @options.update( 40 | :return_url => 'http://example.com', 41 | :cancel_return_url => 'http://example.com', 42 | :email => 'Buyer1@paypal.com' 43 | ) 44 | response = @gateway.setup_purchase(500, @options) 45 | assert response.success? 46 | assert response.test? 47 | assert !response.params['token'].blank? 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /test/remote/gateways/remote_psigate_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class PsigateRemoteTest < Test::Unit::TestCase 4 | 5 | def setup 6 | Base.mode = :test 7 | @gateway = PsigateGateway.new(fixtures(:psigate)) 8 | 9 | @amount = 2400 10 | @creditcard = credit_card('4242424242424242') 11 | @options = { 12 | :order_id => generate_unique_id, 13 | :billing_address => address, 14 | :email => 'jack@example.com' 15 | } 16 | end 17 | 18 | def test_successful_authorization 19 | assert response = @gateway.authorize(@amount, @creditcard, @options) 20 | assert_success response 21 | assert_equal @options[:order_id], response.authorization 22 | end 23 | 24 | def test_successful_purchase 25 | assert response = @gateway.purchase(@amount, @creditcard, @options) 26 | assert_success response 27 | assert_equal @options[:order_id], response.authorization 28 | end 29 | 30 | def test_successful_authorization_and_capture 31 | assert authorization = @gateway.authorize(@amount, @creditcard, @options) 32 | assert_success authorization 33 | 34 | assert capture = @gateway.capture(@amount, authorization.authorization) 35 | assert_success capture 36 | end 37 | 38 | def test_successful_purchase_and_credit 39 | assert purchase = @gateway.purchase(@amount, @creditcard, @options) 40 | assert_success purchase 41 | 42 | assert credit = @gateway.credit(@amount, purchase.authorization) 43 | assert_success credit 44 | end 45 | 46 | def test_failed_purchase 47 | assert response = @gateway.purchase(@amount, @creditcard, @options.update(:test_result => 'D')) 48 | assert_failure response 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/e_payment_plans.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module EPaymentPlans 5 | autoload :Helper, File.dirname(__FILE__) + '/e_payment_plans/helper.rb' 6 | autoload :Notification, File.dirname(__FILE__) + '/e_payment_plans/notification.rb' 7 | 8 | mattr_accessor :production_url 9 | self.production_url = 'https://www.epaymentplans.com' 10 | 11 | mattr_accessor :test_url 12 | self.test_url = 'https://test.epaymentplans.com' 13 | 14 | def self.service_url 15 | mode = ActiveMerchant::Billing::Base.integration_mode 16 | case mode 17 | when :production 18 | "#{production_url}/order/purchase" 19 | when :test 20 | "#{test_url}/order/purchase" 21 | else 22 | raise StandardError, "Integration mode set to an invalid value: #{mode}" 23 | end 24 | end 25 | 26 | def self.notification_confirmation_url 27 | mode = ActiveMerchant::Billing::Base.integration_mode 28 | case mode 29 | when :production 30 | "#{production_url}/order/confirmation" 31 | when :test 32 | "#{test_url}/order/confirmation" 33 | else 34 | raise StandardError, "Integration mode set to an invalid value: #{mode}" 35 | end 36 | end 37 | 38 | def self.notification(post, options = {}) 39 | Notification.new(post, options) 40 | end 41 | 42 | def self.return(query_string, options = {}) 43 | Return.new(query_string, options) 44 | end 45 | end 46 | end 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /test/remote/gateways/remote_sallie_mae_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class RemoteSallieMaeTest < Test::Unit::TestCase 4 | def setup 5 | @gateway = SallieMaeGateway.new(fixtures(:sallie_mae)) 6 | 7 | @amount = 100 8 | @credit_card = credit_card('5454545454545454') 9 | @declined_card = credit_card('4000300011112220') 10 | 11 | @options = { 12 | :billing_address => address, 13 | :description => 'Store Purchase' 14 | } 15 | end 16 | 17 | def test_successful_purchase 18 | assert response = @gateway.purchase(@amount, @credit_card, @options) 19 | assert_success response 20 | assert_equal 'Accepted', response.message 21 | end 22 | 23 | def test_unsuccessful_purchase 24 | assert response = @gateway.purchase(@amount, @declined_card, @options) 25 | assert_failure response 26 | assert_equal 'Cvv2 mismatch', response.message 27 | end 28 | 29 | def test_authorize_and_capture 30 | amount = (@amount * rand).to_i 31 | assert auth = @gateway.authorize(amount, @credit_card, @options) 32 | assert_success auth 33 | assert_equal 'Accepted', auth.message 34 | assert auth.authorization 35 | assert capture = @gateway.capture(amount, auth.authorization) 36 | assert_success capture 37 | end 38 | 39 | def test_failed_capture 40 | assert response = @gateway.capture(@amount, '') 41 | assert_failure response 42 | assert_equal 'Missing account number', response.message 43 | end 44 | 45 | def test_invalid_login 46 | gateway = SallieMaeGateway.new(:login => '') 47 | assert response = gateway.purchase(@amount, @credit_card, @options) 48 | assert_failure response 49 | assert_equal 'Invalid merchant', response.message 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /test/unit/integrations/notifications/nochex_notification_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class NochexNotificationTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def setup 7 | @nochex = Nochex::Notification.new(http_raw_data) 8 | end 9 | 10 | def test_accessors 11 | assert @nochex.complete? 12 | assert_equal "Completed", @nochex.status 13 | assert_equal "91191", @nochex.transaction_id 14 | assert_equal "11", @nochex.item_id 15 | assert_equal "31.66", @nochex.gross 16 | assert_equal "GBP", @nochex.currency 17 | assert_equal Time.utc(2006, 9, 27, 22, 30, 53), @nochex.received_at 18 | assert @nochex.test? 19 | end 20 | 21 | def test_compositions 22 | assert_equal Money.new(3166, 'GBP'), @nochex.amount 23 | end 24 | 25 | def test_successful_acknowledgement 26 | Nochex::Notification.any_instance.expects(:ssl_post).returns('AUTHORISED') 27 | 28 | assert @nochex.acknowledge 29 | end 30 | 31 | def test_failed_acknowledgement 32 | Nochex::Notification.any_instance.expects(:ssl_post).returns('DECLINED') 33 | 34 | assert !@nochex.acknowledge 35 | end 36 | 37 | def test_respond_to_acknowledge 38 | assert @nochex.respond_to?(:acknowledge) 39 | end 40 | 41 | def test_nil_notification 42 | Nochex::Notification.any_instance.expects(:ssl_post).returns('DECLINED') 43 | notification = Nochex::Notification.new(nil) 44 | assert !notification.acknowledge 45 | end 46 | 47 | private 48 | def http_raw_data 49 | "transaction_date=27/09/2006 22:30:53&transaction_id=91191&order_id=11&from_email=test2@nochex.com&to_email=test1@nochex.com&amount=31.6600&security_key=L254524366479818252491366&status=test&custom=" 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /generators/integration/templates/helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class <%= class_name %>HelperTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def setup 7 | @helper = <%= class_name %>::Helper.new('order-500','cody@example.com', :amount => 500, :currency => 'USD') 8 | end 9 | 10 | def test_basic_helper_fields 11 | assert_field '', 'cody@example.com' 12 | 13 | assert_field '', '5.00' 14 | assert_field '', 'order-500' 15 | end 16 | 17 | def test_customer_fields 18 | @helper.customer :first_name => 'Cody', :last_name => 'Fauser', :email => 'cody@example.com' 19 | assert_field '', 'Cody' 20 | assert_field '', 'Fauser' 21 | assert_field '', 'cody@example.com' 22 | end 23 | 24 | def test_address_mapping 25 | @helper.billing_address :address1 => '1 My Street', 26 | :address2 => '', 27 | :city => 'Leeds', 28 | :state => 'Yorkshire', 29 | :zip => 'LS2 7EE', 30 | :country => 'CA' 31 | 32 | assert_field '', '1 My Street' 33 | assert_field '', 'Leeds' 34 | assert_field '', 'Yorkshire' 35 | assert_field '', 'LS2 7EE' 36 | end 37 | 38 | def test_unknown_address_mapping 39 | @helper.billing_address :farm => 'CA' 40 | assert_equal 3, @helper.fields.size 41 | end 42 | 43 | def test_unknown_mapping 44 | assert_nothing_raised do 45 | @helper.company_address :address => '500 Dwemthy Fox Road' 46 | end 47 | end 48 | 49 | def test_setting_invalid_address_field 50 | fields = @helper.fields.dup 51 | @helper.billing_address :street => 'My Street' 52 | assert_equal fields, @helper.fields 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/directebanking.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module Directebanking 5 | autoload :Return, File.dirname(__FILE__) + '/directebanking/return.rb' 6 | autoload :Helper, File.dirname(__FILE__) + '/directebanking/helper.rb' 7 | autoload :Notification, File.dirname(__FILE__) + '/directebanking/notification.rb' 8 | 9 | # Supported countries: 10 | # Germany - DE 11 | # Austria - AT 12 | # Belgium - BE 13 | # Netherlands - NL 14 | # Switzerland - CH 15 | # Great Britain - GB 16 | 17 | # Overwrite this if you want to change the directebanking test url 18 | mattr_accessor :test_url 19 | self.test_url = 'https://www.directebanking.com/payment/start' 20 | 21 | # Overwrite this if you want to change the directebanking production url 22 | mattr_accessor :production_url 23 | self.production_url = 'https://www.directebanking.com/payment/start' 24 | 25 | def self.service_url 26 | mode = ActiveMerchant::Billing::Base.integration_mode 27 | case mode 28 | when :production 29 | self.production_url 30 | when :test 31 | self.test_url 32 | else 33 | raise StandardError, "Integration mode set to an invalid value: #{mode}" 34 | end 35 | end 36 | 37 | def self.notification(post, options = {}) 38 | Notification.new(post, options) 39 | end 40 | 41 | def self.return(post, options = {}) 42 | Return.new(post, options) 43 | end 44 | end 45 | end 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /test/unit/integrations/returns/dwolla_return_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class DwollaReturnTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def setup 7 | @error_dwolla = Dwolla::Return.new(http_raw_data_failure) 8 | @failed_callback_dwolla = Dwolla::Return.new(http_raw_data_failed_callback) 9 | @dwolla = Dwolla::Return.new(http_raw_data_success) 10 | end 11 | 12 | def test_error_return 13 | assert_false @error_dwolla.success? 14 | end 15 | 16 | def test_error_accessors 17 | assert_equal "failure", @error_dwolla.error 18 | assert_equal "Invalid application credentials.", @error_dwolla.error_description 19 | end 20 | 21 | def test_failed_callback_return 22 | assert_false @failed_callback_dwolla.success? 23 | end 24 | 25 | def test_failed_callback_accessors 26 | assert_equal "4ac56e71-8a45-4be2-be5e-03a2db87f418", @failed_callback_dwolla.checkout_id 27 | assert_equal "1", @failed_callback_dwolla.transaction 28 | assert @failed_callback_dwolla.test? 29 | end 30 | 31 | def test_success_return 32 | assert @dwolla.success? 33 | end 34 | 35 | def test_success_accessors 36 | assert_equal "4ac56e71-8a45-4be2-be5e-03a2db87f418", @dwolla.checkout_id 37 | assert_equal "1", @dwolla.transaction 38 | assert @dwolla.test? 39 | end 40 | 41 | private 42 | def http_raw_data_success 43 | "checkoutid=4ac56e71-8a45-4be2-be5e-03a2db87f418&transaction=1&postback=success&test=true" 44 | end 45 | 46 | def http_raw_data_failed_callback 47 | "checkoutid=4ac56e71-8a45-4be2-be5e-03a2db87f418&transaction=1&postback=failure&test=true" 48 | end 49 | 50 | def http_raw_data_failure 51 | "error=failure&error_description=Invalid+application+credentials." 52 | end 53 | end 54 | 55 | 56 | -------------------------------------------------------------------------------- /test/unit/integrations/helpers/nochex_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class NochexHelperTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def setup 7 | @helper = Nochex::Helper.new('order-500','cody@example.com', :amount => 500, :currency => 'GBP') 8 | end 9 | 10 | def test_basic_helper_fields 11 | assert_field 'email', 'cody@example.com' 12 | 13 | # Nochex requires 2 decimal places on the amount 14 | assert_field 'amount', '5.00' 15 | assert_field 'ordernumber', 'order-500' 16 | end 17 | 18 | def test_customer_fields 19 | @helper.customer :first_name => 'Cody', :last_name => 'Fauser', :email => 'cody@example.com' 20 | assert_field 'firstname', 'Cody' 21 | assert_field 'lastname', 'Fauser' 22 | assert_field 'email_address_sender', 'cody@example.com' 23 | end 24 | 25 | def test_address_mapping 26 | @helper.billing_address :address1 => '1 My Street', 27 | :city => 'Leeds', 28 | :state => 'Yorkshire', 29 | :zip => 'LS2 7EE' 30 | 31 | assert_field 'firstline', '1 My Street' 32 | assert_field 'town', 'Leeds' 33 | assert_field 'county', 'Yorkshire' 34 | assert_field 'postcode', 'LS2 7EE' 35 | end 36 | 37 | def test_unknown_address_mapping 38 | @helper.billing_address :country => 'CA' 39 | assert_equal 3, @helper.fields.size 40 | end 41 | 42 | def test_unknown_mapping 43 | assert_nothing_raised do 44 | @helper.company_address :address => '500 Dwemthy Fox Road' 45 | end 46 | end 47 | 48 | def test_setting_invalid_address_field 49 | fields = @helper.fields.dup 50 | @helper.billing_address :street => 'My Street' 51 | assert_equal fields, @helper.fields 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /test/unit/avs_result_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class AVSResultTest < Test::Unit::TestCase 4 | def test_nil 5 | result = AVSResult.new(nil) 6 | end 7 | 8 | def test_no_match 9 | result = AVSResult.new(:code => 'N') 10 | assert_equal 'N', result.code 11 | assert_equal 'N', result.street_match 12 | assert_equal 'N', result.postal_match 13 | assert_equal AVSResult.messages['N'], result.message 14 | end 15 | 16 | def test_only_street_match 17 | result = AVSResult.new(:code => 'A') 18 | assert_equal 'A', result.code 19 | assert_equal 'Y', result.street_match 20 | assert_equal 'N', result.postal_match 21 | assert_equal AVSResult.messages['A'], result.message 22 | end 23 | 24 | def test_only_postal_match 25 | result = AVSResult.new(:code => 'W') 26 | assert_equal 'W', result.code 27 | assert_equal 'N', result.street_match 28 | assert_equal 'Y', result.postal_match 29 | assert_equal AVSResult.messages['W'], result.message 30 | end 31 | 32 | def test_nil_data 33 | result = AVSResult.new(:code => nil) 34 | assert_nil result.code 35 | assert_nil result.message 36 | end 37 | 38 | def test_empty_data 39 | result = AVSResult.new(:code => '') 40 | assert_nil result.code 41 | assert_nil result.message 42 | end 43 | 44 | def test_to_hash 45 | avs_data = AVSResult.new(:code => 'X').to_hash 46 | assert_equal 'X', avs_data['code'] 47 | assert_equal AVSResult.messages['X'], avs_data['message'] 48 | end 49 | 50 | def test_street_match 51 | avs_data = AVSResult.new(:street_match => 'Y') 52 | assert_equal 'Y', avs_data.street_match 53 | end 54 | 55 | def test_postal_match 56 | avs_data = AVSResult.new(:postal_match => 'Y') 57 | assert_equal 'Y', avs_data.postal_match 58 | end 59 | end -------------------------------------------------------------------------------- /test/unit/integrations/notifications/dwolla_notification_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class DwollaNotificationTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def setup 7 | @error_dwolla = Dwolla::Notification.new(http_raw_error_data) 8 | @dwolla = Dwolla::Notification.new(http_raw_success_data) 9 | end 10 | 11 | def test_success_accessors 12 | assert @dwolla.complete? 13 | assert_equal "1234asdfasd567", @dwolla.item_id 14 | assert_equal "Completed", @dwolla.status 15 | assert_equal 1.00, @dwolla.gross 16 | assert_equal "USD", @dwolla.currency 17 | assert @dwolla.test? 18 | end 19 | 20 | def test_error_accessors 21 | assert_false @error_dwolla.complete? 22 | assert_equal "order-1", @error_dwolla.item_id 23 | assert_equal nil, @error_dwolla.status 24 | assert_equal nil, @error_dwolla.gross 25 | assert_equal "USD", @error_dwolla.currency 26 | assert_equal "Invalid Credentials", @error_dwolla.error 27 | assert @error_dwolla.test? 28 | end 29 | 30 | def test_compositions 31 | assert_equal Money.new(100, 'USD'), @dwolla.amount 32 | end 33 | 34 | # Replace with real successful acknowledgement code 35 | def test_acknowledgement 36 | assert_equal true, @dwolla.acknowledge 37 | end 38 | 39 | def test_respond_to_acknowledge 40 | assert @dwolla.respond_to?(:acknowledge) 41 | end 42 | 43 | def test_raw_should_be_set 44 | assert @dwolla.raw.present? 45 | end 46 | 47 | private 48 | def http_raw_error_data 49 | %*{"OrderId":"order-1", "Result": "Error", "Message": "Invalid Credentials", "TestMode":true}* 50 | end 51 | 52 | def http_raw_success_data 53 | %*{"Amount":1.0, "OrderId":"1234asdfasd567", "Status":"Completed", "TransactionId":null, "TestMode":true}* 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/gateways/beanstream_interac.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/beanstream/beanstream_core' 2 | 3 | module ActiveMerchant #:nodoc: 4 | module Billing #:nodoc: 5 | class BeanstreamInteracResponse < Response 6 | def redirect 7 | params['pageContents'] 8 | end 9 | end 10 | 11 | class BeanstreamInteracGateway < Gateway 12 | include BeanstreamCore 13 | 14 | # Confirm a transaction posted back from the bank to Beanstream. 15 | # Confirming a transaction does not require any credentials, 16 | # and in an application with many merchants sharing a funded 17 | # URL the application may not yet know which merchant the 18 | # post back is for until the response of the confirmation is 19 | # received, which contains the order number. 20 | def self.confirm(transaction) 21 | gateway = new(:login => '') 22 | gateway.confirm(transaction) 23 | end 24 | 25 | def purchase(money, options = {}) 26 | post = {} 27 | add_amount(post, money) 28 | add_invoice(post, options) 29 | add_address(post, options) 30 | add_interac_details(post, options) 31 | add_transaction_type(post, :purchase) 32 | commit(post) 33 | end 34 | 35 | # Confirm a transaction posted back from the bank to Beanstream. 36 | def confirm(transaction) 37 | post(transaction) 38 | end 39 | 40 | private 41 | 42 | def add_interac_details(post, options) 43 | address = options[:billing_address] || options[:address] || {} 44 | post[:trnCardOwner] = address[:name] 45 | post[:paymentMethod] = 'IO' 46 | end 47 | 48 | def build_response(*args) 49 | BeanstreamInteracResponse.new(*args) 50 | end 51 | end 52 | end 53 | end 54 | 55 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/robokassa.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | 5 | # Documentation: http://robokassa.ru/Doc/En/Interface.aspx 6 | module Robokassa 7 | autoload :Helper, File.dirname(__FILE__) + '/robokassa/helper.rb' 8 | autoload :Notification, File.dirname(__FILE__) + '/robokassa/notification.rb' 9 | autoload :Return, File.dirname(__FILE__) + '/robokassa/return.rb' 10 | autoload :Common, File.dirname(__FILE__) + '/robokassa/common.rb' 11 | 12 | # Overwrite this if you want to change the Robokassa test url 13 | mattr_accessor :test_url 14 | self.test_url = 'http://test.robokassa.ru/Index.aspx' 15 | 16 | # Overwrite this if you want to change the Robokassa production url 17 | mattr_accessor :production_url 18 | self.production_url = 'https://merchant.roboxchange.com/Index.aspx' 19 | 20 | mattr_accessor :signature_parameter_name 21 | self.signature_parameter_name = 'SignatureValue' 22 | 23 | def self.service_url 24 | mode = ActiveMerchant::Billing::Base.integration_mode 25 | case mode 26 | when :production 27 | self.production_url 28 | when :test 29 | self.test_url 30 | else 31 | raise StandardError, "Integration mode set to an invalid value: #{mode}" 32 | end 33 | end 34 | 35 | def self.helper(order, account, options = {}) 36 | Helper.new(order, account, options) 37 | end 38 | 39 | def self.notification(query_string, options = {}) 40 | Notification.new(query_string, options) 41 | end 42 | 43 | def self.return(query_string) 44 | Return.new(query_string) 45 | end 46 | end 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /test/unit/generators/test_gateway_generator.rb: -------------------------------------------------------------------------------- 1 | require File.join(File.dirname(__FILE__), "test_generator_helper.rb") 2 | 3 | class TestGatewayGenerator < Test::Unit::TestCase 4 | include RubiGen::GeneratorTestHelper 5 | 6 | def setup 7 | bare_setup 8 | end 9 | 10 | def teardown 11 | bare_teardown 12 | end 13 | 14 | # Some generator-related assertions: 15 | # assert_generated_file(name, &block) # block passed the file contents 16 | # assert_directory_exists(name) 17 | # assert_generated_class(name, &block) 18 | # assert_generated_module(name, &block) 19 | # assert_generated_test_for(name, &block) 20 | # The assert_generated_(class|module|test_for) &block is passed the body of the class/module within the file 21 | # assert_has_method(body, *methods) # check that the body has a list of methods (methods with parentheses not supported yet) 22 | # 23 | # Other helper methods are: 24 | # app_root_files - put this in teardown to show files generated by the test method (e.g. p app_root_files) 25 | # bare_setup - place this in setup method to create the APP_ROOT folder for each test 26 | # bare_teardown - place this in teardown method to destroy the TMP_ROOT or APP_ROOT folder after each test 27 | 28 | def test_generator_without_options 29 | name = 'miracle' 30 | 31 | run_generator('gateway', [ name ], sources) 32 | assert_generated_file(GatewayGenerator::LIB_DIR + "#{name}.rb") 33 | assert_generated_file(GatewayGenerator::UNIT_TEST_DIR + "#{name}_test.rb") 34 | assert_generated_file(GatewayGenerator::REMOTE_TEST_DIR + "remote_#{name}_test.rb") 35 | end 36 | 37 | private 38 | def sources 39 | [RubiGen::PathSource.new(:test, File.join(File.dirname(__FILE__),"..", generator_path)) 40 | ] 41 | end 42 | 43 | def generator_path 44 | "generators" 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /test/unit/gateways/netbilling_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class NetbillingTest < Test::Unit::TestCase 4 | def setup 5 | @gateway = NetbillingGateway.new( 6 | :login => 'login', 7 | :password => 'password' 8 | ) 9 | 10 | @credit_card = credit_card('4242424242424242') 11 | @amount = 100 12 | @options = { :billing_address => address } 13 | end 14 | 15 | def test_successful_request 16 | @gateway.expects(:ssl_post).returns(successful_purchase_response) 17 | 18 | assert response = @gateway.purchase(@amount, @credit_card, @options) 19 | assert_success response 20 | assert_equal '110270311543', response.authorization 21 | assert response.test? 22 | end 23 | 24 | def test_unsuccessful_request 25 | @gateway.expects(:ssl_post).returns(unsuccessful_purchase_response) 26 | 27 | assert response = @gateway.purchase(@amount, @credit_card, @options) 28 | assert_failure response 29 | assert response.test? 30 | end 31 | 32 | def test_avs_result 33 | @gateway.expects(:ssl_post).returns(successful_purchase_response) 34 | 35 | response = @gateway.purchase(@amount, @credit_card, @options) 36 | assert_equal 'X', response.avs_result['code'] 37 | end 38 | 39 | def test_cvv_result 40 | @gateway.expects(:ssl_post).returns(successful_purchase_response) 41 | 42 | response = @gateway.purchase(@amount, @credit_card, @options) 43 | assert_equal 'M', response.cvv_result['code'] 44 | end 45 | 46 | private 47 | def successful_purchase_response 48 | "avs_code=X&cvv2_code=M&status_code=1&auth_code=999999&trans_id=110270311543&auth_msg=TEST+APPROVED&auth_date=2008-01-25+16:43:54" 49 | end 50 | 51 | def unsuccessful_purchase_response 52 | "status_code=0&auth_msg=CARD+EXPIRED&trans_id=110492608613&auth_date=2008-01-25+17:47:44" 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /test/unit/integrations/helpers/authorize_net_sim_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class AuthorizeNetSimHelperTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def setup 7 | # currency is currently ignored... 8 | @helper = AuthorizeNetSim::Helper.new('order-500','cody@example.com', :amount => 500, :currency => 'USD') 9 | end 10 | 11 | def test_basic_helper_fields 12 | assert_field 'x_login', 'cody@example.com' 13 | assert_field 'x_amount', '500.0' 14 | assert_field 'x_fp_sequence', 'order-500' 15 | end 16 | 17 | def test_customer_fields 18 | @helper.customer :first_name => 'Cody', :last_name => 'Fauser', :email => 'cody@example.com' 19 | assert_field 'x_first_name', 'Cody' 20 | assert_field 'x_last_name', 'Fauser' 21 | assert_field 'x_email', 'cody@example.com' 22 | end 23 | 24 | def test_address_mapping 25 | @helper.billing_address :address1 => '1 My Street', 26 | :address2 => '', 27 | :city => 'Leeds', 28 | :state => 'Yorkshire', 29 | :zip => 'LS2 7EE', 30 | :country => 'CA' 31 | assert_field 'x_address', '1 My Street' 32 | assert_field 'x_city', 'Leeds' 33 | assert_field 'x_state', 'Yorkshire' 34 | assert_field 'x_zip', 'LS2 7EE' 35 | end 36 | 37 | def test_unknown_address_mapping 38 | @helper.billing_address :farm => 'CA' 39 | assert_equal 8, @helper.fields.size 40 | end 41 | 42 | def test_unknown_mapping 43 | assert_nothing_raised do 44 | @helper.company_address :address => '500 Dwemthy Fox Road' 45 | end 46 | end 47 | 48 | def test_setting_invalid_address_field 49 | fields = @helper.fields.dup 50 | @helper.billing_address :street => 'My Street' 51 | assert_equal fields, @helper.fields 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /test/unit/integrations/returns/direc_pay_return_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class DirecPayReturnTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def test_success 7 | direc_pay = DirecPay::Return.new(http_raw_data_success) 8 | assert direc_pay.success? 9 | assert_equal 'Completed', direc_pay.message 10 | end 11 | 12 | def test_failure_is_successful 13 | direc_pay = DirecPay::Return.new(http_raw_data_failure) 14 | assert direc_pay.success? 15 | assert_equal 'Pending', direc_pay.message 16 | end 17 | 18 | def test_treat_initial_failures_as_pending 19 | direc_pay = DirecPay::Return.new(http_raw_data_failure) 20 | assert_equal 'Pending', direc_pay.notification.status 21 | end 22 | 23 | def test_return_has_notification 24 | direc_pay = DirecPay::Return.new(http_raw_data_success) 25 | notification = direc_pay.notification 26 | 27 | assert_equal '1001010000026481', direc_pay.notification.transaction_id 28 | assert notification.complete? 29 | assert_equal 'Completed', notification.status 30 | assert_equal '1001', notification.item_id 31 | assert_equal '1.00', notification.gross 32 | assert_equal 100, notification.gross_cents 33 | assert_equal Money.new(100, 'INR'), notification.amount 34 | assert_equal 'INR', notification.currency 35 | assert_equal 'IND', notification.country 36 | assert_equal 'NULL', notification.other_details 37 | end 38 | 39 | def test_treat_failed_return_as_complete 40 | direc_pay = DirecPay::Return.new(http_raw_data_failure) 41 | assert direc_pay.notification.complete? 42 | end 43 | 44 | private 45 | 46 | def http_raw_data_success 47 | "responseparams=1001010000026481|SUCCESS|IND|INR|NULL|1001|1.00|" 48 | end 49 | 50 | def http_raw_data_failure 51 | "responseparams=1001010000026516|FAIL|IND|INR|NULL|1001|1.00|" 52 | end 53 | 54 | end 55 | -------------------------------------------------------------------------------- /test/unit/base_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class BaseTest < Test::Unit::TestCase 4 | def setup 5 | ActiveMerchant::Billing::Base.mode = :test 6 | end 7 | 8 | def teardown 9 | ActiveMerchant::Billing::Base.mode = :test 10 | end 11 | 12 | def test_should_return_a_new_gateway_specified_by_symbol_name 13 | assert_equal BogusGateway, Base.gateway(:bogus) 14 | assert_equal MonerisGateway, Base.gateway(:moneris) 15 | assert_equal MonerisUsGateway, Base.gateway(:moneris_us) 16 | assert_equal AuthorizeNetGateway, Base.gateway(:authorize_net) 17 | assert_equal UsaEpayGateway, Base.gateway(:usa_epay) 18 | assert_equal LinkpointGateway, Base.gateway(:linkpoint) 19 | end 20 | 21 | def test_should_return_an_integration_by_name 22 | chronopay = Base.integration(:chronopay) 23 | 24 | assert_equal Integrations::Chronopay, chronopay 25 | assert_instance_of Integrations::Chronopay::Notification, chronopay.notification('name=cody') 26 | end 27 | 28 | def test_should_set_modes 29 | Base.mode = :test 30 | assert_equal :test, Base.mode 31 | assert_equal :test, Base.gateway_mode 32 | assert_equal :test, Base.integration_mode 33 | 34 | Base.mode = :production 35 | assert_equal :production, Base.mode 36 | assert_equal :production, Base.gateway_mode 37 | assert_equal :production, Base.integration_mode 38 | 39 | Base.mode = :development 40 | Base.gateway_mode = :test 41 | Base.integration_mode = :staging 42 | assert_equal :development, Base.mode 43 | assert_equal :test, Base.gateway_mode 44 | assert_equal :staging, Base.integration_mode 45 | end 46 | 47 | def test_should_identify_if_test_mode 48 | Base.gateway_mode = :test 49 | assert Base.test? 50 | 51 | Base.gateway_mode = :production 52 | assert_false Base.test? 53 | end 54 | 55 | end 56 | -------------------------------------------------------------------------------- /generators/gateway/gateway_generator.rb: -------------------------------------------------------------------------------- 1 | class GatewayGenerator < RubiGen::Base 2 | LIB_DIR = "lib/active_merchant/billing/gateways/" 3 | UNIT_TEST_DIR = "test/unit/gateways/" 4 | REMOTE_TEST_DIR = "test/remote/gateways/" 5 | 6 | 7 | default_options :author => nil 8 | 9 | attr_reader :name 10 | 11 | def initialize(runtime_args, runtime_options = {}) 12 | super 13 | usage if args.length < 1 14 | @name = args.shift 15 | extract_options 16 | end 17 | 18 | def class_name 19 | @name.classify 20 | end 21 | 22 | def manifest 23 | record do |m| 24 | 25 | m.directory LIB_DIR 26 | m.directory UNIT_TEST_DIR 27 | m.directory REMOTE_TEST_DIR 28 | 29 | m.template 'gateway.rb', LIB_DIR + "#{name}.rb" 30 | m.template 'gateway_test.rb', UNIT_TEST_DIR + "#{name}_test.rb" 31 | m.template 'remote_gateway_test.rb', REMOTE_TEST_DIR + "remote_#{name}_test.rb" 32 | end 33 | end 34 | 35 | protected 36 | def banner 37 | <<-EOS 38 | Creates a ... 39 | 40 | USAGE: #{$0} #{spec.name} name" 41 | EOS 42 | end 43 | 44 | def add_options!(opts) 45 | # opts.separator '' 46 | # opts.separator 'Options:' 47 | # For each option below, place the default 48 | # at the top of the file next to "default_options" 49 | # opts.on("-a", "--author=\"Your Name\"", String, 50 | # "Some comment about this option", 51 | # "Default: none") { |options[:author]| } 52 | # opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.") 53 | end 54 | 55 | def extract_options 56 | # for each option, extract it into a local variable (and create an "attr_reader :author" at the top) 57 | # Templates can access these value via the attr_reader-generated methods, but not the 58 | # raw instance variable value. 59 | # @author = options[:author] 60 | end 61 | end -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/epay/helper.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module Epay 5 | class Helper < ActiveMerchant::Billing::Integrations::Helper 6 | 7 | def initialize(order, merchantnumber, options = {}) 8 | super 9 | add_field('windowstate', 3) 10 | add_field('language', '0') 11 | add_field('orderid', format_order_number(order)) 12 | @fields = Hash[@fields.sort] 13 | end 14 | 15 | def md5secret(value) 16 | @md5secret = value 17 | end 18 | 19 | def form_fields 20 | @fields.merge('hash' => generate_md5hash) 21 | end 22 | 23 | def generate_md5string 24 | @fields.sort.each.map { |key, value| key != 'hash' ? value.to_s : ''} * "" + @md5secret 25 | end 26 | 27 | def generate_md5hash 28 | Digest::MD5.hexdigest(generate_md5string) 29 | end 30 | 31 | # Limited to 20 digits max 32 | def format_order_number(number) 33 | number.to_s.gsub(/[^\w_]/, '').rjust(4, "0")[0...20] 34 | end 35 | 36 | mapping :account, 'merchantnumber' 37 | mapping :language, 'language' 38 | mapping :amount, 'amount' 39 | mapping :currency, 'currency' 40 | mapping :return_url, 'accepturl' 41 | mapping :cancel_return_url, 'cancelurl' 42 | mapping :notify_url, 'callbackurl' 43 | mapping :autocapture, 'instantcapture' 44 | mapping :description, 'description' 45 | mapping :credential3, 'md5secret' 46 | mapping :customer, '' 47 | mapping :billing_address, {} 48 | mapping :tax, '' 49 | mapping :shipping, '' 50 | 51 | end 52 | end 53 | end 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /generators/gateway/templates/remote_gateway_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class Remote<%= class_name %>Test < Test::Unit::TestCase 4 | 5 | 6 | def setup 7 | @gateway = <%= class_name %>Gateway.new(fixtures(:<%= class_name.underscore %>)) 8 | 9 | @amount = 100 10 | @credit_card = credit_card('4000100011112224') 11 | @declined_card = credit_card('4000300011112220') 12 | 13 | @options = { 14 | :order_id => '1', 15 | :billing_address => address, 16 | :description => 'Store Purchase' 17 | } 18 | end 19 | 20 | def test_successful_purchase 21 | assert response = @gateway.purchase(@amount, @credit_card, @options) 22 | assert_success response 23 | assert_equal 'REPLACE WITH SUCCESS MESSAGE', response.message 24 | end 25 | 26 | def test_unsuccessful_purchase 27 | assert response = @gateway.purchase(@amount, @declined_card, @options) 28 | assert_failure response 29 | assert_equal 'REPLACE WITH FAILED PURCHASE MESSAGE', response.message 30 | end 31 | 32 | def test_authorize_and_capture 33 | amount = @amount 34 | assert auth = @gateway.authorize(amount, @credit_card, @options) 35 | assert_success auth 36 | assert_equal 'Success', auth.message 37 | assert auth.authorization 38 | assert capture = @gateway.capture(amount, auth.authorization) 39 | assert_success capture 40 | end 41 | 42 | def test_failed_capture 43 | assert response = @gateway.capture(@amount, '') 44 | assert_failure response 45 | assert_equal 'REPLACE WITH GATEWAY FAILURE MESSAGE', response.message 46 | end 47 | 48 | def test_invalid_login 49 | gateway = <%= class_name %>Gateway.new( 50 | :login => '', 51 | :password => '' 52 | ) 53 | assert response = gateway.purchase(@amount, @credit_card, @options) 54 | assert_failure response 55 | assert_equal 'REPLACE WITH FAILURE MESSAGE', response.message 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/verkkomaksut/notification.rb: -------------------------------------------------------------------------------- 1 | require 'net/http' 2 | 3 | module ActiveMerchant #:nodoc: 4 | module Billing #:nodoc: 5 | module Integrations #:nodoc: 6 | module Verkkomaksut 7 | class Notification < ActiveMerchant::Billing::Integrations::Notification 8 | 9 | # Is the payment complete or not. Verkkomaksut only has two statuses: random string or 0000000000 which means pending 10 | def complete? 11 | params['PAID'] != "0000000000" 12 | end 13 | 14 | # Order id 15 | def order_id 16 | params['ORDER_NUMBER'] 17 | end 18 | 19 | # Payment method used 20 | def method 21 | params['METHOD'] 22 | end 23 | 24 | # When was this payment received by the client. 25 | def received_at 26 | params['TIMESTAMP'] 27 | end 28 | 29 | # Security key got from Verkkomaksut 30 | def security_key 31 | params['RETURN_AUTHCODE'] 32 | end 33 | 34 | # Another way of asking the payment status 35 | def status 36 | if complete? 37 | "PAID" 38 | else 39 | "PENDING" 40 | end 41 | end 42 | 43 | # Acknowldges the payment. If the authcodes match, returns true. 44 | def acknowledge(authcode) 45 | return_authcode = [params["ORDER_NUMBER"], params["TIMESTAMP"], params["PAID"], params["METHOD"], authcode].join("|") 46 | Digest::MD5.hexdigest(return_authcode).upcase == params["RETURN_AUTHCODE"] 47 | end 48 | private 49 | 50 | def parse(post) 51 | post.each do |key, value| 52 | params[key] = value 53 | end 54 | end 55 | end 56 | end 57 | end 58 | end 59 | end 60 | -------------------------------------------------------------------------------- /test/remote/gateways/remote_modern_payments_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class RemoteModernPaymentTest < Test::Unit::TestCase 4 | 5 | def setup 6 | @gateway = ModernPaymentsGateway.new(fixtures(:modern_payments)) 7 | 8 | @amount = 100 9 | @credit_card = credit_card('4111111111111111') 10 | @declined_card = credit_card('4000000000000000') 11 | 12 | @options = { 13 | :order_id => '1', 14 | :billing_address => address, 15 | :description => 'Store Purchase' 16 | } 17 | 18 | end 19 | 20 | def test_successful_purchase 21 | assert response = @gateway.purchase(@amount, @credit_card, @options) 22 | 23 | # Test mode seems to not return "approved = true" 24 | assert_failure response 25 | assert_match /RESPONSECODE=A/, response.params["auth_string"] 26 | assert_equal ModernPaymentsCimGateway::FAILURE_MESSAGE, response.message 27 | end 28 | 29 | def test_unsuccessful_purchase 30 | assert response = @gateway.purchase(@amount, @declined_card, @options) 31 | assert_failure response 32 | assert_match /RESPONSECODE=D/, response.params["auth_string"] 33 | assert_equal ModernPaymentsCimGateway::FAILURE_MESSAGE, response.message 34 | end 35 | 36 | def test_invalid_login 37 | gateway = ModernPaymentsGateway.new( 38 | :login => '5000', 39 | :password => 'password' 40 | ) 41 | assert response = gateway.purchase(@amount, @credit_card, @options) 42 | assert_failure response 43 | assert_equal ModernPaymentsCimGateway::FAILURE_MESSAGE, response.message 44 | end 45 | 46 | def test_invalid_login 47 | gateway = ModernPaymentsGateway.new( 48 | :login => '', 49 | :password => '' 50 | ) 51 | 52 | assert_raises(ActiveMerchant::ResponseError) do 53 | gateway.purchase(@amount, @credit_card, @options) 54 | end 55 | end 56 | 57 | end 58 | -------------------------------------------------------------------------------- /test/remote/gateways/remote_sage_virtual_check_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class RemoteSageCheckTest < Test::Unit::TestCase 4 | 5 | def setup 6 | @gateway = SageVirtualCheckGateway.new(fixtures(:sage)) 7 | 8 | @amount = 100 9 | @check = check 10 | 11 | @options = { 12 | :order_id => generate_unique_id, 13 | :billing_address => address, 14 | :shipping_address => address, 15 | :email => 'longbob@example.com', 16 | :drivers_license_state => 'CA', 17 | :drivers_license_number => '12345689', 18 | :date_of_birth => Date.new(1978, 8, 11), 19 | :ssn => '078051120' 20 | } 21 | end 22 | 23 | def test_successful_check_purchase 24 | assert response = @gateway.purchase(@amount, @check, @options) 25 | assert_success response 26 | assert response.test? 27 | assert_false response.authorization.blank? 28 | end 29 | 30 | def test_failed_check_purchase 31 | @check.routing_number = "" 32 | 33 | assert response = @gateway.purchase(@amount, @check, @options) 34 | assert_failure response 35 | assert response.test? 36 | assert_false response.authorization.blank? 37 | end 38 | 39 | def test_purchase_and_void 40 | assert purchase = @gateway.purchase(@amount, @check, @options) 41 | assert_success purchase 42 | 43 | assert void = @gateway.void(purchase.authorization) 44 | assert_success void 45 | end 46 | 47 | def test_credit 48 | assert response = @gateway.credit(@amount, @check, @options) 49 | assert_success response 50 | assert response.test? 51 | end 52 | 53 | def test_invalid_login 54 | gateway = SageVirtualCheckGateway.new( 55 | :login => '', 56 | :password => '' 57 | ) 58 | assert response = gateway.purchase(@amount, @check, @options) 59 | assert_failure response 60 | assert_equal 'SECURITY VIOLATION', response.message 61 | end 62 | end 63 | -------------------------------------------------------------------------------- /test/remote/gateways/remote_secure_pay_tech_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class RemoteSecurePayTechTest < Test::Unit::TestCase 4 | $verbose = true 5 | 6 | def setup 7 | @gateway = SecurePayTechGateway.new(fixtures(:secure_pay_tech)) 8 | 9 | @accepted_amount = 10000 10 | @declined_amount = 10075 11 | 12 | @credit_card = credit_card('4987654321098769', :month => '5', :year => '2013') 13 | @options = { :billing_address => address } 14 | end 15 | 16 | def test_successful_purchase 17 | assert response = @gateway.purchase(@accepted_amount, @credit_card, @options) 18 | assert_equal 'Transaction OK', response.message 19 | assert_success response 20 | end 21 | 22 | def test_unsuccessful_purchase 23 | assert response = @gateway.purchase(@declined_amount, @credit_card, @options) 24 | assert_equal 'Card declined', response.message 25 | assert_failure response 26 | end 27 | 28 | def test_successful_cvv_check 29 | @credit_card.verification_value = '100' 30 | 31 | # Use a different amount to the previous test, otherwise SPT assumes that this is a repost of a previous transaction 32 | assert response = @gateway.purchase(@accepted_amount + 100, @credit_card, @options) 33 | assert_equal 'Transaction OK', response.message 34 | assert_success response 35 | end 36 | 37 | def test_unsuccessful_cvv_check 38 | @credit_card.verification_value = '104' 39 | assert response = @gateway.purchase(@accepted_amount + 200, @credit_card, @options) 40 | assert_equal 'Card declined', response.message 41 | assert_failure response 42 | end 43 | 44 | def test_invalid_login 45 | gateway = SecurePayTechGateway.new( 46 | :login => 'foo', 47 | :password => 'bar' 48 | ) 49 | assert response = gateway.purchase(@accepted_amount, @credit_card, @options) 50 | assert_equal 'Bad or malformed request', response.message 51 | assert_failure response 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /test/remote/gateways/remote_modern_payments_cim_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class RemoteModernPaymentsCimTest < Test::Unit::TestCase 4 | 5 | 6 | def setup 7 | @gateway = ModernPaymentsCimGateway.new(fixtures(:modern_payments)) 8 | 9 | @amount = 100 10 | @credit_card = credit_card('4111111111111111') 11 | @declined_card = credit_card('4000000000000000') 12 | 13 | @options = { 14 | :billing_address => address, 15 | :customer => 'JIMSMITH2000' 16 | } 17 | end 18 | 19 | def test_successful_create_customer 20 | response = @gateway.create_customer(@options) 21 | assert_success response 22 | assert !response.params["create_customer_result"].blank? 23 | end 24 | 25 | def test_successful_modify_customer_credit_card 26 | customer = @gateway.create_customer(@options) 27 | assert_success customer 28 | 29 | customer_id = customer.params["create_customer_result"] 30 | 31 | credit_card = @gateway.modify_customer_credit_card(customer_id, @credit_card) 32 | assert_success credit_card 33 | assert !credit_card.params["modify_customer_credit_card_result"].blank? 34 | end 35 | 36 | def test_succsessful_authorize_credit_card_payment 37 | customer = @gateway.create_customer(@options) 38 | assert_success customer 39 | 40 | customer_id = customer.params["create_customer_result"] 41 | 42 | credit_card = @gateway.modify_customer_credit_card(customer_id, @credit_card) 43 | assert_success credit_card 44 | 45 | payment = @gateway.authorize_credit_card_payment(customer_id, @amount) 46 | assert_success payment 47 | end 48 | 49 | def test_invalid_login 50 | gateway = ModernPaymentsCimGateway.new( 51 | :login => '', 52 | :password => '' 53 | ) 54 | assert response = gateway.create_customer(@options) 55 | assert_failure response 56 | assert_equal ModernPaymentsCimGateway::ERROR_MESSAGE, response.message 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /test/unit/integrations/helpers/e_payment_plans_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class EPaymentPlansHelperTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def setup 7 | @helper = EPaymentPlans::Helper.new('order-500','cody@example.com', :amount => 500, :currency => 'USD') 8 | end 9 | 10 | def test_basic_helper_fields 11 | assert_field 'order[account]', 'cody@example.com' 12 | 13 | assert_field 'order[amount]', '500' 14 | assert_field 'order[num]', 'order-500' 15 | end 16 | 17 | def test_customer_fields 18 | @helper.customer :first_name => 'Cody', :last_name => 'Fauser', :email => 'cody@example.com' 19 | assert_field 'order[first_name]', 'Cody' 20 | assert_field 'order[last_name]', 'Fauser' 21 | assert_field 'order[email]', 'cody@example.com' 22 | end 23 | 24 | def test_address_mapping 25 | @helper.billing_address :address1 => '1 My Street', 26 | :address2 => '', 27 | :company => 'Shopify', 28 | :city => 'Leeds', 29 | :state => 'Yorkshire', 30 | :zip => 'LS2 7EE', 31 | :country => 'CA' 32 | 33 | assert_field 'order[address1]', '1 My Street' 34 | assert_field 'order[city]', 'Leeds' 35 | assert_field 'order[company]', 'Shopify' 36 | assert_field 'order[state]', 'Yorkshire' 37 | assert_field 'order[zip]', 'LS2 7EE' 38 | end 39 | 40 | def test_unknown_address_mapping 41 | @helper.billing_address :farm => 'CA' 42 | assert_equal 3, @helper.fields.size 43 | end 44 | 45 | def test_unknown_mapping 46 | assert_nothing_raised do 47 | @helper.company_address :address => '500 Dwemthy Fox Road' 48 | end 49 | end 50 | 51 | def test_setting_invalid_address_field 52 | fields = @helper.fields.dup 53 | @helper.billing_address :street => 'My Street' 54 | assert_equal fields, @helper.fields 55 | end 56 | end 57 | -------------------------------------------------------------------------------- /test/remote/gateways/remote_instapay_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class RemoteInstapayTest < Test::Unit::TestCase 4 | 5 | def setup 6 | @gateway = InstapayGateway.new(fixtures(:instapay)) 7 | 8 | @amount = 100 9 | @credit_card = credit_card('5454545454545454') 10 | @declined_card = credit_card('4000300011112220') 11 | 12 | @options = { 13 | :order_id => generate_unique_id, 14 | :billing_address => address, 15 | :shipping_address => address, 16 | :description => 'Store Purchase' 17 | } 18 | end 19 | 20 | def test_successful_purchase 21 | assert response = @gateway.purchase(@amount, @credit_card, @options) 22 | assert_success response 23 | assert_equal InstapayGateway::SUCCESS_MESSAGE, response.message 24 | end 25 | 26 | def test_failed_purchase 27 | assert response = @gateway.purchase(@amount, @declined_card, @options) 28 | assert_failure response 29 | end 30 | 31 | def test_succesful_authorization 32 | assert response = @gateway.authorize(@amount, @credit_card, @options) 33 | assert_success response 34 | assert_equal InstapayGateway::SUCCESS_MESSAGE, response.message 35 | end 36 | 37 | def test_failed_authorization 38 | assert response = @gateway.authorize(@amount, @declined_card, @options) 39 | assert_failure response 40 | end 41 | 42 | def test_authorization_and_capture 43 | assert authorization = @gateway.authorize(@amount, @credit_card, @options) 44 | assert_success authorization 45 | 46 | assert capture = @gateway.capture(@amount, authorization.authorization) 47 | assert_success capture 48 | assert_equal InstapayGateway::SUCCESS_MESSAGE, capture.message 49 | end 50 | 51 | def test_invalid_login 52 | gateway = InstapayGateway.new( 53 | :login => 'X', 54 | :password => 'Y' 55 | ) 56 | 57 | assert response = gateway.purchase(@amount, @credit_card) 58 | assert_failure response 59 | assert_equal "Invalid merchant", response.message 60 | end 61 | end 62 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/hi_trust/helper.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module HiTrust 5 | class Helper < ActiveMerchant::Billing::Integrations::Helper 6 | 7 | # Transaction types 8 | # * Auth 9 | # * AuthRe 10 | # * Capture 11 | # * CaptureRe 12 | # * Refund 13 | # * RefundRe 14 | # * Query 15 | def initialize(order, account, options = {}) 16 | super 17 | # Perform an authorization by default 18 | add_field('Type', 'Auth') 19 | 20 | # Capture the payment right away 21 | add_field('depositflag', '1') 22 | 23 | # Disable auto query - who knows what it does? 24 | add_field('queryflag', '1') 25 | 26 | add_field('orderdesc', 'Store purchase') 27 | end 28 | 29 | mapping :account, 'storeid' 30 | mapping :amount, 'amount' 31 | 32 | def amount=(money) 33 | cents = money.respond_to?(:cents) ? money.cents : money 34 | 35 | if money.is_a?(String) or cents.to_i < 0 36 | raise ArgumentError, 'money amount must be either a Money object or a positive integer in cents.' 37 | end 38 | 39 | add_field(mappings[:amount], cents) 40 | end 41 | # Supported currencies include: 42 | # * CNY:Chinese Yuan (Renminbi) 43 | # * TWD:New Taiwan Dollar 44 | # * HKD:Hong Kong Dollar 45 | # * USD:US Dollar 46 | # * AUD:Austrian Dollar 47 | mapping :currency, 'currency' 48 | 49 | mapping :order, 'ordernumber' 50 | mapping :description, 'orderdesc' 51 | 52 | mapping :notify_url, 'merUpdateURL' 53 | mapping :return_url, 'returnURL' 54 | end 55 | end 56 | end 57 | end 58 | end -------------------------------------------------------------------------------- /lib/active_merchant/billing/base.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Base 4 | # Set ActiveMerchant gateways in test mode. 5 | # 6 | # ActiveMerchant::Billing::Base.gateway_mode = :test 7 | mattr_accessor :gateway_mode 8 | 9 | # Set ActiveMerchant integrations in test mode. 10 | # 11 | # ActiveMerchant::Billing::Base.integration_mode = :test 12 | mattr_accessor :integration_mode 13 | 14 | # Set both the mode of both the gateways and integrations 15 | # at once 16 | mattr_reader :mode 17 | 18 | def self.mode=(mode) 19 | @@mode = mode 20 | self.gateway_mode = mode 21 | self.integration_mode = mode 22 | end 23 | 24 | self.mode = :production 25 | 26 | # Return the matching gateway for the provider 27 | # * bogus: BogusGateway - Does nothing (for testing) 28 | # * moneris: MonerisGateway 29 | # * authorize_net: AuthorizeNetGateway 30 | # * trust_commerce: TrustCommerceGateway 31 | # 32 | # ActiveMerchant::Billing::Base.gateway('moneris').new 33 | def self.gateway(name) 34 | Billing.const_get("#{name.to_s.downcase}_gateway".camelize) 35 | end 36 | 37 | # Return the matching integration module 38 | # You can then get the notification from the module 39 | # * bogus: Bogus - Does nothing (for testing) 40 | # * chronopay: Chronopay - Does nothing (for testing) 41 | # * paypal: Chronopay - Does nothing (for testing) 42 | # 43 | # chronopay = ActiveMerchant::Billing::Base.integration('chronopay') 44 | # notification = chronopay.notification(raw_post) 45 | # 46 | def self.integration(name) 47 | Billing::Integrations.const_get("#{name.to_s.downcase}".camelize) 48 | end 49 | 50 | # A check to see if we're in test mode 51 | def self.test? 52 | self.gateway_mode == :test 53 | end 54 | end 55 | end 56 | end 57 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/gateways/paypal_digital_goods.rb: -------------------------------------------------------------------------------- 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 PaypalDigitalGoodsGateway < PaypalExpressGateway 8 | self.test_redirect_url = 'https://www.sandbox.paypal.com/incontext' 9 | self.live_redirect_url = 'https://www.paypal.com/incontext' 10 | 11 | self.supported_countries = %w(AU CA CN FI GB ID IN IT MY NO NZ PH PL SE SG TH VN) 12 | self.homepage_url = 'https://www.x.com/community/ppx/xspaces/digital_goods' 13 | self.display_name = 'PayPal Express Checkout for Digital Goods' 14 | 15 | def redirect_url_for(token, options = {}) 16 | "#{redirect_url}?token=#{token}&useraction=commit" 17 | end 18 | 19 | # GATEWAY.setup_purchase(100, 20 | # :ip => "127.0.0.1", 21 | # :description => "Test Title", 22 | # :return_url => "http://return.url", 23 | # :cancel_return_url => "http://cancel.url", 24 | # :items => [ { :name => "Charge", 25 | # :number => "1", 26 | # :quantity => "1", 27 | # :amount => 100, 28 | # :description => "Description", 29 | # :category => "Digital" } ] ) 30 | def build_setup_request(action, money, options) 31 | requires!(options, :items) 32 | raise ArgumentError, "Must include at least 1 Item" unless options[:items].length > 0 33 | options[:items].each do |item| 34 | requires!(item, :name, :number, :quantity, :amount, :description, :category) 35 | raise ArgumentError, "Each of the items must have the category 'Digital'" unless item[:category] == 'Digital' 36 | end 37 | 38 | super 39 | end 40 | 41 | end 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /test/remote/gateways/remote_exact_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class RemoteExactTest < Test::Unit::TestCase 4 | 5 | def setup 6 | 7 | @gateway = ExactGateway.new(fixtures(:exact)) 8 | @credit_card = credit_card 9 | @amount = 100 10 | @options = { 11 | :order_id => '1', 12 | :billing_address => address, 13 | :description => 'Store Purchase' 14 | } 15 | end 16 | 17 | def test_successful_purchase 18 | assert response = @gateway.purchase(@amount, @credit_card, @options) 19 | assert_match /Transaction Normal/, response.message 20 | assert_success response 21 | end 22 | 23 | def test_unsuccessful_purchase 24 | # ask for error 13 response (Amount Error) via dollar amount 5,000 + error 25 | @amount = 501300 26 | assert response = @gateway.purchase(@amount, @credit_card, @options ) 27 | assert_match /Transaction Normal/, response.message 28 | assert_failure response 29 | end 30 | 31 | def test_purchase_and_credit 32 | assert purchase = @gateway.purchase(@amount, @credit_card, @options) 33 | assert_success purchase 34 | assert purchase.authorization 35 | assert credit = @gateway.credit(@amount, purchase.authorization) 36 | assert_success credit 37 | end 38 | 39 | def test_authorize_and_capture 40 | assert auth = @gateway.authorize(@amount, @credit_card, @options) 41 | assert_success auth 42 | assert auth.authorization 43 | assert capture = @gateway.capture(@amount, auth.authorization) 44 | assert_success capture 45 | end 46 | 47 | def test_failed_capture 48 | assert response = @gateway.capture(@amount, '') 49 | assert_failure response 50 | assert_match /Precondition Failed/i, response.message 51 | end 52 | 53 | def test_invalid_login 54 | gateway = ExactGateway.new( :login => "NotARealUser", 55 | :password => "NotARealPassword" ) 56 | assert response = gateway.purchase(@amount, @credit_card, @options) 57 | assert_equal "Invalid Logon", response.message 58 | assert_failure response 59 | end 60 | end 61 | -------------------------------------------------------------------------------- /test/unit/integrations/notifications/hi_trust_notification_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class HiTrustNotificationTest < Test::Unit::TestCase 4 | include ActiveMerchant::Billing::Integrations 5 | 6 | def setup 7 | @notification = HiTrust::Notification.new(successful_response) 8 | end 9 | 10 | def teardown 11 | ActiveMerchant::Billing::Base.integration_mode = :test 12 | end 13 | 14 | def test_accessors 15 | assert @notification.complete? 16 | assert_equal "Completed", @notification.status 17 | assert_equal "012345678901", @notification.transaction_id 18 | assert_equal "1000", @notification.item_id 19 | assert_equal "101010", @notification.account 20 | assert_equal "5.00", @notification.gross 21 | assert_equal "USD", @notification.currency 22 | assert_equal Time.parse("2007-12-01.12.35.40.123456"), @notification.received_at 23 | assert @notification.test? 24 | end 25 | 26 | def test_compositions 27 | assert_equal Money.new(500, 'USD'), @notification.amount 28 | end 29 | 30 | def test_send_acknowledgement 31 | assert @notification.acknowledge 32 | end 33 | 34 | def test_respond_to_acknowledge 35 | assert @notification.respond_to?(:acknowledge) 36 | end 37 | 38 | def test_valid_sender_in_testmode_always_true 39 | assert @notification.test? 40 | assert @notification.valid_sender?('127.0.0.1') 41 | assert @notification.valid_sender?(nil) 42 | end 43 | 44 | def test_valid_sender 45 | ActiveMerchant::Billing::Base.integration_mode = :production 46 | assert @notification.valid_sender?('203.75.242.8') 47 | end 48 | 49 | def test_invalid_sender 50 | ActiveMerchant::Billing::Base.integration_mode = :production 51 | assert_false @notification.valid_sender?('127.0.0.1') 52 | assert_false @notification.valid_sender?(nil) 53 | end 54 | 55 | private 56 | def successful_response 57 | 'retcode=00&ordernumber=1000&orderstatus=02&authCode=123456&eci=VISA3D&authRRN=012345678901&storeid=101010&approveamount=500¤cy=USD&orderdate=2007-12-01.12.35.40.123456' 58 | end 59 | end 60 | -------------------------------------------------------------------------------- /test/remote/gateways/remote_eway_managed_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/../../test_helper' 2 | 3 | class RemoteEwayManagedTest < Test::Unit::TestCase 4 | 5 | def setup 6 | @gateway = EwayManagedGateway.new(fixtures(:eway_managed).merge({ :test => true })) 7 | 8 | @valid_card='4444333322221111' 9 | @valid_customer_id='9876543211000' 10 | 11 | @credit_card = credit_card(@valid_card) 12 | 13 | @options = { 14 | :billing_address => { 15 | :country => 'au', 16 | :title => 'Mr.' 17 | } 18 | } 19 | 20 | @amount = 100 21 | end 22 | 23 | def test_successful_purchase 24 | assert response = @gateway.purchase(@amount, @valid_customer_id, @options) 25 | assert_equal "00,Transaction Approved(Test Gateway)", response.message 26 | assert_success response 27 | assert response.test? 28 | assert_not_nil response.authorization 29 | end 30 | 31 | def test_invalid_login 32 | gateway = EwayManagedGateway.new( 33 | :login => '', 34 | :password => '', 35 | :username => '' 36 | ) 37 | assert response = gateway.purchase(@amount, @valid_customer_id, @options) 38 | assert_equal 'Login failed. ', response.message 39 | assert_failure response 40 | end 41 | 42 | def test_store_credit_card 43 | assert response = @gateway.store(@credit_card, @options) 44 | assert_success response 45 | assert_equal "OK", response.message 46 | assert !response.token.blank? 47 | assert_not_nil response.token 48 | end 49 | 50 | def test_update_credit_card 51 | assert response = @gateway.update(@valid_customer_id, @credit_card, @options) 52 | assert_success response 53 | assert_equal "OK", response.message 54 | assert response.token.blank? 55 | end 56 | 57 | def test_store_invalid_credit_card 58 | original_number = @credit_card.number 59 | @credit_card.number = 2 60 | 61 | assert response = @gateway.store(@credit_card, @options) 62 | assert_failure response 63 | ensure 64 | @credit_card.number = original_number 65 | end 66 | 67 | end 68 | -------------------------------------------------------------------------------- /test/remote/gateways/remote_garanti_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | # NOTE: tests may fail randomly because Garanti returns random(!) responses for their test server 4 | class RemoteGarantiTest < Test::Unit::TestCase 5 | 6 | def setup 7 | @gateway = GarantiGateway.new(fixtures(:garanti)) 8 | 9 | @amount = 1 # 1 cents = 0.01$ 10 | @declined_card = credit_card('4000100011112224') 11 | @credit_card = credit_card('4000300011112220') 12 | 13 | @options = { 14 | :order_id => ActiveMerchant::Utils.generate_unique_id, 15 | :billing_address => address, 16 | :description => 'Store Purchase' 17 | } 18 | end 19 | 20 | def test_successful_purchase 21 | assert response = @gateway.purchase(@amount, @credit_card, @options) 22 | assert_success response 23 | assert_equal 'Approved', response.message 24 | end 25 | 26 | def test_unsuccessful_purchase 27 | assert response = @gateway.purchase(@amount, @declined_card, @options) 28 | assert_failure response 29 | assert_match /Declined/, response.message 30 | end 31 | 32 | def test_authorize_and_capture 33 | amount = @amount 34 | assert auth = @gateway.authorize(amount, @credit_card, @options) 35 | assert_success auth 36 | assert_equal 'Approved', auth.message 37 | assert auth.authorization 38 | assert capture = @gateway.capture(amount, auth.authorization) 39 | assert_success capture 40 | end 41 | 42 | def test_failed_capture 43 | assert response = @gateway.capture(@amount, '') 44 | assert_failure response 45 | assert_match /Declined/, response.message 46 | end 47 | 48 | def test_invalid_login 49 | gateway = GarantiGateway.new( 50 | :provision_user_id => 'PROVAUT', 51 | :user_id => 'PROVAUT', 52 | :terminal_id => '10000174', 53 | :merchant_id => '', 54 | :password => '' 55 | ) 56 | assert response = gateway.purchase(@amount, @credit_card, @options) 57 | assert_failure response 58 | assert_equal '0651', response.params["reason_code"] 59 | end 60 | end 61 | -------------------------------------------------------------------------------- /test/remote/gateways/remote_eway_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class EwayTest < Test::Unit::TestCase 4 | def setup 5 | Base.gateway_mode = :test 6 | @gateway = EwayGateway.new(fixtures(:eway)) 7 | 8 | @credit_card_success = credit_card('4444333322221111') 9 | 10 | @credit_card_fail = credit_card('1234567812345678', 11 | :month => Time.now.month, 12 | :year => Time.now.year 13 | ) 14 | 15 | @params = { 16 | :order_id => '1230123', 17 | :email => 'bob@testbob.com', 18 | :billing_address => { :address1 => '47 Bobway', 19 | :city => 'Bobville', 20 | :state => 'WA', 21 | :country => 'AU', 22 | :zip => '2000' 23 | } , 24 | :description => 'purchased items' 25 | } 26 | end 27 | 28 | def test_invalid_amount 29 | assert response = @gateway.purchase(101, @credit_card_success, @params) 30 | assert_failure response 31 | assert response.test? 32 | assert_equal EwayGateway::MESSAGES["01"], response.message 33 | end 34 | 35 | def test_purchase_success_with_verification_value 36 | assert response = @gateway.purchase(100, @credit_card_success, @params) 37 | assert_equal '123456', response.authorization 38 | assert_success response 39 | assert response.test? 40 | assert_equal EwayGateway::MESSAGES["00"], response.message 41 | end 42 | 43 | def test_purchase_success_without_verification_value 44 | @credit_card_success.verification_value = nil 45 | 46 | assert response = @gateway.purchase(100, @credit_card_success, @params) 47 | assert_equal '123456', response.authorization 48 | assert_success response 49 | assert response.test? 50 | assert_equal EwayGateway::MESSAGES["00"], response.message 51 | end 52 | 53 | def test_purchase_error 54 | assert response = @gateway.purchase(100, @credit_card_fail, @params) 55 | assert_nil response.authorization 56 | assert_equal false, response.success? 57 | assert response.test? 58 | end 59 | end 60 | -------------------------------------------------------------------------------- /test/unit/generators/test_integration_generator.rb: -------------------------------------------------------------------------------- 1 | require File.join(File.dirname(__FILE__), "test_generator_helper.rb") 2 | 3 | class TestIntegrationGenerator < Test::Unit::TestCase 4 | include RubiGen::GeneratorTestHelper 5 | 6 | def setup 7 | bare_setup 8 | end 9 | 10 | def teardown 11 | bare_teardown 12 | end 13 | 14 | # Some generator-related assertions: 15 | # assert_generated_file(name, &block) # block passed the file contents 16 | # assert_directory_exists(name) 17 | # assert_generated_class(name, &block) 18 | # assert_generated_module(name, &block) 19 | # assert_generated_test_for(name, &block) 20 | # The assert_generated_(class|module|test_for) &block is passed the body of the class/module within the file 21 | # assert_has_method(body, *methods) # check that the body has a list of methods (methods with parentheses not supported yet) 22 | # 23 | # Other helper methods are: 24 | # app_root_files - put this in teardown to show files generated by the test method (e.g. p app_root_files) 25 | # bare_setup - place this in setup method to create the APP_ROOT folder for each test 26 | # bare_teardown - place this in teardown method to destroy the TMP_ROOT or APP_ROOT folder after each test 27 | 28 | def test_generator_without_options 29 | name = 'miracle' 30 | 31 | run_generator('integration', [ name ], sources) 32 | 33 | lib_dir = IntegrationGenerator::BASE_DIR + name 34 | test_dir = IntegrationGenerator::TEST_DIR 35 | assert_generated_file("#{lib_dir}.rb") 36 | assert_generated_file(lib_dir + "/helper.rb") 37 | assert_generated_file(lib_dir + "/notification.rb") 38 | 39 | assert_generated_file(test_dir + "#{name}_module_test.rb") 40 | assert_generated_file(test_dir + "helpers/#{name}_helper_test.rb") 41 | assert_generated_file(test_dir + "notifications/#{name}_notification_test.rb") 42 | end 43 | 44 | private 45 | def sources 46 | [RubiGen::PathSource.new(:test, File.join(File.dirname(__FILE__),"..", generator_path)) 47 | ] 48 | end 49 | 50 | def generator_path 51 | "generators" 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /lib/active_merchant/billing/integrations/moneybookers/helper.rb: -------------------------------------------------------------------------------- 1 | module ActiveMerchant #:nodoc: 2 | module Billing #:nodoc: 3 | module Integrations #:nodoc: 4 | module Moneybookers 5 | class Helper < ActiveMerchant::Billing::Integrations::Helper 6 | mapping :account, 'pay_to_email' 7 | mapping :order, 'transaction_id' 8 | mapping :amount, 'amount' 9 | mapping :currency, 'currency' 10 | 11 | mapping :customer, 12 | :first_name => 'firstname', 13 | :last_name => 'lastname', 14 | :email => 'pay_from_email', 15 | :phone => 'phone_number' 16 | 17 | mapping :billing_address, 18 | :city => 'city', 19 | :address1 => 'address', 20 | :address2 => 'address2', 21 | :state => 'state', 22 | :zip => 'postal_code', 23 | :country => 'country' 24 | 25 | mapping :notify_url, 'status_url' 26 | mapping :return_url, 'return_url' 27 | mapping :cancel_return_url, 'cancel_url' 28 | mapping :description, 'detail1_text' 29 | 30 | def initialize(order, account, options = {}) 31 | super 32 | add_tracking_token 33 | add_default_parameters 34 | add_seller_details(options) 35 | end 36 | 37 | 38 | private 39 | 40 | def add_tracking_token 41 | return if application_id.blank? || application_id == 'ActiveMerchant' 42 | 43 | add_field('merchant_fields', 'platform') 44 | add_field('platform', application_id) 45 | end 46 | 47 | def add_default_parameters 48 | add_field('hide_login', 1) 49 | end 50 | 51 | def add_seller_details(options) 52 | add_field('recipient_description', options[:account_name]) if options[:account_name] 53 | add_field('country', lookup_country_code(options[:country], :alpha3)) if options[:country] 54 | end 55 | end 56 | end 57 | end 58 | end 59 | end 60 | --------------------------------------------------------------------------------