newebpay-rails 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.rspec +3 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +7 -0
  6. data/CODE_OF_CONDUCT.md +74 -0
  7. data/Gemfile +6 -0
  8. data/Gemfile.lock +234 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +12 -0
  11. data/Rakefile +12 -0
  12. data/app/controllers/newebpay/application_controller.rb +23 -0
  13. data/app/controllers/newebpay/cancel_auth_notify_callbacks_controller.rb +12 -0
  14. data/app/controllers/newebpay/donation_notify_callbacks_controller.rb +12 -0
  15. data/app/controllers/newebpay/mpg_callbacks_controller.rb +23 -0
  16. data/app/controllers/newebpay/notify_callbacks_controller.rb +18 -0
  17. data/app/controllers/newebpay/payment_code_callbacks_controller.rb +18 -0
  18. data/app/controllers/newebpay/periodical_callbacks_controller.rb +23 -0
  19. data/app/controllers/newebpay/periodical_notify_callbacks_controller.rb +23 -0
  20. data/app/helpers/newebpay/application_helper.rb +7 -0
  21. data/app/helpers/newebpay/donation_helper.rb +36 -0
  22. data/app/helpers/newebpay/mpg_helper.rb +35 -0
  23. data/app/helpers/newebpay/periodical_helper.rb +35 -0
  24. data/app/jobs/newebpay/rails/application_job.rb +6 -0
  25. data/bin/rails +13 -0
  26. data/config/initializers/inflections.rb +3 -0
  27. data/config/routes.rb +13 -0
  28. data/lib/generators/newebpay/install_generator.rb +19 -0
  29. data/lib/generators/newebpay/templates/newebpay_initializer.rb +117 -0
  30. data/lib/newebpay.rb +46 -0
  31. data/lib/newebpay/attr_key_helper.rb +7 -0
  32. data/lib/newebpay/bank_codes.rb +17 -0
  33. data/lib/newebpay/cancel_auth/request.rb +69 -0
  34. data/lib/newebpay/cancel_auth/response.rb +38 -0
  35. data/lib/newebpay/close_fund/base.rb +69 -0
  36. data/lib/newebpay/close_fund/refund.rb +10 -0
  37. data/lib/newebpay/close_fund/request.rb +10 -0
  38. data/lib/newebpay/close_fund/response.rb +26 -0
  39. data/lib/newebpay/config.rb +65 -0
  40. data/lib/newebpay/donation/form.rb +90 -0
  41. data/lib/newebpay/donation/response.rb +38 -0
  42. data/lib/newebpay/engine.rb +9 -0
  43. data/lib/newebpay/error_codes.rb +131 -0
  44. data/lib/newebpay/mpg/form.rb +92 -0
  45. data/lib/newebpay/mpg/response.rb +27 -0
  46. data/lib/newebpay/newebpay_helper.rb +98 -0
  47. data/lib/newebpay/periodical/form.rb +83 -0
  48. data/lib/newebpay/periodical/response.rb +25 -0
  49. data/lib/newebpay/query_trade/response.rb +35 -0
  50. data/lib/newebpay/query_trade/search.rb +53 -0
  51. data/lib/newebpay/rails.rb +6 -0
  52. data/lib/newebpay/rails/engine.rb +9 -0
  53. data/lib/newebpay/version.rb +3 -0
  54. data/newebpay-rails.gemspec +50 -0
  55. metadata +233 -0
@@ -0,0 +1,7 @@
1
+ module Newebpay
2
+ module AttrKeyHelper
3
+ def convert_to_attr_key(term)
4
+ term.to_s.gsub(/(^|_)(url|id|[a-z0-9])/) { Regexp.last_match[2].upcase }
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,17 @@
1
+ module Newebpay
2
+
3
+ class BankCodes
4
+ @@bank_codes = {
5
+ CathayBK: "國泰世華銀行",
6
+ CTBC: "中國信託銀行",
7
+ Esun: "玉山銀行",
8
+ HNCB: "華南銀行",
9
+ NCCC: "聯合信用卡",
10
+ Taishin: "台新銀行"
11
+ }
12
+
13
+ def self.bank_codes
14
+ @@bank_codes
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Newebpay::CancelAuth
4
+ class Request
5
+ attr_accessor :attrs, :merchant_id
6
+ REQUIRED_ATTRS = %i[order_number price].freeze
7
+
8
+ def initialize(options)
9
+ check_valid(options)
10
+ @attrs = {}
11
+ @merchant_id = options[:merchant_id] || Newebpay.config.merchant_id
12
+ parse_attr(options)
13
+
14
+ @attrs['Version'] = version
15
+ @attrs['TimeStamp'] = Time.now.to_i
16
+ @attrs['RespondType'] = 'JSON'
17
+
18
+ result = HTTP.post(Newebpay.config.cancel_auth_url, form: form_attrs).body.to_s
19
+
20
+ instance_exec(Response.new(result), &Newebpay.config.cancel_auth_notify_callback)
21
+ end
22
+
23
+ def form_attrs
24
+ @form_attrs ||= {
25
+ MerchantID_: merchant_id,
26
+ PostData_: trade_info
27
+ }
28
+ end
29
+
30
+ def trade_info
31
+ @trade_info ||= Newebpay::NewebpayHelper.encrypt_data(encode_url_params)
32
+ end
33
+
34
+ def encode_url_params
35
+ URI.encode_www_form(attrs)
36
+ end
37
+
38
+ def version
39
+ '1.0'
40
+ end
41
+
42
+ private
43
+
44
+ def parse_attr(options)
45
+ attrs['Amt'] = options[:price]
46
+ attrs['IndexType'] = options[:number_type] || '1'
47
+ attrs['NotifyURL'] = Newebpay::Engine.routes.url_helpers.cancel_auth_notify_callbacks_url(host: Newebpay.host) if Newebpay.config.cancel_auth_notify_callback
48
+
49
+ case attrs['IndexType'].to_s
50
+ when '1'
51
+ attrs['MerchantOrderNo'] = options[:order_number]
52
+ when '2'
53
+ attrs['TradeNo'] = options[:order_number]
54
+ else
55
+ raise ArgumentError, "Invalid number_type: #{options[:number_type]}"
56
+ end
57
+ end
58
+
59
+ def check_valid(options)
60
+ unless options.is_a? Hash
61
+ raise ArgumentError, "When initializing #{self.class.name}, you must pass a hash."
62
+ end
63
+
64
+ REQUIRED_ATTRS.each do |argument|
65
+ raise ArgumentError, "Missing required argument: #{argument}." unless options[argument]
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Newebpay::CancelAuth
4
+ class Response
5
+ attr_reader :status, :message
6
+
7
+ def initialize(response_params)
8
+ response_data = JSON.parse(response_params)
9
+
10
+ @status = response_data['Status']
11
+ @message = response_data['Message']
12
+
13
+ @result = response_data['Result']
14
+
15
+ @result.each do |key, values|
16
+ define_singleton_method(key.underscore) do
17
+ values
18
+ end
19
+ end
20
+ end
21
+
22
+ def success?
23
+ status == 'SUCCESS'
24
+ end
25
+
26
+ def valid?
27
+ check_code == expected_check_code
28
+ end
29
+
30
+ def expected_check_code
31
+ Newebpay::NewebpayHelper.create_check_code(check_data_raw)
32
+ end
33
+
34
+ def check_data_raw
35
+ @check_data_raw ||= URI.encode_www_form(@result.slice('Amt', 'MerchantID', 'MerchantOrderNo', 'TradeNo').sort)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Newebpay::CloseFund
4
+ class Base
5
+ attr_accessor :attrs, :merchant_id, :response
6
+ REQUIRED_ATTRS = %i[order_number price].freeze
7
+
8
+ def initialize(options)
9
+ check_valid(options)
10
+ @attrs = {}
11
+ @merchant_id = options[:merchant_id] || Newebpay.config.merchant_id
12
+ parse_attr(options)
13
+
14
+ @attrs['Version'] = version
15
+ @attrs['TimeStamp'] = Time.now.to_i
16
+ @attrs['RespondType'] = 'JSON'
17
+ @attrs['CloseType'] = close_type
18
+
19
+ result = HTTP.post(Newebpay.config.close_fund_url, form: form_attrs).body.to_s
20
+ @response = Response.new(result)
21
+ end
22
+
23
+ def form_attrs
24
+ @form_attrs ||= {
25
+ MerchantID_: merchant_id,
26
+ PostData_: trade_info
27
+ }
28
+ end
29
+
30
+ def trade_info
31
+ @trade_info ||= Newebpay::NewebpayHelper.encrypt_data(encode_url_params)
32
+ end
33
+
34
+ def encode_url_params
35
+ URI.encode_www_form(attrs)
36
+ end
37
+
38
+ def version
39
+ '1.1'
40
+ end
41
+
42
+ private
43
+
44
+ def parse_attr(options)
45
+ attrs['Amt'] = options[:price]
46
+ attrs['IndexType'] = options[:number_type] || '1'
47
+ attrs['Cancel'] = '1' if options[:cancel]
48
+
49
+ case attrs['IndexType'].to_s
50
+ when '1'
51
+ attrs['MerchantOrderNo'] = options[:order_number]
52
+ when '2'
53
+ attrs['TradeNo'] = options[:order_number]
54
+ else
55
+ raise ArgumentError, "Invalid number_type: #{options[:number_type]}"
56
+ end
57
+ end
58
+
59
+ def check_valid(options)
60
+ unless options.is_a? Hash
61
+ raise ArgumentError, "When initializing #{self.class.name}, you must pass a hash as an argument."
62
+ end
63
+
64
+ REQUIRED_ATTRS.each do |argument|
65
+ raise ArgumentError, "Missing required argument: #{argument}." unless options[argument]
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Newebpay::CloseFund
4
+ # 退款
5
+ class Refund < Base
6
+ def close_type
7
+ @close_type ||= '2'
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Newebpay::CloseFund
4
+ # 請款
5
+ class Request < Base
6
+ def close_type
7
+ @close_type ||= '1'
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Newebpay::CloseFund
4
+ class Response
5
+ attr_reader :status, :message
6
+
7
+ def initialize(response_params)
8
+ response_data = JSON.parse(response_params)
9
+
10
+ @status = response_data['Status']
11
+ @message = response_data['Message']
12
+
13
+ @result = response_data['Result']
14
+
15
+ @result.each do |key, values|
16
+ define_singleton_method(key.underscore) do
17
+ values
18
+ end
19
+ end
20
+ end
21
+
22
+ def success?
23
+ status == 'SUCCESS'
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,65 @@
1
+ module Newebpay
2
+
3
+ class Config
4
+ include ActiveSupport::Configurable
5
+ config_accessor :merchant_id
6
+ config_accessor :hash_iv, :hash_key
7
+ config_accessor :mpg_gateway_url, :periodical_gateway_url, :query_trade_url, :cancel_auth_url, :close_fund_url
8
+ config_accessor :mpg_callback, :notify_callback, :payment_code_callback, :periodical_callback, :periodical_notify_callback, :donation_notify_callback, :cancel_auth_notify_callback
9
+
10
+ def mpg_callback(&block)
11
+ if block
12
+ config.mpg_callback = block
13
+ else
14
+ config.mpg_callback
15
+ end
16
+ end
17
+
18
+ def notify_callback(&block)
19
+ if block
20
+ config.notify_callback = block
21
+ else
22
+ config.notify_callback
23
+ end
24
+ end
25
+
26
+ def payment_code_callback(&block)
27
+ if block
28
+ config.payment_code_callback = block
29
+ else
30
+ config.payment_code_callback
31
+ end
32
+ end
33
+ def periodical_callback(&block)
34
+ if block
35
+ config.periodical_callback = block
36
+ else
37
+ config.periodical_callback
38
+ end
39
+ end
40
+ def periodical_notify_callback(&block)
41
+ if block
42
+ config.periodical_notify_callback = block
43
+ else
44
+ config.periodical_notify_callback
45
+ end
46
+ end
47
+
48
+ def donation_notify_callback(&block)
49
+ if block
50
+ config.donation_notify_callback = block
51
+ else
52
+ config.donation_notify_callback
53
+ end
54
+ end
55
+
56
+ def cancel_auth_notify_callback(&block)
57
+ if block
58
+ config.cancel_auth_notify_callback = block
59
+ else
60
+ config.cancel_auth_notify_callback
61
+ end
62
+ end
63
+ end
64
+
65
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Newebpay::Donation
4
+ class Form
5
+ attr_accessor :attrs, :merchant_id, :donation_url
6
+ REQUIRED_ATTRS = %i[order_number description price].freeze
7
+ PAYMENT_METHODS = %i[credit webatm vacc cvs barcode].freeze
8
+
9
+ def initialize(donation_url, options)
10
+ @attrs = {}
11
+ @merchant_id = options[:merchant_id] || Newebpay.config.merchant_id
12
+ @donation_url = donation_url
13
+
14
+ check_valid(options)
15
+ parse_attr(options)
16
+
17
+ @attrs['Version'] = version
18
+ @attrs['TimeStamp'] = Time.now.to_i
19
+ @attrs['RespondType'] = 'JSON'
20
+ @attrs['CheckValue'] = check_value
21
+ end
22
+
23
+ def form_attrs
24
+ @form_attrs ||= @attrs
25
+ end
26
+
27
+ def check_value
28
+ @check_value ||= Newebpay::NewebpayHelper.sha256_encode(Newebpay.config.hash_key, Newebpay.config.hash_iv, check_value_raw)
29
+ end
30
+
31
+ def check_value_raw
32
+ URI.encode_www_form(attrs.slice('Amt', 'MerchantID', 'MerchantOrderNo', 'TimeStamp', 'Version').sort)
33
+ end
34
+
35
+ def version
36
+ '1.0'
37
+ end
38
+
39
+ private
40
+
41
+ def parse_attr(options)
42
+ attrs['MerchantID'] = merchant_id
43
+ attrs['MerchantOrderNo'] = options[:order_number]
44
+ attrs['ItemDesc'] = options[:description]
45
+ attrs['Amt'] = options[:price]
46
+ attrs['Templates'] = options[:template_type] || 'donate'
47
+ attrs['ExpireDate'] = options[:expire_date]
48
+ attrs['Nickname'] = options[:anonymous] ? 'on' : 'off'
49
+ attrs['PaymentMAIL'] = options[:email]
50
+ attrs['PaymentName'] = options[:name]
51
+ attrs['PaymentID'] = options[:uni_no]
52
+ attrs['PaymentTEL'] = options[:phone]
53
+ attrs['PaymentRegisterAddress'] = options[:id_address]
54
+ attrs['PaymentMailAddress'] = options[:address]
55
+ attrs['Receipt'] = 'on'
56
+ attrs['ReceiptTitle'] = options[:receipt_name]
57
+ attrs['PaymentReceiptAddress'] = options[:receipt_address]
58
+ attrs['ReturnURL'] = options[:return_url]
59
+ attrs['NotifyURL'] = Newebpay::Engine.routes.url_helpers.donation_notify_callbacks_url(host: Newebpay.host) if Newebpay.config.donation_notify_callback
60
+
61
+ options[:payment_methods].each do |payment_method|
62
+ attrs[payment_method.to_s.upcase] = 'on'
63
+ end
64
+ end
65
+
66
+ def check_valid(options)
67
+ unless options.is_a? Hash
68
+ raise ArgumentError, "When initializing #{self.class.name}, you must pass a hash."
69
+ end
70
+
71
+ raise ArgumentError, 'Missing required argument: donation_url.' unless donation_url
72
+
73
+ unless Newebpay.config.donation_notify_callback
74
+ raise ArgumentError, 'Missing donation_notify_callback block in initializer'
75
+ end
76
+
77
+ %i[order_number description price].each do |argument|
78
+ raise ArgumentError, "Missing required argument: #{argument}." unless options[argument]
79
+ end
80
+
81
+ unless options[:payment_methods].is_a? Array
82
+ raise ArgumentError, 'payment_methods must be an Array'
83
+ end
84
+
85
+ if (options[:payment_methods] - PAYMENT_METHODS).any?
86
+ raise ArgumentError, 'Invalid payment method'
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Newebpay::Donation
4
+ class Response
5
+ attr_reader :status, :message
6
+
7
+ def initialize(response_params)
8
+ @response_data = JSON.parse(response_params.to_json)
9
+
10
+ @status = @response_data['Status']
11
+ @message = @response_data['Message']
12
+
13
+ @result = @response_data['Result']
14
+
15
+ @result.each do |key, values|
16
+ define_singleton_method(key.underscore) do
17
+ values
18
+ end
19
+ end
20
+ end
21
+
22
+ def success?
23
+ status == 'SUCCESS'
24
+ end
25
+
26
+ def valid?
27
+ check_code == expected_check_code
28
+ end
29
+
30
+ def expected_check_code
31
+ Newebpay::NewebpayHelper.sha256_encode(Newebpay.config.hash_key, Newebpay.config.hash_iv, check_data_raw)
32
+ end
33
+
34
+ def check_data_raw
35
+ @check_data_raw ||= URI.encode_www_form(@result.slice('Amt', 'MerchantID', 'MerchantOrderNo', 'TradeNo').sort)
36
+ end
37
+ end
38
+ end