zipMoney 1.0.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.
@@ -0,0 +1,46 @@
1
+ module ZipMoney
2
+ class Refund
3
+ include Request
4
+
5
+ attr_accessor :params
6
+
7
+ Struct.new("RefundParams", :reason, :refund_amount, :txn_id, :order_id, :quote_id, :order, :reference, :version, :metadata, :merchant_id, :merchant_key)
8
+
9
+ # Initializes a ZipMoney::Refund object
10
+ #
11
+ # Returns ZipMoney::Refund object
12
+ def initialize
13
+ @params = Struct::RefundParams.new
14
+ @params.order = Struct::Order.new
15
+ @params.metadata = Struct::Metadata.new
16
+ @params.version = Struct::Version.new
17
+ @params.order.detail = Array.new
18
+ end
19
+
20
+ # Performs the Refund api call on zipMoney endpoint
21
+ #
22
+ # Returns ZipMoney::Refund object
23
+ def do
24
+ validate
25
+ ZipMoney.api.refund(@params)
26
+ end
27
+
28
+ # Performs the parameters validation
29
+ def validate
30
+ raise ArgumentError, "Params emtpy" if @params.nil?
31
+ @errors = []
32
+ @errors << 'reason must be provided' if @params.reason.nil?
33
+ @errors << 'refund_amount must be provided' if @params.refund_amount.nil?
34
+ @errors << 'txn_id must be provided' if @params.txn_id.nil?
35
+ @errors << 'order.id must be provided' if @params.order.id.nil?
36
+ @errors << 'order.total must be provided' if @params.order.total.nil?
37
+ @errors << 'order.shipping_value must be provided' if @params.order.shipping_value.nil?
38
+ @errors << 'order.tax must be provided' if @params.order.tax.nil?
39
+ @errors << 'order detail must be provided' if @params.order.detail.nil?
40
+
41
+ validate_item_details @params.order.detail
42
+
43
+ raise ZipMoney::RequestError.new("Following error(s) occurred while making request, please resolve them to make the request: #{@errors}") if @errors.any?
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,16 @@
1
+ module ZipMoney
2
+ class Settings
3
+ include Request
4
+
5
+ attr_accessor :params
6
+
7
+ Struct.new("SettingsParams", :merchant_id, :merchant_key, :version, :metadata)
8
+
9
+ # Performs the Checkout api call on zipMoney endpoint
10
+ #
11
+ # Returns ZipMoney::Checkout object
12
+ def do
13
+ ZipMoney.api.settings()
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,49 @@
1
+ module ZipMoney
2
+ class Configuration
3
+
4
+ API_VERSION = "1.0.1"
5
+ API_PLATFORM = "ruby"
6
+ API_NAME = "zipMoney Ruby SDK"
7
+
8
+ ENV_LIVE_API_URL = "https://api.zipmoney.com.au/v1/"
9
+ ENV_TEST_API_URL = "https://api.sandbox.zipmoney.com.au/v1/"
10
+
11
+ ATTRIBUTES = [
12
+ :merchant_id,
13
+ :merchant_key,
14
+ :environment,
15
+ ]
16
+
17
+ attr_accessor *ATTRIBUTES
18
+
19
+ class << self
20
+ attr_accessor *ATTRIBUTES
21
+
22
+ # Checks if passed value is valid and assigns it true
23
+ #
24
+ # @param [env] Environment sandbox|live
25
+ #
26
+ # @return true|false
27
+ def environment=(env)
28
+ env = env.to_sym
29
+ raise ArgumentError, "#{env.inspect} is not a valid environment" unless [:sandbox, :live].include?(env)
30
+ @environment = env
31
+ end
32
+
33
+ # Checks if environment is sandbox
34
+ #
35
+ # @return true|false
36
+ def is_sandbox
37
+ environment.to_s == "sandbox"
38
+ end
39
+
40
+ # Checks if passed merchant_id and merchant_key match with the one provided during setup
41
+ #
42
+ # @param [merchant_id] Merchant Id
43
+ # @param [merchant_key] Merchant Key
44
+ def credentials_valid(merchant_id,merchant_key)
45
+ raise ExpressError, "Invalid merchant credentials in the request" unless @merchant_id.to_i.eql?(merchant_id.to_i) && @merchant_key.to_s.eql?(merchant_key.to_s)
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,11 @@
1
+ module ZipMoney
2
+ class ApiError < StandardError; end
3
+ class InvalidArgumentError < StandardError; end
4
+ class RequestError < StandardError; end
5
+ class ResponseError < StandardError; end
6
+ class WebHookError < StandardError; end
7
+ class WebHookRequestError < StandardError; end
8
+ class ExpressError < StandardError; end
9
+ class ExpressRequestError < StandardError; end
10
+ class ExpressResponseError < StandardError; end
11
+ end
@@ -0,0 +1,65 @@
1
+ module ZipMoney
2
+ module Express
3
+ attr_accessor :merchant_id, :merchant_key
4
+
5
+ ACTION_GET_QUOTE_DETAILS = 'quotedetails';
6
+ ACTION_GET_SHIPPING_METHODS = 'shippingmethods';
7
+ ACTION_CONFIRM_SHIPPING_METHOD = 'confirmshippingmethod';
8
+ ACTION_CONFIRM_ORDER = 'confirmorder';
9
+ ACTION_FINALISE_ORDER = 'finaliseorder';
10
+ ACTION_CANCEL_QUOTE = 'cancelquote';
11
+
12
+ # Process the express checkout action
13
+ #
14
+ # @param [action] Action
15
+ # @param [request] Express checkout request
16
+ # @param [block] Actions to be taken for respective actions
17
+ #
18
+ # Returns the response to the zipMoney Express Api
19
+ def self.process(action, request, &block)
20
+ raise ExpressRequestError, "Action empty" if action.nil?
21
+ raise ExpressRequestError, "Request empty" if request.nil?
22
+ request = Util.json_parse(request)
23
+ Configuration.credentials_valid(request["merchant_id"], request["merchant_key"])
24
+ if (block.arity > 0)
25
+ response = block.call(action, request)
26
+ raise ExpressResponseError, "No response provided" if response.nil?
27
+ puts send_response(response)
28
+ end
29
+ end
30
+
31
+ # Appends api credentials to the express checkout response
32
+ #
33
+ # @param [response] response
34
+ def self.append_api_credentials(response)
35
+ response = Hash.new if !response.is_a?(Hash)
36
+
37
+ if response["merchant_id"] == nil
38
+ response["merchant_id"] = Configuration.merchant_id
39
+ end
40
+
41
+ if response["merchant_key"] == nil
42
+ response["merchant_key"] = Configuration.merchant_key
43
+ end
44
+ response
45
+ end
46
+
47
+ # Prepars the express checkout response
48
+ #
49
+ # @param [response] response
50
+ def self.prepare_response(response)
51
+ response = Util.json_parse(response)
52
+ append_api_credentials(response)
53
+ end
54
+
55
+ # Prints the express checkout response
56
+ #
57
+ # @param [response] response
58
+ def self.send_response(response)
59
+ prepare_response(response).to_json
60
+ end
61
+ end
62
+ end
63
+
64
+
65
+
@@ -0,0 +1,22 @@
1
+ module ZipMoney
2
+ module Request
3
+ Struct.new("Order", :id, :tax, :shipping_value, :total, :detail)
4
+ Struct.new("Detail", :quantity, :name, :price, :description, :sku, :id, :category, :image_url)
5
+ Struct.new("Address",:first_name, :last_name, :line1, :line2, :country, :zip, :city, :state)
6
+ Struct.new("Consumer",:first_name, :last_name,:city, :phone, :gender, :dob, :email, :title)
7
+ Struct.new("Metadata",:order_reference, :attributes)
8
+ Struct.new("Version",:client, :platform)
9
+ Struct.new("ApiCredentials",:merchant_id, :merchant_key, :version)
10
+
11
+ attr_accessor :errors
12
+
13
+ def validate_item_details(order_items)
14
+ order_items.each_with_index do |item,index|
15
+ @errors << "order.detail[#{index}].id must be provided" if item.id.nil?
16
+ @errors << "order.detail[#{index}].name must be provided" if item.name.nil?
17
+ @errors << "order.detail[#{index}].quantity must be provided" if item.quantity.nil?
18
+ @errors << "order.detail[#{index}].price must be provided" if item.price.nil?
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,71 @@
1
+ module ZipMoney
2
+ class Resources
3
+
4
+ RESOURCE_SETTINGS = 'settings'
5
+ RESOURCE_CONFIGURE = 'configure'
6
+ RESOURCE_QUOTE = 'quote'
7
+ RESOURCE_CANCEL = 'cancel'
8
+ RESOURCE_REFUND = 'refund'
9
+ RESOURCE_CHECKOUT = 'checkout'
10
+ RESOURCE_QUERY = 'query'
11
+ RESOURCE_CAPTURE = 'capture'
12
+ RESOURCE_HEART_BEAT = 'Heartbeat'
13
+
14
+ class << self
15
+ # Checks if passed resource is valid and returns RestClient::Resource object
16
+ # configured with the passed resource and url
17
+ #
18
+ # @param [resource] endpoint resource
19
+ # @param [method] method get|post
20
+ # @param [query_string] query_string parameters
21
+ #
22
+ # @return RestClient::Resource object
23
+ def get(resource, method = :post, query_string = nil)
24
+ return false unless resource_exists(resource)
25
+ url = get_url(resource, (method == :get ? query_string : nil))
26
+ ssl_opts = {:verify_ssl => OpenSSL::SSL::VERIFY_PEER}
27
+ opts = {}
28
+ RestClient::Resource.new(url, opts.merge(ssl_opts))
29
+ end
30
+
31
+ # Checks if passed resource exists
32
+ #
33
+ # @param [resource] endpoint resource
34
+ #
35
+ # @return ZipMoney::Response object
36
+ def resource_exists(resource)
37
+ if resource.is_a?(String)
38
+ if self.constants.map{ |k| self.const_get(k).downcase }.include?resource
39
+ resource
40
+ end
41
+ else
42
+ raise ArgumentError, "#{resource} should be a string"
43
+ end
44
+ end
45
+
46
+ # Builds the proper endpoint url with the given resource
47
+ #
48
+ # @param [resource] endpoint resource
49
+ # @param [query_string] query_string parameters
50
+ #
51
+ # @return String
52
+ def get_url(resource, query_string = nil)
53
+ if Configuration.is_sandbox
54
+ url = "#{Configuration::ENV_TEST_API_URL}"
55
+ else
56
+ url = "#{Configuration::ENV_LIVE_API_URL}"
57
+ end
58
+
59
+ url = url + resource
60
+
61
+ unless query_string.nil?
62
+ url = url + "?" +
63
+ query_string.map do |key, value|
64
+ "#{key}=#{value}"
65
+ end.join("&")
66
+ end
67
+ url
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,68 @@
1
+ module ZipMoney
2
+ class Response
3
+
4
+ attr_accessor :_response , :_responseBody, :_responseHeader, :_statusCode
5
+
6
+ # Initializes a new api response object
7
+ #
8
+ # @param [response] response
9
+ #
10
+ # @return ZipMoney::Response object
11
+ def initialize(response)
12
+ raise ArgumentError, "Response doesnot exist" if ((response.nil? || response.empty?) && response.code.nil? && response.code.empty?)
13
+ @_response = response
14
+ @_statusCode = response.code
15
+ @_responseBody = response.body
16
+ end
17
+
18
+ # Converts the response body to Hash
19
+ #
20
+ # @return Hash
21
+ def toHash
22
+ raise ResponseError, "Response body doesnot exist" if @_responseBody.nil? || @_responseBody.empty?
23
+ JSON.parse(@_responseBody)
24
+ end
25
+
26
+ # Converts the response body to Object
27
+ #
28
+ # @return OpenStruct
29
+ def toObject
30
+ raise ResponseError, "Response body doesnot exist" if @_responseBody.nil? || @_responseBody.empty?
31
+ responseObject = JSON.parse(@_responseBody, object_class: OpenStruct)
32
+ responseObject
33
+ end
34
+
35
+ # Returns the redirect_url from the checkout and quote calls
36
+ #
37
+ # @return String
38
+ def getRedirectUrl
39
+ raise ArgumentError, "Response body doesnot exist" if @_responseBody.nil? || @_responseBody.empty?
40
+ resObj = toObject
41
+ return false if resObj.redirect_url.nil? || resObj.redirect_url.empty?
42
+ resObj.redirect_url
43
+ end
44
+
45
+ # Returns the http status code
46
+ #
47
+ # @return Int
48
+ def getStatusCode
49
+ @_statusCode
50
+ end
51
+
52
+ # Returns if the api call was a success or failure
53
+ #
54
+ # @return true|false
55
+ def isSuccess
56
+ return @_statusCode == 200 || @_statusCode == 201? true : false
57
+ end
58
+
59
+ # Returns error string
60
+ #
61
+ # @return String
62
+ def getError
63
+ raise ArgumentError, "Response body doesnot exist" if @_responseBody.nil? || @_responseBody.empty?
64
+ resObj = toObject
65
+ resObj.Message
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,53 @@
1
+ module ZipMoney
2
+ class Util
3
+ class << self
4
+
5
+ # Converts Struct objects to Hash
6
+ #
7
+ # @param [object] Struct Object
8
+ #
9
+ # @return Hash
10
+ def struct_to_hash(object)
11
+ hash = {}
12
+ object.to_h.each do |k,v|
13
+ if v.is_a?(Struct)
14
+ v = struct_to_hash(v)
15
+ hash[k] = v unless v.empty?
16
+ elsif v.is_a?(Array)
17
+
18
+ a = Array.new
19
+ v.each_with_index do |k1,v1|
20
+ v2 = struct_to_hash(k1)
21
+ a[v1] = v2 unless v2.empty?
22
+ end
23
+
24
+ hash[k] = a
25
+ else
26
+ hash[k] = v unless v.nil?
27
+ end
28
+ end
29
+ hash
30
+ end
31
+
32
+ # Converts Hash|Struct|OpenStruct objects to Hash
33
+ #
34
+ # @param [data] Json String
35
+ #
36
+ # @return data
37
+ def json_parse(data)
38
+ begin
39
+ data = JSON.parse(data)
40
+ rescue TypeError => e
41
+ if !data.is_a?(Hash) && !data.is_a?(Struct) && !data.is_a?(OpenStruct)
42
+ raise ArgumentError, "Invalid params provided"
43
+ end
44
+ rescue JSON::ParserError => e
45
+ if !data.is_a?(Hash) && !data.is_a?(Struct) && !data.is_a?(OpenStruct)
46
+ raise ArgumentError, "Invalid params provided"
47
+ end
48
+ end
49
+ data
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,3 @@
1
+ module ZipMoney
2
+ VERSION = "1.0.1"
3
+ end
@@ -0,0 +1,67 @@
1
+ module ZipMoney
2
+ module WebHook
3
+ attr_accessor :merchant_id, :merchant_key
4
+
5
+ EVENT_AUTH_SUCCESS = "authorise_succeeded"
6
+ EVENT_AUTH_FAIL = "authorise_failed"
7
+ EVENT_AUTH_REVIEW = "authorise_under_review"
8
+ EVENT_AUTH_DECLINED = "authorise_declined"
9
+ EVENT_CANCEL_SUCCESS = "cancel_succeeded"
10
+ EVENT_CANCEL_FAIL = "cancel_failed"
11
+ EVENT_CAPTURE_SUCCESS = "capture_succeeded"
12
+ EVENT_CAPTURE_FAIL = "capture_failed"
13
+ EVENT_REFUND_SUCCESS = "refund_succeeded"
14
+ EVENT_REFUND_FAIL = "refund_failed"
15
+ EVENT_ORDER_CANCELLED = "order_cancelled"
16
+ EVENT_CHARGE_SUCCESS = "charge_succeeded"
17
+ EVENT_CHARGE_FAIL = "charge_failed"
18
+ EVENT_CONFIG_UPDATE = "configuration_updated"
19
+
20
+ TYPE_SUBSCRIPTION_CONFIRMATION = "SubscriptionConfirmation"
21
+ TYPE_NOTIFICATION = "Notification"
22
+
23
+ # Process the webhook
24
+ #
25
+ # @param [request] WebHook's request
26
+ # @param [block] Actions to be taken for respective notifications
27
+ def self.process(request,&block)
28
+ raise WebHookRequestError, "Payload emtpy" if request.nil?
29
+ request = Util.json_parse(request)
30
+ if request["Type"] == TYPE_SUBSCRIPTION_CONFIRMATION
31
+ subscribe(request["SubscribeURL"])
32
+ elsif request["Type"] == TYPE_NOTIFICATION
33
+ process_notifications(request, &block)
34
+ end
35
+ end
36
+
37
+ # Process the webhook notifications
38
+ #
39
+ # @param [request] WebHook's request
40
+ # @param [block] Actions to be taken for respective notifications
41
+ def self.process_notifications(request, &block)
42
+ raise ArgumentError, "Invalid params provided" if request["Message"].nil?
43
+ message = Util.json_parse(request["Message"])
44
+ Configuration.credentials_valid(message["response"]["merchant_id"], message["response"]["merchant_key"])
45
+ raise ArgumentError, "Response empty" if message["response"].nil?
46
+
47
+ if (block.arity > 0)
48
+ block.call(message['type'], message["response"])
49
+ end
50
+ end
51
+
52
+ # Subscribes for the webhook notifications by calling the subscription url
53
+ #
54
+ # @param [request] WebHook's request
55
+ # @param [block] Actions to be taken for respective notifications
56
+ def self.subscribe(url)
57
+ raise WebHookError, "Url emtpy" if url.nil?
58
+
59
+ begin
60
+ response = RestClient.get(url)
61
+ rescue
62
+ raise WebHookError, "Unable to reach the subscription url #{url}" if response.nil?
63
+ end
64
+ response.code == 200 || response.code == 201
65
+ end
66
+ end
67
+ end