fawry 0.1.0 → 0.2.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 +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +20 -3
- data/fawry.gemspec +1 -0
- data/lib/fawry.rb +30 -2
- data/lib/fawry/connection.rb +26 -0
- data/lib/fawry/contracts/payment_status_request_contract.rb +15 -0
- data/lib/fawry/fawry_request.rb +6 -0
- data/lib/fawry/requests/charge_request.rb +7 -1
- data/lib/fawry/requests/payment_status_request.rb +49 -0
- data/lib/fawry/requests/refund_request.rb +1 -1
- data/lib/fawry/version.rb +1 -1
- metadata +6 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 801fa2ec9cada4bf14b44b1733ff0010eae8c26ccc72ed23c500ae0b55ff6e30
|
|
4
|
+
data.tar.gz: c48087c1e6f133664be53c2e2d28d6a6b228379367eb4817a88e9d2ef9b5a669
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b721a5d9d20bf0a7c4faccc2d6db668b9c3aae73fbffec5c3a917b9463ac6753b3e28189674d749239f6065f659e938b44c9bd3cb8588d57af83d8cfd114808a
|
|
7
|
+
data.tar.gz: 97a8f8acf8eb6c41531a8b1ef8d72a26f650d95b0cb9ad5a41deb306f152b0d8d70ece22f4c6284e218de04311d2ba187d434fe3ba07844948428cded4a7feda
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Fawry
|
|
2
2
|
A plug-and-play library that makes interfacing with Fawry's payment gateway API a breeze:
|
|
3
|
-
- [Charge customers](https://github.com/
|
|
4
|
-
- [Refund customers](https://github.com/
|
|
5
|
-
- Get payment status
|
|
3
|
+
- [Charge customers](https://github.com/fawry-api/fawry#charge-customers)
|
|
4
|
+
- [Refund customers](https://github.com/fawry-api/fawry#refund-customers)
|
|
5
|
+
- [Get payment status](https://github.com/fawry-api/fawry#get-payment-status)
|
|
6
6
|
- Parse Fawry's service callback V2 _(Not yet implemented)_
|
|
7
7
|
|
|
8
8
|
_Fawry's production and sandbox environments are supported._
|
|
@@ -61,6 +61,23 @@ res = Fawry.refund(params, sandbox: true)
|
|
|
61
61
|
|
|
62
62
|
res.success? # => true
|
|
63
63
|
```
|
|
64
|
+
|
|
65
|
+
### Get Payment Status
|
|
66
|
+
```ruby
|
|
67
|
+
params = { "merchant_code": 'merchant_code',
|
|
68
|
+
"merchant_ref_number": 'ssshxb98phmyvm434es62kage3nsm2cj',
|
|
69
|
+
"fawry_secure_key": 'fawry_secure_key' }
|
|
70
|
+
|
|
71
|
+
res = Fawry.payment_status(params, sandbox: true)
|
|
72
|
+
# => #<Fawry::FawryResponse:0x0000559974056898 @type="PaymentStatusResponse", @reference_number="931922417",
|
|
73
|
+
# @merchant_ref_number="ssshxb98phmyvm434es62kage3nsm2cj",
|
|
74
|
+
# @expiration_time=1573297736167, @status_code=200,
|
|
75
|
+
# @status_description="Operation done successfully", @payment_amount=20,
|
|
76
|
+
# @payment_method="PAYATFAWRY", @payment_status="UNPAID">
|
|
77
|
+
|
|
78
|
+
res.success? # => true
|
|
79
|
+
res.payment_status # => UNPAID
|
|
80
|
+
```
|
|
64
81
|
## Development
|
|
65
82
|
|
|
66
83
|
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.
|
data/fawry.gemspec
CHANGED
|
@@ -14,6 +14,7 @@ Gem::Specification.new do |spec|
|
|
|
14
14
|
service callback)."
|
|
15
15
|
spec.homepage = 'https://github.com/amrrbakry/fawry'
|
|
16
16
|
spec.license = 'MIT'
|
|
17
|
+
spec.required_ruby_version = '~> 2.6'
|
|
17
18
|
|
|
18
19
|
spec.metadata['homepage_uri'] = 'https://github.com/amrrbakry/fawry'
|
|
19
20
|
spec.metadata['source_code_uri'] = 'https://github.com/amrrbakry/fawry'
|
data/lib/fawry.rb
CHANGED
|
@@ -7,8 +7,10 @@ require 'fawry/fawry_request'
|
|
|
7
7
|
require 'fawry/fawry_response'
|
|
8
8
|
require 'fawry/requests/charge_request'
|
|
9
9
|
require 'fawry/requests/refund_request'
|
|
10
|
+
require 'fawry/requests/payment_status_request'
|
|
10
11
|
require 'fawry/contracts/charge_request_contract'
|
|
11
12
|
require 'fawry/contracts/refund_request_contract'
|
|
13
|
+
require 'fawry/contracts/payment_status_request_contract'
|
|
12
14
|
|
|
13
15
|
module Fawry
|
|
14
16
|
class << self
|
|
@@ -51,7 +53,7 @@ module Fawry
|
|
|
51
53
|
# has Fawry API response keys as instance methods
|
|
52
54
|
# plus some convenience methods e.g. success?
|
|
53
55
|
def charge(params, opts = {})
|
|
54
|
-
FawryRequest.new('charge', params, opts).
|
|
56
|
+
FawryRequest.new('charge', params, opts).fire_charge_request
|
|
55
57
|
end
|
|
56
58
|
|
|
57
59
|
# Sends a refund request to Fawry API
|
|
@@ -79,7 +81,33 @@ module Fawry
|
|
|
79
81
|
# has Fawry API response keys as instance methods
|
|
80
82
|
# plus some convenience methods e.g. success?
|
|
81
83
|
def refund(params, opts = {})
|
|
82
|
-
FawryRequest.new('refund', params, opts).
|
|
84
|
+
FawryRequest.new('refund', params, opts).fire_refund_request
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Sends a payment status request to Fawry API
|
|
88
|
+
# performs param validation and builds
|
|
89
|
+
# the request signature
|
|
90
|
+
#
|
|
91
|
+
# @param params [Hash] list of params to send to fawry
|
|
92
|
+
# required(:merchant_code).value(:string)
|
|
93
|
+
# required(:merchant_ref_number).value(:string)
|
|
94
|
+
# required(:fawry_secure_key).value(:string)
|
|
95
|
+
#
|
|
96
|
+
# @param opts [Hash] list of options to
|
|
97
|
+
# configure the request
|
|
98
|
+
# @option opts :sandbox [Boolean] whether to
|
|
99
|
+
# send the request to fawry sandbox env or not
|
|
100
|
+
# false by default
|
|
101
|
+
#
|
|
102
|
+
# @raise [Fawry::InvalidFawryRequest] raised when one
|
|
103
|
+
# or more of the params are invalid. the message
|
|
104
|
+
# specifices which params and why are they invalid
|
|
105
|
+
#
|
|
106
|
+
# @return [Fawry::FawryResponse] an object that
|
|
107
|
+
# has Fawry API response keys as instance methods
|
|
108
|
+
# plus some convenience methods e.g. success?
|
|
109
|
+
def payment_status(params, opts = {})
|
|
110
|
+
FawryRequest.new('payment_status', params, opts).fire_payment_status_request
|
|
83
111
|
end
|
|
84
112
|
end
|
|
85
113
|
end
|
data/lib/fawry/connection.rb
CHANGED
|
@@ -19,6 +19,17 @@ module Fawry
|
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
def get(path, params, body, options)
|
|
23
|
+
conn = options[:sandbox] ? sandbox_connection : connection
|
|
24
|
+
|
|
25
|
+
conn.get(path) do |request|
|
|
26
|
+
request.params = params
|
|
27
|
+
request.body = body.to_json
|
|
28
|
+
# Fawry doesn't understand encoded params
|
|
29
|
+
request.options = request.options.merge(params_encoder: ParamsSpecialEncoder)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
22
33
|
private
|
|
23
34
|
|
|
24
35
|
def connection
|
|
@@ -30,6 +41,21 @@ module Fawry
|
|
|
30
41
|
@sandbox_connection ||= Faraday.new(url: FAWRY_SANDBOX_BASE_URL, headers: { 'Content-Type': 'application/json',
|
|
31
42
|
'Accept': 'application/json' })
|
|
32
43
|
end
|
|
44
|
+
|
|
45
|
+
# Fawry does not understand encoded params
|
|
46
|
+
# so we use this encoder to convert the params
|
|
47
|
+
# hash to a string of query params without encoding
|
|
48
|
+
# { a: 1, b: 2 } => a=1&b=2
|
|
49
|
+
class ParamsSpecialEncoder
|
|
50
|
+
def self.encode(hash)
|
|
51
|
+
hash.each_with_object([]) { |(k, v), arr| arr << "#{k}=#{v}" }.join('&')
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def self.decode(string)
|
|
55
|
+
arr = string.split('&')
|
|
56
|
+
arr.map { |str| str.split('=') }.to_h
|
|
57
|
+
end
|
|
58
|
+
end
|
|
33
59
|
end
|
|
34
60
|
end
|
|
35
61
|
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'dry-validation'
|
|
4
|
+
|
|
5
|
+
module Fawry
|
|
6
|
+
module Contracts
|
|
7
|
+
class PaymentStatusRequestContract < Dry::Validation::Contract
|
|
8
|
+
params do
|
|
9
|
+
required(:merchant_code).value(:string)
|
|
10
|
+
required(:merchant_ref_number).value(:string)
|
|
11
|
+
required(:fawry_secure_key).value(:string)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
data/lib/fawry/fawry_request.rb
CHANGED
|
@@ -16,6 +16,7 @@ module Fawry
|
|
|
16
16
|
|
|
17
17
|
private
|
|
18
18
|
|
|
19
|
+
# rubocop:disable Metrics/MethodLength
|
|
19
20
|
def build_request
|
|
20
21
|
case action
|
|
21
22
|
when 'charge'
|
|
@@ -26,7 +27,12 @@ module Fawry
|
|
|
26
27
|
self.class.include Requests::RefundRequest
|
|
27
28
|
validate_refund_params!
|
|
28
29
|
@request = build_refund_request
|
|
30
|
+
when 'payment_status'
|
|
31
|
+
self.class.include Requests::PaymentStatusRequest
|
|
32
|
+
validate_payment_status_params!
|
|
33
|
+
@request = build_payment_status_request
|
|
29
34
|
end
|
|
35
|
+
# rubocop:enable Metrics/MethodLength
|
|
30
36
|
end
|
|
31
37
|
end
|
|
32
38
|
end
|
|
@@ -7,7 +7,7 @@ module Fawry
|
|
|
7
7
|
module ChargeRequest
|
|
8
8
|
DEFAULTS = { payment_method: 'PAYATFAWRY', currency_code: 'EGP' }.freeze
|
|
9
9
|
|
|
10
|
-
def
|
|
10
|
+
def fire_charge_request
|
|
11
11
|
fawry_api_response = Connection.post(request[:path], request[:params], request[:body], request[:options])
|
|
12
12
|
response_body = JSON.parse(fawry_api_response.body)
|
|
13
13
|
|
|
@@ -29,6 +29,8 @@ module Fawry
|
|
|
29
29
|
@request_params ||= DEFAULTS.merge(params)
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
+
# rubocop:disable Metrics/AbcSize
|
|
33
|
+
# rubocop:disable Metrics/MethodLength
|
|
32
34
|
def charge_request_transformed_params
|
|
33
35
|
{
|
|
34
36
|
merchantCode: request_params[:merchant_code],
|
|
@@ -46,6 +48,8 @@ module Fawry
|
|
|
46
48
|
signature: charge_request_signature
|
|
47
49
|
}.compact
|
|
48
50
|
end
|
|
51
|
+
# rubocop:enable Metrics/MethodLength
|
|
52
|
+
# rubocop:enable Metrics/AbcSize
|
|
49
53
|
|
|
50
54
|
def validate_charge_params!
|
|
51
55
|
contract = Contracts::ChargeRequestContract.new.call(request_params)
|
|
@@ -56,12 +60,14 @@ module Fawry
|
|
|
56
60
|
request_params[:charge_items].each { |hash| hash[:itemId] = hash.delete(:item_id) }
|
|
57
61
|
end
|
|
58
62
|
|
|
63
|
+
# rubocop:disable Metrics/AbcSize
|
|
59
64
|
def charge_request_signature
|
|
60
65
|
Digest::SHA256.hexdigest("#{request_params[:merchant_code]}#{request_params[:merchant_ref_num]}"\
|
|
61
66
|
"#{request_params[:customer_profile_id]}#{request_params[:payment_method]}"\
|
|
62
67
|
"#{format('%<amount>.2f', amount: request_params[:amount])}"\
|
|
63
68
|
"#{request_params[:card_token]}#{request_params[:fawry_secure_key]}")
|
|
64
69
|
end
|
|
70
|
+
# rubocop:enable Metrics/AbcSize
|
|
65
71
|
end
|
|
66
72
|
end
|
|
67
73
|
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'digest'
|
|
4
|
+
|
|
5
|
+
module Fawry
|
|
6
|
+
module Requests
|
|
7
|
+
module PaymentStatusRequest
|
|
8
|
+
def fire_payment_status_request
|
|
9
|
+
fawry_api_response = Connection.get(request[:path], request[:params], request[:body], request[:options])
|
|
10
|
+
response_body = JSON.parse(fawry_api_response.body)
|
|
11
|
+
|
|
12
|
+
FawryResponse.new(response_body)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def build_payment_status_request
|
|
18
|
+
{
|
|
19
|
+
path: 'status',
|
|
20
|
+
params: payment_status_request_transformed_params,
|
|
21
|
+
body: {},
|
|
22
|
+
options: options
|
|
23
|
+
}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def request_params
|
|
27
|
+
@request_params = params
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def payment_status_request_transformed_params
|
|
31
|
+
{
|
|
32
|
+
merchantCode: request_params[:merchant_code],
|
|
33
|
+
merchantRefNumber: request_params[:merchant_ref_number],
|
|
34
|
+
signature: payment_status_request_signature
|
|
35
|
+
}.compact
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def validate_payment_status_params!
|
|
39
|
+
contract = Contracts::PaymentStatusRequestContract.new.call(request_params)
|
|
40
|
+
raise InvalidFawryRequest, contract.errors.to_h if contract.failure?
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def payment_status_request_signature
|
|
44
|
+
Digest::SHA256.hexdigest("#{request_params[:merchant_code]}#{request_params[:merchant_ref_number]}"\
|
|
45
|
+
"#{request_params[:fawry_secure_key]}")
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -5,7 +5,7 @@ require 'digest'
|
|
|
5
5
|
module Fawry
|
|
6
6
|
module Requests
|
|
7
7
|
module RefundRequest
|
|
8
|
-
def
|
|
8
|
+
def fire_refund_request
|
|
9
9
|
fawry_api_response = Connection.post(request[:path], request[:params], request[:body], request[:options])
|
|
10
10
|
response_body = JSON.parse(fawry_api_response.body)
|
|
11
11
|
|
data/lib/fawry/version.rb
CHANGED
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.
|
|
4
|
+
version: 0.2.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-
|
|
11
|
+
date: 2019-11-07 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: dry-validation
|
|
@@ -149,11 +149,13 @@ files:
|
|
|
149
149
|
- lib/fawry.rb
|
|
150
150
|
- lib/fawry/connection.rb
|
|
151
151
|
- lib/fawry/contracts/charge_request_contract.rb
|
|
152
|
+
- lib/fawry/contracts/payment_status_request_contract.rb
|
|
152
153
|
- lib/fawry/contracts/refund_request_contract.rb
|
|
153
154
|
- lib/fawry/errors.rb
|
|
154
155
|
- lib/fawry/fawry_request.rb
|
|
155
156
|
- lib/fawry/fawry_response.rb
|
|
156
157
|
- lib/fawry/requests/charge_request.rb
|
|
158
|
+
- lib/fawry/requests/payment_status_request.rb
|
|
157
159
|
- lib/fawry/requests/refund_request.rb
|
|
158
160
|
- lib/fawry/version.rb
|
|
159
161
|
homepage: https://github.com/amrrbakry/fawry
|
|
@@ -168,9 +170,9 @@ require_paths:
|
|
|
168
170
|
- lib
|
|
169
171
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
170
172
|
requirements:
|
|
171
|
-
- - "
|
|
173
|
+
- - "~>"
|
|
172
174
|
- !ruby/object:Gem::Version
|
|
173
|
-
version: '
|
|
175
|
+
version: '2.6'
|
|
174
176
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
175
177
|
requirements:
|
|
176
178
|
- - ">="
|