tinker-pay-ruby-sdk 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/.rspec_status +31 -0
- data/.rubocop.yml +64 -0
- data/Gemfile +11 -0
- data/README.md +166 -0
- data/Rakefile +8 -0
- data/lib/tinker/api/base_manager.rb +47 -0
- data/lib/tinker/api/transaction_manager.rb +21 -0
- data/lib/tinker/auth/authentication_manager.rb +66 -0
- data/lib/tinker/config/configuration.rb +19 -0
- data/lib/tinker/config/endpoints.rb +13 -0
- data/lib/tinker/enum/gateway.rb +11 -0
- data/lib/tinker/enum/payment_status.rb +12 -0
- data/lib/tinker/exception/api_exception.rb +14 -0
- data/lib/tinker/exception/authentication_exception.rb +15 -0
- data/lib/tinker/exception/client_exception.rb +15 -0
- data/lib/tinker/exception/exception_code.rb +15 -0
- data/lib/tinker/exception/invalid_payload_exception.rb +15 -0
- data/lib/tinker/exception/network_exception.rb +15 -0
- data/lib/tinker/exception/webhook_exception.rb +15 -0
- data/lib/tinker/http/http_client.rb +48 -0
- data/lib/tinker/model/dto/callback_data_dto.rb +40 -0
- data/lib/tinker/model/dto/initiate_payment_request_dto.rb +44 -0
- data/lib/tinker/model/dto/initiation_data_dto.rb +30 -0
- data/lib/tinker/model/dto/query_data_dto.rb +40 -0
- data/lib/tinker/model/dto/query_payment_request_dto.rb +25 -0
- data/lib/tinker/model/transaction.rb +49 -0
- data/lib/tinker/payments.rb +34 -0
- data/lib/tinker/version.rb +5 -0
- data/lib/tinker/webhook/dto/invoice_event_data_dto.rb +35 -0
- data/lib/tinker/webhook/dto/payment_event_data_dto.rb +40 -0
- data/lib/tinker/webhook/dto/settlement_event_data_dto.rb +33 -0
- data/lib/tinker/webhook/dto/subscription_event_data_dto.rb +35 -0
- data/lib/tinker/webhook/webhook_event.rb +75 -0
- data/lib/tinker/webhook/webhook_handler.rb +35 -0
- data/lib/tinker/webhook/webhook_meta.rb +15 -0
- data/lib/tinker/webhook/webhook_security.rb +14 -0
- data/lib/tinker.rb +33 -0
- metadata +110 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tinker
|
|
4
|
+
module Model
|
|
5
|
+
module Dto
|
|
6
|
+
class CallbackDataDto
|
|
7
|
+
attr_reader :id, :status, :reference, :amount, :currency, :paid_at, :created_at, :channel
|
|
8
|
+
|
|
9
|
+
def initialize(data)
|
|
10
|
+
@id = data['id']
|
|
11
|
+
status_value = data['status'] || 'pending'
|
|
12
|
+
@status = begin
|
|
13
|
+
Tinker::Enum::PaymentStatus.const_get(status_value.upcase)
|
|
14
|
+
rescue NameError
|
|
15
|
+
Tinker::Enum::PaymentStatus::PENDING
|
|
16
|
+
end
|
|
17
|
+
@reference = data['reference']
|
|
18
|
+
@amount = data['amount'].to_f
|
|
19
|
+
@currency = data['currency']
|
|
20
|
+
@paid_at = data['paid_at']
|
|
21
|
+
@created_at = data['created_at']
|
|
22
|
+
@channel = data['channel']
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def to_hash
|
|
26
|
+
{
|
|
27
|
+
id: @id,
|
|
28
|
+
status: @status,
|
|
29
|
+
reference: @reference,
|
|
30
|
+
amount: @amount,
|
|
31
|
+
currency: @currency,
|
|
32
|
+
paid_at: @paid_at,
|
|
33
|
+
created_at: @created_at,
|
|
34
|
+
channel: @channel
|
|
35
|
+
}
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tinker
|
|
4
|
+
module Model
|
|
5
|
+
module Dto
|
|
6
|
+
class InitiatePaymentRequestDto
|
|
7
|
+
attr_reader :amount, :currency, :gateway, :merchant_reference, :return_url,
|
|
8
|
+
:customer_phone, :customer_email, :transaction_desc, :metadata
|
|
9
|
+
|
|
10
|
+
def initialize(amount:, currency:, gateway:, merchant_reference:, return_url:,
|
|
11
|
+
customer_phone: nil, customer_email: nil, transaction_desc: nil, metadata: nil)
|
|
12
|
+
@amount = amount
|
|
13
|
+
@currency = currency
|
|
14
|
+
@gateway = gateway
|
|
15
|
+
@merchant_reference = merchant_reference
|
|
16
|
+
@return_url = return_url
|
|
17
|
+
@customer_phone = customer_phone
|
|
18
|
+
@customer_email = customer_email
|
|
19
|
+
@transaction_desc = transaction_desc
|
|
20
|
+
@metadata = metadata
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def to_hash
|
|
24
|
+
gateway_value = @gateway.is_a?(String) ? @gateway : @gateway.to_s
|
|
25
|
+
|
|
26
|
+
payload = {
|
|
27
|
+
amount: @amount,
|
|
28
|
+
currency: @currency,
|
|
29
|
+
gateway: gateway_value,
|
|
30
|
+
merchantReference: @merchant_reference,
|
|
31
|
+
returnUrl: @return_url
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
payload[:customerPhone] = @customer_phone if @customer_phone
|
|
35
|
+
payload[:customerEmail] = @customer_email if @customer_email
|
|
36
|
+
payload[:transactionDesc] = @transaction_desc if @transaction_desc
|
|
37
|
+
payload[:metadata] = @metadata if @metadata
|
|
38
|
+
|
|
39
|
+
payload
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tinker
|
|
4
|
+
module Model
|
|
5
|
+
module Dto
|
|
6
|
+
class InitiationDataDto
|
|
7
|
+
attr_reader :payment_reference, :status, :authorization_url
|
|
8
|
+
|
|
9
|
+
def initialize(data)
|
|
10
|
+
@payment_reference = data['payment_reference']
|
|
11
|
+
status_value = data['status'] || 'pending'
|
|
12
|
+
@status = begin
|
|
13
|
+
Tinker::Enum::PaymentStatus.const_get(status_value.upcase)
|
|
14
|
+
rescue NameError
|
|
15
|
+
Tinker::Enum::PaymentStatus::PENDING
|
|
16
|
+
end
|
|
17
|
+
@authorization_url = data['authorization_url']
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def to_hash
|
|
21
|
+
{
|
|
22
|
+
payment_reference: @payment_reference,
|
|
23
|
+
status: @status,
|
|
24
|
+
authorization_url: @authorization_url
|
|
25
|
+
}
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tinker
|
|
4
|
+
module Model
|
|
5
|
+
module Dto
|
|
6
|
+
class QueryDataDto
|
|
7
|
+
attr_reader :id, :status, :reference, :amount, :currency, :paid_at, :created_at, :channel
|
|
8
|
+
|
|
9
|
+
def initialize(data)
|
|
10
|
+
@id = data['id']
|
|
11
|
+
status_value = data['status'] || 'pending'
|
|
12
|
+
@status = begin
|
|
13
|
+
Tinker::Enum::PaymentStatus.const_get(status_value.upcase)
|
|
14
|
+
rescue NameError
|
|
15
|
+
Tinker::Enum::PaymentStatus::PENDING
|
|
16
|
+
end
|
|
17
|
+
@reference = data['reference']
|
|
18
|
+
@amount = data['amount'].to_f
|
|
19
|
+
@currency = data['currency']
|
|
20
|
+
@paid_at = data['paid_at']
|
|
21
|
+
@created_at = data['created_at']
|
|
22
|
+
@channel = data['channel']
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def to_hash
|
|
26
|
+
{
|
|
27
|
+
id: @id,
|
|
28
|
+
status: @status,
|
|
29
|
+
reference: @reference,
|
|
30
|
+
amount: @amount,
|
|
31
|
+
currency: @currency,
|
|
32
|
+
paid_at: @paid_at,
|
|
33
|
+
created_at: @created_at,
|
|
34
|
+
channel: @channel
|
|
35
|
+
}
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tinker
|
|
4
|
+
module Model
|
|
5
|
+
module Dto
|
|
6
|
+
class QueryPaymentRequestDto
|
|
7
|
+
attr_reader :payment_reference, :gateway
|
|
8
|
+
|
|
9
|
+
def initialize(payment_reference:, gateway:)
|
|
10
|
+
@payment_reference = payment_reference
|
|
11
|
+
@gateway = gateway
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def to_hash
|
|
15
|
+
gateway_value = @gateway.is_a?(String) ? @gateway : @gateway.to_s
|
|
16
|
+
|
|
17
|
+
{
|
|
18
|
+
payment_reference: @payment_reference,
|
|
19
|
+
gateway: gateway_value
|
|
20
|
+
}
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tinker
|
|
4
|
+
module Model
|
|
5
|
+
class Transaction
|
|
6
|
+
attr_reader :status, :initiation_data, :query_data, :callback_data
|
|
7
|
+
|
|
8
|
+
def initialize(data)
|
|
9
|
+
if data['payment_reference'] && !data['id']
|
|
10
|
+
@initiation_data = Dto::InitiationDataDto.new(data)
|
|
11
|
+
@query_data = nil
|
|
12
|
+
@callback_data = nil
|
|
13
|
+
@status = @initiation_data.status
|
|
14
|
+
elsif data['id'] && data['reference']
|
|
15
|
+
@initiation_data = nil
|
|
16
|
+
@query_data = Dto::QueryDataDto.new(data)
|
|
17
|
+
@callback_data = Dto::CallbackDataDto.new(data)
|
|
18
|
+
@status = @query_data.status
|
|
19
|
+
else
|
|
20
|
+
@initiation_data = nil
|
|
21
|
+
@query_data = nil
|
|
22
|
+
@callback_data = nil
|
|
23
|
+
status_value = data['status'] || 'pending'
|
|
24
|
+
@status = begin
|
|
25
|
+
Enum::PaymentStatus.const_get(status_value.upcase)
|
|
26
|
+
rescue NameError
|
|
27
|
+
Enum::PaymentStatus::PENDING
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def successful?
|
|
33
|
+
@status == Enum::PaymentStatus::SUCCESS
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def pending?
|
|
37
|
+
@status == Enum::PaymentStatus::PENDING
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def cancelled?
|
|
41
|
+
@status == Enum::PaymentStatus::CANCELLED
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def failed?
|
|
45
|
+
@status == Enum::PaymentStatus::FAILED
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'version'
|
|
4
|
+
require_relative 'config/configuration'
|
|
5
|
+
require_relative 'config/endpoints'
|
|
6
|
+
require_relative 'http/http_client'
|
|
7
|
+
require_relative 'auth/authentication_manager'
|
|
8
|
+
require_relative 'api/base_manager'
|
|
9
|
+
require_relative 'api/transaction_manager'
|
|
10
|
+
require_relative 'webhook/webhook_handler'
|
|
11
|
+
|
|
12
|
+
module Tinker
|
|
13
|
+
class Payments
|
|
14
|
+
def initialize(api_public_key:, api_secret_key:, http_client: nil)
|
|
15
|
+
@config = Config::Configuration.new(api_public_key: api_public_key, api_secret_key: api_secret_key)
|
|
16
|
+
@http_client = http_client || Http::HttpClient.new
|
|
17
|
+
@auth_manager = Auth::AuthenticationManager.new(config: @config, http_client: @http_client)
|
|
18
|
+
@transactions_manager = nil
|
|
19
|
+
@webhook_handler = nil
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def transactions
|
|
23
|
+
@transactions ||= Api::TransactionManager.new(
|
|
24
|
+
config: @config,
|
|
25
|
+
http_client: @http_client,
|
|
26
|
+
auth_manager: @auth_manager
|
|
27
|
+
)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def webhooks
|
|
31
|
+
@webhooks ||= Webhook::WebhookHandler.new
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tinker
|
|
4
|
+
module Webhook
|
|
5
|
+
module Dto
|
|
6
|
+
class InvoiceEventDataDto
|
|
7
|
+
attr_reader :id, :status, :invoice_number, :amount, :currency, :subscription_id, :created_at, :paid_at
|
|
8
|
+
|
|
9
|
+
def initialize(data)
|
|
10
|
+
@id = data['id']
|
|
11
|
+
@status = data['status']
|
|
12
|
+
@invoice_number = data['invoice_number'] || ''
|
|
13
|
+
@amount = data['amount'].to_f
|
|
14
|
+
@currency = data['currency']
|
|
15
|
+
@subscription_id = data['subscription_id'] || ''
|
|
16
|
+
@created_at = data['created_at'] || ''
|
|
17
|
+
@paid_at = data['paid_at']
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def to_hash
|
|
21
|
+
{
|
|
22
|
+
id: @id,
|
|
23
|
+
status: @status,
|
|
24
|
+
invoice_number: @invoice_number,
|
|
25
|
+
amount: @amount,
|
|
26
|
+
currency: @currency,
|
|
27
|
+
subscription_id: @subscription_id,
|
|
28
|
+
created_at: @created_at,
|
|
29
|
+
paid_at: @paid_at
|
|
30
|
+
}
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tinker
|
|
4
|
+
module Webhook
|
|
5
|
+
module Dto
|
|
6
|
+
class PaymentEventDataDto
|
|
7
|
+
attr_reader :id, :status, :reference, :amount, :currency, :channel, :created_at, :paid_at
|
|
8
|
+
|
|
9
|
+
def initialize(data)
|
|
10
|
+
@id = data['id']
|
|
11
|
+
status_value = data['status'] || 'pending'
|
|
12
|
+
@status = begin
|
|
13
|
+
Tinker::Enum::PaymentStatus.const_get(status_value.upcase)
|
|
14
|
+
rescue NameError
|
|
15
|
+
Tinker::Enum::PaymentStatus::PENDING
|
|
16
|
+
end
|
|
17
|
+
@reference = data['reference']
|
|
18
|
+
@amount = data['amount'].to_f
|
|
19
|
+
@currency = data['currency']
|
|
20
|
+
@channel = data['channel']
|
|
21
|
+
@created_at = data['created_at']
|
|
22
|
+
@paid_at = data['paid_at']
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def to_hash
|
|
26
|
+
{
|
|
27
|
+
'id' => @id,
|
|
28
|
+
'status' => @status.to_s,
|
|
29
|
+
'reference' => @reference,
|
|
30
|
+
'amount' => @amount,
|
|
31
|
+
'currency' => @currency,
|
|
32
|
+
'channel' => @channel,
|
|
33
|
+
'created_at' => @created_at,
|
|
34
|
+
'paid_at' => @paid_at
|
|
35
|
+
}
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tinker
|
|
4
|
+
module Webhook
|
|
5
|
+
module Dto
|
|
6
|
+
class SettlementEventDataDto
|
|
7
|
+
attr_reader :id, :status, :amount, :currency, :settlement_date, :created_at, :processed_at
|
|
8
|
+
|
|
9
|
+
def initialize(data)
|
|
10
|
+
@id = data['id']
|
|
11
|
+
@status = data['status']
|
|
12
|
+
@amount = data['amount'].to_f
|
|
13
|
+
@currency = data['currency']
|
|
14
|
+
@settlement_date = data['settlement_date'] || ''
|
|
15
|
+
@created_at = data['created_at'] || ''
|
|
16
|
+
@processed_at = data['processed_at']
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def to_hash
|
|
20
|
+
{
|
|
21
|
+
id: @id,
|
|
22
|
+
status: @status,
|
|
23
|
+
amount: @amount,
|
|
24
|
+
currency: @currency,
|
|
25
|
+
settlement_date: @settlement_date,
|
|
26
|
+
created_at: @created_at,
|
|
27
|
+
processed_at: @processed_at
|
|
28
|
+
}
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tinker
|
|
4
|
+
module Webhook
|
|
5
|
+
module Dto
|
|
6
|
+
class SubscriptionEventDataDto
|
|
7
|
+
attr_reader :id, :status, :plan_id, :customer_id, :created_at, :cancelled_at, :paused_at, :reactivated_at
|
|
8
|
+
|
|
9
|
+
def initialize(data)
|
|
10
|
+
@id = data['id']
|
|
11
|
+
@status = data['status']
|
|
12
|
+
@plan_id = data['plan_id'] || ''
|
|
13
|
+
@customer_id = data['customer_id'] || ''
|
|
14
|
+
@created_at = data['created_at'] || ''
|
|
15
|
+
@cancelled_at = data['cancelled_at']
|
|
16
|
+
@paused_at = data['paused_at']
|
|
17
|
+
@reactivated_at = data['reactivated_at']
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def to_hash
|
|
21
|
+
{
|
|
22
|
+
id: @id,
|
|
23
|
+
status: @status,
|
|
24
|
+
plan_id: @plan_id,
|
|
25
|
+
customer_id: @customer_id,
|
|
26
|
+
created_at: @created_at,
|
|
27
|
+
cancelled_at: @cancelled_at,
|
|
28
|
+
paused_at: @paused_at,
|
|
29
|
+
reactivated_at: @reactivated_at
|
|
30
|
+
}
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tinker
|
|
4
|
+
module Webhook
|
|
5
|
+
class WebhookEvent
|
|
6
|
+
attr_reader :id, :type, :source, :timestamp, :data, :meta, :security
|
|
7
|
+
|
|
8
|
+
def initialize(payload)
|
|
9
|
+
@id = payload['id']
|
|
10
|
+
@type = payload['type']
|
|
11
|
+
@source = payload['source']
|
|
12
|
+
@timestamp = payload['timestamp']
|
|
13
|
+
@data = create_event_data(payload['data'], @source)
|
|
14
|
+
@meta = WebhookMeta.new(payload['meta'] || {})
|
|
15
|
+
@security = WebhookSecurity.new(payload['security'] || {})
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def payment_event?
|
|
19
|
+
@source == 'payment'
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def subscription_event?
|
|
23
|
+
@source == 'subscription'
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def invoice_event?
|
|
27
|
+
@source == 'invoice'
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def settlement_event?
|
|
31
|
+
@source == 'settlement'
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def payment_data
|
|
35
|
+
@data.is_a?(Dto::PaymentEventDataDto) ? @data : nil
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def subscription_data
|
|
39
|
+
@data.is_a?(Dto::SubscriptionEventDataDto) ? @data : nil
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def invoice_data
|
|
43
|
+
@data.is_a?(Dto::InvoiceEventDataDto) ? @data : nil
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def settlement_data
|
|
47
|
+
@data.is_a?(Dto::SettlementEventDataDto) ? @data : nil
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def to_transaction
|
|
51
|
+
return nil unless payment_event?
|
|
52
|
+
return nil unless @data.is_a?(Dto::PaymentEventDataDto)
|
|
53
|
+
|
|
54
|
+
Model::Transaction.new(@data.to_hash)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
def create_event_data(data, source)
|
|
60
|
+
case source
|
|
61
|
+
when 'payment'
|
|
62
|
+
Dto::PaymentEventDataDto.new(data)
|
|
63
|
+
when 'subscription'
|
|
64
|
+
Dto::SubscriptionEventDataDto.new(data)
|
|
65
|
+
when 'invoice'
|
|
66
|
+
Dto::InvoiceEventDataDto.new(data)
|
|
67
|
+
when 'settlement'
|
|
68
|
+
Dto::SettlementEventDataDto.new(data)
|
|
69
|
+
else
|
|
70
|
+
raise Exception::InvalidPayloadException.new("Unknown webhook source: #{source}", Exception::ExceptionCode::INVALID_PAYLOAD)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'json'
|
|
4
|
+
|
|
5
|
+
module Tinker
|
|
6
|
+
module Webhook
|
|
7
|
+
class WebhookHandler
|
|
8
|
+
def handle(payload)
|
|
9
|
+
data = if payload.is_a?(String)
|
|
10
|
+
JSON.parse(payload)
|
|
11
|
+
else
|
|
12
|
+
payload
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
raise Exception::InvalidPayloadException, 'Webhook payload must be a hash' unless data.is_a?(Hash)
|
|
16
|
+
|
|
17
|
+
WebhookEvent.new(data)
|
|
18
|
+
rescue JSON::ParserError => e
|
|
19
|
+
raise Exception::InvalidPayloadException, "Invalid JSON payload: #{e.message}"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def handle_from_request(request_body = nil)
|
|
23
|
+
payload = request_body || $stdin.read
|
|
24
|
+
raise Exception::WebhookException, 'Unable to read request body' if payload.nil? || payload.empty?
|
|
25
|
+
|
|
26
|
+
handle(payload)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def handle_as_transaction(payload)
|
|
30
|
+
event = handle(payload)
|
|
31
|
+
event.to_transaction
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tinker
|
|
4
|
+
module Webhook
|
|
5
|
+
class WebhookMeta
|
|
6
|
+
attr_reader :version, :app_id, :gateway
|
|
7
|
+
|
|
8
|
+
def initialize(meta = {})
|
|
9
|
+
@version = meta['version'] || '1.0'
|
|
10
|
+
@app_id = meta['app_id'] || ''
|
|
11
|
+
@gateway = meta['gateway']
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tinker
|
|
4
|
+
module Webhook
|
|
5
|
+
class WebhookSecurity
|
|
6
|
+
attr_reader :signature, :algorithm
|
|
7
|
+
|
|
8
|
+
def initialize(security = {})
|
|
9
|
+
@signature = security['signature'] || ''
|
|
10
|
+
@algorithm = security['algorithm'] || 'HMAC-SHA256'
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
data/lib/tinker.rb
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'tinker/version'
|
|
4
|
+
require_relative 'tinker/config/configuration'
|
|
5
|
+
require_relative 'tinker/config/endpoints'
|
|
6
|
+
require_relative 'tinker/exception/exception_code'
|
|
7
|
+
require_relative 'tinker/exception/api_exception'
|
|
8
|
+
require_relative 'tinker/exception/network_exception'
|
|
9
|
+
require_relative 'tinker/exception/authentication_exception'
|
|
10
|
+
require_relative 'tinker/exception/invalid_payload_exception'
|
|
11
|
+
require_relative 'tinker/exception/webhook_exception'
|
|
12
|
+
require_relative 'tinker/exception/client_exception'
|
|
13
|
+
require_relative 'tinker/enum/gateway'
|
|
14
|
+
require_relative 'tinker/enum/payment_status'
|
|
15
|
+
require_relative 'tinker/http/http_client'
|
|
16
|
+
require_relative 'tinker/auth/authentication_manager'
|
|
17
|
+
require_relative 'tinker/api/base_manager'
|
|
18
|
+
require_relative 'tinker/api/transaction_manager'
|
|
19
|
+
require_relative 'tinker/model/dto/initiate_payment_request_dto'
|
|
20
|
+
require_relative 'tinker/model/dto/query_payment_request_dto'
|
|
21
|
+
require_relative 'tinker/model/dto/initiation_data_dto'
|
|
22
|
+
require_relative 'tinker/model/dto/query_data_dto'
|
|
23
|
+
require_relative 'tinker/model/dto/callback_data_dto'
|
|
24
|
+
require_relative 'tinker/model/transaction'
|
|
25
|
+
require_relative 'tinker/webhook/dto/payment_event_data_dto'
|
|
26
|
+
require_relative 'tinker/webhook/dto/subscription_event_data_dto'
|
|
27
|
+
require_relative 'tinker/webhook/dto/invoice_event_data_dto'
|
|
28
|
+
require_relative 'tinker/webhook/dto/settlement_event_data_dto'
|
|
29
|
+
require_relative 'tinker/webhook/webhook_meta'
|
|
30
|
+
require_relative 'tinker/webhook/webhook_security'
|
|
31
|
+
require_relative 'tinker/webhook/webhook_event'
|
|
32
|
+
require_relative 'tinker/webhook/webhook_handler'
|
|
33
|
+
require_relative 'tinker/payments'
|