├── .gitignore ├── .rspec ├── .travis.yml ├── CODE_OF_CONDUCT.md ├── Gemfile ├── LICENSE.txt ├── README.md ├── Rakefile ├── bin ├── console └── setup ├── lib ├── paystack.rb └── paystack │ ├── error.rb │ ├── modules │ └── api.rb │ ├── objects │ ├── balance.rb │ ├── banks.rb │ ├── base.rb │ ├── card.rb │ ├── customers.rb │ ├── plans.rb │ ├── recipients.rb │ ├── refunds.rb │ ├── settlements.rb │ ├── subaccounts.rb │ ├── subscriptions.rb │ ├── transactions.rb │ └── transfers.rb │ ├── utils │ └── utils.rb │ └── version.rb ├── paystack.gemspec └── spec ├── paystack_balance_spec.rb ├── paystack_banks_spec.rb ├── paystack_card_spec.rb ├── paystack_customers_spec.rb ├── paystack_plans_spec.rb ├── paystack_recipients_spec.rb ├── paystack_settlements_spec.rb ├── paystack_spec.rb ├── paystack_subaccounts_spec.rb ├── paystack_subscriptions_spec.rb ├── paystack_transactions_spec.rb ├── paystack_transfers_spec.rb └── spec_helper.rb /.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle/ 2 | /.yardoc 3 | /Gemfile.lock 4 | /_yardoc/ 5 | /coverage/ 6 | /doc/ 7 | /pkg/ 8 | /spec/reports/ 9 | /tmp/ 10 | /vendor 11 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --require spec_helper 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | language: ruby 3 | rvm: 4 | - 2.4.0 5 | before_install: gem install bundler 6 | cache: 7 | directories: 8 | - vendor/bundle 9 | 10 | script: 11 | - rspec 12 | 13 | deploy: 14 | provider: rubygems 15 | api_key: "bcc5d3ff98af614e950b21a2df77af20" 16 | gem: paystack 17 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, and in the interest of 4 | fostering an open and welcoming community, we pledge to respect all people who 5 | contribute through reporting issues, posting feature requests, updating 6 | documentation, submitting pull requests or patches, and other activities. 7 | 8 | We are committed to making participation in this project a harassment-free 9 | experience for everyone, regardless of level of experience, gender, gender 10 | identity and expression, sexual orientation, disability, personal appearance, 11 | body size, race, ethnicity, age, religion, or nationality. 12 | 13 | Examples of unacceptable behavior by participants include: 14 | 15 | * The use of sexualized language or imagery 16 | * Personal attacks 17 | * Trolling or insulting/derogatory comments 18 | * Public or private harassment 19 | * Publishing other's private information, such as physical or electronic 20 | addresses, without explicit permission 21 | * Other unethical or unprofessional conduct 22 | 23 | Project maintainers have the right and responsibility to remove, edit, or 24 | reject comments, commits, code, wiki edits, issues, and other contributions 25 | that are not aligned to this Code of Conduct, or to ban temporarily or 26 | permanently any contributor for other behaviors that they deem inappropriate, 27 | threatening, offensive, or harmful. 28 | 29 | By adopting this Code of Conduct, project maintainers commit themselves to 30 | fairly and consistently applying these principles to every aspect of managing 31 | this project. Project maintainers who do not follow or enforce the Code of 32 | Conduct may be permanently removed from the project team. 33 | 34 | This code of conduct applies both within project spaces and in public spaces 35 | when an individual is representing the project or its community. 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 38 | reported by contacting a project maintainer at ikoro.victor@gmail.com. All 39 | complaints will be reviewed and investigated and will result in a response that 40 | is deemed necessary and appropriate to the circumstances. Maintainers are 41 | obligated to maintain confidentiality with regard to the reporter of an 42 | incident. 43 | 44 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 45 | version 1.3.0, available at 46 | [http://contributor-covenant.org/version/1/3/0/][version] 47 | 48 | [homepage]: http://contributor-covenant.org 49 | [version]: http://contributor-covenant.org/version/1/3/0/ -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Specify your gem's dependencies in paystack.gemspec 4 | gemspec 5 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Victor Ikoro 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Paystack 2 | 3 | [![Build Status](https://travis-ci.org/IkoroVictor/paystack-ruby.svg?branch=master)](https://travis-ci.org/IkoroVictor/paystack-ruby) [![Gem Version](https://badge.fury.io/rb/paystack.svg)](https://badge.fury.io/rb/paystack) 4 | 5 | A ruby gem for easy integration of [Paystack](https://paystack.co/). 6 | 7 | 8 | ## Installation 9 | 10 | Add this line to your application's Gemfile: 11 | 12 | ```ruby 13 | gem 'paystack' 14 | ``` 15 | 16 | And then execute: 17 | 18 | $ bundle 19 | 20 | Or install it yourself as: 21 | 22 | $ gem install paystack 23 | 24 | ## Basic Usage 25 | 26 | 27 | 28 | ### Instantiate Paystack Object 29 | 30 | ```ruby 31 | 32 | paystackObj = Paystack.new(public_key, secret_key) 33 | 34 | ``` 35 | 36 | A secure way is to set your public and private keys as environmental variables `PAYSTACK_PUBLIC_KEY` and `PAYSTACK_PRIVATE_KEY` respectively. Then you instantiate without parameters 37 | 38 | ```ruby 39 | 40 | paystackObj = Paystack.new 41 | 42 | ``` 43 | It throws a `PaystackBadKeyError` when either of the keys are invalid or cannot be found as environment variables. 44 | 45 | 46 | 47 | ### Initialize transaction and get Authorization URL 48 | 49 | ```ruby 50 | 51 | transactions = PaystackTransactions.new(paystackObj) 52 | result = transactions.initializeTransaction( 53 | :reference => "blablablabla-YOUR-UNIQUE-REFERENCE-HERE", 54 | :amount => 300000, 55 | :email => "xxxxxx@gmail.com", 56 | ) 57 | auth_url = result['data']['authorization_url'] 58 | ``` 59 | NOTE: Amount is in kobo i.e. `100000 = 100000 kobo = 1000 naira` 60 | 61 | 62 | 63 | ### Charge using Authorization code for returning customers 64 | 65 | ```ruby 66 | 67 | result = transactions.chargeAuthorization( 68 | "WwdkojpoAJo", # Authorization code 69 | "xxxxxx@gmail.com", # Customer email 70 | 2000000, # Amount 71 | :reference => "blablablabla-YOUR-UNIQUE-REFERENCE-HERE" 72 | ) 73 | ``` 74 | 75 | 76 | 77 | ## Transactions 78 | 79 | 80 | 81 | ### List transactions 82 | 83 | ```ruby 84 | 85 | page_number = 1 86 | transactions = PaystackTransactions.new(paystackObj) 87 | result = transactions.list(page_number) #Optional `page_number` parameter 88 | 89 | ``` 90 | 91 | ### Get a transaction 92 | 93 | ```ruby 94 | 95 | transaction_id = "123456778" 96 | transactions = PaystackTransactions.new(paystackObj) 97 | result = transactions.get(transaction_id) 98 | 99 | ``` 100 | 101 | ### Verify a transaction 102 | 103 | ```ruby 104 | 105 | transaction_reference = "blablablabla-YOUR-VALID-UNIQUE-REFERENCE-HERE" 106 | transactions = PaystackTransactions.new(paystackObj) 107 | result = transactions.verify(transaction_reference) 108 | 109 | ``` 110 | 111 | 112 | ### Get transaction totals 113 | 114 | ```ruby 115 | 116 | transactions = PaystackTransactions.new(paystackObj) 117 | result = transactions.totals() 118 | 119 | ``` 120 | 121 | 122 | ## Customers 123 | 124 | 125 | ### List Customers 126 | 127 | ```ruby 128 | 129 | page_number = 1 130 | customers = PaystackCustomers.new(paystackObj) 131 | result = customers.list(page_number) #Optional `page_number` parameter, 50 items per page 132 | customers_list = result['data'] 133 | 134 | ``` 135 | 136 | ### Get a customer 137 | 138 | ```ruby 139 | 140 | customer_id = "123456778" 141 | customers = PaystackCustomers.new(paystackObj) 142 | result = customers.get(customer_id) 143 | customer = result['data'] 144 | 145 | ``` 146 | 147 | ### Create new customer 148 | 149 | ```ruby 150 | 151 | customers = PaystackCustomers.new(paystackObj) 152 | result = customers.create( 153 | :first_name => "Victor", 154 | :last_name => "Ikoro", 155 | :phone => "+234707666669" 156 | :email => "xxxxx@gmail.com" 157 | ) 158 | 159 | ``` 160 | 161 | ### Update customer details 162 | 163 | ```ruby 164 | 165 | customer_id = "123456778" 166 | customers = PaystackCustomers.new(paystackObj) 167 | # Updating last name and email of customer 168 | result = customers.update( 169 | customer_id, 170 | :last_name => "Ikorodu", 171 | :email => "xxxxx-modified@gmail.com" 172 | ) 173 | 174 | ``` 175 | 176 | ## Plans 177 | 178 | ### List Plans 179 | 180 | ```ruby 181 | 182 | page_number = 1 183 | plans = PaystackPlans.new(paystackObj) 184 | result = plans.list(page_number) #Optional `page_number` parameter, 50 items per page 185 | plans_list = result['data'] 186 | 187 | ``` 188 | 189 | ### Get plan detail 190 | 191 | ```ruby 192 | 193 | plan_id = "123456778" 194 | plans = PaystackPlans.new(paystackObj) 195 | result = plans.get(plan_id) 196 | plan = result['data'] 197 | 198 | ``` 199 | 200 | ### Create new plan 201 | 202 | ```ruby 203 | 204 | plans = PaystackPlans.new(paystackObj) 205 | result = plans.create( 206 | 207 | :name => "Test Plan", 208 | :description => "Dev Test Plan", 209 | :amount => 30000, #in KOBO 210 | :interval => "monthly", #monthly, yearly, quarterly, weekly etc 211 | :currency => "NGN" 212 | ) 213 | 214 | ``` 215 | 216 | ### Update plan details 217 | 218 | ```ruby 219 | 220 | plan_id = "123456778" 221 | plans = PaystackPlans.new(paystackObj) 222 | result = plans.update( 223 | plan_id, 224 | :name => "Test Plan Updated", 225 | :amount => 500000, #in KOBO 226 | :interval => "weekly" 227 | ) 228 | 229 | ``` 230 | 231 | 232 | ## Subscriptions 233 | 234 | ### Create new subscription 235 | 236 | ```ruby 237 | 238 | subscriptions = PaystackSubscriptions.new(paystackObj) 239 | result = subscriptions.create( 240 | 241 | :customer => "customer@email.com", 242 | :plan => "123557", #plan id 243 | :amount => 30000 #in KOBO 244 | ) 245 | 246 | ``` 247 | 248 | ### Get subscription detail 249 | 250 | ```ruby 251 | 252 | subscription_id = "123456778" 253 | subscriptions = PaystackSubscriptions.new(paystackObj) 254 | result = subscriptions.get(subscription_id) 255 | subscription = result['data'] 256 | 257 | ``` 258 | 259 | ### Enable subscription 260 | 261 | ```ruby 262 | 263 | subscriptions = PaystackSubscriptions.new(paystackObj) 264 | result = subscriptions.enable( 265 | :code => "12328833", 266 | :token => "EWFWKFJWE" #user email token 267 | ) 268 | 269 | ``` 270 | 271 | ### Disable subscription 272 | 273 | ```ruby 274 | 275 | subscriptions = PaystackSubscriptions.new(paystackObj) 276 | result = subscriptions.disable( 277 | :code => "12328833", 278 | :token => "EWFWKFJWE" #user email token 279 | ) 280 | 281 | ``` 282 | 283 | 284 | ## Split Payments 285 | 286 | This Gem is also aware of the API calls that allow you to perform split payments on Paystack. The [Paystack documentation on split payments](https://developers.paystack.co/docs/split-payments-overview) can get you started. Below are some sample calls for [subaccounts](https://developers.paystack.co/docs/create-subaccount) and [banks](https://developers.paystack.co/docs/list-banks). 287 | 288 | ## Banks 289 | 290 | ### List Banks 291 | 292 | ```ruby 293 | 294 | page_number = 1 295 | banks = PaystackBanks.new(paystackObj) 296 | result = banks.list(page_number) #Optional `page_number` parameter, 50 items per page 297 | banks_list = result['data'] 298 | 299 | ``` 300 | 301 | ## Subaccounts 302 | 303 | ### List Subaccounts 304 | 305 | ```ruby 306 | 307 | page_number = 1 308 | subaccounts = PaystackSubaccounts.new(paystackObj) 309 | result = subaccounts.list(page_number) #Optional `page_number` parameter, 50 items per page 310 | subaccounts_list = result['data'] 311 | 312 | ``` 313 | 314 | ### Get a subaccount 315 | 316 | ```ruby 317 | 318 | subaccount_id = "123456778" 319 | subaccounts = PaystackSubaccounts.new(paystackObj) 320 | result = subaccounts.get(subaccount_id) 321 | subaccount = result['data'] 322 | 323 | ``` 324 | 325 | ### Create new subaccount 326 | 327 | ```ruby 328 | 329 | subaccounts = PaystackSubaccounts.new(paystackObj) 330 | result = subaccounts.create( 331 | :business_name => "Madam Ikoro Holdings", 332 | :settlement_bank => "Providus Bank", 333 | :account_number => "1170766666", 334 | :percentage_charge => 3.2 335 | ) 336 | 337 | ``` 338 | 339 | ### Update subaccount details 340 | 341 | ```ruby 342 | 343 | subaccount_id = "123456778" 344 | subaccounts = PaystackSubaccounts.new(paystackObj) 345 | # Updating primary contact name and email of subaccount 346 | result = subaccounts.update( 347 | subaccount_id, 348 | :primary_contact_name => "Victoria Ikorodu", 349 | :primary_contact_email => "xxxxx-modified@gmail.com" 350 | ) 351 | 352 | ``` 353 | 354 | ## Settlements 355 | Fetch settlements made to your bank accounts and the bank accounts for your subaccounts 356 | 357 | ### List settlements 358 | 359 | ```ruby 360 | 361 | settlements = PaystackSettlements.new(paystackObj) 362 | results = settlements.list 363 | settlements_list = result['data'] 364 | 365 | ``` 366 | 367 | ## Transfers 368 | 369 | The funds transfers feature enables you send money directly from your paystack balance to any Nigerian Bank account. The [Paystack documentation on transfers](https://developers.paystack.co/docs/funds_transfers) can get you started. 370 | 371 | ## Balance 372 | 373 | ### Check Paystack Balance 374 | 375 | ```ruby 376 | 377 | balance = PaystackBalance.new(paystackObj) 378 | result = balance.get 379 | account_balance = result['data'] 380 | 381 | ``` 382 | 383 | ## Transfers 384 | 385 | ### Initialize a transfer 386 | 387 | ```ruby 388 | 389 | transfer = PaystackTransfers.new(paystackObj) 390 | results = transfers.initializeTransfer( 391 | :source => "balance", # Must be balance 392 | :reason => "Your reason", 393 | :amount => 30000, # Amount in kobo 394 | :recipient => recipient_code, # Unique recipient code 395 | ) 396 | 397 | ``` 398 | 399 | 400 | 401 | ### Bulk transfer 402 | 403 | ```ruby 404 | 405 | transfer = PaystackTransfers.new(paystackObj) 406 | results = transfers.initializeBulkTransfer( 407 | :source => "balance", # Must be balance 408 | :transfer => [ 409 | { 410 | :reason => "Your reason", 411 | :amount => 30000, # Amount in kobo 412 | :recipient => recipient_code, # Unique recipient code 413 | }, 414 | { 415 | :reason => "Your reason", 416 | :amount => 30000, # Amount in kobo 417 | :recipient => recipient_code, # Unique recipient code 418 | }, 419 | ] 420 | ) 421 | 422 | ``` 423 | 424 | 425 | ### List transfers 426 | 427 | ```ruby 428 | 429 | page_number = 1 430 | transfers = PaystackTransfers.new(paystackObj) 431 | result = transfers.list(page_number) #Optional `page_number` parameter 432 | 433 | ``` 434 | 435 | ### Get a transfer 436 | 437 | ```ruby 438 | 439 | transfer_code = "TRF_uniquecode" 440 | transfer = PaystackTransfers.new(paystackObj) 441 | result = transfer.get(transfer_code) 442 | 443 | ``` 444 | 445 | ### Finalize a transfer 446 | 447 | ```ruby 448 | 449 | transfer = PaystackTransfers.new(paystackObj) 450 | results = transfer.authorize( 451 | :transfer_code => "TRF_blablabla", # Must be balance 452 | :otp => "12350", 453 | ) 454 | 455 | ``` 456 | 457 | 458 | ## Transfer Recipients 459 | 460 | ### Create new recipient 461 | 462 | ```ruby 463 | 464 | recipient = PaystackRecipients.new(paystackObj) 465 | result = recipient.create( 466 | :type => "nuban", #Must be nuban 467 | :name => "Test Plan", 468 | :description => "Bla-bla-bla", 469 | :account_number => 0123456789, #10 digit account number 470 | :bank_code => "044", #monthly, yearly, quarterly, weekly etc 471 | :currency => "NGN", 472 | 473 | ) 474 | 475 | ``` 476 | 477 | ### List transfer recipients 478 | 479 | ```ruby 480 | page_number = 1 481 | recipients = PaystackRecipients.new(paystackObj) 482 | result = recipients.list(page_number) #Optional `page_number` parameter, 50 items per page 483 | recipients_list = result['data'] 484 | 485 | ``` 486 | 487 | ## Transfer Control 488 | 489 | ### Resend OTP 490 | 491 | ```ruby 492 | transfer_code = "TRF_asdfghjkl" #A unique Transfer code is generated when transfer is created 493 | transfer = PaystackTransfers.new(paystackObj) 494 | result = transfer.resendOtp(transfer_code) 495 | 496 | 497 | ``` 498 | 499 | ### Disable OTP for transfers 500 | 501 | ```ruby 502 | 503 | transfer = PaystackTransfers.new(paystackObj) 504 | result = transfer.disableOtp 505 | #OTP is sent to the registered phone number of the account 506 | 507 | ``` 508 | 509 | ### Confirm disabling of OTP for transfers 510 | 511 | ```ruby 512 | 513 | otp = "12345" 514 | transfer = PaystackTransfers.new(paystackObj) 515 | # Updating primary contact name and email of subaccount 516 | result = transfer.confirmDisableOtp( 517 | :otp => otp, #Must be valid OTP sent to the registered phone number 518 | ) 519 | 520 | ``` 521 | 522 | ### Enable OTP for transfers 523 | 524 | ```ruby 525 | 526 | transfer = PaystackTransfers.new(paystackObj) 527 | result = transfer.enableOtp 528 | 529 | ``` 530 | 531 | ## Refunds 532 | 533 | ### Create a refund 534 | 535 | ```ruby 536 | 537 | refund = PaystackRefunds.new(paystackObj) 538 | 539 | #full refund 540 | transaction = {transaction: transaction_reference} 541 | refund.createRefund(transaction) #must be a valid transaction reference or transaction id 542 | 543 | #partial refund 544 | transaction = {transaction: transaction_reference, amount: 5000} # minimum amount 50 NGN or 5000 kobos 545 | refund.createRefund(transaction) 546 | 547 | ``` 548 | 549 | ### List refunds 550 | 551 | ```ruby 552 | 553 | page_number = 1 554 | refund = PaystackRefunds.new(paystackObj) 555 | refund.list(page_number) # page_number is optional 556 | 557 | ``` 558 | 559 | 560 | ### Fetch refund 561 | 562 | ```ruby 563 | 564 | refund = PaystackRefunds.new(paystackObj) 565 | refund.get(refund_id) # returned at the time of creating a refund 566 | 567 | ``` 568 | 569 | ## Static methods 570 | `PaystackTransactions`, `PaystackCustomers`, `PaystackPlans`, `PaystackSubaccounts`, `PaystackRefunds`, `PaystackBanks` , `PaystackSubscriptions` , `PaystackSettlements`, `PaystackBalance`, and `PaystackTransfers` methods can be called statically, You just need to pass the paystack object as the first parameter e.g. `verify` method in `PaystackTransactions` can be called like this 571 | 572 | 573 | ```ruby 574 | 575 | transaction_reference = "blablablabla-YOUR-VALID-UNIQUE-REFERENCE-HERE" 576 | result = PaystackTransactions.verify(paystackObj, transaction_reference) 577 | puts result['message'] 578 | 579 | ``` 580 | 581 | 582 | 583 | 584 | ## Contributing 585 | 586 | Bug reports and pull requests are welcome on GitHub at https://github.com/IkoroVictor/paystack-ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct. 587 | 588 | 589 | ## License 590 | 591 | The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT). 592 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/gem_tasks" 2 | require "rspec/core/rake_task" 3 | 4 | RSpec::Core::RakeTask.new(:spec) 5 | 6 | task :default => :spec 7 | -------------------------------------------------------------------------------- /bin/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require "bundler/setup" 4 | require "paystack" 5 | 6 | # You can add fixtures and/or initialization code here to make experimenting 7 | # with your gem easier. You can also use a different console, if you like. 8 | 9 | # (If you use this, don't forget to add pry to your Gemfile!) 10 | # require "pry" 11 | # Pry.start 12 | 13 | require "irb" 14 | IRB.start 15 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | IFS=$'\n\t' 4 | set -vx 5 | 6 | bundle install 7 | 8 | # Do any other automated setup that you need to do here 9 | -------------------------------------------------------------------------------- /lib/paystack.rb: -------------------------------------------------------------------------------- 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 | require 'paystack/objects/refunds.rb' 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 59 | -------------------------------------------------------------------------------- /lib/paystack/error.rb: -------------------------------------------------------------------------------- 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 12 | end -------------------------------------------------------------------------------- /lib/paystack/modules/api.rb: -------------------------------------------------------------------------------- 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 | REFUND_PATH = "/refund" 15 | end 16 | -------------------------------------------------------------------------------- /lib/paystack/objects/balance.rb: -------------------------------------------------------------------------------- 1 | require 'paystack/objects/base.rb' 2 | 3 | class PaystackBalance < PaystackBaseObject 4 | def get 5 | return PaystackBalance.get(@paystack) 6 | end 7 | 8 | 9 | def PaystackBalance.get(paystackObj) 10 | initGetRequest(paystackObj, "#{API::BALANCE_PATH}") 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/paystack/objects/banks.rb: -------------------------------------------------------------------------------- 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 13 | -------------------------------------------------------------------------------- /lib/paystack/objects/base.rb: -------------------------------------------------------------------------------- 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 104 | -------------------------------------------------------------------------------- /lib/paystack/objects/card.rb: -------------------------------------------------------------------------------- 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 | end -------------------------------------------------------------------------------- /lib/paystack/objects/customers.rb: -------------------------------------------------------------------------------- 1 | require 'paystack/objects/base.rb' 2 | 3 | class PaystackCustomers < PaystackBaseObject 4 | def create(data={}) 5 | return PaystackCustomers.create(@paystack, data) 6 | end 7 | 8 | def get(customer_id) 9 | return PaystackCustomers.get(@paystack, customer_id) 10 | end 11 | 12 | 13 | def update(customer_id, data={}) 14 | return PaystackCustomers.update(@paystack, customer_id, data) 15 | end 16 | 17 | def list(page=1) 18 | return PaystackCustomers.list(@paystack, page) 19 | end 20 | 21 | 22 | def PaystackCustomers.create(paystackObj, data) 23 | initPostRequest(paystackObj,"#{API::CUSTOMER_PATH}", data) 24 | end 25 | 26 | def PaystackCustomers.update(paystackObj, customer_id, data) 27 | initPutRequest(paystackObj,"#{API::CUSTOMER_PATH}/#{customer_id}", data) 28 | end 29 | 30 | def PaystackCustomers.get(paystackObj, customer_id) 31 | initGetRequest(paystackObj, "#{API::CUSTOMER_PATH}/#{customer_id}") 32 | end 33 | 34 | def PaystackCustomers.list(paystackObj, page=1) 35 | initGetRequest(paystackObj, "#{API::CUSTOMER_PATH}?page=#{page}") 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /lib/paystack/objects/plans.rb: -------------------------------------------------------------------------------- 1 | require 'paystack/objects/base.rb' 2 | 3 | class PaystackPlans < PaystackBaseObject 4 | 5 | def create(data={}) 6 | return PaystackPlans.create(@paystack, data) 7 | end 8 | 9 | def get(plan_id) 10 | return PaystackPlans.get(@paystack, plan_id) 11 | end 12 | 13 | 14 | def update(plan_id, data={}) 15 | return PaystackPlans.update(@paystack, plan_id, data) 16 | end 17 | 18 | def list(page=1) 19 | return PaystackPlans.list(@paystack, page) 20 | end 21 | 22 | 23 | def PaystackPlans.create(paystackObj, data) 24 | initPostRequest(paystackObj,"#{API::PLAN_PATH}", data) 25 | end 26 | 27 | def PaystackPlans.update(paystackObj, plan_id, data) 28 | initPutRequest(paystackObj,"#{API::PLAN_PATH}/#{plan_id}", data) 29 | end 30 | 31 | def PaystackPlans.get(paystackObj, plan_id) 32 | initGetRequest(paystackObj, "#{API::PLAN_PATH}/#{plan_id}") 33 | end 34 | 35 | def PaystackPlans.list(paystackObj, page=1) 36 | initGetRequest(paystackObj, "#{API::PLAN_PATH}?page=#{page}") 37 | end 38 | 39 | 40 | end -------------------------------------------------------------------------------- /lib/paystack/objects/recipients.rb: -------------------------------------------------------------------------------- 1 | require 'paystack/objects/base.rb' 2 | 3 | 4 | class PaystackRecipients < PaystackBaseObject 5 | 6 | def create(data={}) 7 | return PaystackRecipients.create(@paystack, data) 8 | end 9 | 10 | def list(page=1) 11 | return PaystackRecipients.list(@paystack, page) 12 | end 13 | 14 | 15 | def PaystackRecipients.create(paystackObj, data={}) 16 | initPostRequest(paystackObj, "#{API::RECIPIENT_PATH}", data, true) 17 | end 18 | 19 | def PaystackRecipients.list(paystackObj, page=1) 20 | initGetRequest(paystackObj, "#{API::RECIPIENT_PATH}/?page=#{page}") 21 | end 22 | 23 | 24 | 25 | 26 | end -------------------------------------------------------------------------------- /lib/paystack/objects/refunds.rb: -------------------------------------------------------------------------------- 1 | require 'paystack/objects/base.rb' 2 | 3 | class PaystackRefunds < PaystackBaseObject 4 | 5 | def createRefund(args={}) 6 | return PaystackRefunds.createRefund(@paystack, args) 7 | end 8 | 9 | def list(page=1) 10 | return PaystackRefunds.list(@paystack, page) 11 | end 12 | 13 | def get(refund_id) 14 | return PaystackRefunds.get(@paystack, refund_id) 15 | end 16 | 17 | # => Public Static methods 18 | def PaystackRefunds.createRefund(paystackObj, args) 19 | initPostRequest(paystackObj,"#{API::REFUND_PATH}", args,true) 20 | end 21 | 22 | def PaystackRefunds.list(paystackObj, page=1) 23 | initGetRequest(paystackObj, "#{API::REFUND_PATH}?page=#{page}") 24 | end 25 | 26 | def PaystackRefunds.get(paystackObj, refund_id) 27 | initGetRequest(paystackObj, "#{API::REFUND_PATH}/#{refund_id}") 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /lib/paystack/objects/settlements.rb: -------------------------------------------------------------------------------- 1 | require 'paystack/objects/base.rb' 2 | 3 | class PaystackSettlements < PaystackBaseObject 4 | def list 5 | return PaystackSettlements.list(@paystack) 6 | end 7 | 8 | 9 | def PaystackSettlements.list(paystackObj) 10 | initGetRequest(paystackObj, "#{API::SETTLEMENT_PATH}") 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/paystack/objects/subaccounts.rb: -------------------------------------------------------------------------------- 1 | require 'paystack/objects/base.rb' 2 | 3 | class PaystackSubaccounts < PaystackBaseObject 4 | def create(data={}) 5 | return PaystackSubaccounts.create(@paystack, data) 6 | end 7 | 8 | def get(subaccount_id) 9 | return PaystackSubaccounts.get(@paystack, subaccount_id) 10 | end 11 | 12 | 13 | def update(subaccount_id, data={}) 14 | return PaystackSubaccounts.update(@paystack, subaccount_id, data) 15 | end 16 | 17 | def list(page=1) 18 | return PaystackSubaccounts.list(@paystack, page) 19 | end 20 | 21 | 22 | def PaystackSubaccounts.create(paystackObj, data) 23 | initPostRequest(paystackObj,"#{API::SUBACCOUNT_PATH}", data) 24 | end 25 | 26 | def PaystackSubaccounts.update(paystackObj, subaccount_id, data) 27 | initPutRequest(paystackObj,"#{API::SUBACCOUNT_PATH}/#{subaccount_id}", data) 28 | end 29 | 30 | def PaystackSubaccounts.get(paystackObj, subaccount_id) 31 | initGetRequest(paystackObj, "#{API::SUBACCOUNT_PATH}/#{subaccount_id}") 32 | end 33 | 34 | def PaystackSubaccounts.list(paystackObj, page=1) 35 | initGetRequest(paystackObj, "#{API::SUBACCOUNT_PATH}?page=#{page}") 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /lib/paystack/objects/subscriptions.rb: -------------------------------------------------------------------------------- 1 | require 'paystack/objects/base.rb' 2 | 3 | 4 | class PaystackSubscriptions < PaystackBaseObject 5 | 6 | def create(data={}) 7 | return PaystackSubscriptions.create(@paystack, data) 8 | end 9 | 10 | def get(subscription_id) 11 | return PaystackSubscriptions.get(@paystack, subscription_id) 12 | end 13 | 14 | def disable(data={}) 15 | return PaystackSubscriptions.disable(@paystack, data) 16 | end 17 | 18 | def enable(data={}) 19 | return PaystackSubscriptions.enable(@paystack, data) 20 | end 21 | 22 | 23 | def PaystackSubscriptions.create(paystackObj, data) 24 | initPostRequest(paystackObj, "#{API::SUBSCRIPTION_PATH}", data) 25 | end 26 | 27 | def PaystackSubscriptions.get(paystackObj, subscription_id) 28 | initGetRequest(paystackObj, "#{API::SUBSCRIPTION_PATH}/#{subscription_id}") 29 | end 30 | 31 | def PaystackSubscriptions.enable(paystackObj, data={}) 32 | initPostRequest(paystackObj, "#{API::SUBSCRIPTION_PATH}/enable", data) 33 | end 34 | 35 | def PaystackSubscriptions.disable(paystackObj, data) 36 | initPostRequest(paystackObj, "#{API::SUBSCRIPTION_PATH}/disable", data) 37 | end 38 | 39 | 40 | end -------------------------------------------------------------------------------- /lib/paystack/objects/transactions.rb: -------------------------------------------------------------------------------- 1 | require 'paystack/objects/base.rb' 2 | 3 | class PaystackTransactions < PaystackBaseObject 4 | 5 | def initializeTransaction(args={}) 6 | return PaystackTransactions.initializeTransaction(@paystack, args) 7 | end 8 | 9 | def list(page=1) 10 | return PaystackTransactions.list(@paystack, page) 11 | end 12 | 13 | def get(transaction_id) 14 | return PaystackTransactions.get(@paystack, transaction_id) 15 | end 16 | 17 | def verify transaction_reference 18 | return PaystackTransactions.verify(@paystack, transaction_reference) 19 | end 20 | 21 | def totals page=1 22 | return PaystackTransactions.totals(@paystack, page) 23 | end 24 | 25 | 26 | def chargeAuthorization(authorization_code, email, amount,args = {}) 27 | return PaystackTransactions.chargeAuthorization(@paystack,authorization_code,email, amount, args) 28 | end 29 | 30 | 31 | # => Public Static methods 32 | 33 | 34 | def PaystackTransactions.initializeTransaction(paystackObj, args) 35 | initPostRequest(paystackObj,"#{API::TRANSACTION_PATH}/initialize", args,true) 36 | end 37 | 38 | def PaystackTransactions.list(paystackObj, page=1) 39 | 40 | initGetRequest(paystackObj, "#{API::TRANSACTION_PATH}?page=#{page}") 41 | end 42 | 43 | def PaystackTransactions.get(paystackObj, transaction_id) 44 | initGetRequest(paystackObj, "#{API::TRANSACTION_PATH}/#{transaction_id}") 45 | end 46 | 47 | 48 | def PaystackTransactions.verify(paystackObj, transaction_reference) 49 | initGetRequest(paystackObj, "#{API::TRANSACTION_PATH}/verify/#{transaction_reference}") 50 | end 51 | 52 | def PaystackTransactions.totals(paystackObj, page=1) 53 | initGetRequest(paystackObj, "#{API::TRANSACTION_PATH}/totals?page=#{page}") 54 | end 55 | 56 | def PaystackTransactions.chargeAuthorization(paystackObj,authorization_code,email, amount,args = {}) 57 | hash = {:authorization_code => authorization_code, :amount => amount, :email => email}.merge(args) 58 | initPostRequest(paystackObj,"#{API::TRANSACTION_PATH}/charge_authorization", hash, true) 59 | end 60 | 61 | 62 | 63 | end 64 | -------------------------------------------------------------------------------- /lib/paystack/objects/transfers.rb: -------------------------------------------------------------------------------- 1 | require 'paystack/objects/base.rb' 2 | 3 | class PaystackTransfers < PaystackBaseObject 4 | 5 | def initializeTransfer(args={}) 6 | return PaystackTransfers.initializeTransfer(@paystack, args) 7 | end 8 | 9 | def initializeBulkTransfer(args={}) 10 | return PaystackTransfers.initializeBulkTransfer(@paystack, args) 11 | end 12 | 13 | def list(page=1) 14 | return PaystackTransfers.list(@paystack, page) 15 | end 16 | 17 | def get(transfer_code) 18 | return PaystackTransfers.get(@paystack, transfer_code) 19 | end 20 | 21 | def authorize(data={}) 22 | return PaystackTransfers.authorize(@paystack,data) 23 | end 24 | 25 | def resendOtp(data={}) 26 | return PaystackTransfers.resendOtp(@paystack,data) 27 | end 28 | 29 | def disableOtp 30 | return PaystackTransfers.disableOtp(@paystack) 31 | end 32 | 33 | def confirmDisableOtp(data={}) 34 | return PaystackTransfers.confirmDisableOTP(@paystack,otp) 35 | end 36 | 37 | def enableOtp 38 | return PaystackTransfers.enableOtp(@paystack) 39 | end 40 | 41 | # => Public Static methods 42 | 43 | def PaystackTransfers.initializeTransfer(paystackObj, args) 44 | initPostRequest(paystackObj,"#{API::TRANSFER_PATH}", args,true) 45 | end 46 | 47 | def PaystackTransfers.initializeBulkTransfer(paystackObj, args) 48 | initPostRequest(paystackObj,"#{API::TRANSFER_PATH}/bulk", args,true) 49 | end 50 | 51 | def PaystackTransfers.list(paystackObj, page=1) 52 | initGetRequest(paystackObj, "#{API::TRANSFER_PATH}?page=#{page}") 53 | end 54 | 55 | def PaystackTransfers.get(paystackObj, transfer_code) 56 | initGetRequest(paystackObj, "#{API::TRANSFER_PATH}/#{transfer_code}") 57 | end 58 | 59 | def PaystackTransfers.authorize(paystackObj, data={}) 60 | initPostRequest(paystackObj, "#{API::TRANSFER_PATH}/finalize_transfer/",data) 61 | end 62 | 63 | def PaystackTransfers.resendOtp(paystackObj, data={}) 64 | initPostRequest(paystackObj, "#{API::TRANSFER_PATH}/resend_otp",data) 65 | end 66 | 67 | def PaystackTransfers.disableOtp(paystackObj) 68 | initPostRequest(paystackObj, "#{API::TRANSFER_PATH}/disable_otp") 69 | end 70 | 71 | def PaystackTransfers.confirmDisableOtp(paystackObj, data={}) 72 | initPostRequest(paystackObj, "#{API::TRANSFER_PATH}/disable_otp_finalize",data) 73 | end 74 | 75 | def PaystackTransfers.enableOtp(paystackObj) 76 | initPostRequest(paystackObj, "#{API::TRANSFER_PATH}/enable_otp") 77 | end 78 | 79 | 80 | 81 | 82 | 83 | end 84 | -------------------------------------------------------------------------------- /lib/paystack/utils/utils.rb: -------------------------------------------------------------------------------- 1 | require 'paystack/error.rb' 2 | 3 | module Utils 4 | 5 | def Utils.nullifyString(value) 6 | if value.nil? 7 | return nil 8 | end 9 | 10 | if (value.strip.eql? "") 11 | return nil 12 | end 13 | return value; 14 | end 15 | 16 | def Utils.isWholePositiveNumber(value) 17 | if(value == nil) 18 | return false 19 | end 20 | length = value.length; 21 | 22 | for i in 0..(length-1) 23 | c = value[i] 24 | 25 | if((c =~ /[[:digit:]]/) == nil) 26 | return false 27 | end 28 | end 29 | return true 30 | end 31 | 32 | def Utils.isLuhnValidNumber(number) 33 | sum = 0 34 | length = number.strip.length; 35 | 36 | for i in 0..(length-1) 37 | c = number[length - 1 -i] 38 | 39 | if((c =~ /[[:digit:]]/) == nil) 40 | return false 41 | end 42 | digit = c.to_i 43 | if (i % 2 == 1) 44 | digit *= 2 45 | end 46 | sum += digit > 9 ? digit - 9 : digit 47 | end 48 | 49 | return (sum % 10 == 0) 50 | end 51 | 52 | def Utils.isEmpty(value) 53 | return (value.nil? || value.strip.eql?("")) 54 | end 55 | 56 | def Utils.hasYearPassed(year) 57 | return year < Time.new.year 58 | end 59 | def Utils.hasMonthPassed(year, month) 60 | t = Time.new 61 | return hasYearPassed(year) || year == t.year && month < (t.month) 62 | end 63 | 64 | def Utils.hasCardExpired(year, month) 65 | # Normalize Year value e.g 14 becomes 2014 or 2114 etc. 66 | year_int = year.strip.to_i 67 | if(year_int < 100 && year_int >= 0) 68 | cal_year = Time.new.year.to_s 69 | year_int = ("#{cal_year[0..1]}#{year.strip}").to_i 70 | end 71 | 72 | # Check for expiration 73 | return !hasYearPassed(year_int) && !hasMonthPassed(year_int, month.to_i) 74 | 75 | end 76 | 77 | 78 | 79 | 80 | 81 | def Utils.serverErrorHandler(e) 82 | 83 | if(e.response == nil) 84 | raise e 85 | return 86 | end 87 | error = PaystackServerError.new(e.response); 88 | case e.response.code 89 | when 400 90 | raise error, "HTTP Code 400: A validation or client side error occurred and the request was not fulfilled. " 91 | when 401 92 | raise error, "HTTP Code 401: The request was not authorized. This can be triggered by passing an invalid secret key in the authorization header or the lack of one" 93 | when 404 94 | raise error, "HTTP Code 404: Request could not be fulfilled as the request resource does not exist." 95 | when 500, 501,502,503,504 96 | raise error, "HTTP Code #{e.response.code}: Request could not be fulfilled due to an error on Paystack's end. This shouldn't happen so please report as soon as you encounter any instance of this." 97 | else 98 | raise error, "HTTP Code #{e.response.code}: #{e.response.body}" 99 | 100 | end 101 | 102 | end 103 | 104 | end 105 | -------------------------------------------------------------------------------- /lib/paystack/version.rb: -------------------------------------------------------------------------------- 1 | class Paystack 2 | VERSION = "0.1.10" 3 | end 4 | -------------------------------------------------------------------------------- /paystack.gemspec: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | lib = File.expand_path('../lib', __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | require 'paystack/version' 5 | 6 | Gem::Specification.new do |spec| 7 | spec.name = "paystack" 8 | spec.version = Paystack::VERSION 9 | spec.authors = ["Victor Ikoro"] 10 | spec.email = ["ikoro.victor@gmail.com"] 11 | 12 | spec.summary = %q{PayStack.co gem for Ruby/Rails} 13 | spec.description = %q{Client Library Gem for PayStack.co} 14 | spec.homepage = "https://github.com/IkoroVictor/paystack-ruby" 15 | spec.license = "MIT" 16 | 17 | spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } 18 | spec.bindir = "exe" 19 | spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } 20 | spec.require_paths = ["lib"] 21 | 22 | #Dev dependencies 23 | spec.add_development_dependency "bundler", "~> 2.2" 24 | spec.add_development_dependency "rake", "~> 10.0" 25 | spec.add_development_dependency 'rspec', '~> 3.0' 26 | 27 | #Dependencies 28 | spec.required_ruby_version = '>= 2.0.0' 29 | spec.add_runtime_dependency 'rest-client', '~> 2.0' 30 | 31 | 32 | end 33 | -------------------------------------------------------------------------------- /spec/paystack_balance_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | require 'paystack/objects/balance.rb' 3 | require 'paystack.rb' 4 | 5 | public_test_key = "pk_test_ea7c71f838c766922873f1dd3cc529afe13da1c0" 6 | private_test_key = "sk_test_40e9340686e6187697f8309dbae57c002bb16dd0" 7 | 8 | describe PaystackBalance do 9 | 10 | it "should return paystack account balance" do 11 | paystack = Paystack.new(public_test_key, private_test_key) 12 | balance = PaystackBalance.new(paystack) 13 | expect(balance.nil?).to eq false 14 | hash = balance.get 15 | expect(hash.nil?).to eq false 16 | expect(hash['message']).to eq "Balances retrieved" 17 | end 18 | 19 | end 20 | -------------------------------------------------------------------------------- /spec/paystack_banks_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | require 'paystack/objects/banks.rb' 3 | require 'paystack.rb' 4 | 5 | public_test_key = "pk_test_ea7c71f838c766922873f1dd3cc529afe13da1c0" 6 | private_test_key = "sk_test_40e9340686e6187697f8309dbae57c002bb16dd0" 7 | 8 | describe PaystackBanks do 9 | 10 | it "should return a list of banks" do 11 | paystack = Paystack.new(public_test_key, private_test_key) 12 | banks = PaystackBanks.new(paystack) 13 | expect(banks.nil?).to eq false 14 | list = banks.list(1) 15 | expect(list.nil?).to eq false 16 | end 17 | 18 | end 19 | -------------------------------------------------------------------------------- /spec/paystack_card_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | require 'paystack/objects/card.rb' 3 | 4 | 5 | describe PaystackCard do 6 | it "should be valid" do 7 | card = PaystackCard.new(:name => 'Victor Ikoro', :number => '4123450131001381', :cvc => '883', :expiryMonth => '09', :expiryYear => '24') 8 | expect(card.isValidCard).to eq true 9 | end 10 | 11 | it "should be invalid" do 12 | card = PaystackCard.new(:name => 'Victor Ikoro', :number => '9343450131001381', :cvc => '883', :expiryMonth => '09', :expiryYear => '24') 13 | expect(card.isValidCard).to eq false 14 | end 15 | 16 | it "should be invalid" do 17 | card = PaystackCard.new(:name => 'Victor Ikoro', :number => '4123450131001381', :cvc => '83', :expiryMonth => '09', :expiryYear => '12') 18 | expect(card.isValidCard).to eq false 19 | end 20 | 21 | it "should be invalid" do 22 | card = PaystackCard.new(:name => 'Victor Ikoro', :number => '4123450131001381', :cvc => '83', :expiryMonth => '12', :expiryYear => '18') 23 | expect(card.isValidCard).to eq false 24 | end 25 | 26 | it "should be invalid" do 27 | card = PaystackCard.new(:name => 'Victor Ikoro', :number => '4123450131001381', :cvc => '838', :expiryMonth => '09', :expiryYear => '12') 28 | expect(card.isValidCard).to eq false 29 | end 30 | 31 | 32 | end -------------------------------------------------------------------------------- /spec/paystack_customers_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | require 'paystack/objects/customers.rb' 3 | require 'paystack.rb' 4 | 5 | public_test_key = "pk_test_ea7c71f838c766922873f1dd3cc529afe13da1c0" 6 | private_test_key = "sk_test_40e9340686e6187697f8309dbae57c002bb16dd0" 7 | 8 | describe PaystackCustomers do 9 | it "should return a valid customers object" do 10 | paystack = Paystack.new(public_test_key, private_test_key) 11 | customers = PaystackCustomers.new(paystack) 12 | expect(customers.nil?).to eq false 13 | end 14 | 15 | it "should return a list of customers" do 16 | paystack = Paystack.new(public_test_key, private_test_key) 17 | customers = PaystackCustomers.new(paystack) 18 | expect(customers.nil?).to eq false 19 | list = customers.list(1) 20 | expect(list.nil?).to eq false 21 | end 22 | 23 | it "should return a customer hashset/object" do 24 | paystack = Paystack.new(public_test_key, private_test_key) 25 | customers = PaystackCustomers.new(paystack) 26 | expect(customers.nil?).to eq false 27 | list = customers.list(1) 28 | expect(list.nil?).to eq false 29 | temp = list["data"][0] 30 | puts temp.inspect 31 | hash=customers.get(temp['customer_code']) 32 | expect(hash.nil?).to eq false 33 | expect(hash['data']['customer_code'].nil?).to eq false 34 | end 35 | 36 | it "should successfuly update a customer" do 37 | paystack = Paystack.new(public_test_key, private_test_key) 38 | customers = PaystackCustomers.new(paystack) 39 | expect(customers.nil?).to eq false 40 | list = customers.list(1) 41 | expect(list.nil?).to eq false 42 | temp = list["data"][0] 43 | hash=customers.update(temp['id'], :first_name => "Victor", :last_name => "Ikoro", :phone => "+2347061544884") 44 | expect(hash.nil?).to eq false 45 | expect(hash['data']['id'].nil?).to eq false 46 | end 47 | 48 | it "should successfuly create a customer" do 49 | paystack = Paystack.new(public_test_key, private_test_key) 50 | customers = PaystackCustomers.new(paystack) 51 | expect(customers.nil?).to eq false 52 | temp = Random.new_seed.to_s 53 | hash=customers.create(:first_name => "#{temp[0..6]}-person", :last_name => "Ogbonge", :phone => "+23470#{temp[0..6]}",:email => "#{temp[0..6]}@gmail.com") 54 | puts hash 55 | expect(hash.nil?).to eq false 56 | expect(hash['data']['id'].nil?).to eq false 57 | end 58 | 59 | 60 | end 61 | 62 | -------------------------------------------------------------------------------- /spec/paystack_plans_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | require 'paystack/objects/plans.rb' 3 | require 'paystack.rb' 4 | 5 | public_test_key = "pk_test_ea7c71f838c766922873f1dd3cc529afe13da1c0" 6 | private_test_key = "sk_test_40e9340686e6187697f8309dbae57c002bb16dd0" 7 | 8 | describe PaystackPlans do 9 | it "should return a valid plans object" do 10 | paystack = Paystack.new(public_test_key, private_test_key) 11 | plans = PaystackPlans.new(paystack) 12 | expect(plans.nil?).to eq false 13 | end 14 | 15 | it "should return a list of plans" do 16 | paystack = Paystack.new(public_test_key, private_test_key) 17 | plans = PaystackPlans.new(paystack) 18 | expect(plans.nil?).to eq false 19 | list = plans.list(1) 20 | #puts list 21 | expect(list.nil?).to eq false 22 | end 23 | 24 | it "should return a plan hashset/object" do 25 | paystack = Paystack.new(public_test_key, private_test_key) 26 | plans = PaystackPlans.new(paystack) 27 | expect(plans.nil?).to eq false 28 | list = plans.list(1) 29 | expect(list.nil?).to eq false 30 | temp = list["data"][0] 31 | hash=plans.get(temp['id']) 32 | expect(hash.nil?).to eq false 33 | expect(hash['data']['id'].nil?).to eq false 34 | end 35 | 36 | it "should successfuly update a plan" do 37 | paystack = Paystack.new(public_test_key, private_test_key) 38 | plans = PaystackPlans.new(paystack) 39 | expect(plans.nil?).to eq false 40 | list = plans.list(1) 41 | expect(list.nil?).to eq false 42 | temp = list["data"][0] 43 | hash = plans.update( 44 | temp['id'], 45 | :name => "Test Plan Updated", 46 | :description => "Dev Test Plan Updated", 47 | :amount => 30000, #in KOBO 48 | #:interval => "monthly", 49 | :currency => "NGN" 50 | ) 51 | puts hash 52 | expect(hash.nil?).to eq false 53 | expect(hash['status']).to eq true 54 | end 55 | 56 | it "should successfuly create a plan" do 57 | paystack = Paystack.new(public_test_key, private_test_key) 58 | plans = PaystackPlans.new(paystack) 59 | expect(plans.nil?).to eq false 60 | temp = Random.new_seed.to_s 61 | hash=plans.create( 62 | :name => "#{temp[0..6]} Test Plan", 63 | :description => "Dev Test Plan Updated", 64 | :amount => 30000, #in KOBO 65 | :interval => "monthly", #monthly, yearly, quarterly, weekly etc 66 | :currency => "NGN" 67 | 68 | ) 69 | 70 | expect(hash.nil?).to eq false 71 | expect(hash['data']['id'].nil?).to eq false 72 | end 73 | 74 | 75 | end -------------------------------------------------------------------------------- /spec/paystack_recipients_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | require 'paystack/objects/recipients.rb' 3 | require 'paystack.rb' 4 | 5 | public_test_key = "pk_test_ea7c71f838c766922873f1dd3cc529afe13da1c0" 6 | private_test_key = "sk_test_40e9340686e6187697f8309dbae57c002bb16dd0" 7 | 8 | describe PaystackRecipients do 9 | it "should return a valid recipients object" do 10 | paystack = Paystack.new(public_test_key, private_test_key) 11 | plans = PaystackRecipients.new(paystack) 12 | expect(plans.nil?).to eq false 13 | end 14 | 15 | it "should return a list of recipients" do 16 | paystack = Paystack.new(public_test_key, private_test_key) 17 | plans = PaystackRecipients.new(paystack) 18 | expect(plans.nil?).to eq false 19 | list = plans.list(1) 20 | puts list 21 | expect(list.nil?).to eq false 22 | end 23 | 24 | #Skipping test as it requires nuban account validation and test payment accounts do not work 25 | xit "should successfuly create a recipient" do 26 | paystack = Paystack.new(public_test_key, private_test_key) 27 | recipients = PaystackRecipients.new(paystack) 28 | expect(recipients.nil?).to eq false 29 | temp = "Random.new_seed.to_s" 30 | hash=recipients.create( 31 | :type => "nuban", #Must be nuban 32 | :name => "#{temp[0..2]} Test Plan", 33 | :description => "Dev Test Receipt transfer", 34 | :account_number => "0000000000", #10 digit account number 35 | :bank_code => "011", #First bank 36 | :currency => "NGN", 37 | ) 38 | puts hash 39 | expect(hash.nil?).to eq false 40 | expect(hash['data']['id'].nil?).to eq false 41 | #expect(hash['message']).to eq "Recipient created" 42 | end 43 | 44 | 45 | end -------------------------------------------------------------------------------- /spec/paystack_settlements_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | require 'paystack/objects/settlements.rb' 3 | require 'paystack.rb' 4 | 5 | public_test_key = "pk_test_ea7c71f838c766922873f1dd3cc529afe13da1c0" 6 | private_test_key = "sk_test_40e9340686e6187697f8309dbae57c002bb16dd0" 7 | 8 | describe PaystackSettlements do 9 | 10 | it "should return a list of settlements made" do 11 | paystack = Paystack.new(public_test_key, private_test_key) 12 | settlements = PaystackSettlements.new(paystack) 13 | expect(settlements.nil?).to eq false 14 | list = settlements.list 15 | #puts list 16 | expect(settlements.nil?).to eq false 17 | end 18 | 19 | 20 | 21 | end -------------------------------------------------------------------------------- /spec/paystack_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | require 'paystack.rb' 3 | require 'paystack/objects/card.rb' 4 | 5 | 6 | public_test_key = "pk_test_ea7c71f838c766922873f1dd3cc529afe13da1c0" 7 | private_test_key = "sk_test_40e9340686e6187697f8309dbae57c002bb16dd0" 8 | 9 | describe Paystack do 10 | it "should create a valid object" do 11 | paystack = Paystack.new(public_test_key,private_test_key) 12 | expect(paystack.nil?).to eq false 13 | end 14 | 15 | it "should throw a PaystackBadKeyError" do 16 | begin 17 | paystack = Paystack.new(public_test_key) 18 | rescue => e 19 | expect(e.instance_of? PaystackBadKeyError).to eq true 20 | end 21 | 22 | end 23 | 24 | it "should throw a PaystackBadKeyError" do 25 | begin 26 | paystack = Paystack.new 27 | rescue => e 28 | expect(e.instance_of? PaystackBadKeyError).to eq true 29 | end 30 | 31 | end 32 | it "should throw a PaystackBadKeyError" do 33 | begin 34 | paystack = Paystack.new(nil, private_test_key) 35 | rescue => e 36 | expect(e.instance_of? PaystackBadKeyError).to eq true 37 | end 38 | 39 | end 40 | it "should throw a PaystackBadKeyError" do 41 | begin 42 | paystack = Paystack.new("33444", "444444") 43 | rescue => e 44 | expect(e.instance_of? PaystackBadKeyError).to eq true 45 | end 46 | 47 | end 48 | 49 | end 50 | -------------------------------------------------------------------------------- /spec/paystack_subaccounts_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | require 'paystack/objects/subaccounts.rb' 3 | require 'paystack.rb' 4 | 5 | public_test_key = "pk_test_ea7c71f838c766922873f1dd3cc529afe13da1c0" 6 | private_test_key = "sk_test_40e9340686e6187697f8309dbae57c002bb16dd0" 7 | 8 | describe PaystackSubaccounts do 9 | it "should return a valid subaccounts object" do 10 | paystack = Paystack.new(public_test_key, private_test_key) 11 | subaccounts = PaystackSubaccounts.new(paystack) 12 | expect(subaccounts.nil?).to eq false 13 | end 14 | 15 | it "should return a list of subaccounts" do 16 | paystack = Paystack.new(public_test_key, private_test_key) 17 | subaccounts = PaystackSubaccounts.new(paystack) 18 | expect(subaccounts.nil?).to eq false 19 | list = subaccounts.list(1) 20 | expect(list.nil?).to eq false 21 | end 22 | 23 | it "should return a subaccount hashset/object" do 24 | paystack = Paystack.new(public_test_key, private_test_key) 25 | subaccounts = PaystackSubaccounts.new(paystack) 26 | expect(subaccounts.nil?).to eq false 27 | list = subaccounts.list(1) 28 | expect(list.nil?).to eq false 29 | temp = list["data"][0] 30 | hash=subaccounts.get(temp['id']) 31 | expect(hash.nil?).to eq false 32 | expect(hash['data']['id'].nil?).to eq false 33 | end 34 | 35 | it "should successfuly update a subaccount" do 36 | paystack = Paystack.new(public_test_key, private_test_key) 37 | subaccounts = PaystackSubaccounts.new(paystack) 38 | expect(subaccounts.nil?).to eq false 39 | list = subaccounts.list(1) 40 | expect(list.nil?).to eq false 41 | temp = list["data"][0] 42 | hash=subaccounts.update(temp['id'], :percentage_charge => 2.5, :primary_contact_email => "xxxrr@gmail.com") 43 | expect(hash.nil?).to eq false 44 | expect(hash['data']['id'].nil?).to eq false 45 | end 46 | 47 | it "should successfuly create a subaccount" do 48 | paystack = Paystack.new(public_test_key, private_test_key) 49 | subaccounts = PaystackSubaccounts.new(paystack) 50 | expect(subaccounts.nil?).to eq false 51 | temp = Random.new_seed.to_s 52 | hash=subaccounts.create(:business_name => "#{temp[0..6]}-business", :settlement_bank => "011", :account_number => "0000000000", :percentage_charge => 2.5) 53 | puts hash 54 | expect(hash.nil?).to eq false 55 | expect(hash['data']['id'].nil?).to eq false 56 | end 57 | 58 | 59 | end 60 | -------------------------------------------------------------------------------- /spec/paystack_subscriptions_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | require 'paystack/objects/subscriptions.rb' 3 | require 'paystack.rb' 4 | 5 | 6 | describe PaystackSubscriptions do 7 | 8 | public_test_key = "pk_test_ea7c71f838c766922873f1dd3cc529afe13da1c0" 9 | private_test_key = "sk_test_40e9340686e6187697f8309dbae57c002bb16dd0" 10 | 11 | it "should return a valid subscriptions object" do 12 | paystack = Paystack.new(public_test_key, private_test_key) 13 | subscriptions = PaystackSubscriptions.new(paystack) 14 | expect(subscriptions.nil?).to eq false 15 | end 16 | 17 | it "should return a subscription hashset/object" do 18 | paystack = Paystack.new(public_test_key, private_test_key) 19 | subscriptions = PaystackSubscriptions.new(paystack) 20 | expect(subscriptions.nil?).to eq false 21 | 22 | plans = PaystackPlans.new(paystack) 23 | temp = Random.new_seed.to_s 24 | 25 | plan = plans.create( 26 | :name => "#{temp[0..6]} Test Plan", 27 | :description => "Dev Test Plan Updated", 28 | :amount => 30000, #in KOBO 29 | :interval => "monthly", 30 | :currency => "NGN" 31 | 32 | ) 33 | 34 | subscription = subscriptions.create( 35 | :customer => "lol@gmail.com", 36 | :plan => plan["data"]["plan_code"] 37 | ) 38 | 39 | 40 | hash = subscriptions.get(subscription['data']['id']) 41 | 42 | puts hash 43 | 44 | expect(hash.nil?).to eq false 45 | expect(hash['data']['id'].nil?).to eq false 46 | end 47 | 48 | 49 | it "should successfuly create a subscription" do 50 | paystack = Paystack.new(public_test_key, private_test_key) 51 | subscriptions = PaystackSubscriptions.new(paystack) 52 | expect(subscriptions.nil?).to eq false 53 | 54 | plans = PaystackPlans.new(paystack) 55 | temp = Random.new_seed.to_s 56 | 57 | plan= plans.create( 58 | :name => "#{temp[0..6]} Test Plan", 59 | :description => "Dev Test Plan Updated", 60 | :amount => 30000, #in KOBO 61 | :interval => "monthly", 62 | :currency => "NGN" 63 | 64 | ) 65 | 66 | hash = subscriptions.create( 67 | :customer => "lol@gmail.com", 68 | :plan => plan["data"]["plan_code"] 69 | ) 70 | 71 | puts hash 72 | 73 | expect(hash.nil?).to eq false 74 | expect(hash['data']['id'].nil?).to eq false 75 | end 76 | 77 | it "should successfully disable a subscription" do 78 | paystack = Paystack.new(public_test_key, private_test_key) 79 | subscriptions = PaystackSubscriptions.new(paystack) 80 | plans = PaystackPlans.new(paystack) 81 | 82 | 83 | temp = Random.new_seed.to_s 84 | plan = plans.create( 85 | :name => "#{temp[0..6]} Test Plan", 86 | :description => "Dev Test Plan Updated", 87 | :amount => 30000, #in KOBO 88 | :interval => "monthly", #monthly, yearly, quarterly, weekly etc 89 | :currency => "NGN" 90 | 91 | ) 92 | 93 | subscription = subscriptions.create( 94 | :customer => "lol@gmail.com", 95 | :plan => plan["data"]["plan_code"] 96 | ) 97 | 98 | hash = subscriptions.disable( 99 | :code => subscription["data"]["subscription_code"], 100 | :token => subscription["data"]["email_token"] 101 | ) 102 | 103 | expect(hash.nil?).to eq false 104 | expect(hash['status']).to eq true 105 | end 106 | 107 | #Skipping test as cancelled subscriptions cannot be re-enabled 108 | xit "should successfully enable a subscription" do 109 | paystack = Paystack.new(public_test_key, private_test_key) 110 | subscriptions = PaystackSubscriptions.new(paystack) 111 | plans = PaystackPlans.new(paystack) 112 | 113 | 114 | temp = Random.new_seed.to_s 115 | plan = plans.create( 116 | :name => "#{temp[0..6]} Test Plan", 117 | :description => "Dev Test Plan Updated", 118 | :amount => 30000, #in KOBO 119 | :interval => "monthly", #monthly, yearly, quarterly, weekly etc 120 | :currency => "NGN" 121 | 122 | ) 123 | 124 | subscription = subscriptions.create( 125 | :customer => "lol@gmail.com", 126 | :plan => plan["data"]["plan_code"] 127 | ) 128 | 129 | subscriptions.disable( 130 | :code => subscription["data"]["subscription_code"], 131 | :token => subscription["data"]["email_token"] 132 | ) 133 | 134 | hash = subscriptions.enable( 135 | :code => subscription["data"]["subscription_code"], 136 | :token => subscription["data"]["email_token"] 137 | ) 138 | 139 | expect(hash.nil?).to eq false 140 | expect(hash['status']).to eq true 141 | end 142 | 143 | 144 | end 145 | -------------------------------------------------------------------------------- /spec/paystack_transactions_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | require 'paystack/objects/transactions.rb' 3 | require 'paystack.rb' 4 | 5 | public_test_key = "pk_test_ea7c71f838c766922873f1dd3cc529afe13da1c0" 6 | private_test_key = "sk_test_40e9340686e6187697f8309dbae57c002bb16dd0" 7 | 8 | describe PaystackTransactions do 9 | it "should return a valid transaction object" do 10 | paystack = Paystack.new(public_test_key, private_test_key) 11 | transactions = PaystackTransactions.new(paystack) 12 | expect(transactions.nil?).to eq false 13 | end 14 | 15 | it "should return a list of transactions" do 16 | paystack = Paystack.new(public_test_key, private_test_key) 17 | transactions = PaystackTransactions.new(paystack) 18 | expect(transactions.nil?).to eq false 19 | list = transactions.list(1) 20 | #puts list 21 | expect(list.nil?).to eq false 22 | end 23 | 24 | it "should return a valid transaction hashset" do 25 | paystack = Paystack.new(public_test_key, private_test_key) 26 | transactions = PaystackTransactions.new(paystack) 27 | expect(transactions.nil?).to eq false 28 | list = transactions.list(1) 29 | expect(list.nil?).to eq false 30 | temp = list["data"][0] 31 | #puts temp 32 | hash=transactions.get(temp['id']) 33 | #puts hash 34 | expect(hash.nil?).to eq false 35 | expect(hash['data']['id'].nil?).to eq false 36 | 37 | end 38 | 39 | it "should initialize a transaction and expect an authorization url" do 40 | reference = Random.new_seed.to_s[0..9] 41 | paystack = Paystack.new(public_test_key, private_test_key) 42 | transactions = PaystackTransactions.new(paystack) 43 | expect(transactions.nil?).to eq false 44 | temp = transactions.initializeTransaction( 45 | :reference => reference, 46 | :email => "xxxrr@gmail.com", 47 | :amount => 30000, 48 | ) 49 | puts temp 50 | expect(temp.nil?).to eq false 51 | expect(temp['data']['authorization_url'].nil?).to eq false 52 | 53 | end 54 | 55 | it "should successfully verify a transaction" do 56 | paystack = Paystack.new(public_test_key, private_test_key) 57 | transaction = PaystackTransactions.new(paystack) 58 | expect(transaction.nil?).to eq false 59 | list = transaction.list(1) 60 | expect(list.nil?).to eq false 61 | temp = list["data"][0] 62 | #puts temp 63 | hash=transaction.verify(temp['reference']) 64 | #puts hash 65 | expect(hash.nil?).to eq false 66 | #expect(hash['data']['id'].nil?).to eq false 67 | end 68 | 69 | it "should return a list of transaction totals" do 70 | paystack = Paystack.new(public_test_key, private_test_key) 71 | transaction = PaystackTransactions.new(paystack) 72 | expect(transaction.nil?).to eq false 73 | totals = transaction.totals(1) 74 | #puts totals 75 | expect(totals.nil?).to eq false 76 | end 77 | 78 | 79 | it "should recharge an authorization for returning customers.\n Test is bound to fail for invaild reference " do 80 | 81 | #TODO: Manually get valid reference for this test 82 | # i.e Initailize transaction with your reference, redirect to authorization url, fill card details, 83 | # if transaction successful, replace your reference with the value below 84 | reference = "c2v7vxelg2" 85 | 86 | paystack = Paystack.new(public_test_key, private_test_key) 87 | transactions = PaystackTransactions.new(paystack) 88 | expect(transactions.nil?).to eq false 89 | 90 | v = transactions.verify(reference) 91 | expect(v.nil?).to eq false 92 | #puts v 93 | auth = v['data']['authorization']['authorization_code'] 94 | email = v['data']['customer']['email'] 95 | result = transactions.chargeAuthorization(auth, email , 2000, :reference => Random.new_seed.to_s ) 96 | #puts result 97 | expect(result.nil?).to eq false 98 | 99 | end 100 | 101 | end -------------------------------------------------------------------------------- /spec/paystack_transfers_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | require 'paystack/objects/transfers.rb' 3 | require 'paystack.rb' 4 | 5 | public_test_key = "pk_test_ea7c71f838c766922873f1dd3cc529afe13da1c0" 6 | private_test_key = "sk_test_40e9340686e6187697f8309dbae57c002bb16dd0" 7 | 8 | describe PaystackTransfers do 9 | it "should return a valid transfer object" do 10 | paystack = Paystack.new(public_test_key, private_test_key) 11 | transfers = PaystackTransfers.new(paystack) 12 | expect(transfers.nil?).to eq false 13 | end 14 | 15 | it "should initialize a transfer and expect a transfer code" do 16 | recipient_code = "RCP_213xswghvej0gzv" #manually generated recipient code to avoid errors 17 | paystack = Paystack.new(public_test_key, private_test_key) 18 | transfers = PaystackTransfers.new(paystack) 19 | expect(transfers.nil?).to eq false 20 | temp = transfers.initializeTransfer( 21 | :source => "balance", 22 | :reason => "Keep the change", 23 | :amount => 30000, # amount in kobo 24 | :recipient => recipient_code, 25 | ) 26 | #puts temp 27 | expect(temp.nil?).to eq false 28 | expect(temp['data']['transfer_code'].nil?).to eq false 29 | 30 | end 31 | 32 | it "should return a list of transfers" do 33 | paystack = Paystack.new(public_test_key, private_test_key) 34 | transfers = PaystackTransfers.new(paystack) 35 | expect(transfers.nil?).to eq false 36 | list = transfers.list(1) 37 | #puts list 38 | expect(list.nil?).to eq false 39 | end 40 | 41 | it "should return a valid transfer hashset" do 42 | paystack = Paystack.new(public_test_key, private_test_key) 43 | transfers = PaystackTransfers.new(paystack) 44 | expect(transfers.nil?).to eq false 45 | list = transfers.list(1) 46 | expect(list.nil?).to eq false 47 | temp = list["data"][0] 48 | #puts temp["transfer_code"] 49 | hash = transfers.get(temp["transfer_code"]) 50 | expect(hash.nil?).to eq false 51 | expect(hash['data']['transfer_code']).to eq temp["transfer_code"] 52 | 53 | 54 | end 55 | 56 | it "should resend OTP to authorize a transfer" do 57 | paystack = Paystack.new(public_test_key, private_test_key) 58 | transfers = PaystackTransfers.new(paystack) 59 | expect(transfers.nil?).to eq false 60 | list = transfers.list(1) 61 | expect(list.nil?).to eq false 62 | temp = list["data"][0] 63 | hash = transfers.resendOtp(temp["transfer_code"]) 64 | expect(hash.nil?).to eq false 65 | end 66 | 67 | it "should disable OTP for transfers" do 68 | paystack = Paystack.new(public_test_key, private_test_key) 69 | transfer = PaystackTransfers.new(paystack) 70 | expect(transfer.nil?).to eq false 71 | hash = transfer.disableOtp 72 | #puts totals 73 | expect(hash.nil?).to eq false 74 | end 75 | 76 | it "should enable OTP for transfers" do 77 | paystack = Paystack.new(public_test_key, private_test_key) 78 | transfer = PaystackTransfers.new(paystack) 79 | expect(transfer.nil?).to eq false 80 | hash = transfer.enableOtp 81 | #puts totals 82 | expect(hash.nil?).to eq false 83 | end 84 | 85 | 86 | 87 | end -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # This file was generated by the `rspec --init` command. Conventionally, all 2 | # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. 3 | # The generated `.rspec` file contains `--require spec_helper` which will cause 4 | # this file to always be loaded, without a need to explicitly require it in any 5 | # files. 6 | # 7 | # Given that it is always loaded, you are encouraged to keep this file as 8 | # light-weight as possible. Requiring heavyweight dependencies from this file 9 | # will add to the boot time of your test suite on EVERY test run, even for an 10 | # individual file that may not need all of that loaded. Instead, consider making 11 | # a separate helper file that requires the additional dependencies and performs 12 | # the additional setup, and require it from the spec files that actually need 13 | # it. 14 | # 15 | # The `.rspec` file also contains a few flags that are not defaults but that 16 | # users commonly want. 17 | # 18 | # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration 19 | 20 | 21 | RSpec.configure do |config| 22 | # rspec-expectations config goes here. You can use an alternate 23 | # assertion/expectation library such as wrong or the stdlib/minitest 24 | # assertions if you prefer. 25 | config.expect_with :rspec do |expectations| 26 | # This option will default to `true` in RSpec 4. It makes the `description` 27 | # and `failure_message` of custom matchers include text for helper methods 28 | # defined using `chain`, e.g.: 29 | # be_bigger_than(2).and_smaller_than(4).description 30 | # # => "be bigger than 2 and smaller than 4" 31 | # ...rather than: 32 | # # => "be bigger than 2" 33 | expectations.include_chain_clauses_in_custom_matcher_descriptions = true 34 | end 35 | 36 | # rspec-mocks config goes here. You can use an alternate test double 37 | # library (such as bogus or mocha) by changing the `mock_with` option here. 38 | config.mock_with :rspec do |mocks| 39 | # Prevents you from mocking or stubbing a method that does not exist on 40 | # a real object. This is generally recommended, and will default to 41 | # `true` in RSpec 4. 42 | mocks.verify_partial_doubles = true 43 | end 44 | 45 | # The settings below are suggested to provide a good initial experience 46 | # with RSpec, but feel free to customize to your heart's content. 47 | =begin 48 | # These two settings work together to allow you to limit a spec run 49 | # to individual examples or groups you care about by tagging them with 50 | # `:focus` metadata. When nothing is tagged with `:focus`, all examples 51 | # get run. 52 | config.filter_run :focus 53 | config.run_all_when_everything_filtered = true 54 | 55 | # Allows RSpec to persist some state between runs in order to support 56 | # the `--only-failures` and `--next-failure` CLI options. We recommend 57 | # you configure your source control system to ignore this file. 58 | config.example_status_persistence_file_path = "spec/examples.txt" 59 | 60 | # Limits the available syntax to the non-monkey patched syntax that is 61 | # recommended. For more details, see: 62 | # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/ 63 | # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ 64 | # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode 65 | config.disable_monkey_patching! 66 | 67 | # This setting enables warnings. It's recommended, but in some cases may 68 | # be too noisy due to issues in dependencies. 69 | config.warnings = true 70 | 71 | # Many RSpec users commonly either run the entire suite or an individual 72 | # file, and it's useful to allow more verbose output when running an 73 | # individual spec file. 74 | if config.files_to_run.one? 75 | # Use the documentation formatter for detailed output, 76 | # unless a formatter has already been configured 77 | # (e.g. via a command-line flag). 78 | config.default_formatter = 'doc' 79 | end 80 | 81 | # Print the 10 slowest examples and example groups at the 82 | # end of the spec run, to help surface which specs are running 83 | # particularly slow. 84 | config.profile_examples = 10 85 | 86 | # Run specs in random order to surface order dependencies. If you find an 87 | # order dependency and want to debug it, you can fix the order by providing 88 | # the seed, which is printed after each run. 89 | # --seed 1234 90 | config.order = :random 91 | 92 | # Seed global randomization in this process using the `--seed` CLI option. 93 | # Setting this allows you to use `--seed` to deterministically reproduce 94 | # test failures related to randomization by passing the same `--seed` value 95 | # as the one that triggered the failure. 96 | Kernel.srand config.seed 97 | =end 98 | end 99 | --------------------------------------------------------------------------------