fawry 0.2.0 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 801fa2ec9cada4bf14b44b1733ff0010eae8c26ccc72ed23c500ae0b55ff6e30
4
- data.tar.gz: c48087c1e6f133664be53c2e2d28d6a6b228379367eb4817a88e9d2ef9b5a669
3
+ metadata.gz: 5b36b534916d6923f8bc715652eac726e83e4d5bac78dc5ae3aabb2af08a28d7
4
+ data.tar.gz: 4cb3e3db3f83c80b130e2de91a43f85f4e489876b90a7f2dbedcf7417b53bbb2
5
5
  SHA512:
6
- metadata.gz: b721a5d9d20bf0a7c4faccc2d6db668b9c3aae73fbffec5c3a917b9463ac6753b3e28189674d749239f6065f659e938b44c9bd3cb8588d57af83d8cfd114808a
7
- data.tar.gz: 97a8f8acf8eb6c41531a8b1ef8d72a26f650d95b0cb9ad5a41deb306f152b0d8d70ece22f4c6284e218de04311d2ba187d434fe3ba07844948428cded4a7feda
6
+ metadata.gz: e049a63ce51c39786f674160e66b044ff0d72dd1c3e52fe4f0abb7aa829c99b16238f329f9a83e2ae3840609799d80160227b74874b610dd27bba6d9eaad4c84
7
+ data.tar.gz: 8dc4bd0949b640b3ab99a141938677351ec7c03ccf8c0b8b9297acfdb54b5ade84a97185accc39eb289667789df4fcbd4bcc04f3da34c01acc2466384292d84c
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fawry (0.2.0)
4
+ fawry (0.3.0)
5
5
  dry-validation (~> 1.3, >= 1.3.1)
6
6
  faraday (~> 0.17.0)
7
7
 
data/README.md CHANGED
@@ -3,7 +3,7 @@ A plug-and-play library that makes interfacing with Fawry's payment gateway API
3
3
  - [Charge customers](https://github.com/fawry-api/fawry#charge-customers)
4
4
  - [Refund customers](https://github.com/fawry-api/fawry#refund-customers)
5
5
  - [Get payment status](https://github.com/fawry-api/fawry#get-payment-status)
6
- - Parse Fawry's service callback V2 _(Not yet implemented)_
6
+ - [Parse Fawry's service callback V2](https://github.com/fawry-api/fawry#parse-fawry-service-callback-v2)
7
7
 
8
8
  _Fawry's production and sandbox environments are supported._
9
9
 
@@ -78,6 +78,26 @@ res = Fawry.payment_status(params, sandbox: true)
78
78
  res.success? # => true
79
79
  res.payment_status # => UNPAID
80
80
  ```
81
+
82
+ ### Parse Fawry service callback v2
83
+ ```ruby
84
+ callback_params = { "requestId": 'c72827d084ea4b88949d91dd2db4996e', "fawryRefNumber": '970177',
85
+ "merchantRefNumber": '9708f1cea8b5426cb57922df51b7f790',
86
+ "customerMobile": '01004545545', "customerMail": 'fawry@fawry.com',
87
+ "paymentAmount": 152.00, "orderAmount": 150.00, "fawryFees": 2.00,
88
+ "shippingFees": '', "orderStatus": 'NEW', "paymentMethod": 'PAYATFAWRY',
89
+ "messageSignature": 'b0175565323e464b01dc9407160368af5568196997fb6e379374a4f4fbbcf587',
90
+ "orderExpiryDate": 1_533_554_719_314,
91
+ "orderItems": [{ "itemCode": 'e6aacbd5a498487ab1a10ae71061535d', "price": 150.0, "quantity": 1 }] }
92
+
93
+ fawry_callback = Fawry.parse_callback(callback_params, 'fawry_secure_key')
94
+ # <Fawry::FawryCallback:0x000056339ac43730 @request_id="c72827d084ea4b88949d91dd2db4996e", @fawry_ref_number="970177",
95
+ # @merchant_ref_number="9708f1cea8b5426cb57922df51b7f790", @customer_mobile="01004545545",
96
+ # @customer_mail="fawry@fawry.com", @order_status="NEW", @order_amount=150.0, @fawry_fees=2.0, ...>
97
+
98
+ fawry_callback.fawry_ref_number # => 970177
99
+ fawry_callback.order_status # => NEW
100
+ ```
81
101
  ## Development
82
102
 
83
103
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -3,8 +3,10 @@
3
3
  require 'fawry/version'
4
4
  require 'fawry/connection'
5
5
  require 'fawry/errors'
6
+ require 'fawry/utils'
6
7
  require 'fawry/fawry_request'
7
8
  require 'fawry/fawry_response'
9
+ require 'fawry/fawry_callback'
8
10
  require 'fawry/requests/charge_request'
9
11
  require 'fawry/requests/refund_request'
10
12
  require 'fawry/requests/payment_status_request'
@@ -45,7 +47,7 @@ module Fawry
45
47
  # false by default
46
48
  # Example: `Fawry.charge(params, sandbox: true)`
47
49
  #
48
- # @raise [Fawry::InvalidFawryRequest] raised when one
50
+ # @raise [Fawry::InvalidFawryRequestError] raised when one
49
51
  # or more of the params are invalid. the message
50
52
  # specifices which params and why are they invalid
51
53
  #
@@ -73,7 +75,7 @@ module Fawry
73
75
  # send the request to fawry sandbox env or not
74
76
  # false by default
75
77
  #
76
- # @raise [Fawry::InvalidFawryRequest] raised when one
78
+ # @raise [Fawry::InvalidFawryRequestError] raised when one
77
79
  # or more of the params are invalid. the message
78
80
  # specifices which params and why are they invalid
79
81
  #
@@ -99,7 +101,7 @@ module Fawry
99
101
  # send the request to fawry sandbox env or not
100
102
  # false by default
101
103
  #
102
- # @raise [Fawry::InvalidFawryRequest] raised when one
104
+ # @raise [Fawry::InvalidFawryRequestError] raised when one
103
105
  # or more of the params are invalid. the message
104
106
  # specifices which params and why are they invalid
105
107
  #
@@ -109,5 +111,25 @@ module Fawry
109
111
  def payment_status(params, opts = {})
110
112
  FawryRequest.new('payment_status', params, opts).fire_payment_status_request
111
113
  end
114
+
115
+ # Parses Fawry callback v2 into
116
+ # FawryCallback object with callback
117
+ # params as instance methods
118
+ #
119
+ # @param params [Hash] list of params sent
120
+ # from fawry server callback
121
+ #
122
+ # @param opts [Hash] list of options to
123
+ # configure the request. currently no
124
+ # options available
125
+ #
126
+ # @raise [Fawry::InvalidSignatureError] raised when
127
+ # request signature cannot be verified
128
+ #
129
+ # @return [Fawry::FawryCallback] an object that
130
+ # has Fawry server callback params' keys as instance methods
131
+ def parse_callback(params, fawry_secure_key, opts = {})
132
+ FawryCallback.new(params, fawry_secure_key, opts).parse
133
+ end
112
134
  end
113
135
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fawry
4
- class InvalidFawryRequest < StandardError; end
4
+ class InvalidFawryRequestError < StandardError; end
5
+ class InvalidSignatureError < StandardError; end
5
6
  end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fawry
4
+ class FawryCallback
5
+ include Utils
6
+
7
+ attr_reader :callback_params, :fawry_secure_key, :options
8
+
9
+ def initialize(callback_params, fawry_secure_key, opts)
10
+ @callback_params = callback_params
11
+ @fawry_secure_key = fawry_secure_key
12
+ @options = opts
13
+ end
14
+
15
+ def parse
16
+ verify_callback_signature!
17
+ build_callback
18
+
19
+ self
20
+ end
21
+
22
+ private
23
+
24
+ # Adds keys from fawry API response as methods
25
+ # on FawryCallback instance that return the value
26
+ # of each key
27
+ #
28
+ # type => type
29
+ # referenceNumber => reference_number
30
+ # merchantRefNumber => merchant_ref_number
31
+ # expirationTime => expiration_time
32
+ # statusCode => status_code
33
+ # statusDescription => status_description
34
+ #
35
+ # fawry_callback = FawryCallback.new(callback_params, fawry_secure_key)
36
+ # fawry_callback.order_status => PAID
37
+ # fawry_callback.fawry_ref_number => 1234567
38
+ def build_callback
39
+ enrich_object(callback_params)
40
+ end
41
+
42
+ def verify_callback_signature!
43
+ raise InvalidSignatureError, 'Invalid Signature' unless signature == callback_params[:messageSignature]
44
+ end
45
+
46
+ # rubocop:disable Metrics/AbcSize
47
+ def signature
48
+ Digest::SHA256.hexdigest("#{callback_params[:fawryRefNumber]}#{callback_params[:merchantRefNum]}"\
49
+ "#{format('%<paymentAmount>.2f', paymentAmount: callback_params[:paymentAmount])}"\
50
+ "#{format('%<orderAmount>.2f', orderAmount: callback_params[:orderAmount])}"\
51
+ "#{callback_params[:orderStatus]}#{callback_params[:paymentMethod]}"\
52
+ "#{callback_params[:paymentRefrenceNumber]}#{fawry_secure_key}")
53
+ end
54
+ # rubocop:enable Metrics/AbcSize
55
+ end
56
+ end
@@ -2,6 +2,8 @@
2
2
 
3
3
  module Fawry
4
4
  class FawryResponse
5
+ include Utils
6
+
5
7
  attr_reader :fawry_api_response
6
8
 
7
9
  def initialize(fawry_api_response)
@@ -39,13 +41,7 @@ module Fawry
39
41
  # fawry_res.status_code => 200
40
42
  # fawry_res.reference_number => 1234567
41
43
  def build_response
42
- fawry_api_response.keys.each do |key|
43
- method_name = key.split(/(?=[A-Z])/).map(&:downcase).join('_') # statusCode => status_code
44
- instance_variable_set("@#{method_name}", fawry_api_response[key])
45
- method_body = proc { instance_variable_get("@#{method_name}") }
46
-
47
- self.class.public_send(:define_method, method_name, method_body)
48
- end
44
+ enrich_object(fawry_api_response)
49
45
  end
50
46
  end
51
47
  end
@@ -53,7 +53,7 @@ module Fawry
53
53
 
54
54
  def validate_charge_params!
55
55
  contract = Contracts::ChargeRequestContract.new.call(request_params)
56
- raise InvalidFawryRequest, contract.errors.to_h if contract.failure?
56
+ raise InvalidFawryRequestError, contract.errors.to_h if contract.failure?
57
57
  end
58
58
 
59
59
  def charge_items
@@ -37,7 +37,7 @@ module Fawry
37
37
 
38
38
  def validate_payment_status_params!
39
39
  contract = Contracts::PaymentStatusRequestContract.new.call(request_params)
40
- raise InvalidFawryRequest, contract.errors.to_h if contract.failure?
40
+ raise InvalidFawryRequestError, contract.errors.to_h if contract.failure?
41
41
  end
42
42
 
43
43
  def payment_status_request_signature
@@ -39,7 +39,7 @@ module Fawry
39
39
 
40
40
  def validate_refund_params!
41
41
  contract = Contracts::RefundRequestContract.new.call(request_params)
42
- raise InvalidFawryRequest, contract.errors.to_h if contract.failure?
42
+ raise InvalidFawryRequestError, contract.errors.to_h if contract.failure?
43
43
  end
44
44
 
45
45
  def refund_request_signature
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fawry
4
+ module Utils
5
+ # Adds keys from fawry API response as methods
6
+ # on object instance that return the value
7
+ # of each key
8
+ #
9
+ # type => type
10
+ # referenceNumber => reference_number
11
+ # merchantRefNumber => merchant_ref_number
12
+ # expirationTime => expiration_time
13
+ # statusCode => status_code
14
+ # statusDescription => status_description
15
+ #
16
+ # fawry_res = FawryResponse.new(response)
17
+ # fawry_res.status_code => 200
18
+ # fawry_res.reference_number => 1234567
19
+ def enrich_object(fawry_params)
20
+ fawry_params.keys.each do |key|
21
+ method_name = key.to_s.split(/(?=[A-Z])/).map(&:downcase).join('_') # statusCode => status_code
22
+ instance_variable_set("@#{method_name}", fawry_params[key])
23
+ method_body = proc { instance_variable_get("@#{method_name}") }
24
+
25
+ self.class.public_send(:define_method, method_name, method_body)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fawry
4
- VERSION = '0.2.0'
4
+ VERSION = '0.3.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fawry
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Amr Bakry
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-11-07 00:00:00.000000000 Z
11
+ date: 2019-11-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-validation
@@ -152,11 +152,13 @@ files:
152
152
  - lib/fawry/contracts/payment_status_request_contract.rb
153
153
  - lib/fawry/contracts/refund_request_contract.rb
154
154
  - lib/fawry/errors.rb
155
+ - lib/fawry/fawry_callback.rb
155
156
  - lib/fawry/fawry_request.rb
156
157
  - lib/fawry/fawry_response.rb
157
158
  - lib/fawry/requests/charge_request.rb
158
159
  - lib/fawry/requests/payment_status_request.rb
159
160
  - lib/fawry/requests/refund_request.rb
161
+ - lib/fawry/utils.rb
160
162
  - lib/fawry/version.rb
161
163
  homepage: https://github.com/amrrbakry/fawry
162
164
  licenses: