afterpay 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.circleci/config.yml +24 -0
- data/.gitignore +13 -0
- data/.rspec +3 -0
- data/.rubocop.yml +5 -0
- data/.travis.yml +5 -0
- data/Gemfile +8 -0
- data/LICENSE +224 -0
- data/README.md +103 -0
- data/Rakefile +8 -0
- data/afterpay.gemspec +41 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/lib/afterpay/api/base.rb +37 -0
- data/lib/afterpay/api/configuration/retrieve.rb +20 -0
- data/lib/afterpay/api/configuration.rb +9 -0
- data/lib/afterpay/api/order/create.rb +27 -0
- data/lib/afterpay/api/order.rb +9 -0
- data/lib/afterpay/api/payment/auth.rb +29 -0
- data/lib/afterpay/api/payment/capture.rb +29 -0
- data/lib/afterpay/api/payment/deferred_capture.rb +30 -0
- data/lib/afterpay/api/payment/find.rb +28 -0
- data/lib/afterpay/api/payment/refund.rb +30 -0
- data/lib/afterpay/api/payment/void.rb +30 -0
- data/lib/afterpay/api/payment.rb +9 -0
- data/lib/afterpay/callable.rb +11 -0
- data/lib/afterpay/components/base.rb +14 -0
- data/lib/afterpay/components/consumer.rb +27 -0
- data/lib/afterpay/components/contact.rb +52 -0
- data/lib/afterpay/components/courier.rb +27 -0
- data/lib/afterpay/components/discount.rb +17 -0
- data/lib/afterpay/components/item.rb +48 -0
- data/lib/afterpay/components/merchant.rb +17 -0
- data/lib/afterpay/components/money.rb +17 -0
- data/lib/afterpay/components/order.rb +67 -0
- data/lib/afterpay/components/payment.rb +22 -0
- data/lib/afterpay/components/payment_event.rb +17 -0
- data/lib/afterpay/components/refund.rb +29 -0
- data/lib/afterpay/error_handler.rb +38 -0
- data/lib/afterpay/errors.rb +31 -0
- data/lib/afterpay/http_service/request.rb +46 -0
- data/lib/afterpay/http_service/response.rb +34 -0
- data/lib/afterpay/http_service.rb +30 -0
- data/lib/afterpay/initializable.rb +27 -0
- data/lib/afterpay/representable.rb +47 -0
- data/lib/afterpay/version.rb +5 -0
- data/lib/afterpay.rb +66 -0
- metadata +311 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Afterpay
|
4
|
+
module Components
|
5
|
+
class Courier < Base
|
6
|
+
# @attribute shipped_at
|
7
|
+
# @return [String]
|
8
|
+
# The time at which the order was shipped (ISO 8601 UTC/Zulu time).
|
9
|
+
attr_accessor :shipped_at
|
10
|
+
|
11
|
+
# @attribute name
|
12
|
+
# @return [String]
|
13
|
+
# The name of the courier.
|
14
|
+
attr_accessor :name
|
15
|
+
|
16
|
+
# @attribute tracking
|
17
|
+
# @return [String]
|
18
|
+
# The tracking number provided by the courier.
|
19
|
+
attr_accessor :tracking
|
20
|
+
|
21
|
+
# @attribute priority
|
22
|
+
# @return [String]
|
23
|
+
# The shipping priority. If provided, must be either 'STANDARD' or 'EXPRESS'.
|
24
|
+
attr_accessor :priority
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Afterpay
|
4
|
+
module Components
|
5
|
+
class Discount < Base
|
6
|
+
# @attribute display_name
|
7
|
+
# @return [String]
|
8
|
+
# A display name for the discount.
|
9
|
+
attr_accessor :display_name
|
10
|
+
|
11
|
+
# @attribute amount
|
12
|
+
# @return [Afterpay::Components::Money]
|
13
|
+
# The discount amount.
|
14
|
+
attr_accessor :amount
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Afterpay
|
4
|
+
module Components
|
5
|
+
class Item < Base
|
6
|
+
# @attribute name
|
7
|
+
# @return [String]
|
8
|
+
# Product's name
|
9
|
+
attr_accessor :name
|
10
|
+
|
11
|
+
# @attribute sku
|
12
|
+
# @return [String]
|
13
|
+
# Product's SKU
|
14
|
+
attr_accessor :sku
|
15
|
+
|
16
|
+
# @attribute page_url
|
17
|
+
# @return [String]
|
18
|
+
# The canonical URL for the item's Product Detail Page. Limited to 2048 characters.
|
19
|
+
attr_accessor :page_url
|
20
|
+
|
21
|
+
# @attribute image_url
|
22
|
+
# @return [String]
|
23
|
+
# A URL for a web-optimised photo of the item, suitable for use directly as the src attribute of an img tag. Limited to 2048 characters.
|
24
|
+
attr_accessor :image_url
|
25
|
+
|
26
|
+
# @attribute quantity
|
27
|
+
# @return [Integer]
|
28
|
+
# The quantity of the item.
|
29
|
+
attr_accessor :quantity
|
30
|
+
|
31
|
+
# @attribute price
|
32
|
+
# @return [Afterpay::Components::Money]
|
33
|
+
# The unit price of the individual item. Must be a positive value.
|
34
|
+
attr_accessor :price
|
35
|
+
|
36
|
+
# @attribute categories
|
37
|
+
# @return [Array]
|
38
|
+
# An array of arrays to accommodate multiple categories that apply to the item.
|
39
|
+
# Each array represents a hierarchical path to a category, with the left-most category being the top-level parent category.
|
40
|
+
attr_accessor :categories
|
41
|
+
|
42
|
+
# @attribute estimated_shipment_date
|
43
|
+
# @return [String]
|
44
|
+
# The estimated date when the order will be shipped, in YYYY-MM or YYYY-MM-DD format
|
45
|
+
attr_accessor :estimated_shipment_date
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Afterpay
|
4
|
+
module Components
|
5
|
+
class Merchant < Base
|
6
|
+
# @attribute redirect_confirm_url
|
7
|
+
# @return [String]
|
8
|
+
# The user is redirected to this URL on confirmation.
|
9
|
+
attr_accessor :redirect_confirm_url
|
10
|
+
|
11
|
+
# @attribute redirect_cancel_url
|
12
|
+
# @return [String]
|
13
|
+
# The user to redirected to this URL if the payment process is cancelled.
|
14
|
+
attr_accessor :redirect_cancel_url
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Afterpay
|
4
|
+
module Components
|
5
|
+
class Money < Base
|
6
|
+
# @attribute amount
|
7
|
+
# @return [String]
|
8
|
+
# The amount should be a string representation of a decimal number, rounded to 2 decimal places.
|
9
|
+
attr_accessor :amount
|
10
|
+
|
11
|
+
# @attribute currency
|
12
|
+
# @return [String]
|
13
|
+
# The currency is a ISO 4217 format value. Currently only USD is supported.
|
14
|
+
attr_accessor :currency
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Afterpay
|
4
|
+
module Components
|
5
|
+
class Order < Base
|
6
|
+
# @attribute amount
|
7
|
+
# @return [Afterpay::Components::Money]
|
8
|
+
# Total amount for order to be charged to consumer.
|
9
|
+
attr_accessor :amount
|
10
|
+
|
11
|
+
# @attribute consumer
|
12
|
+
# @return [Afterpay::Components::Consumer]
|
13
|
+
# The consumer requesting the order.
|
14
|
+
attr_accessor :consumer
|
15
|
+
|
16
|
+
# @attribute billing
|
17
|
+
# @return [Afterpay::Components::Contact]
|
18
|
+
# Billing address.
|
19
|
+
attr_accessor :billing
|
20
|
+
|
21
|
+
# @attribute shipping
|
22
|
+
# @return [Afterpay::Components::Contact]
|
23
|
+
# Shipping address.
|
24
|
+
attr_accessor :shipping
|
25
|
+
|
26
|
+
# @attribute courier
|
27
|
+
# @return [Afterpay::Components::Courier]
|
28
|
+
# Shipping Courier details.
|
29
|
+
attr_accessor :courier
|
30
|
+
|
31
|
+
# @attribute items
|
32
|
+
# @return [Array<Afterpay::Components::Item>]
|
33
|
+
# An array of order items.
|
34
|
+
attr_accessor :items
|
35
|
+
|
36
|
+
# @attribute discounts
|
37
|
+
# @return [Array<Afterpay::Components::Discount>]
|
38
|
+
# An array of discounts.
|
39
|
+
attr_accessor :discounts
|
40
|
+
|
41
|
+
# @attribute merchant
|
42
|
+
# @return [Afterpay::Components::Merchant]
|
43
|
+
# Merchant's redirection links..
|
44
|
+
attr_accessor :merchant
|
45
|
+
|
46
|
+
# @attribute payment_type
|
47
|
+
# @return [String]
|
48
|
+
# Supported payment types: 'PAY_BY_INSTALLMENT'. Default is 'PAY_BY_INSTALLMENT'.
|
49
|
+
attr_accessor :payment_type
|
50
|
+
|
51
|
+
# @attribute merchant_reference
|
52
|
+
# @return [String]
|
53
|
+
# The merchant's id / reference that this order corresponds to.
|
54
|
+
attr_accessor :merchant_reference
|
55
|
+
|
56
|
+
# @attribute tax_amount
|
57
|
+
# @return [Afterpay::Components::Money]
|
58
|
+
# The included tax amount after applying all discounts.
|
59
|
+
attr_accessor :tax_amount
|
60
|
+
|
61
|
+
# @attribute shipping_amount
|
62
|
+
# @return [Afterpay::Components::Money]
|
63
|
+
# The shipping amount.
|
64
|
+
attr_accessor :shipping_amount
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Afterpay
|
4
|
+
module Components
|
5
|
+
class Payment < Base
|
6
|
+
# @attribute token
|
7
|
+
# @return [String]
|
8
|
+
# The token returned in the order creation request.
|
9
|
+
attr_accessor :token
|
10
|
+
|
11
|
+
# @attribute merchant_reference
|
12
|
+
# @return [String]
|
13
|
+
# The merchant's order id / reference that this payment corresponds to
|
14
|
+
attr_accessor :merchant_reference
|
15
|
+
|
16
|
+
# @attribute amount
|
17
|
+
# @return [Afterpay::Components::Money]
|
18
|
+
# The refund amount.
|
19
|
+
attr_accessor :amount
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Afterpay
|
4
|
+
module Components
|
5
|
+
class PaymentEvent < Base
|
6
|
+
# @attribute created
|
7
|
+
# @return [String]
|
8
|
+
# The payment event creation time (ISO 8601 UTC/Zulu time).
|
9
|
+
attr_accessor :created
|
10
|
+
|
11
|
+
# @attribute type
|
12
|
+
# @return [String]
|
13
|
+
# The payment event type of {'AUTHORISE', 'CAPTURE', 'VOID'}
|
14
|
+
attr_accessor :type
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Afterpay
|
4
|
+
module Components
|
5
|
+
class Refund < Base
|
6
|
+
# @attribute request_id
|
7
|
+
# @return [String]
|
8
|
+
# A unique request ID, required for safe retries. It is recommended that the merchant generate a UUID for each
|
9
|
+
# unique refund.
|
10
|
+
attr_accessor :request_id
|
11
|
+
|
12
|
+
# @attribute merchant_reference
|
13
|
+
# @return [String]
|
14
|
+
# The merchant's refund id / reference that this refund corresponds to.
|
15
|
+
attr_accessor :merchant_reference
|
16
|
+
|
17
|
+
# @attribute refund_merchant_reference
|
18
|
+
# @return [String]
|
19
|
+
# A unique reference for the individual refund event. If provided, the value will appear in the daily settlement
|
20
|
+
# file as "Payment Event ID". Limited to 128 characters.
|
21
|
+
attr_accessor :refund_merchant_reference
|
22
|
+
|
23
|
+
# @attribute amount
|
24
|
+
# @return [Afterpay::Components::Money]
|
25
|
+
# The refund amount.
|
26
|
+
attr_accessor :amount
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'afterpay/errors'
|
4
|
+
|
5
|
+
module Afterpay
|
6
|
+
module ErrorHandler
|
7
|
+
class << self
|
8
|
+
# Returns a response if request was successful, raises an error otherwise
|
9
|
+
# @param [Afterpay::HTTPService::Response] response
|
10
|
+
# @return [Afterpay::HTTPService::Response] if request was successful
|
11
|
+
def inspect(response)
|
12
|
+
return response if response.ok?
|
13
|
+
|
14
|
+
raise ERRORS[response.status], response_message(response)
|
15
|
+
end
|
16
|
+
|
17
|
+
def response_message(response)
|
18
|
+
response.body.is_a?(String) ? JSON.parse(response.body)['message'] : response.message
|
19
|
+
end
|
20
|
+
|
21
|
+
ERRORS = {
|
22
|
+
400 => BadRequestError,
|
23
|
+
401 => UnathorizedError,
|
24
|
+
402 => PaymentRequiredError,
|
25
|
+
404 => NotFoundError,
|
26
|
+
405 => MethodNotAllowedError,
|
27
|
+
406 => NotAcceptableError,
|
28
|
+
409 => ConflictError,
|
29
|
+
410 => GoneError,
|
30
|
+
412 => PreconditionFailedError,
|
31
|
+
422 => UnprocessableEntityError,
|
32
|
+
429 => TooManyRequestsError,
|
33
|
+
500 => InternalServerError,
|
34
|
+
503 => ServiceUnavailableError
|
35
|
+
}.freeze
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Afterpay
|
4
|
+
class BaseError < StandardError; end
|
5
|
+
|
6
|
+
class BadRequestError < BaseError; end
|
7
|
+
|
8
|
+
class UnathorizedError < BaseError; end
|
9
|
+
|
10
|
+
class PaymentRequiredError < BaseError; end
|
11
|
+
|
12
|
+
class NotFoundError < BaseError; end
|
13
|
+
|
14
|
+
class MethodNotAllowedError < BaseError; end
|
15
|
+
|
16
|
+
class NotAcceptableError < BaseError; end
|
17
|
+
|
18
|
+
class ConflictError < BaseError; end
|
19
|
+
|
20
|
+
class GoneError < BaseError; end
|
21
|
+
|
22
|
+
class PreconditionFailedError < BaseError; end
|
23
|
+
|
24
|
+
class UnprocessableEntityError < BaseError; end
|
25
|
+
|
26
|
+
class TooManyRequestsError < BaseError; end
|
27
|
+
|
28
|
+
class InternalServerError < BaseError; end
|
29
|
+
|
30
|
+
class ServiceUnavailableError < BaseError; end
|
31
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'faraday'
|
4
|
+
|
5
|
+
module Afterpay
|
6
|
+
module HTTPService
|
7
|
+
class Request
|
8
|
+
# @attribute middleware
|
9
|
+
# @return [Proc] A proc containing Faraday configuration
|
10
|
+
attr_reader :middleware
|
11
|
+
|
12
|
+
# @attribute server
|
13
|
+
# @return [String] an API endpoint
|
14
|
+
attr_reader :server
|
15
|
+
|
16
|
+
# Creates Afterpay::HTTPService::Request instance
|
17
|
+
# @param [Hash] params hash of parameters
|
18
|
+
# @return [Afterpay::HTTPService::Request] Request instance
|
19
|
+
def initialize(params = {})
|
20
|
+
@middleware = params[:middleware]
|
21
|
+
@server = params[:server]
|
22
|
+
end
|
23
|
+
|
24
|
+
# Performs an HTTP request to the specified endpoint with given body
|
25
|
+
# @param [Hash] params hash of parameters.
|
26
|
+
# @return [Farday::Response] Faraday::Response instance
|
27
|
+
def perform(params = {})
|
28
|
+
adapter.send(*params.values_at(:action, :endpoint, :body))
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
# Creates memoized Faraday::Connection instance
|
34
|
+
# @return [Faraday::Connection] Faraday::Connection instance
|
35
|
+
def adapter
|
36
|
+
@adapter ||= Faraday.new(server, faraday_options, &middleware)
|
37
|
+
end
|
38
|
+
|
39
|
+
def faraday_options
|
40
|
+
return {} unless ::Afterpay.user_agent
|
41
|
+
|
42
|
+
{ "headers" => { "User-Agent" => ::Afterpay.user_agent } }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Afterpay
|
4
|
+
module HTTPService
|
5
|
+
class Response
|
6
|
+
extend Forwardable
|
7
|
+
# @attribute status
|
8
|
+
# @return [Integer] HTTP response status
|
9
|
+
attr_reader :status
|
10
|
+
|
11
|
+
# @attribute body
|
12
|
+
# @return [Hash] HTTP response body
|
13
|
+
attr_reader :body
|
14
|
+
|
15
|
+
# @attribute headers
|
16
|
+
# @return [Hash] HTTP response headers
|
17
|
+
attr_reader :headers
|
18
|
+
|
19
|
+
def_delegators :body, :message
|
20
|
+
# Creates Afterpay::HTTPService::Response instance
|
21
|
+
# @param [Hash] params hash of parameters
|
22
|
+
# @return [Afterpay::HTTPService::Response] Response instance
|
23
|
+
def initialize(params = {})
|
24
|
+
@status = params[:status]
|
25
|
+
@body = params[:body]
|
26
|
+
@headers = params[:headers]
|
27
|
+
end
|
28
|
+
|
29
|
+
def ok?
|
30
|
+
(200..201).cover?(status.to_i)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'faraday'
|
4
|
+
require 'faraday_middleware'
|
5
|
+
|
6
|
+
module Afterpay
|
7
|
+
module HTTPService
|
8
|
+
class << self
|
9
|
+
# @return [Hash] default HTTPService configuration
|
10
|
+
def configuration
|
11
|
+
{
|
12
|
+
middleware: DEFAULT_MIDDLEWARE,
|
13
|
+
server: ::Afterpay.server
|
14
|
+
}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Afterpay default middleware stack
|
19
|
+
DEFAULT_MIDDLEWARE = proc do |builder|
|
20
|
+
builder.request :json
|
21
|
+
|
22
|
+
builder.basic_auth(*::Afterpay.configuration.values)
|
23
|
+
|
24
|
+
builder.response :mashify
|
25
|
+
builder.response :json, content_type: /\bjson$/
|
26
|
+
|
27
|
+
builder.adapter Faraday.default_adapter
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|