workarea-payware_connect 2.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +20 -0
  3. data/.github/ISSUE_TEMPLATE/bug_report.md +37 -0
  4. data/.github/ISSUE_TEMPLATE/documentation-request.md +17 -0
  5. data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  6. data/.github/workflows/ci.yml +54 -0
  7. data/.gitignore +13 -0
  8. data/.rubocop.yml +2 -0
  9. data/CHANGELOG.md +63 -0
  10. data/CODE_OF_CONDUCT.md +3 -0
  11. data/CONTRIBUTING.md +3 -0
  12. data/Gemfile +9 -0
  13. data/LICENSE.md +3 -0
  14. data/README.md +53 -0
  15. data/Rakefile +54 -0
  16. data/app/models/workarea/payment/authorize/credit_card.decorator +37 -0
  17. data/app/models/workarea/payment/capture/credit_card.decorator +14 -0
  18. data/app/models/workarea/payment/payware_credit_card.decorator +24 -0
  19. data/app/models/workarea/payment/purchase/credit_card.decorator +37 -0
  20. data/app/models/workarea/payment/refund/credit_card.decorator +14 -0
  21. data/app/models/workarea/payment/store_credit_card.decorator +13 -0
  22. data/app/workers/workarea/save_user_order_details.decorator +33 -0
  23. data/bin/rails +18 -0
  24. data/config/initializers/00_defaults.rb +1 -0
  25. data/doc/PWCTestAccount_WorldPay ecom.pages +0 -0
  26. data/doc/validation/(Completed v2)PAYware Connect Validation Worksheet 2015 V2 .doc +0 -0
  27. data/doc/validation/(Completed v3)PAYware Connect Validation Worksheet 2015 V2 .doc +0 -0
  28. data/doc/validation/PAYware Connect Validation Letter Weblinc 09-11-2015.pdf +0 -0
  29. data/doc/validation/PAYware Connect Validation Letter Weblinc 10-21-2015.pdf +0 -0
  30. data/lib/active_merchant/billing/bogus_payware_connect_gateway.rb +130 -0
  31. data/lib/active_merchant/billing/payware_connect_gateway.rb +137 -0
  32. data/lib/active_merchant/billing/payware_connect_gateway/actions/authorize.rb +63 -0
  33. data/lib/active_merchant/billing/payware_connect_gateway/actions/capture.rb +26 -0
  34. data/lib/active_merchant/billing/payware_connect_gateway/actions/purchase.rb +59 -0
  35. data/lib/active_merchant/billing/payware_connect_gateway/actions/refund.rb +29 -0
  36. data/lib/active_merchant/billing/payware_connect_gateway/actions/void.rb +20 -0
  37. data/lib/active_merchant/billing/payware_connect_gateway/admin_actions/add_contract.rb +9 -0
  38. data/lib/active_merchant/billing/payware_connect_gateway/admin_actions/add_customer.rb +9 -0
  39. data/lib/active_merchant/billing/payware_connect_gateway/admin_actions/add_customer_and_contract.rb +10 -0
  40. data/lib/active_merchant/billing/payware_connect_gateway/admin_actions/update_contract.rb +9 -0
  41. data/lib/active_merchant/billing/payware_connect_gateway/admin_actions/update_customer.rb +9 -0
  42. data/lib/active_merchant/billing/payware_connect_gateway/admin_xml_builder.rb +105 -0
  43. data/lib/active_merchant/billing/payware_connect_gateway/xml_builder.rb +35 -0
  44. data/lib/active_merchant/billing/payware_response.rb +9 -0
  45. data/lib/validation.rb +25 -0
  46. data/lib/workarea/payware_connect.rb +43 -0
  47. data/lib/workarea/payware_connect/engine.rb +8 -0
  48. data/lib/workarea/payware_connect/version.rb +5 -0
  49. data/test/dummy/Rakefile +6 -0
  50. data/test/dummy/app/assets/config/manifest.js +4 -0
  51. data/test/dummy/app/assets/images/.keep +0 -0
  52. data/test/dummy/app/assets/javascripts/application.js +13 -0
  53. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  54. data/test/dummy/app/controllers/application_controller.rb +3 -0
  55. data/test/dummy/app/controllers/concerns/.keep +0 -0
  56. data/test/dummy/app/helpers/application_helper.rb +2 -0
  57. data/test/dummy/app/jobs/application_job.rb +2 -0
  58. data/test/dummy/app/mailers/application_mailer.rb +4 -0
  59. data/test/dummy/app/models/concerns/.keep +0 -0
  60. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  61. data/test/dummy/app/views/layouts/mailer.html.erb +13 -0
  62. data/test/dummy/app/views/layouts/mailer.text.erb +1 -0
  63. data/test/dummy/bin/bundle +3 -0
  64. data/test/dummy/bin/rails +4 -0
  65. data/test/dummy/bin/rake +4 -0
  66. data/test/dummy/bin/setup +34 -0
  67. data/test/dummy/bin/update +29 -0
  68. data/test/dummy/config.ru +5 -0
  69. data/test/dummy/config/application.rb +24 -0
  70. data/test/dummy/config/boot.rb +5 -0
  71. data/test/dummy/config/cable.yml +9 -0
  72. data/test/dummy/config/environment.rb +5 -0
  73. data/test/dummy/config/environments/development.rb +56 -0
  74. data/test/dummy/config/environments/production.rb +86 -0
  75. data/test/dummy/config/environments/test.rb +44 -0
  76. data/test/dummy/config/initializers/application_controller_renderer.rb +6 -0
  77. data/test/dummy/config/initializers/assets.rb +11 -0
  78. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  79. data/test/dummy/config/initializers/cookies_serializer.rb +5 -0
  80. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  81. data/test/dummy/config/initializers/inflections.rb +16 -0
  82. data/test/dummy/config/initializers/mime_types.rb +4 -0
  83. data/test/dummy/config/initializers/new_framework_defaults.rb +23 -0
  84. data/test/dummy/config/initializers/workarea.rb +3 -0
  85. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  86. data/test/dummy/config/locales/en.yml +23 -0
  87. data/test/dummy/config/puma.rb +47 -0
  88. data/test/dummy/config/routes.rb +5 -0
  89. data/test/dummy/config/secrets.yml +22 -0
  90. data/test/dummy/config/spring.rb +6 -0
  91. data/test/dummy/db/seeds.rb +3 -0
  92. data/test/dummy/lib/assets/.keep +0 -0
  93. data/test/dummy/log/.keep +0 -0
  94. data/test/dummy/public/404.html +67 -0
  95. data/test/dummy/public/422.html +67 -0
  96. data/test/dummy/public/500.html +66 -0
  97. data/test/dummy/public/apple-touch-icon-precomposed.png +0 -0
  98. data/test/dummy/public/apple-touch-icon.png +0 -0
  99. data/test/dummy/public/favicon.ico +0 -0
  100. data/test/integration/workarea/storefront/checkout_side_effects_integration_test.decorator +44 -0
  101. data/test/lib/active_merchant/billing/payware_connect_gateway_test.rb +280 -0
  102. data/test/models/workarea/payment/authorize/credit_card_test.decorator +47 -0
  103. data/test/models/workarea/payment/capture/credit_card_test.decorator +33 -0
  104. data/test/models/workarea/payment/credit_card_integration_test.decorator +25 -0
  105. data/test/models/workarea/payment/payware_credit_card_test.rb +44 -0
  106. data/test/models/workarea/payment/purchase/credit_card_test.decorator +54 -0
  107. data/test/models/workarea/payment/refund/credit_card_test.decorator +33 -0
  108. data/test/models/workarea/payment/store_credit_card_test.decorator +10 -0
  109. data/test/support/workarea/payware_connect_gateway_vcr_config.rb +24 -0
  110. data/test/system/workarea/admin/payment_transactions_system_test.decorator +37 -0
  111. data/test/test_helper.rb +12 -0
  112. data/test/vcr_cassettes/credit_card/auth_capture.yml +127 -0
  113. data/test/vcr_cassettes/credit_card/auth_void.yml +126 -0
  114. data/test/vcr_cassettes/credit_card/purchase_void.yml +126 -0
  115. data/test/vcr_cassettes/credit_card/store_auth.yml +67 -0
  116. data/test/vcr_cassettes/credit_card/store_purchase.yml +67 -0
  117. data/test/vcr_cassettes/payware/add_contract.yml +99 -0
  118. data/test/vcr_cassettes/payware/add_customer.yml +52 -0
  119. data/test/vcr_cassettes/payware/authorize_credit_card.yml +67 -0
  120. data/test/vcr_cassettes/payware/authorize_customer_and_contract.yml +161 -0
  121. data/test/vcr_cassettes/payware/authorize_for_0_credit_card.yml +67 -0
  122. data/test/vcr_cassettes/payware/authorize_for_0_troutd.yml +130 -0
  123. data/test/vcr_cassettes/payware/authorize_troutd.yml +130 -0
  124. data/test/vcr_cassettes/payware/capture.yml +127 -0
  125. data/test/vcr_cassettes/payware/refund.yml +223 -0
  126. data/test/vcr_cassettes/payware/refund_troutd.yml +128 -0
  127. data/test/vcr_cassettes/payware/void_authorization.yml +126 -0
  128. data/test/workers/workarea/save_user_order_details_test.decorator +56 -0
  129. data/workarea-payware_connect.gemspec +18 -0
  130. metadata +190 -0
@@ -0,0 +1,37 @@
1
+ module Workarea
2
+ decorate Payment::Purchase::CreditCard, with: :payware_connect do
3
+ decorated { delegate :address, to: :tender }
4
+
5
+ def complete!
6
+ transaction.response = handle_active_merchant_errors do
7
+ gateway.purchase(
8
+ transaction.amount.cents,
9
+ tender_payment.merge(billing_address: address)
10
+ )
11
+ end
12
+
13
+ if transaction.response.success?
14
+ tender.token = transaction.response.troutd
15
+ tender.save!
16
+ end
17
+
18
+ transaction.response
19
+ end
20
+
21
+ def cancel!
22
+ return unless transaction.success?
23
+
24
+ transaction.cancellation = handle_active_merchant_errors do
25
+ gateway.void(transaction.response.troutd)
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def tender_payment
32
+ return { troutd: tender.token } if tender.tokenized?
33
+
34
+ { credit_card: tender.to_active_merchant }
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,14 @@
1
+ module Workarea
2
+ decorate Payment::Refund::CreditCard, with: :payware_connect do
3
+ def complete!
4
+ validate_reference!
5
+
6
+ transaction.response = handle_active_merchant_errors do
7
+ gateway.refund(
8
+ transaction.amount.cents,
9
+ transaction.reference.response.troutd
10
+ )
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ module Workarea
2
+ decorate Payment::StoreCreditCard, with: :payware_connect do
3
+ def perform!
4
+ return true if @credit_card.token.present?
5
+
6
+ response = handle_active_merchant_errors do
7
+ gateway.store(@credit_card.to_active_merchant)
8
+ end
9
+
10
+ @credit_card.token = response.troutd
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,33 @@
1
+ module Workarea
2
+ decorate SaveUserOrderDetails, with: :payware_connect do
3
+ def save_payment_details(order, user)
4
+ payment = Payment.find_or_initialize_by(id: order.id)
5
+ payment_profile = Payment::Profile.lookup(PaymentReference.new(user))
6
+ billing_address = extract_address_attributes(payment.address)
7
+
8
+ if billing_address.present?
9
+ user.auto_save_billing_address(billing_address)
10
+
11
+ if user.public_info.blank?
12
+ user.update_attributes!(
13
+ first_name: billing_address[:first_name],
14
+ last_name: billing_address[:last_name]
15
+ )
16
+ end
17
+ end
18
+
19
+ if payment.credit_card? && !payment.credit_card.saved?
20
+ payment_profile.credit_cards.create(
21
+ first_name: payment.credit_card.first_name,
22
+ last_name: payment.credit_card.last_name,
23
+ display_number: payment.credit_card.display_number,
24
+ issuer: payment.credit_card.issuer,
25
+ month: payment.credit_card.month,
26
+ year: payment.credit_card.year,
27
+ token: payment.credit_card.token,
28
+ partial_number: payment.credit_card.partial_number
29
+ )
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails gems
3
+ # installed from the root of your application.
4
+
5
+ ENGINE_ROOT = File.expand_path("../..", __FILE__)
6
+ ENGINE_PATH = File.expand_path("../../lib/payware_connect/engine", __FILE__)
7
+
8
+ # Set up gems listed in the Gemfile.
9
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", __FILE__)
10
+ require "bundler/setup" if File.exist?(ENV["BUNDLE_GEMFILE"])
11
+
12
+ require "action_controller/railtie"
13
+ require "action_view/railtie"
14
+ require "action_mailer/railtie"
15
+ require "rails/test_unit/railtie"
16
+ require "sprockets/railtie"
17
+
18
+ require "rails/engine/commands"
@@ -0,0 +1 @@
1
+ Workarea::PaywareConnect.auto_configure_gateway
@@ -0,0 +1,130 @@
1
+ module ActiveMerchant
2
+ module Billing
3
+ class BogusPaywareConnectGateway < ActiveMerchant::Billing::BogusGateway
4
+ def authorize(cents, credit_card_or_troutd, options = {})
5
+ credit_card_or_troutd = credit_card_or_troutd[:credit_card] || credit_card_or_troutd[:troutd]
6
+ case normalize(credit_card_or_troutd)
7
+ when /1$/, ActiveMerchant::Billing::BogusGateway::AUTHORIZATION
8
+ successful_auth_response(cents)
9
+ when /2$/
10
+ failure_response(cents)
11
+ else
12
+ raise Error, error_message(credit_card_or_troutd)
13
+ end
14
+ end
15
+
16
+ def purchase(cents, credit_card_or_troutd, options = {})
17
+ credit_card_or_troutd = credit_card_or_troutd[:credit_card] || credit_card_or_troutd[:troutd]
18
+ case normalize(credit_card_or_troutd)
19
+ when /1$/, ActiveMerchant::Billing::BogusGateway::AUTHORIZATION
20
+ successful_purchase_response(cents)
21
+ when /2$/
22
+ failure_response(cents)
23
+ else
24
+ raise Error, error_message(credit_card_or_troutd)
25
+ end
26
+ end
27
+
28
+ def store(credit_card, options = {})
29
+ authorize(0, credit_card: credit_card, amount: "0.0")
30
+ end
31
+
32
+ private
33
+
34
+ def failure_response(money)
35
+ Response.new(
36
+ false,
37
+ FAILURE_MESSAGE,
38
+ { authorized_amount: money, error: FAILURE_MESSAGE },
39
+ { test: true, error_code: STANDARD_ERROR_CODE[:processing_error] }
40
+ )
41
+ end
42
+
43
+ def successful_auth_response(cents)
44
+ result = "APPROVED"
45
+ troutd = ActiveMerchant::Billing::BogusGateway::AUTHORIZATION
46
+
47
+ params = {
48
+ "RESPONSE" => {
49
+ "AUTH_CODE" => "094073",
50
+ "AVS_CODE" => "Y",
51
+ "BATCH_NUM" => "329001",
52
+ "CLIENT_ID" => "7769900010001",
53
+ "COMMAND" => "PRE_AUTH",
54
+ "CTROUTD" => "24",
55
+ "CVV2_CODE" => "Y",
56
+ "INTRN_SEQ_NUM" => "4666700",
57
+ "INVOICE" => "4666700",
58
+ "PAYMENT_MEDIA" => "VISA",
59
+ "PAYMENT_TYPE" => "CREDIT",
60
+ "PY_RESP_CODE" => "A",
61
+ "REFERENCE" => "00000020",
62
+ "RESPONSE_CODE" => "A",
63
+ "RESPONSE_TEXT" => result,
64
+ "RESULT" => result,
65
+ "RESULT_CODE" => "5",
66
+ "TERMINATION_STATUS" => "SUCCESS",
67
+ "TRANS_AMOUNT" => "%.2f" % (cents.to_f / 100.0),
68
+ "TRANS_DATE" => "2013.11.25",
69
+ "TRANS_SEQ_NUM" => "30",
70
+ "TRANS_TIME" => "15:13:17",
71
+ "TROUTD" => troutd
72
+ }
73
+ }
74
+
75
+ ActiveMerchant::Billing::Response.new(
76
+ true,
77
+ "APPROVED",
78
+ params,
79
+ test: true,
80
+ authorization: params["RESPONSE"]["TROUTD"],
81
+ cvv_result: params["RESPONSE"]["CVV2_CODE"],
82
+ avs_result: { code: params["RESPONSE"]["AVS_CODE"] }
83
+ )
84
+ end
85
+
86
+ def successful_purchase_response(cents)
87
+ result = "APPROVED"
88
+ troutd = ActiveMerchant::Billing::BogusGateway::AUTHORIZATION
89
+
90
+ params = {
91
+ "RESPONSE" => {
92
+ "AUTH_CODE" => "094073",
93
+ "AVS_CODE" => "Y",
94
+ "BATCH_NUM" => "329001",
95
+ "CLIENT_ID" => "7769900010001",
96
+ "COMMAND" => "SALE",
97
+ "CTROUTD" => "24",
98
+ "CVV2_CODE" => "Y",
99
+ "INTRN_SEQ_NUM" => "4666700",
100
+ "INVOICE" => "4666700",
101
+ "PAYMENT_MEDIA" => "VISA",
102
+ "PAYMENT_TYPE" => "CREDIT",
103
+ "PY_RESP_CODE" => "A",
104
+ "REFERENCE" => "00000020",
105
+ "RESPONSE_CODE" => "A",
106
+ "RESPONSE_TEXT" => result,
107
+ "RESULT" => result,
108
+ "RESULT_CODE" => "5",
109
+ "TERMINATION_STATUS" => "SUCCESS",
110
+ "TRANS_AMOUNT" => "%.2f" % (cents.to_f / 100.0),
111
+ "TRANS_DATE" => "2013.11.25",
112
+ "TRANS_SEQ_NUM" => "30",
113
+ "TRANS_TIME" => "15:13:17",
114
+ "TROUTD" => troutd
115
+ }
116
+ }
117
+
118
+ ActiveMerchant::Billing::Response.new(
119
+ true,
120
+ "APPROVED",
121
+ params,
122
+ test: true,
123
+ authorization: params["RESPONSE"]["TROUTD"],
124
+ cvv_result: params["RESPONSE"]["CVV2_CODE"],
125
+ avs_result: { code: params["RESPONSE"]["AVS_CODE"] }
126
+ )
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,137 @@
1
+ module ActiveMerchant
2
+ module Billing
3
+ class PaywareConnectGateway < ActiveMerchant::Billing::Gateway
4
+ require "active_merchant/billing/payware_response"
5
+ require "active_merchant/billing/payware_connect_gateway/xml_builder"
6
+ require "active_merchant/billing/payware_connect_gateway/actions/authorize"
7
+ require "active_merchant/billing/payware_connect_gateway/actions/capture"
8
+ require "active_merchant/billing/payware_connect_gateway/actions/purchase"
9
+ require "active_merchant/billing/payware_connect_gateway/actions/refund"
10
+ require "active_merchant/billing/payware_connect_gateway/actions/void"
11
+ require "active_merchant/billing/payware_connect_gateway/admin_xml_builder"
12
+ require "active_merchant/billing/payware_connect_gateway/admin_actions/add_contract"
13
+ require "active_merchant/billing/payware_connect_gateway/admin_actions/add_customer"
14
+ require "active_merchant/billing/payware_connect_gateway/admin_actions/add_customer_and_contract"
15
+ require "active_merchant/billing/payware_connect_gateway/admin_actions/update_contract"
16
+ require "active_merchant/billing/payware_connect_gateway/admin_actions/update_customer"
17
+
18
+ self.ssl_version = :TLSv1_2
19
+ self.test_url = "https://cert.api.vfipayna.com/IPCHAPI/RH.ASPX"
20
+ self.live_url = "https://api.vfipayna.com/IPCHAPI/RH.ASPX"
21
+
22
+ cattr_accessor :test_admin_url, :live_admin_url
23
+ self.test_admin_url = "https://cert1.ipcharge.net/ipcadminapi/RH.ipc"
24
+ self.live_admin_url = "https://prod1.ipcharge.net/ipcadminapi/RH.ipc"
25
+
26
+ def initialize(options = {})
27
+ requires!(options, :login, :password)
28
+ super
29
+ end
30
+
31
+ def authorize(cents, command_options = {})
32
+ commit(Actions::Authorize.new(cents, command_options.merge(options)).build)
33
+ end
34
+
35
+ def store(credit_card, command_options = {})
36
+ command_options = command_options.merge(credit_card: credit_card)
37
+ commit(Actions::Authorize.new(0, command_options.merge(options)).build)
38
+ end
39
+
40
+ def refund(cents, command_options = {})
41
+ commit(Actions::Refund.new(cents, command_options.merge(options)).build)
42
+ end
43
+
44
+ def purchase(cents, command_options = {})
45
+ commit(Actions::Purchase.new(cents, command_options.merge(options)).build)
46
+ end
47
+
48
+ def capture(cents, authorization, command_options = {})
49
+ commit(Actions::Capture.new(cents, authorization, command_options.merge(options)).build)
50
+ end
51
+
52
+ def void(authorization, command_options = {})
53
+ commit(Actions::Void.new(authorization, command_options.merge(options)).build)
54
+ end
55
+
56
+ def add_customer(command_options = {})
57
+ requires!(command_options, :customer_id)
58
+ commit_admin(AdminActions::AddCustomer.new(command_options.merge(options)).build)
59
+ end
60
+
61
+ def update_customer(command_options = {})
62
+ requires!(command_options, :customer_id)
63
+ commit_admin(AdminActions::UpdateCustomer.new(command_options.merge(options)).build)
64
+ end
65
+
66
+ def add_customer_and_contract(command_options = {})
67
+ requires!(command_options, :customer_id, :contract_id)
68
+ commit_admin(AdminActions::AddCustomerAndContract.new(command_options.merge(options)).build)
69
+ end
70
+
71
+ def add_contract(command_options = {})
72
+ requires!(command_options, :customer_id, :contract_id, :credit_card)
73
+ commit_admin(AdminActions::AddContract.new(command_options.merge(options)).build)
74
+ end
75
+
76
+ def update_contract(command_options = {})
77
+ requires!(command_options, :customer_id, :contract_id, :credit_card)
78
+ commit_admin(AdminActions::UpdateContract.new(command_options.merge(options)).build)
79
+ end
80
+
81
+ private
82
+
83
+ def commit_admin(request)
84
+ url = test? ? test_admin_url : live_admin_url
85
+ response = perform_api_call(request, url)
86
+
87
+ success = response["AdminResponse"]["Status_Code"] == "1"
88
+ message = response["AdminResponse"]["Message"]
89
+ params = response
90
+
91
+ ActiveMerchant::Billing::Response.new(
92
+ success,
93
+ message,
94
+ params,
95
+ test: test?
96
+ )
97
+ end
98
+
99
+ SUCCESS_CODES = ["APPROVED", "CAPTURED", "VOIDED", "VERIFIED"]
100
+
101
+ def commit(request)
102
+ url = test? ? test_url : live_url
103
+ response = perform_api_call(request, url)
104
+
105
+ success = SUCCESS_CODES.include?(response["RESPONSE"]["RESULT"])
106
+ message = response["RESPONSE"]["RESPONSE_TEXT"]
107
+ params = response
108
+
109
+ response_options = {
110
+ authorization: response["RESPONSE"]["AUTH_CODE"],
111
+ test: test?
112
+ }
113
+
114
+ if response["RESPONSE"]["AVS_CODE"].present?
115
+ response_options.merge!(avs_result: { code: response["RESPONSE"]["AVS_CODE"] })
116
+ end
117
+
118
+ if response["RESPONSE"]["CVV2_CODE"].present?
119
+ response_options.merge!(cvv_result: response["RESPONSE"]["CVV2_CODE"])
120
+ end
121
+
122
+ ActiveMerchant::Billing::Response.new(success, message, params, response_options)
123
+ end
124
+
125
+ def perform_api_call(request, url)
126
+ ::Rails.logger.debug(request) if ::Rails.env.development?
127
+
128
+ raw_response = ssl_post(url, request, "Content-Type" => "text/xml")
129
+
130
+ ::Rails.logger.debug(raw_response) if ::Rails.env.development?
131
+
132
+ raw_response.gsub!(/[\n\r]/, "")
133
+ Hash.from_xml(raw_response)
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,63 @@
1
+ module ActiveMerchant
2
+ module Billing
3
+ class PaywareConnectGateway < ActiveMerchant::Billing::Gateway
4
+ module Actions
5
+ class Authorize < PaywareConnectGateway::XMLBuilder
6
+ attr_reader :cents
7
+
8
+ def initialize(cents, merged_options)
9
+ @cents = cents
10
+
11
+ super(merged_options)
12
+ end
13
+
14
+ def build
15
+ build_credit_request do |xml|
16
+ xml.COMMAND "PRE_AUTH"
17
+ xml.TRANS_AMOUNT "%.2f" % (cents.to_f / 100.0)
18
+ xml.PRESENT_FLAG "1"
19
+
20
+ if options[:invoice_number]
21
+ xml.INVOICE options[:invoice_number]
22
+ end
23
+
24
+ if options[:force]
25
+ xml.FORCE_FLAG "true"
26
+ end
27
+
28
+ if options[:billing_address]
29
+ address = options[:billing_address]
30
+ xml.CARDHOLDER "#{address.first_name} #{address.last_name}"
31
+ xml.CUSTOMER_STREET address.street[0..19] # max length of this field is 20 characters
32
+ xml.CUSTOMER_CITY address.city
33
+ xml.CUSTOMER_STATE address.region
34
+ xml.CUSTOMER_ZIP address.postal_code
35
+ end
36
+
37
+ if options[:customer_id] && options[:contract_id]
38
+ xml.RBCUSTOMER_ID options[:customer_id]
39
+ xml.RBCONTRACT_ID options[:contract_id]
40
+
41
+ elsif options[:credit_card]
42
+ credit_card = options[:credit_card]
43
+ xml.ACCT_NUM credit_card.number
44
+ xml.CVV2 credit_card.verification_value
45
+
46
+ month = credit_card.month
47
+ month = month.to_s.rjust(2, "0")
48
+ xml.EXP_MONTH month
49
+ xml.EXP_YEAR credit_card.year.to_s[-2, 2] # last two digits of year
50
+
51
+ elsif options[:troutd]
52
+ xml.REF_TROUTD options[:troutd]
53
+
54
+ else
55
+ raise "Authorize requires either 1) customer and contract ids, 2) credit card, 3) troutd from previous authorization"
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end