nihaopay-ruby 0.1.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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +5 -0
- data/LICENSE +22 -0
- data/README.md +344 -0
- data/lib/nihaopay-ruby.rb +29 -0
- data/lib/nihaopay/configure.rb +14 -0
- data/lib/nihaopay/credit_card.rb +27 -0
- data/lib/nihaopay/errors.rb +6 -0
- data/lib/nihaopay/merchant.rb +47 -0
- data/lib/nihaopay/mixins/api.rb +41 -0
- data/lib/nihaopay/mixins/queryable.rb +41 -0
- data/lib/nihaopay/query.rb +61 -0
- data/lib/nihaopay/secure_pay/ali_pay.rb +11 -0
- data/lib/nihaopay/secure_pay/base.rb +48 -0
- data/lib/nihaopay/secure_pay/union_pay.rb +11 -0
- data/lib/nihaopay/secure_pay/we_chat_pay.rb +11 -0
- data/lib/nihaopay/transactions/authorize.rb +37 -0
- data/lib/nihaopay/transactions/base.rb +78 -0
- data/lib/nihaopay/transactions/cancel.rb +28 -0
- data/lib/nihaopay/transactions/capture.rb +29 -0
- data/lib/nihaopay/transactions/purchase.rb +11 -0
- data/lib/nihaopay/transactions/refund.rb +31 -0
- data/lib/nihaopay/transactions/release.rb +28 -0
- data/lib/nihaopay/util/hash_util.rb +30 -0
- data/lib/nihaopay/version.rb +3 -0
- data/spec/credit_card_spec.rb +56 -0
- data/spec/merchant_spec.rb +142 -0
- data/spec/mixins/api_spec.rb +81 -0
- data/spec/mixins/queryable_spec.rb +95 -0
- data/spec/query_spec.rb +129 -0
- data/spec/secure_pay/ali_pay_spec.rb +112 -0
- data/spec/secure_pay/union_pay_spec.rb +13 -0
- data/spec/secure_pay/we_chat_pay_spec.rb +13 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/transactions/authorize_spec.rb +115 -0
- data/spec/transactions/base_spec.rb +184 -0
- data/spec/transactions/cancel_spec.rb +83 -0
- data/spec/transactions/capture_spec.rb +85 -0
- data/spec/transactions/purchase_spec.rb +7 -0
- data/spec/transactions/refund_spec.rb +98 -0
- data/spec/transactions/release_spec.rb +83 -0
- data/spec/util/hash_util_spec.rb +22 -0
- metadata +187 -0
@@ -0,0 +1,47 @@
|
|
1
|
+
module Nihaopay
|
2
|
+
class Merchant
|
3
|
+
attr_accessor :token
|
4
|
+
|
5
|
+
def initialize(token)
|
6
|
+
self.token = token
|
7
|
+
end
|
8
|
+
|
9
|
+
def union_pay(amount, currency, options = {})
|
10
|
+
options[:token] = token
|
11
|
+
Nihaopay::SecurePay::UnionPay.start(amount, currency, options)
|
12
|
+
end
|
13
|
+
|
14
|
+
def ali_pay(amount, currency, options = {})
|
15
|
+
options[:token] = token
|
16
|
+
Nihaopay::SecurePay::AliPay.start(amount, currency, options)
|
17
|
+
end
|
18
|
+
|
19
|
+
def wechat_pay(amount, currency, options = {})
|
20
|
+
options[:token] = token
|
21
|
+
Nihaopay::SecurePay::WeChatPay.start(amount, currency, options)
|
22
|
+
end
|
23
|
+
|
24
|
+
def authorize(amount, credit_card, options = {})
|
25
|
+
options[:token] = token
|
26
|
+
Nihaopay::Transactions::Authorize.start(amount, credit_card, options)
|
27
|
+
end
|
28
|
+
|
29
|
+
def capture(transaction_id, amount, currency)
|
30
|
+
Nihaopay::Transactions::Capture.start(transaction_id, amount, currency, token: token)
|
31
|
+
end
|
32
|
+
|
33
|
+
def purchase(amount, credit_card, options = {})
|
34
|
+
options[:token] = token
|
35
|
+
Nihaopay::Transactions::Purchase.start(amount, credit_card, options)
|
36
|
+
end
|
37
|
+
|
38
|
+
def release(transaction_id)
|
39
|
+
Nihaopay::Transactions::Release.start(transaction_id, token: token)
|
40
|
+
end
|
41
|
+
|
42
|
+
def refund(transaction_id, amount, currency, options = {})
|
43
|
+
options[:token] = token
|
44
|
+
Nihaopay::Transactions::Refund.start(transaction_id, amount, currency, options)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Nihaopay
|
2
|
+
module Api
|
3
|
+
def self.included(base)
|
4
|
+
base.extend(ClassMethods)
|
5
|
+
end
|
6
|
+
|
7
|
+
LIVE_HOST = 'https://api.nihaopay.com'.freeze
|
8
|
+
TEST_HOST = 'http://api.test.nihaopay.com'.freeze
|
9
|
+
VERSION = 'v1.1'.freeze
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
def host
|
13
|
+
Nihaopay.test_mode ? TEST_HOST : LIVE_HOST
|
14
|
+
end
|
15
|
+
|
16
|
+
def base_url
|
17
|
+
"#{host}/#{VERSION}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def authorization
|
21
|
+
{ 'Authorization' => "Bearer #{merchant_token}" }
|
22
|
+
end
|
23
|
+
|
24
|
+
def merchant_token
|
25
|
+
@token || Nihaopay.token
|
26
|
+
end
|
27
|
+
|
28
|
+
def validate_resource!(response)
|
29
|
+
return if response.parsed_response['id']
|
30
|
+
parsed_response = response.parsed_response.map { |k, v| "#{k}: #{v}" }.join(', ')
|
31
|
+
fail Nihaopay::TransactionError, parsed_response
|
32
|
+
end
|
33
|
+
|
34
|
+
def validate_collection!(response)
|
35
|
+
return if response.parsed_response['transactions']
|
36
|
+
parsed_response = response.parsed_response.map { |k, v| "#{k}: #{v}" }.join(', ')
|
37
|
+
fail Nihaopay::TransactionError, parsed_response
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Nihaopay
|
2
|
+
module Queryable
|
3
|
+
def self.included(base)
|
4
|
+
base.extend(ClassMethods)
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def find(transaction_id)
|
9
|
+
url = "#{base_url}/transactions/#{transaction_id}"
|
10
|
+
response = HTTParty.get(url, headers: request_headers)
|
11
|
+
build_from_response!(response)
|
12
|
+
rescue Nihaopay::TransactionError => e
|
13
|
+
raise Nihaopay::TransactionLookUpError, e.message
|
14
|
+
end
|
15
|
+
|
16
|
+
def fetch(options = {})
|
17
|
+
options[:starting_after] = options.delete(:after) if options[:after]
|
18
|
+
options[:ending_before] = options.delete(:before) if options[:before]
|
19
|
+
q.fetch(options)
|
20
|
+
end
|
21
|
+
|
22
|
+
def limit(num)
|
23
|
+
q.limit(num)
|
24
|
+
end
|
25
|
+
|
26
|
+
def before(time)
|
27
|
+
q.before(time)
|
28
|
+
end
|
29
|
+
|
30
|
+
def after(time)
|
31
|
+
q.after(time)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def q
|
37
|
+
Nihaopay::Query.new
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Nihaopay
|
2
|
+
class Query
|
3
|
+
include ::Nihaopay::Api
|
4
|
+
|
5
|
+
VALID_OPTIONS = %i(limit starting_after ending_before).freeze
|
6
|
+
|
7
|
+
def limit(num)
|
8
|
+
@limit = num
|
9
|
+
self
|
10
|
+
end
|
11
|
+
|
12
|
+
def before(time)
|
13
|
+
@ending_before = time
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
def after(time)
|
18
|
+
@starting_after = time
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def fetch(options = nil)
|
23
|
+
options ||= { limit: @limit, starting_after: @starting_after, ending_before: @ending_before }
|
24
|
+
self.class.fetch(options)
|
25
|
+
end
|
26
|
+
|
27
|
+
class << self
|
28
|
+
def fetch(options = {})
|
29
|
+
query = query_params(options)
|
30
|
+
response = if query && !query.empty?
|
31
|
+
HTTParty.get(url, headers: request_headers, query: query)
|
32
|
+
else
|
33
|
+
HTTParty.get(url, headers: request_headers)
|
34
|
+
end
|
35
|
+
build_transactions(response)
|
36
|
+
rescue Nihaopay::TransactionError => e
|
37
|
+
raise Nihaopay::TransactionLookUpError, e.message
|
38
|
+
end
|
39
|
+
|
40
|
+
def url
|
41
|
+
"#{base_url}/transactions"
|
42
|
+
end
|
43
|
+
|
44
|
+
def request_headers
|
45
|
+
authorization
|
46
|
+
end
|
47
|
+
|
48
|
+
def query_params(options)
|
49
|
+
Nihaopay::HashUtil.slice(options, *VALID_OPTIONS).select { |_, v| v && (!v.respond_to?(:empty?) || !v.empty?) }
|
50
|
+
end
|
51
|
+
|
52
|
+
def build_transactions(response)
|
53
|
+
validate_collection!(response)
|
54
|
+
transactions = response.parsed_response['transactions']
|
55
|
+
transactions.map do |transaction|
|
56
|
+
Nihaopay::Transactions::Base.build(transaction)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Nihaopay
|
2
|
+
module SecurePay
|
3
|
+
class Base
|
4
|
+
include ::Nihaopay::Api
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def with_failure(&_)
|
8
|
+
response = yield
|
9
|
+
if response.code != 200
|
10
|
+
message = response.parsed_response.map { |k, v| "#{k}: #{v}" }.join(', ')
|
11
|
+
fail SecurePayTransactionError, message
|
12
|
+
end
|
13
|
+
response
|
14
|
+
end
|
15
|
+
|
16
|
+
def start(amount, currency, options = {})
|
17
|
+
with_failure do
|
18
|
+
@token = options.delete(:token)
|
19
|
+
params = request_params(amount, currency, options)
|
20
|
+
body = request_body(params)
|
21
|
+
HTTParty.post(request_url, headers: request_headers, body: body)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def request_url
|
26
|
+
"#{base_url}/transactions/securepay"
|
27
|
+
end
|
28
|
+
|
29
|
+
def request_headers
|
30
|
+
authorization
|
31
|
+
end
|
32
|
+
|
33
|
+
def request_params(amount, currency, options)
|
34
|
+
{ amount: amount.to_i,
|
35
|
+
currency: currency.to_s,
|
36
|
+
vendor: vendor.to_s,
|
37
|
+
reference: options[:reference].to_s.slice(0, 30),
|
38
|
+
ipn_url: options[:ipn_url].to_s,
|
39
|
+
callback_url: options[:callback_url].to_s }
|
40
|
+
end
|
41
|
+
|
42
|
+
def request_body(params = {})
|
43
|
+
params.map { |k, v| "#{k}=#{v}" }.join('&')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Nihaopay
|
2
|
+
module Transactions
|
3
|
+
class Authorize < Base
|
4
|
+
class << self
|
5
|
+
def start(amount, credit_card, options = {})
|
6
|
+
@token = options.delete(:token)
|
7
|
+
params = request_params(amount, credit_card, options)
|
8
|
+
body = request_body(params)
|
9
|
+
response = HTTParty.post(request_url, headers: request_headers, body: body)
|
10
|
+
build_from_response!(response)
|
11
|
+
end
|
12
|
+
|
13
|
+
def request_url
|
14
|
+
"#{base_url}/transactions/expresspay"
|
15
|
+
end
|
16
|
+
|
17
|
+
def request_params(amount, credit_card, options)
|
18
|
+
params = {}
|
19
|
+
params.merge! credit_card.to_params_hash
|
20
|
+
params.merge! Nihaopay::HashUtil.slice(options, *valid_options)
|
21
|
+
params[:capture] = capture_param
|
22
|
+
params[:amount] = amount
|
23
|
+
params[:currency] ||= Nihaopay.currency
|
24
|
+
params
|
25
|
+
end
|
26
|
+
|
27
|
+
def valid_options
|
28
|
+
%i(currency description note reference)
|
29
|
+
end
|
30
|
+
|
31
|
+
def capture_param
|
32
|
+
false
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Nihaopay
|
2
|
+
module Transactions
|
3
|
+
class Base
|
4
|
+
include ::Nihaopay::Api
|
5
|
+
include ::Nihaopay::Queryable
|
6
|
+
|
7
|
+
attr_accessor :token, :transaction_id, :type, :status
|
8
|
+
attr_accessor :captured, :reference, :currency, :amount, :note, :time
|
9
|
+
|
10
|
+
def initialize(attributes = {})
|
11
|
+
assign_attributes(attributes)
|
12
|
+
end
|
13
|
+
|
14
|
+
def capture
|
15
|
+
Nihaopay::Transactions::Capture.start(transaction_id, amount, currency, token: token)
|
16
|
+
end
|
17
|
+
|
18
|
+
def partial_capture(capture_amount)
|
19
|
+
Nihaopay::Transactions::Capture.start(transaction_id, capture_amount, currency, token: token)
|
20
|
+
end
|
21
|
+
|
22
|
+
def release
|
23
|
+
Nihaopay::Transactions::Release.start(transaction_id, token: token)
|
24
|
+
end
|
25
|
+
|
26
|
+
def cancel
|
27
|
+
Nihaopay::Transactions::Cancel.start(transaction_id, token: token)
|
28
|
+
end
|
29
|
+
|
30
|
+
def refund(options = {})
|
31
|
+
options[:token] = token
|
32
|
+
Nihaopay::Transactions::Refund.start(transaction_id, amount, currency, options)
|
33
|
+
end
|
34
|
+
|
35
|
+
def partial_refund(refund_amount, options = {})
|
36
|
+
options[:token] = token
|
37
|
+
Nihaopay::Transactions::Refund.start(transaction_id, refund_amount, currency, options)
|
38
|
+
end
|
39
|
+
|
40
|
+
class << self
|
41
|
+
def request_headers
|
42
|
+
authorization.merge('Content-Type' => 'application/x-www-form-urlencoded')
|
43
|
+
end
|
44
|
+
|
45
|
+
def request_body(params = {})
|
46
|
+
params.map { |k, v| "#{k}=#{v}" }.join('&')
|
47
|
+
end
|
48
|
+
|
49
|
+
def build_from_response!(response)
|
50
|
+
validate_resource!(response)
|
51
|
+
build(response.parsed_response)
|
52
|
+
end
|
53
|
+
|
54
|
+
def build(options = {})
|
55
|
+
options = Nihaopay::HashUtil.symbolize_keys(options)
|
56
|
+
attributes = Nihaopay::HashUtil.slice(options, *valid_attributes)
|
57
|
+
attributes[:token] ||= merchant_token
|
58
|
+
response_keys_map.each { |k, v| attributes[v] = options[k] }
|
59
|
+
new(attributes)
|
60
|
+
end
|
61
|
+
|
62
|
+
def valid_attributes
|
63
|
+
%i(token transaction_id type status captured currency reference amount note time)
|
64
|
+
end
|
65
|
+
|
66
|
+
def response_keys_map
|
67
|
+
{ id: :transaction_id }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def assign_attributes(attributes)
|
74
|
+
self.class.valid_attributes.each { |f| send("#{f}=", attributes[f]) }
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Nihaopay
|
2
|
+
module Transactions
|
3
|
+
class Cancel < Base
|
4
|
+
attr_accessor :cancelled, :cancel_transaction_id
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def start(transaction_id, options = {})
|
8
|
+
@token = options.delete(:token)
|
9
|
+
url = request_url(transaction_id)
|
10
|
+
response = HTTParty.post(url, headers: request_headers, body: request_body)
|
11
|
+
build_from_response!(response)
|
12
|
+
end
|
13
|
+
|
14
|
+
def request_url(transaction_id)
|
15
|
+
"#{base_url}/transactions/#{transaction_id}/cancel"
|
16
|
+
end
|
17
|
+
|
18
|
+
def valid_attributes
|
19
|
+
%i(transaction_id status cancelled cancel_transaction_id)
|
20
|
+
end
|
21
|
+
|
22
|
+
def response_keys_map
|
23
|
+
{ id: :transaction_id, transaction_id: :cancel_transaction_id }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Nihaopay
|
2
|
+
module Transactions
|
3
|
+
class Capture < Base
|
4
|
+
attr_accessor :captured, :capture_transaction_id
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def start(transaction_id, amount, currency, options = {})
|
8
|
+
@token = options.delete(:token)
|
9
|
+
url = request_url(transaction_id)
|
10
|
+
params = request_body(amount: amount, currency: currency)
|
11
|
+
response = HTTParty.post(url, headers: request_headers, body: params)
|
12
|
+
build_from_response!(response)
|
13
|
+
end
|
14
|
+
|
15
|
+
def request_url(transaction_id)
|
16
|
+
"#{base_url}/transactions/#{transaction_id}/capture"
|
17
|
+
end
|
18
|
+
|
19
|
+
def valid_attributes
|
20
|
+
%i(transaction_id status captured capture_transaction_id)
|
21
|
+
end
|
22
|
+
|
23
|
+
def response_keys_map
|
24
|
+
{ id: :transaction_id, transaction_id: :capture_transaction_id }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|