paystack 0.1.3 → 0.1.10
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 +5 -5
- data/.gitignore +1 -0
- data/.rspec +2 -2
- data/.travis.yml +16 -0
- data/README.md +475 -20
- data/Rakefile +1 -2
- data/bin/console +0 -0
- data/bin/setup +0 -0
- data/lib/paystack.rb +58 -84
- data/lib/paystack/error.rb +11 -12
- data/lib/paystack/modules/api.rb +14 -7
- data/lib/paystack/objects/balance.rb +12 -0
- data/lib/paystack/objects/banks.rb +12 -0
- data/lib/paystack/objects/base.rb +103 -102
- data/lib/paystack/objects/card.rb +105 -105
- data/lib/paystack/objects/customers.rb +37 -37
- data/lib/paystack/objects/plans.rb +39 -41
- data/lib/paystack/objects/recipients.rb +26 -0
- data/lib/paystack/objects/settlements.rb +12 -0
- data/lib/paystack/objects/subaccounts.rb +37 -0
- data/lib/paystack/objects/subscriptions.rb +40 -0
- data/lib/paystack/objects/transactions.rb +63 -70
- data/lib/paystack/objects/transfers.rb +75 -0
- data/lib/paystack/utils/utils.rb +104 -105
- data/lib/paystack/version.rb +2 -2
- data/paystack.gemspec +8 -6
- metadata +19 -15
- data/key.pem +0 -0
- data/lib/paystack/modules/crypto.rb +0 -11
- data/lib/paystack/modules/tokenmanager.rb +0 -60
data/Rakefile
CHANGED
data/bin/console
CHANGED
File without changes
|
data/bin/setup
CHANGED
File without changes
|
data/lib/paystack.rb
CHANGED
@@ -1,84 +1,58 @@
|
|
1
|
-
require 'rest-client'
|
2
|
-
require 'paystack/
|
3
|
-
require 'paystack/
|
4
|
-
require 'paystack/utils/utils.rb'
|
5
|
-
|
6
|
-
require 'paystack/objects/
|
7
|
-
require 'paystack/objects/
|
8
|
-
require 'paystack/objects/
|
9
|
-
require 'paystack/objects/transactions.rb'
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
# token = token;
|
60
|
-
# amount = amount
|
61
|
-
# email = args[:email]
|
62
|
-
# reference = args[:reference]
|
63
|
-
# result = nil;
|
64
|
-
#
|
65
|
-
# begin
|
66
|
-
# response = RestClient.post "#{API::BASE_URL}#{API::TRANSACTION_PATH}/charge_token", {:token => token, :amount => amount, :email => email, :reference => reference}.to_json, :Authorization => "Bearer #{@private_key}", :content_type => :json, :accept => :json
|
67
|
-
# unless (response.code == 200 || response.code == 201)
|
68
|
-
# raise PaystackServerError.new(response), "HTTP Code #{response.code}: #{response.body}"
|
69
|
-
# end
|
70
|
-
# result = JSON.parse(response.body)
|
71
|
-
# unless(result['status'] != 0 )
|
72
|
-
# raise PaystackServerError.new(response), "Server Message: #{result['message']}"
|
73
|
-
# end
|
74
|
-
#
|
75
|
-
# rescue JSON::ParserError => jsonerr
|
76
|
-
# raise PaystackServerError.new(response) , "Invalid result data. Could not parse JSON response body \n #{jsonerr.message}"
|
77
|
-
#
|
78
|
-
# rescue PaystackServerError => e
|
79
|
-
# Utils.serverErrorHandler(e)
|
80
|
-
# end
|
81
|
-
# return result
|
82
|
-
# end
|
83
|
-
|
84
|
-
end
|
1
|
+
require 'rest-client'
|
2
|
+
require 'paystack/error.rb'
|
3
|
+
require 'paystack/modules/api.rb'
|
4
|
+
require 'paystack/utils/utils.rb'
|
5
|
+
require 'paystack/objects/card.rb'
|
6
|
+
require 'paystack/objects/customers.rb'
|
7
|
+
require 'paystack/objects/plans.rb'
|
8
|
+
require 'paystack/objects/subscriptions.rb'
|
9
|
+
require 'paystack/objects/transactions.rb'
|
10
|
+
require 'paystack/objects/banks.rb'
|
11
|
+
require 'paystack/objects/balance.rb'
|
12
|
+
require 'paystack/objects/settlements.rb'
|
13
|
+
require 'paystack/objects/recipients.rb'
|
14
|
+
require 'paystack/objects/transfers.rb'
|
15
|
+
require 'paystack/objects/subaccounts.rb'
|
16
|
+
|
17
|
+
|
18
|
+
class Paystack
|
19
|
+
attr_reader :public_key, :private_key
|
20
|
+
|
21
|
+
def initialize paystack_public_key=nil, paystack_private_key=nil
|
22
|
+
if (paystack_public_key.nil?)
|
23
|
+
@public_key = ENV['PAYSTACK_PUBLIC_KEY']
|
24
|
+
else
|
25
|
+
@public_key = paystack_public_key
|
26
|
+
end
|
27
|
+
|
28
|
+
if (paystack_private_key.nil?)
|
29
|
+
@private_key = ENV['PAYSTACK_PRIVATE_KEY']
|
30
|
+
else
|
31
|
+
@private_key = paystack_private_key
|
32
|
+
end
|
33
|
+
|
34
|
+
unless !@public_key.nil?
|
35
|
+
raise PaystackBadKeyError, "No public key supplied and couldn't find any in environment variables. Make sure to set public key as an environment variable PAYSTACK_PUBLIC_KEY"
|
36
|
+
end
|
37
|
+
unless @public_key[0..2] == 'pk_'
|
38
|
+
raise PaystackBadKeyError, "Invalid public key #{@public_key}"
|
39
|
+
end
|
40
|
+
|
41
|
+
unless !@private_key.nil?
|
42
|
+
raise PaystackBadKeyError, "No private key supplied and couldn't find any in environment variables. Make sure to set private key as an environment variable PAYSTACK_PRIVATE_KEY"
|
43
|
+
end
|
44
|
+
unless @private_key[0..2] == 'sk_'
|
45
|
+
raise PaystackBadKeyError, "Invalid private key #{@private_key}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
#TODO delete if not used
|
50
|
+
def setPublicKey public_key
|
51
|
+
@public_key = public_key
|
52
|
+
end
|
53
|
+
|
54
|
+
def setPrivateKey public_key
|
55
|
+
@public_key = public_key
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
data/lib/paystack/error.rb
CHANGED
@@ -1,13 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
class PaystackBadKeyError < StandardError
|
1
|
+
class PaystackServerError < StandardError
|
2
|
+
attr_reader :response
|
3
|
+
def initialize(response=nil)
|
4
|
+
@response = response
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
class PaystackCardError < StandardError
|
9
|
+
end
|
10
|
+
|
11
|
+
class PaystackBadKeyError < StandardError
|
13
12
|
end
|
data/lib/paystack/modules/api.rb
CHANGED
@@ -1,7 +1,14 @@
|
|
1
|
-
module API
|
2
|
-
BASE_URL = "https://api.paystack.co"
|
3
|
-
TOKEN_URL ='https://standard.paystack.co/bosco/createmobiletoken'
|
4
|
-
TRANSACTION_PATH = "/transaction"
|
5
|
-
PLAN_PATH = "/plan"
|
6
|
-
CUSTOMER_PATH = "/customer"
|
7
|
-
|
1
|
+
module API
|
2
|
+
BASE_URL = "https://api.paystack.co"
|
3
|
+
TOKEN_URL ='https://standard.paystack.co/bosco/createmobiletoken'
|
4
|
+
TRANSACTION_PATH = "/transaction"
|
5
|
+
PLAN_PATH = "/plan"
|
6
|
+
CUSTOMER_PATH = "/customer"
|
7
|
+
SUBSCRIPTION_PATH = "/subscription"
|
8
|
+
BANK_PATH = "/bank"
|
9
|
+
SUBACCOUNT_PATH = "/subaccount"
|
10
|
+
BALANCE_PATH = "/balance"
|
11
|
+
RECIPIENT_PATH = "/transferrecipient"
|
12
|
+
TRANSFER_PATH = "/transfer"
|
13
|
+
SETTLEMENT_PATH = "/settlement"
|
14
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'paystack/objects/base.rb'
|
2
|
+
|
3
|
+
class PaystackBanks < PaystackBaseObject
|
4
|
+
def list(page=1)
|
5
|
+
return PaystackBanks.list(@paystack, page)
|
6
|
+
end
|
7
|
+
|
8
|
+
|
9
|
+
def PaystackBanks.list(paystackObj, page=1)
|
10
|
+
initGetRequest(paystackObj, "#{API::BANK_PATH}?page=#{page}")
|
11
|
+
end
|
12
|
+
end
|
@@ -1,102 +1,103 @@
|
|
1
|
-
class PaystackBaseObject
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
end
|
1
|
+
class PaystackBaseObject
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
attr_reader :paystack
|
5
|
+
|
6
|
+
def initialize(paystackObj)
|
7
|
+
unless !paystackObj.nil?
|
8
|
+
raise ArgumentError, "Paystack object cannot be nil!!"
|
9
|
+
end
|
10
|
+
@paystack = paystackObj
|
11
|
+
end
|
12
|
+
|
13
|
+
protected
|
14
|
+
# =>Static methods
|
15
|
+
def self.initGetRequest(paystackObj, url)
|
16
|
+
result = nil
|
17
|
+
begin
|
18
|
+
response = RestClient.get "#{API::BASE_URL}#{url}" , :Authorization => "Bearer #{paystackObj.private_key}", :content_type => :json, :accept => :json
|
19
|
+
unless (response.code == 200 || response.code == 201)
|
20
|
+
raise PaystackServerError.new(response), "HTTP Code #{response.code}: #{response.body}"
|
21
|
+
end
|
22
|
+
result = JSON.parse(response.body)
|
23
|
+
unless(result['status'] != 0 )
|
24
|
+
raise PaystackServerError.new(response), "Server Message: #{result['message']}"
|
25
|
+
end
|
26
|
+
|
27
|
+
rescue JSON::ParserError => jsonerr
|
28
|
+
raise PaystackServerError.new(response) , "Invalid result data. Could not parse JSON response body \n #{jsonerr.message}"
|
29
|
+
|
30
|
+
rescue PaystackServerError => e
|
31
|
+
Utils.serverErrorHandler(e)
|
32
|
+
end
|
33
|
+
return result
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.initPostRequest(paystackObj, url, data = {}, json=false )
|
37
|
+
result = nil
|
38
|
+
begin
|
39
|
+
if !json
|
40
|
+
response = RestClient.post "#{API::BASE_URL}#{url}" , data, :authorization => "Bearer #{paystackObj.private_key}"
|
41
|
+
else
|
42
|
+
response = RestClient.post "#{API::BASE_URL}#{url}" , data.to_json, :authorization => "Bearer #{paystackObj.private_key}", :content_type => :json, :accept => :json
|
43
|
+
|
44
|
+
end
|
45
|
+
unless (response.code == 200 || response.code == 201)
|
46
|
+
raise PaystackServerError.new(response), "HTTP Code #{response.code}: #{response.body}"
|
47
|
+
end
|
48
|
+
result = JSON.parse(response.body)
|
49
|
+
unless(result['status'] != 0 )
|
50
|
+
raise PaystackServerError.new(response), "Server Message: #{result['message']}"
|
51
|
+
end
|
52
|
+
|
53
|
+
rescue JSON::ParserError => jsonerr
|
54
|
+
raise PaystackServerError.new(response) , "Invalid result data. Could not parse JSON response body \n #{jsonerr.message}"
|
55
|
+
|
56
|
+
rescue PaystackServerError => e
|
57
|
+
Utils.serverErrorHandler(e)
|
58
|
+
end
|
59
|
+
return result
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.initPutRequest(paystackObj, url, data = {} )
|
63
|
+
result = nil
|
64
|
+
begin
|
65
|
+
response = RestClient.put "#{API::BASE_URL}#{url}" , data, :Authorization => "Bearer #{paystackObj.private_key}"
|
66
|
+
unless (response.code == 200 || response.code == 201)
|
67
|
+
raise PaystackServerError.new(response), "HTTP Code #{response.code}: #{response.body}"
|
68
|
+
end
|
69
|
+
result = JSON.parse(response.body)
|
70
|
+
unless(result['status'] != 0 )
|
71
|
+
raise PaystackServerError.new(response), "Server Message: #{result['message']}"
|
72
|
+
end
|
73
|
+
|
74
|
+
rescue JSON::ParserError => jsonerr
|
75
|
+
raise PaystackServerError.new(response) , "Invalid result data. Could not parse JSON response body \n #{jsonerr.message}"
|
76
|
+
|
77
|
+
rescue PaystackServerError => e
|
78
|
+
Utils.serverErrorHandler(e)
|
79
|
+
end
|
80
|
+
return result
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.initDeleteRequest(paystackObj, url)
|
84
|
+
result = nil
|
85
|
+
begin
|
86
|
+
response = RestClient.delete "#{API::BASE_URL}#{url}" , :Authorization => "Bearer #{paystackObj.private_key}"
|
87
|
+
unless (response.code == 200 || response.code == 201)
|
88
|
+
raise PaystackServerError.new(response), "HTTP Code #{response.code}: #{response.body}"
|
89
|
+
end
|
90
|
+
result = JSON.parse(response.body)
|
91
|
+
unless(result['status'] != 0 )
|
92
|
+
raise PaystackServerError.new(response), "Server Message: #{result['message']}"
|
93
|
+
end
|
94
|
+
|
95
|
+
rescue JSON::ParserError => jsonerr
|
96
|
+
raise PaystackServerError.new(response) , "Invalid result data. Could not parse JSON response body \n #{jsonerr.message}"
|
97
|
+
|
98
|
+
rescue PaystackServerError => e
|
99
|
+
Utils.serverErrorHandler(e)
|
100
|
+
end
|
101
|
+
return result
|
102
|
+
end
|
103
|
+
end
|
@@ -1,106 +1,106 @@
|
|
1
|
-
require 'paystack/utils/utils.rb'
|
2
|
-
|
3
|
-
class PaystackCard
|
4
|
-
attr_reader :name, :number,:cvc,:expiryMonth,:expiryYear, :addressLine1,:addressLine2, :addressLine3, :addressLine4, :addressCountry, :addressPostalCode, :email, :cardCountry, :cardIssuer
|
5
|
-
|
6
|
-
MAX_DINERS_CARD_LENGTH = 14
|
7
|
-
MAX_AMERICAN_EXPRESS_CARD_LENGTH = 15
|
8
|
-
MAX_NORMAL_CARD_LENGTH = 16
|
9
|
-
|
10
|
-
PATTERN_VISA = /^4[0-9]{6,}$/
|
11
|
-
PATTERN_MASTERCARD = /^5[1-5][0-9]{5,}$/
|
12
|
-
PATTERN_AMERICAN_EXPRESS = /^3[47][0-9]{5,}$/
|
13
|
-
PATTERN_DINERS_CLUB = /^3(?:0[0-5]|[68][0-9])[0-9]{4,}$/
|
14
|
-
PATTERN_DISCOVER = /^6(?:011|5[0-9]{2})[0-9]{3,}$/
|
15
|
-
PATTERN_JCB = /^(?:2131|1800|35[0-9]{3})[0-9]{3,}/
|
16
|
-
|
17
|
-
def initialize(args = {})
|
18
|
-
@name = Utils.nullifyString(args[:name])
|
19
|
-
@number = Utils.nullifyString(args[:number])
|
20
|
-
@cvc = Utils.nullifyString(args[:cvc])
|
21
|
-
@expiryMonth = Utils.nullifyString(args[:expiryMonth])
|
22
|
-
@expiryYear = Utils.nullifyString(args[:expiryYear])
|
23
|
-
@cardIssuer = PaystackCard.getCardType(@number)
|
24
|
-
end
|
25
|
-
|
26
|
-
def isValidCard()
|
27
|
-
if (@cvc != nil)
|
28
|
-
return isValidNumber() && isValidExpiryDate() && isValidCVC()
|
29
|
-
else
|
30
|
-
return isValidNumber() && isValidExpiryDate()
|
31
|
-
end
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
|
-
def PaystackCard.getCardType(number)
|
36
|
-
if(number == nil)
|
37
|
-
return 'invalid'
|
38
|
-
end
|
39
|
-
if(number =~ PATTERN_VISA) != nil
|
40
|
-
return 'visa'
|
41
|
-
end
|
42
|
-
|
43
|
-
if(number =~ PATTERN_MASTERCARD) != nil
|
44
|
-
return 'mastercard'
|
45
|
-
end
|
46
|
-
|
47
|
-
if(number =~ PATTERN_AMERICAN_EXPRESS) != nil
|
48
|
-
return 'american_express'
|
49
|
-
end
|
50
|
-
|
51
|
-
if(number =~ PATTERN_DINERS_CLUB)
|
52
|
-
return 'diners'
|
53
|
-
end
|
54
|
-
if(number =~ PATTERN_DISCOVER)
|
55
|
-
return 'discover'
|
56
|
-
end
|
57
|
-
if(number =~ PATTERN_JCB)
|
58
|
-
return 'jcb'
|
59
|
-
end
|
60
|
-
return 'unknown'
|
61
|
-
end
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
def isValidNumber
|
69
|
-
if(Utils.isEmpty(@number))
|
70
|
-
return false
|
71
|
-
end
|
72
|
-
formatted_number = @number.gsub(/\s+|-/) {|s| '' }.strip
|
73
|
-
|
74
|
-
if(Utils.isEmpty(formatted_number) || !Utils.isWholePositiveNumber(formatted_number) || !Utils.
|
75
|
-
|
76
|
-
return false
|
77
|
-
end
|
78
|
-
if PaystackCard.getCardType(formatted_number).eql?('diners')
|
79
|
-
return (formatted_number.length == MAX_DINERS_CARD_LENGTH)
|
80
|
-
end
|
81
|
-
|
82
|
-
if PaystackCard.getCardType(formatted_number).eql?('american_express')
|
83
|
-
return (formatted_number.length == MAX_AMERICAN_EXPRESS_CARD_LENGTH)
|
84
|
-
end
|
85
|
-
|
86
|
-
return (formatted_number.length == MAX_NORMAL_CARD_LENGTH)
|
87
|
-
|
88
|
-
end
|
89
|
-
|
90
|
-
def isValidCVC
|
91
|
-
if(@cvc.eql?(""))
|
92
|
-
return false
|
93
|
-
end
|
94
|
-
cvc = @cvc.strip
|
95
|
-
cvc_len = cvc.length
|
96
|
-
|
97
|
-
validLength = ((cvc_len >= 3 && cvc_len <= 4) || (@cardIssuer.eql?('american_express') && cvc_len == 4) ||(!@cardIssuer.eql?('american_express') && cvc_len == 3))
|
98
|
-
|
99
|
-
end
|
100
|
-
|
101
|
-
def isValidExpiryDate()
|
102
|
-
return !(@expiryMonth == nil || @expiryYear == nil) && Utils.hasCardExpired(@expiryYear, @expiryMonth);
|
103
|
-
end
|
104
|
-
|
105
|
-
|
1
|
+
require 'paystack/utils/utils.rb'
|
2
|
+
|
3
|
+
class PaystackCard
|
4
|
+
attr_reader :name, :number,:cvc,:expiryMonth,:expiryYear, :addressLine1,:addressLine2, :addressLine3, :addressLine4, :addressCountry, :addressPostalCode, :email, :cardCountry, :cardIssuer
|
5
|
+
|
6
|
+
MAX_DINERS_CARD_LENGTH = 14
|
7
|
+
MAX_AMERICAN_EXPRESS_CARD_LENGTH = 15
|
8
|
+
MAX_NORMAL_CARD_LENGTH = 16
|
9
|
+
|
10
|
+
PATTERN_VISA = /^4[0-9]{6,}$/
|
11
|
+
PATTERN_MASTERCARD = /^5[1-5][0-9]{5,}$/
|
12
|
+
PATTERN_AMERICAN_EXPRESS = /^3[47][0-9]{5,}$/
|
13
|
+
PATTERN_DINERS_CLUB = /^3(?:0[0-5]|[68][0-9])[0-9]{4,}$/
|
14
|
+
PATTERN_DISCOVER = /^6(?:011|5[0-9]{2})[0-9]{3,}$/
|
15
|
+
PATTERN_JCB = /^(?:2131|1800|35[0-9]{3})[0-9]{3,}/
|
16
|
+
|
17
|
+
def initialize(args = {})
|
18
|
+
@name = Utils.nullifyString(args[:name])
|
19
|
+
@number = Utils.nullifyString(args[:number])
|
20
|
+
@cvc = Utils.nullifyString(args[:cvc])
|
21
|
+
@expiryMonth = Utils.nullifyString(args[:expiryMonth])
|
22
|
+
@expiryYear = Utils.nullifyString(args[:expiryYear])
|
23
|
+
@cardIssuer = PaystackCard.getCardType(@number)
|
24
|
+
end
|
25
|
+
|
26
|
+
def isValidCard()
|
27
|
+
if (@cvc != nil)
|
28
|
+
return isValidNumber() && isValidExpiryDate() && isValidCVC()
|
29
|
+
else
|
30
|
+
return isValidNumber() && isValidExpiryDate()
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
def PaystackCard.getCardType(number)
|
36
|
+
if(number == nil)
|
37
|
+
return 'invalid'
|
38
|
+
end
|
39
|
+
if(number =~ PATTERN_VISA) != nil
|
40
|
+
return 'visa'
|
41
|
+
end
|
42
|
+
|
43
|
+
if(number =~ PATTERN_MASTERCARD) != nil
|
44
|
+
return 'mastercard'
|
45
|
+
end
|
46
|
+
|
47
|
+
if(number =~ PATTERN_AMERICAN_EXPRESS) != nil
|
48
|
+
return 'american_express'
|
49
|
+
end
|
50
|
+
|
51
|
+
if(number =~ PATTERN_DINERS_CLUB)
|
52
|
+
return 'diners'
|
53
|
+
end
|
54
|
+
if(number =~ PATTERN_DISCOVER)
|
55
|
+
return 'discover'
|
56
|
+
end
|
57
|
+
if(number =~ PATTERN_JCB)
|
58
|
+
return 'jcb'
|
59
|
+
end
|
60
|
+
return 'unknown'
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
|
68
|
+
def isValidNumber
|
69
|
+
if(Utils.isEmpty(@number))
|
70
|
+
return false
|
71
|
+
end
|
72
|
+
formatted_number = @number.gsub(/\s+|-/) {|s| '' }.strip
|
73
|
+
|
74
|
+
if(Utils.isEmpty(formatted_number) || !Utils.isWholePositiveNumber(formatted_number) || !Utils.isLuhnValidNumber(formatted_number))
|
75
|
+
|
76
|
+
return false
|
77
|
+
end
|
78
|
+
if PaystackCard.getCardType(formatted_number).eql?('diners')
|
79
|
+
return (formatted_number.length == MAX_DINERS_CARD_LENGTH)
|
80
|
+
end
|
81
|
+
|
82
|
+
if PaystackCard.getCardType(formatted_number).eql?('american_express')
|
83
|
+
return (formatted_number.length == MAX_AMERICAN_EXPRESS_CARD_LENGTH)
|
84
|
+
end
|
85
|
+
|
86
|
+
return (formatted_number.length == MAX_NORMAL_CARD_LENGTH)
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
def isValidCVC
|
91
|
+
if(@cvc.eql?(""))
|
92
|
+
return false
|
93
|
+
end
|
94
|
+
cvc = @cvc.strip
|
95
|
+
cvc_len = cvc.length
|
96
|
+
|
97
|
+
validLength = ((cvc_len >= 3 && cvc_len <= 4) || (@cardIssuer.eql?('american_express') && cvc_len == 4) ||(!@cardIssuer.eql?('american_express') && cvc_len == 3))
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
def isValidExpiryDate()
|
102
|
+
return !(@expiryMonth == nil || @expiryYear == nil) && Utils.hasCardExpired(@expiryYear, @expiryMonth);
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
106
|
end
|