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