activemerchant 1.28.0 → 1.29.1

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 (117) hide show
  1. data/CHANGELOG +41 -0
  2. data/CONTRIBUTORS +12 -0
  3. data/README.md +6 -0
  4. data/lib/active_merchant/billing/gateway.rb +2 -1
  5. data/lib/active_merchant/billing/gateways/authorize_net.rb +3 -2
  6. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +77 -78
  7. data/lib/active_merchant/billing/gateways/balanced.rb +0 -1
  8. data/lib/active_merchant/billing/gateways/banwire.rb +1 -2
  9. data/lib/active_merchant/billing/gateways/barclays_epdq.rb +19 -20
  10. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +35 -36
  11. data/lib/active_merchant/billing/gateways/blue_pay.rb +135 -140
  12. data/lib/active_merchant/billing/gateways/braintree_blue.rb +12 -4
  13. data/lib/active_merchant/billing/gateways/card_stream.rb +54 -59
  14. data/lib/active_merchant/billing/gateways/certo_direct.rb +0 -1
  15. data/lib/active_merchant/billing/gateways/cyber_source.rb +19 -14
  16. data/lib/active_merchant/billing/gateways/data_cash.rb +106 -112
  17. data/lib/active_merchant/billing/gateways/efsnet.rb +29 -34
  18. data/lib/active_merchant/billing/gateways/elavon.rb +7 -1
  19. data/lib/active_merchant/billing/gateways/epay.rb +0 -1
  20. data/lib/active_merchant/billing/gateways/eway.rb +88 -93
  21. data/lib/active_merchant/billing/gateways/eway_managed.rb +47 -51
  22. data/lib/active_merchant/billing/gateways/eway_rapid.rb +300 -0
  23. data/lib/active_merchant/billing/gateways/exact.rb +45 -54
  24. data/lib/active_merchant/billing/gateways/federated_canada.rb +3 -4
  25. data/lib/active_merchant/billing/gateways/first_pay.rb +37 -38
  26. data/lib/active_merchant/billing/gateways/garanti.rb +1 -2
  27. data/lib/active_merchant/billing/gateways/hdfc.rb +207 -0
  28. data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +5 -8
  29. data/lib/active_merchant/billing/gateways/inspire.rb +52 -52
  30. data/lib/active_merchant/billing/gateways/instapay.rb +10 -11
  31. data/lib/active_merchant/billing/gateways/iridium.rb +38 -39
  32. data/lib/active_merchant/billing/gateways/itransact.rb +7 -9
  33. data/lib/active_merchant/billing/gateways/jetpay.rb +45 -46
  34. data/lib/active_merchant/billing/gateways/linkpoint.rb +104 -108
  35. data/lib/active_merchant/billing/gateways/litle.rb +1 -5
  36. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +153 -155
  37. data/lib/active_merchant/billing/gateways/merchant_ware.rb +49 -50
  38. data/lib/active_merchant/billing/gateways/mercury.rb +272 -0
  39. data/lib/active_merchant/billing/gateways/metrics_global.rb +9 -10
  40. data/lib/active_merchant/billing/gateways/migs.rb +5 -3
  41. data/lib/active_merchant/billing/gateways/modern_payments.rb +6 -7
  42. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +40 -41
  43. data/lib/active_merchant/billing/gateways/moneris.rb +46 -50
  44. data/lib/active_merchant/billing/gateways/moneris_us.rb +52 -55
  45. data/lib/active_merchant/billing/gateways/nab_transact.rb +0 -5
  46. data/lib/active_merchant/billing/gateways/net_registry.rb +20 -21
  47. data/lib/active_merchant/billing/gateways/netaxept.rb +30 -36
  48. data/lib/active_merchant/billing/gateways/netbilling.rb +2 -2
  49. data/lib/active_merchant/billing/gateways/ogone.rb +0 -5
  50. data/lib/active_merchant/billing/gateways/optimal_payment.rb +1 -6
  51. data/lib/active_merchant/billing/gateways/orbital/avs_result.rb +93 -0
  52. data/lib/active_merchant/billing/gateways/orbital.rb +25 -21
  53. data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +1 -6
  54. data/lib/active_merchant/billing/gateways/pay_junction.rb +62 -63
  55. data/lib/active_merchant/billing/gateways/pay_secure.rb +29 -30
  56. data/lib/active_merchant/billing/gateways/paybox_direct.rb +0 -5
  57. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +33 -38
  58. data/lib/active_merchant/billing/gateways/payment_express.rb +48 -51
  59. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +7 -11
  60. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +7 -0
  61. data/lib/active_merchant/billing/gateways/paypal/paypal_recurring_api.rb +3 -0
  62. data/lib/active_merchant/billing/gateways/paystation.rb +62 -64
  63. data/lib/active_merchant/billing/gateways/payway.rb +2 -9
  64. data/lib/active_merchant/billing/gateways/plugnpay.rb +0 -1
  65. data/lib/active_merchant/billing/gateways/psigate.rb +102 -94
  66. data/lib/active_merchant/billing/gateways/psl_card.rb +66 -67
  67. data/lib/active_merchant/billing/gateways/qbms.rb +0 -6
  68. data/lib/active_merchant/billing/gateways/quantum.rb +2 -8
  69. data/lib/active_merchant/billing/gateways/quickpay.rb +2 -3
  70. data/lib/active_merchant/billing/gateways/realex.rb +6 -16
  71. data/lib/active_merchant/billing/gateways/redsys.rb +394 -0
  72. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +25 -26
  73. data/lib/active_merchant/billing/gateways/sage.rb +15 -16
  74. data/lib/active_merchant/billing/gateways/sage_pay.rb +51 -56
  75. data/lib/active_merchant/billing/gateways/sallie_mae.rb +1 -2
  76. data/lib/active_merchant/billing/gateways/samurai.rb +1 -4
  77. data/lib/active_merchant/billing/gateways/secure_net.rb +0 -1
  78. data/lib/active_merchant/billing/gateways/secure_pay.rb +5 -8
  79. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +0 -5
  80. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +17 -18
  81. data/lib/active_merchant/billing/gateways/skip_jack.rb +29 -34
  82. data/lib/active_merchant/billing/gateways/smart_ps.rb +55 -56
  83. data/lib/active_merchant/billing/gateways/stripe.rb +8 -3
  84. data/lib/active_merchant/billing/gateways/trans_first.rb +28 -29
  85. data/lib/active_merchant/billing/gateways/trust_commerce.rb +85 -87
  86. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +27 -28
  87. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +0 -5
  88. data/lib/active_merchant/billing/gateways/verifi.rb +86 -87
  89. data/lib/active_merchant/billing/gateways/viaklix.rb +42 -47
  90. data/lib/active_merchant/billing/gateways/vindicia.rb +30 -28
  91. data/lib/active_merchant/billing/gateways/webpay.rb +45 -0
  92. data/lib/active_merchant/billing/gateways/wirecard.rb +0 -6
  93. data/lib/active_merchant/billing/gateways/worldpay.rb +4 -9
  94. data/lib/active_merchant/billing/gateways.rb +6 -7
  95. data/lib/active_merchant/billing/integrations/a1agregator/helper.rb +31 -0
  96. data/lib/active_merchant/billing/integrations/a1agregator/notification.rb +186 -0
  97. data/lib/active_merchant/billing/integrations/a1agregator/status.rb +38 -0
  98. data/lib/active_merchant/billing/integrations/a1agregator.rb +26 -0
  99. data/lib/active_merchant/billing/integrations/liqpay/helper.rb +43 -0
  100. data/lib/active_merchant/billing/integrations/liqpay/notification.rb +89 -0
  101. data/lib/active_merchant/billing/integrations/liqpay/return.rb +83 -0
  102. data/lib/active_merchant/billing/integrations/liqpay.rb +30 -0
  103. data/lib/active_merchant/billing/integrations/moneybookers/helper.rb +17 -1
  104. data/lib/active_merchant/billing/integrations/notification.rb +4 -0
  105. data/lib/active_merchant/billing/integrations/pay_fast/common.rb +42 -0
  106. data/lib/active_merchant/billing/integrations/pay_fast/helper.rb +50 -0
  107. data/lib/active_merchant/billing/integrations/pay_fast/notification.rb +134 -0
  108. data/lib/active_merchant/billing/integrations/pay_fast/return.rb +10 -0
  109. data/lib/active_merchant/billing/integrations/pay_fast.rb +70 -0
  110. data/lib/active_merchant/billing/integrations/paypal/notification.rb +64 -0
  111. data/lib/active_merchant/billing/integrations/sage_pay_form/helper.rb +10 -7
  112. data/lib/active_merchant/billing/integrations/webmoney/notification.rb +12 -0
  113. data/lib/active_merchant/billing/response.rb +17 -4
  114. data/lib/active_merchant/version.rb +1 -1
  115. data.tar.gz.sig +0 -0
  116. metadata +46 -27
  117. metadata.gz.sig +0 -0
@@ -0,0 +1,89 @@
1
+ require 'net/http'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ module Integrations #:nodoc:
6
+ module Liqpay
7
+ class Notification < ActiveMerchant::Billing::Integrations::Notification
8
+ def self.recognizes?(params)
9
+ params.has_key?('amount') && params.has_key?('order_id')
10
+ end
11
+
12
+ def initialize(post, options = {})
13
+ raise ArgumentError if post.blank?
14
+ super
15
+ @params.merge!(Hash.from_xml(Base64.decode64(xml))["response"])
16
+ end
17
+
18
+ def xml
19
+ @params["operation_xml"]
20
+ end
21
+
22
+ def complete?
23
+ status == 'success'
24
+ end
25
+
26
+ def account
27
+ params['merchant_id']
28
+ end
29
+
30
+ def amount
31
+ BigDecimal.new(gross)
32
+ end
33
+
34
+ def item_id
35
+ params['order_id']
36
+ end
37
+
38
+ def transaction_id
39
+ params['transaction_id']
40
+ end
41
+
42
+ def action_name
43
+ params['action_name'] # either 'result_url' or 'server_url'
44
+ end
45
+
46
+ def version
47
+ params['version']
48
+ end
49
+
50
+ def sender_phone
51
+ params['sender_phone']
52
+ end
53
+
54
+ def security_key
55
+ params[ActiveMerchant::Billing::Integrations::Liqpay.signature_parameter_name]
56
+ end
57
+
58
+ def gross
59
+ params['amount']
60
+ end
61
+
62
+ def currency
63
+ params['currency']
64
+ end
65
+
66
+ def status
67
+ params['status'] # 'success', 'failure' or 'wait_secure'
68
+ end
69
+
70
+ def code
71
+ params['code']
72
+ end
73
+
74
+ def generate_signature_string
75
+ "#{@options[:secret]}#{Base64.decode64(xml)}#{@options[:secret]}"
76
+ end
77
+
78
+ def generate_signature
79
+ Base64.encode64(Digest::SHA1.digest(generate_signature_string)).strip
80
+ end
81
+
82
+ def acknowledge
83
+ security_key == generate_signature
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,83 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ module Integrations #:nodoc:
4
+ module Liqpay
5
+ class Return < ActiveMerchant::Billing::Integrations::Return
6
+ def self.recognizes?(params)
7
+ params.has_key?('amount') && params.has_key?('order_id')
8
+ end
9
+
10
+ def initialize(post)
11
+ super
12
+ xml = Base64.decode64(@params["operation_xml"])
13
+ @params.merge!(Hash.from_xml(xml)["response"])
14
+ end
15
+
16
+ def complete?
17
+ status == 'success'
18
+ end
19
+
20
+ def account
21
+ params['merchant_id']
22
+ end
23
+
24
+ def amount
25
+ BigDecimal.new(gross)
26
+ end
27
+
28
+ def item_id
29
+ params['order_id']
30
+ end
31
+
32
+ def transaction_id
33
+ params['transaction_id']
34
+ end
35
+
36
+ def action_name
37
+ params['action_name'] # either 'result_url' or 'server_url'
38
+ end
39
+
40
+ def version
41
+ params['version']
42
+ end
43
+
44
+ def sender_phone
45
+ params['sender_phone']
46
+ end
47
+
48
+ def security_key
49
+ params[ActiveMerchant::Billing::Integrations::Liqpay.signature_parameter_name]
50
+ end
51
+
52
+ def gross
53
+ params['amount']
54
+ end
55
+
56
+ def currency
57
+ params['currency']
58
+ end
59
+
60
+ def status
61
+ params['status'] # 'success', 'failure' or 'wait_secure'
62
+ end
63
+
64
+ def code
65
+ params['code']
66
+ end
67
+
68
+ def generate_signature_string
69
+ ['', version, @options[:secret], action_name, sender_phone, account, gross, currency, item_id, transaction_id, status, code, ''].flatten.compact.join('|')
70
+ end
71
+
72
+ def generate_signature
73
+ Base64.encode64(Digest::SHA1.digest(generate_signature_string)).gsub(/\n/, '')
74
+ end
75
+
76
+ def acknowledge
77
+ security_key == generate_signature
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,30 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ module Integrations #:nodoc:
4
+ # Documentation: https://www.liqpay.com/?do=pages&p=cnb10
5
+ module Liqpay
6
+ autoload :Helper, File.dirname(__FILE__) + '/liqpay/helper.rb'
7
+ autoload :Notification, File.dirname(__FILE__) + '/liqpay/notification.rb'
8
+ autoload :Return, File.dirname(__FILE__) + '/liqpay/return.rb'
9
+
10
+ mattr_accessor :service_url
11
+ self.service_url = 'https://liqpay.com/?do=clickNbuy'
12
+
13
+ mattr_accessor :signature_parameter_name
14
+ self.signature_parameter_name = 'signature'
15
+
16
+ def self.helper(order, account, options = {})
17
+ Helper.new(order, account, options)
18
+ end
19
+
20
+ def self.notification(query_string, options = {})
21
+ Notification.new(query_string, options)
22
+ end
23
+
24
+ def self.return(query_string)
25
+ Return.new(query_string)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -26,6 +26,17 @@ module ActiveMerchant #:nodoc:
26
26
  mapping :return_url, 'return_url'
27
27
  mapping :cancel_return_url, 'cancel_url'
28
28
  mapping :description, 'detail1_text'
29
+
30
+ MAPPED_COUNTRY_CODES = {
31
+ 'SE' => 'SV',
32
+ 'DK' => 'DA'
33
+ }
34
+
35
+ SUPPORTED_COUNTRY_CODES = [
36
+ 'FI', 'DE', 'ES', 'FR',
37
+ 'IT','PL', 'GR', 'RO',
38
+ 'RU', 'TR', 'CN', 'CZ', 'NL'
39
+ ]
29
40
 
30
41
  def initialize(order, account, options = {})
31
42
  super
@@ -34,7 +45,6 @@ module ActiveMerchant #:nodoc:
34
45
  add_seller_details(options)
35
46
  end
36
47
 
37
-
38
48
  private
39
49
 
40
50
  def add_tracking_token
@@ -51,6 +61,12 @@ module ActiveMerchant #:nodoc:
51
61
  def add_seller_details(options)
52
62
  add_field('recipient_description', options[:account_name]) if options[:account_name]
53
63
  add_field('country', lookup_country_code(options[:country], :alpha3)) if options[:country]
64
+ add_field('language', locale_code(options[:country])) if options[:country]
65
+ end
66
+
67
+ def locale_code(country_code)
68
+ return country_code if SUPPORTED_COUNTRY_CODES.include?(country_code)
69
+ MAPPED_COUNTRY_CODES[country_code] || 'EN'
54
70
  end
55
71
  end
56
72
  end
@@ -45,6 +45,10 @@ module ActiveMerchant #:nodoc:
45
45
  return true if ActiveMerchant::Billing::Base.integration_mode == :test || production_ips.blank?
46
46
  production_ips.include?(ip)
47
47
  end
48
+
49
+ def test?
50
+ false
51
+ end
48
52
 
49
53
  private
50
54
 
@@ -0,0 +1,42 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ module Integrations #:nodoc:
4
+ module PayFast
5
+ module Common
6
+ def generate_signature(type)
7
+ string = case type
8
+ when :request
9
+ request_signature_string
10
+ when :notify
11
+ notify_signature_string
12
+ end
13
+
14
+ Digest::MD5.hexdigest(string)
15
+ end
16
+
17
+ def request_attributes
18
+ [:merchant_id, :merchant_key, :return_url, :cancel_url,
19
+ :notify_url, :name_first, :name_last, :email_address,
20
+ :payment_id, :amount, :item_name, :item_description,
21
+ :custom_str1, :custom_str2, :custom_str3, :custom_str4,
22
+ :custom_str5, :custom_int1, :custom_int2, :custom_int3,
23
+ :custom_int4, :custom_int5, :email_confirmation,
24
+ :confirmation_address]
25
+ end
26
+
27
+ def request_signature_string
28
+ request_attributes.map do |attr|
29
+ "#{mappings[attr]}=#{CGI.escape(@fields[mappings[attr]])}" if @fields[mappings[attr]].present?
30
+ end.compact.join('&')
31
+ end
32
+
33
+ def notify_signature_string
34
+ params.map do |key, value|
35
+ "#{key}=#{CGI.escape(value)}" unless key == PayFast.signature_parameter_name
36
+ end.compact.join('&')
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,50 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ module Integrations #:nodoc:
4
+ module PayFast
5
+ class Helper < ActiveMerchant::Billing::Integrations::Helper
6
+ include Common
7
+
8
+ def initialize(order, account, options = {})
9
+ super
10
+ add_field('merchant_id', account)
11
+ add_field('merchant_key', options.delete(:credential2))
12
+ add_field('m_payment_id', order)
13
+ end
14
+
15
+ def form_fields
16
+ @fields
17
+ end
18
+
19
+ def params
20
+ @fields
21
+ end
22
+
23
+ mapping :merchant_id, 'merchant_id'
24
+ mapping :merchant_key, 'merchant_key'
25
+ mapping :return_url, 'return_url'
26
+ mapping :cancel_return_url, 'cancel_url'
27
+ mapping :notify_url, 'notify_url'
28
+ mapping :name_first, 'name_first'
29
+ mapping :name_last, 'name_last'
30
+ mapping :email_address, 'email_address'
31
+ mapping :payment_id, 'm_payment_id'
32
+ mapping :amount, 'amount'
33
+ mapping :item_name, 'item_name'
34
+ mapping :description, 'item_name'
35
+
36
+ mapping :customer, :first_name => 'name_first',
37
+ :last_name => 'name_last',
38
+ :email => 'email_address',
39
+ :phone => 'phone'
40
+
41
+ 5.times { |i| mapping :"custom_str#{i}", "custom_str#{i}" }
42
+ 5.times { |i| mapping :"custom_int#{i}", "custom_int#{i}" }
43
+
44
+ mapping :email_confirmation, 'email_confirmation'
45
+ mapping :confirmation_address, 'confirmation_address'
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,134 @@
1
+ require 'net/http'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ module Integrations #:nodoc:
6
+ module PayFast
7
+ # Parser and handler for incoming ITN from PayFast.
8
+ # The Example shows a typical handler in a rails application.
9
+ #
10
+ # Example
11
+ #
12
+ # class BackendController < ApplicationController
13
+ # include ActiveMerchant::Billing::Integrations
14
+ #
15
+ # def pay_fast_itn
16
+ # notify = PayFast::Notification.new(request.raw_post)
17
+ #
18
+ # order = Order.find(notify.item_id)
19
+ #
20
+ # if notify.acknowledge
21
+ # begin
22
+ #
23
+ # if notify.complete? and order.total == notify.amount
24
+ # order.status = 'success'
25
+ #
26
+ # shop.ship(order)
27
+ # else
28
+ # logger.error("Failed to verify Paypal's notification, please investigate")
29
+ # end
30
+ #
31
+ # rescue => e
32
+ # order.status = 'failed'
33
+ # raise
34
+ # ensure
35
+ # order.save
36
+ # end
37
+ # end
38
+ #
39
+ # render :nothing
40
+ # end
41
+ # end
42
+ class Notification < ActiveMerchant::Billing::Integrations::Notification
43
+ include PostsData
44
+ include Common
45
+
46
+ # Was the transaction complete?
47
+ def complete?
48
+ status == "Completed"
49
+ end
50
+
51
+ # Status of transaction. List of possible values:
52
+ # <tt>COMPLETE</tt>::
53
+ def status
54
+ if params['payment_status'] == "COMPLETE"
55
+ "Completed"
56
+ else
57
+ "Failed"
58
+ end
59
+ end
60
+
61
+ # Id of this transaction (uniq PayFast transaction id)
62
+ def transaction_id
63
+ params['pf_payment_id']
64
+ end
65
+
66
+ # Id of this transaction (uniq Shopify transaction id)
67
+ def item_id
68
+ params['m_payment_id']
69
+ end
70
+
71
+ # The total amount which the payer paid.
72
+ def gross
73
+ params['amount_gross']
74
+ end
75
+
76
+ # The total in fees which was deducated from the amount.
77
+ def fee
78
+ params['amount_fee']
79
+ end
80
+
81
+ # The net amount credited to the receiver's account.
82
+ def amount
83
+ params['amount_net']
84
+ end
85
+
86
+ # The name of the item being charged for.
87
+ def item_name
88
+ params['item_name']
89
+ end
90
+
91
+ # The Merchant ID as given by the PayFast system. Used to uniquely identify the receiver's account.
92
+ def merchant_id
93
+ params['merchant_id']
94
+ end
95
+
96
+ def currency
97
+ nil
98
+ end
99
+ # Generated hash depends on params order so use OrderedHash instead of Hash
100
+ def empty!
101
+ super
102
+ @params = ActiveSupport::OrderedHash.new
103
+ end
104
+
105
+ # Acknowledge the transaction to PayFast. This method has to be called after a new
106
+ # ITN arrives. PayFast will verify that all the information we received are correct and will return a
107
+ # VERIFIED or INVALID status.
108
+ #
109
+ # Example:
110
+ #
111
+ # def pay_fast_itn
112
+ # notify = PayFastNotification.new(request.raw_post)
113
+ #
114
+ # if notify.acknowledge
115
+ # ... process order ... if notify.complete?
116
+ # else
117
+ # ... log possible hacking attempt ...
118
+ # end
119
+ def acknowledge
120
+ if params[PayFast.signature_parameter_name] == generate_signature(:notify)
121
+ response = ssl_post(PayFast.validate_service_url, notify_signature_string,
122
+ 'Content-Type' => "application/x-www-form-urlencoded",
123
+ 'Content-Length' => "#{notify_signature_string.size}"
124
+ )
125
+ raise StandardError.new("Faulty PayFast result: #{response}") unless ['VALID', 'INVALID'].include?(response)
126
+
127
+ response == "VALID"
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,10 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ module Integrations #:nodoc:
4
+ module PayFast
5
+ class Return < ActiveMerchant::Billing::Integrations::Return
6
+ end
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,70 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ module Integrations #:nodoc:
4
+
5
+ # Documentation:
6
+ # https://www.payfast.co.za/s/std/integration-guide
7
+ module PayFast
8
+ autoload :Return, File.dirname(__FILE__) + '/pay_fast/return.rb'
9
+ autoload :Helper, File.dirname(__FILE__) + '/pay_fast/helper.rb'
10
+ autoload :Notification, File.dirname(__FILE__) + '/pay_fast/notification.rb'
11
+ autoload :Common, File.dirname(__FILE__) + '/pay_fast/common.rb'
12
+
13
+ # Overwrite this if you want to change the PayFast sandbox url
14
+ mattr_accessor :process_test_url
15
+ self.process_test_url = 'https://sandbox.payfast.co.za/eng/process'
16
+
17
+ # Overwrite this if you want to change the PayFast production url
18
+ mattr_accessor :process_production_url
19
+ self.process_production_url = 'https://www.payfast.co.za/eng/process'
20
+
21
+ # Overwrite this if you want to change the PayFast sandbox url
22
+ mattr_accessor :validate_test_url
23
+ self.validate_test_url = 'https://sandbox.payfast.co.za/eng/query/validate'
24
+
25
+ # Overwrite this if you want to change the PayFast production url
26
+ mattr_accessor :validate_production_url
27
+ self.validate_production_url = 'https://www.payfast.co.za/eng/query/validate'
28
+
29
+ mattr_accessor :signature_parameter_name
30
+ self.signature_parameter_name = 'signature'
31
+
32
+ def self.service_url
33
+ mode = ActiveMerchant::Billing::Base.integration_mode
34
+ case mode
35
+ when :production
36
+ self.process_production_url
37
+ when :test
38
+ self.process_test_url
39
+ else
40
+ raise StandardError, "Integration mode set to an invalid value: #{mode}"
41
+ end
42
+ end
43
+
44
+ def self.validate_service_url
45
+ mode = ActiveMerchant::Billing::Base.integration_mode
46
+ case mode
47
+ when :production
48
+ self.validate_production_url
49
+ when :test
50
+ self.validate_test_url
51
+ else
52
+ raise StandardError, "Integration mode set to an invalid value: #{mode}"
53
+ end
54
+ end
55
+
56
+ def self.helper(order, account, options = {})
57
+ Helper.new(order, account, options)
58
+ end
59
+
60
+ def self.notification(query_string, options = {})
61
+ Notification.new(query_string, options)
62
+ end
63
+
64
+ def self.return(post, options = {})
65
+ Return.new(post, options)
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -16,6 +16,10 @@ module ActiveMerchant #:nodoc:
16
16
  #
17
17
  # def paypal_ipn
18
18
  # notify = Paypal::Notification.new(request.raw_post)
19
+ #
20
+ # if notify.masspay?
21
+ # masspay_items = notify.items
22
+ # end
19
23
  #
20
24
  # order = Order.find(notify.item_id)
21
25
  #
@@ -43,12 +47,22 @@ module ActiveMerchant #:nodoc:
43
47
  # end
44
48
  class Notification < ActiveMerchant::Billing::Integrations::Notification
45
49
  include PostsData
50
+
51
+ def initialize(post, options = {})
52
+ super
53
+ extend MassPayNotification if masspay?
54
+ end
46
55
 
47
56
  # Was the transaction complete?
48
57
  def complete?
49
58
  status == "Completed"
50
59
  end
51
60
 
61
+ # Is it a masspay notification?
62
+ def masspay?
63
+ type == "masspay"
64
+ end
65
+
52
66
  # When was this payment received by the client.
53
67
  # sometimes it can happen that we get the notification much later.
54
68
  # One possible scenario is that our web application was down. In this case paypal tries several
@@ -149,6 +163,56 @@ module ActiveMerchant #:nodoc:
149
163
  response == "VERIFIED"
150
164
  end
151
165
  end
166
+
167
+ module MassPayNotification
168
+ # Mass pay returns a collection of MassPay Items, so inspect items to get the values
169
+ def transaction_id
170
+ end
171
+
172
+ # Mass pay returns a collection of MassPay Items, so inspect items to get the values
173
+ def gross
174
+ end
175
+
176
+ # Mass pay returns a collection of MassPay Items, so inspect items to get the values
177
+ def fee
178
+ end
179
+
180
+ # Mass pay returns a collection of MassPay Items, so inspect items to get the values
181
+ def currency
182
+ end
183
+
184
+ # Mass pay returns a collection of MassPay Items, so inspect items to get the values
185
+ def item_id
186
+ end
187
+
188
+ # Mass pay returns a collection of MassPay Items, so inspect items to get the values
189
+ def account
190
+ end
191
+
192
+ # Collection of notification items returned for MassPay transactions
193
+ def items
194
+ @items ||= (1..number_of_mass_pay_items).map do |item_number|
195
+ MassPayItem.new(
196
+ params["masspay_txn_id_#{item_number}"],
197
+ params["mc_gross_#{item_number}"],
198
+ params["mc_fee_#{item_number}"],
199
+ params["mc_currency_#{item_number}"],
200
+ params["unique_id_#{item_number}"],
201
+ params["receiver_email_#{item_number}"],
202
+ params["status_#{item_number}"]
203
+ )
204
+ end
205
+ end
206
+
207
+ private
208
+
209
+ def number_of_mass_pay_items
210
+ @number_of_mass_pay_items ||= params.keys.select { |k| k.start_with? 'masspay_txn_id' }.size
211
+ end
212
+ end
213
+
214
+ class MassPayItem < Struct.new(:transaction_id, :gross, :fee, :currency, :item_id, :account, :status)
215
+ end
152
216
  end
153
217
  end
154
218
  end