zipMoney 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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